package forge import ( "errors" "fmt" "net/url" "regexp" "runtime" "strings" ) var ( amd64Re = regexp.MustCompile(`amd64|x86_64|64`) linuxRe = regexp.MustCompile(`linux|linux64`) windowsRe = regexp.MustCompile(`windows|win64`) ) type Release struct { Name string Assets []Asset } type Asset struct { Name string DownloadURL string } type Forger interface { Name() string Latest() (Release, error) } func splitURI(uri string) (string, []string, error) { if !strings.HasPrefix(uri, "http") { uri = "https://" + uri } u, err := url.ParseRequestURI(uri) if err != nil { return "", nil, fmt.Errorf("could not parse URI: %w", err) } u.Scheme = "https" paths := strings.FieldsFunc(u.Path, func(r rune) bool { return r == '/' }) u.Path = "" return u.String(), paths, nil } func Latest(f Forger) (Asset, error) { var asset Asset var re *regexp.Regexp switch runtime.GOOS { case "linux": re = linuxRe case "windows": re = windowsRe default: return asset, fmt.Errorf("%q is not a supported OS", runtime.GOOS) } release, err := f.Latest() if err != nil { return asset, fmt.Errorf("could not get latest release: %w", err) } for _, a := range release.Assets { if amd64Re.MatchString(a.Name) && re.MatchString(a.Name) { fmt.Printf("found %q\n", a.Name) asset = a } } if asset.Name == "" { return asset, errors.New("no release found for this OS") } return asset, nil }