Skip to content

Commit

Permalink
First implementation to fetch the PKGBUILD for ARM
Browse files Browse the repository at this point in the history
  • Loading branch information
Necoro committed Oct 3, 2023
1 parent eaf5e69 commit d3a5b68
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 1 deletion.
150 changes: 150 additions & 0 deletions pkg/provider/arm/arm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package arm

import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strings"

"github.com/Necoro/arch-log/pkg/entries"
"github.com/Necoro/arch-log/pkg/log"
"github.com/Necoro/arch-log/pkg/provider"
"github.com/Necoro/arch-log/pkg/provider/arch"
"github.com/Necoro/arch-log/pkg/provider/aur"
)

func checkAvailability(pkg string) (string, error) {
const URL = "https://archlinuxarm.org/data/packages/list"

data := url.Values{}
data.Set("search[value]", pkg)
data.Set("start", "0")
data.Set("length", "1")

body := strings.NewReader(data.Encode())

req, err := http.NewRequest(http.MethodPost, URL, body)
if err != nil {
return "", err
}

// required to make the request work
req.Header.Set("X-Requested-With", "XMLHttpRequest")
req.Header.Set("Referer", "https://archlinuxarm.org/packages")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

resp, err := provider.Request(req)
if err != nil {
return "", err
}
defer resp.Close()

log.Debugf("Fetching from Arch ARM (%s) successful.", URL)

return analyzeARMData(resp)
}

type armData struct {
Data [][]string
}

func analyzeARMData(resp io.ReadCloser) (string, error) {
var data armData

d := json.NewDecoder(resp)
if err := d.Decode(&data); err != nil {
return "", err
}

log.Debugf("Received ARM data: %+v", data)

for _, d := range data.Data {
if d[5] == "1" { // exact match
return d[1], nil
}
}

return "", entries.ErrNotFound
}

func determineBasePkg(pkg, repo string) (string, error) {
bi, err := arch.DetermineBaseInfo(pkg, repo)
if err == nil {
return bi, nil
} else if !errors.Is(err, entries.ErrNotFound) {
return "", err
}

bi, err = aur.DetermineBasePkg(pkg)
if err == nil {
return bi, nil
} else if !errors.Is(err, entries.ErrNotFound) {
return "", err
}

log.Debugf("Package '%s' neither found on Arch nor AUR, assuming base = pkg", pkg)
return pkg, nil
}

func setupFetch(pkg, repo string) (string, string, error) {
if repo != "" {
return "", "", errors.New("repo is not supported by Arch ARM")
}

armRepo, err := checkAvailability(pkg)
if err != nil {
return "", "", err
}

basePkg, err := determineBasePkg(pkg, armRepo)
if err != nil {
return "", "", err
}

if basePkg != pkg {
log.Printf("Mapped pkg '%s' to pkgbase '%s'", pkg, basePkg)
}
return basePkg, armRepo, nil
}

func buildGHUrl(detail string) string {
return "https://api.github.com/repos/archlinuxarm/PKGBUILDs/" + detail
}

func buildPkgBuildRequest(pkg, repo string) (*http.Request, error) {
detail := fmt.Sprintf("contents/%s/%s/PKGBUILD", repo, pkg)
url := buildGHUrl(detail)

req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}

// request raw data
req.Header.Set("Accept", "application/vnd.github.raw")

return req, nil
}

func GetPkgBuild(pkg, repo string) (io.ReadCloser, error) {
basePkg, repo, err := setupFetch(pkg, repo)
if err != nil {
return nil, err
}

req, err := buildPkgBuildRequest(basePkg, repo)
if err != nil {
return nil, err
}
body, err := provider.Request(req)
if err != nil {
return nil, err
}

log.Debugf("Fetching from Arch ARM (%s) successful.", req.URL)

return body, nil
}
3 changes: 2 additions & 1 deletion pkgbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/Necoro/arch-log/pkg/entries"
"github.com/Necoro/arch-log/pkg/log"
"github.com/Necoro/arch-log/pkg/provider/arch"
"github.com/Necoro/arch-log/pkg/provider/arm"
"github.com/Necoro/arch-log/pkg/provider/aur"
)

Expand All @@ -30,7 +31,7 @@ func handleResult(what string, pkg string, repo string, f func(string, string) (

func fetchPkgBuild(pkg string) error {
if options.arm || options.armOnly {
if done, err := handleResult("Arch ARM", pkg, options.repo, arch.GetPkgBuild); err != nil {
if done, err := handleResult("Arch ARM", pkg, options.repo, arm.GetPkgBuild); err != nil {
return err
} else if !done && options.armOnly {
return notFoundError(pkg)
Expand Down

0 comments on commit d3a5b68

Please sign in to comment.