diff --git a/config.go b/config.go index 7ab42a9..1b42581 100644 --- a/config.go +++ b/config.go @@ -40,6 +40,7 @@ type ConfigRepository struct { UpgradeOnly bool `toml:"upgrade_only"` Verify string `toml:"verify_sha256"` DisableSSL bool `toml:"disable_ssl"` + ListOnly bool `toml:"list_only"` } type Config struct { @@ -247,6 +248,7 @@ func SetGlobalOptionsFromConfig(config *Config, parser *flags.Parser, opts *Flag opts.Verify = update("", cli.Verify) opts.Remove = update(false, cli.Remove) opts.DisableSSL = update(false, cli.DisableSSL) + opts.ListOnly = update(false, cli.ListOnly) return nil } @@ -271,6 +273,7 @@ func SetProjectOptionsFromConfig(config *Config, parser *flags.Parser, opts *Fla opts.UpgradeOnly = update(repo.UpgradeOnly, cli.UpgradeOnly) opts.Verify = update(repo.Verify, cli.Verify) opts.DisableSSL = update(repo.DisableSSL, cli.DisableSSL) + opts.ListOnly = update(repo.ListOnly, cli.ListOnly) break } } diff --git a/eget.go b/eget.go index bd46219..9dadf78 100644 --- a/eget.go +++ b/eget.go @@ -423,6 +423,16 @@ func main() { fatal(err) } + if opts.ListOnly { + releases, err := finder.List() + if err != nil { + fatal(err) + } + r := strings.Join(releases, "\n* ") + fmt.Fprintf(output, "available releases in %s:\n* %v\n", target, r) + os.Exit(0) + } + detector, err := getDetector(&opts) if err != nil { fatal(err) diff --git a/find.go b/find.go index cffb9e1..49d0f08 100644 --- a/find.go +++ b/find.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "sort" "strings" "time" ) @@ -13,6 +14,7 @@ import ( // A Finder returns a list of URLs making up a project's assets. type Finder interface { Find() ([]string, error) + List() ([]string, error) } // A GithubRelease matches the Assets portion of Github's release API json. @@ -176,25 +178,47 @@ func (f *GithubAssetFinder) FindMatch() ([]string, error) { return nil, fmt.Errorf("no matching tag for '%s'", tag) } -// finds the latest pre-release and returns the tag -func (f *GithubAssetFinder) getLatestTag() (string, error) { +func (f *GithubAssetFinder) List() ([]string, error) { + releases, err := f.getAllReleases() + if err != nil { + return nil, fmt.Errorf("list releases: %w", err) + } + var tags []string + sort.Slice(releases, func(i, j int) bool { + return releases[i].CreatedAt.After(releases[j].CreatedAt) + }) + for _, r := range releases { + tags = append(tags, r.Tag) + } + return tags, nil +} + +func (f *GithubAssetFinder) getAllReleases() ([]GithubRelease, error) { url := fmt.Sprintf("https://api.github.com/repos/%s/releases", f.Repo) resp, err := Get(url) if err != nil { - return "", fmt.Errorf("pre-release finder: %w", err) + return nil, fmt.Errorf("release finder: %w", err) } var releases []GithubRelease body, err := io.ReadAll(resp.Body) if err != nil { - return "", fmt.Errorf("pre-release finder: %w", err) + return nil, fmt.Errorf("release finder: %w", err) } err = json.Unmarshal(body, &releases) if err != nil { - return "", fmt.Errorf("pre-release finder: %w", err) + return nil, fmt.Errorf("release finder: %w", err) } + return releases, nil +} +// finds the latest pre-release and returns the tag +func (f *GithubAssetFinder) getLatestTag() (string, error) { + releases, err := f.getAllReleases() + if err != nil { + return "", fmt.Errorf("pre-release finders: %w", err) + } if len(releases) <= 0 { return "", fmt.Errorf("no releases found") } @@ -210,6 +234,9 @@ type DirectAssetFinder struct { func (f *DirectAssetFinder) Find() ([]string, error) { return []string{f.URL}, nil } +func (f *DirectAssetFinder) List() ([]string, error) { + return f.Find() +} type GithubSourceFinder struct { Tool string @@ -220,3 +247,6 @@ type GithubSourceFinder struct { func (f *GithubSourceFinder) Find() ([]string, error) { return []string{fmt.Sprintf("https://github.com/%s/tarball/%s/%s.tar.gz", f.Repo, f.Tag, f.Tool)}, nil } +func (f *GithubSourceFinder) List() ([]string, error) { + return f.Find() +} diff --git a/flags.go b/flags.go index 2fa6596..749b702 100644 --- a/flags.go +++ b/flags.go @@ -16,6 +16,7 @@ type Flags struct { Verify string Remove bool DisableSSL bool + ListOnly bool } type CliFlags struct { @@ -38,4 +39,5 @@ type CliFlags struct { Help bool `short:"h" long:"help" description:"show this help message"` DownloadAll bool `short:"D" long:"download-all" description:"download all projects defined in the config file"` DisableSSL *bool `short:"k" long:"disable-ssl" description:"disable SSL verification for download requests"` + ListOnly *bool `short:"l" long:"list-only" description:"only list available releases, don't download any"` }