diff --git a/config.go b/config.go index 90e409c5..16c503f3 100644 --- a/config.go +++ b/config.go @@ -9,6 +9,7 @@ import ( "github.com/BurntSushi/toml" "github.com/jessevdk/go-flags" + "github.com/zyedidia/eget/home" ) @@ -40,6 +41,8 @@ type ConfigRepository struct { UpgradeOnly bool `toml:"upgrade_only"` Verify string `toml:"verify_sha256"` DisableSSL bool `toml:"disable_ssl"` + Host string `toml:"host"` + HostType string `toml:"host_type"` } type Config struct { @@ -54,7 +57,6 @@ type Config struct { func LoadConfigurationFile(path string) (Config, error) { var conf Config meta, err := toml.DecodeFile(path, &conf) - if err != nil { return conf, err } @@ -251,6 +253,8 @@ 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.Host = update("", cli.Host) + opts.HostType = update("", cli.HostType) return nil } @@ -275,6 +279,8 @@ 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.Host = update(repo.Host, cli.Host) + opts.HostType = update(repo.HostType, cli.HostType) break } } diff --git a/dl.go b/dl.go index 0cbb1004..38cea9b3 100644 --- a/dl.go +++ b/dl.go @@ -12,6 +12,7 @@ import ( "time" pb "github.com/schollz/progressbar/v3" + "github.com/zyedidia/eget/home" ) @@ -58,7 +59,6 @@ func SetAuthHeader(req *http.Request) *http.Request { func Get(url string) (*http.Response, error) { req, err := http.NewRequest("GET", url, nil) - if err != nil { return nil, err } diff --git a/eget.go b/eget.go index bd46219b..7bdba4ed 100644 --- a/eget.go +++ b/eget.go @@ -117,6 +117,16 @@ func getFinder(project string, opts *Flags) (finder Finder, tool string) { tag = fmt.Sprintf("tags/%s", opts.Tag) } + host := "github.com" + if opts.Host != "" { + host = opts.Host + } + + hostType := Github + if opts.HostType != "" { + hostType = opts.HostType + } + var mint time.Time if opts.UpgradeOnly { parts := strings.Split(project, "/") @@ -124,11 +134,13 @@ func getFinder(project string, opts *Flags) (finder Finder, tool string) { mint = bintime(last, opts.Output) } - finder = &GithubAssetFinder{ + finder = &AssetFinder{ Repo: repo, Tag: tag, Prerelease: opts.Prerelease, MinTime: mint, + Host: host, + HostType: hostType, } } } @@ -300,12 +312,11 @@ func downloadConfigRepositories(config *Config) error { errorList := []error{} binary, err := os.Executable() - if err != nil { binary = os.Args[0] } - for name, _ := range config.Repositories { + for name := range config.Repositories { cmd := exec.Command(binary, name) cmd.Stderr = os.Stderr @@ -331,7 +342,6 @@ func main() { flagparser := flags.NewParser(&cli, flags.PassDoubleDash|flags.PrintErrors) flagparser.Usage = "[OPTIONS] TARGET" args, err := flagparser.Parse() - if err != nil { os.Exit(1) } @@ -378,7 +388,6 @@ func main() { if cli.DownloadAll { err = downloadConfigRepositories(config) - if err != nil { fatal(err) } diff --git a/find.go b/find.go index cffb9e1d..53f69600 100644 --- a/find.go +++ b/find.go @@ -37,6 +37,11 @@ type errResponse struct { Doc string `json:"documentation_url"` } +const ( + Github = "github" + Gitea = "gitea" +) + func (ge *GithubError) Error() string { var msg errResponse json.Unmarshal(ge.Body, &msg) @@ -47,18 +52,20 @@ func (ge *GithubError) Error() string { return fmt.Sprintf("%s (URL: %s)", ge.Status, ge.Url) } -// A GithubAssetFinder finds assets for the given Repo at the given tag. Tags +// A AssetFinder finds assets for the given Repo at the given tag. Tags // must be given as 'tag/'. Use 'latest' to get the latest release. -type GithubAssetFinder struct { +type AssetFinder struct { Repo string Tag string Prerelease bool + HostType string + Host string MinTime time.Time // release must be after MinTime to be found } var ErrNoUpgrade = errors.New("requested release is not more recent than current version") -func (f *GithubAssetFinder) Find() ([]string, error) { +func (f *AssetFinder) Find() ([]string, error) { if f.Prerelease && f.Tag == "latest" { tag, err := f.getLatestTag() if err != nil { @@ -68,7 +75,7 @@ func (f *GithubAssetFinder) Find() ([]string, error) { } // query github's API for this repo/tag pair. - url := fmt.Sprintf("https://api.github.com/repos/%s/releases/%s", f.Repo, f.Tag) + url := fmt.Sprintf("%s/%s", f.getReleasesUrl(), f.Tag) resp, err := Get(url) if err != nil { return nil, err @@ -117,11 +124,12 @@ func (f *GithubAssetFinder) Find() ([]string, error) { return assets, nil } -func (f *GithubAssetFinder) FindMatch() ([]string, error) { +func (f *AssetFinder) FindMatch() ([]string, error) { tag := f.Tag[len("tags/"):] + url := f.getReleasesUrl() for page := 1; ; page++ { - url := fmt.Sprintf("https://api.github.com/repos/%s/releases?page=%d", f.Repo, page) + url := fmt.Sprintf("%s?page=%d", url, page) resp, err := Get(url) if err != nil { return nil, err @@ -176,9 +184,20 @@ func (f *GithubAssetFinder) FindMatch() ([]string, error) { return nil, fmt.Errorf("no matching tag for '%s'", tag) } +func (f *AssetFinder) getReleasesUrl() string { + switch f.HostType { + case Github: + return fmt.Sprintf("https://api.%s/repos/%s/releases", f.Host, f.Repo) + case Gitea: + return fmt.Sprintf("https://%s/api/v1/repos/%s/releases", f.Host, f.Repo) + default: + return "" + } +} + // finds the latest pre-release and returns the tag -func (f *GithubAssetFinder) getLatestTag() (string, error) { - url := fmt.Sprintf("https://api.github.com/repos/%s/releases", f.Repo) +func (f *AssetFinder) getLatestTag() (string, error) { + url := f.getReleasesUrl() resp, err := Get(url) if err != nil { return "", fmt.Errorf("pre-release finder: %w", err) @@ -212,11 +231,12 @@ func (f *DirectAssetFinder) Find() ([]string, error) { } type GithubSourceFinder struct { + Host string Tool string Repo string Tag string } 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 + return []string{fmt.Sprintf("https://%s/%s/tarball/%s/%s.tar.gz", f.Host, f.Repo, f.Tag, f.Tool)}, nil } diff --git a/flags.go b/flags.go index 2fa6596d..08e779ed 100644 --- a/flags.go +++ b/flags.go @@ -16,26 +16,30 @@ type Flags struct { Verify string Remove bool DisableSSL bool + Host string + HostType string } type CliFlags struct { - Tag *string `short:"t" long:"tag" description:"tagged release to use instead of latest"` - Prerelease *bool `long:"pre-release" description:"include pre-releases when fetching the latest version"` - Source *bool `long:"source" description:"download the source code for the target repo instead of a release"` - Output *string `long:"to" description:"move to given location after extracting"` - System *string `short:"s" long:"system" description:"target system to download for (use \"all\" for all choices)"` - ExtractFile *string `short:"f" long:"file" description:"glob to select files for extraction"` - All *bool `long:"all" description:"extract all candidate files"` - Quiet *bool `short:"q" long:"quiet" description:"only print essential output"` + Tag *string `short:"t" long:"tag" description:"tagged release to use instead of latest"` + Prerelease *bool ` long:"pre-release" description:"include pre-releases when fetching the latest version"` + Source *bool ` long:"source" description:"download the source code for the target repo instead of a release"` + Output *string ` long:"to" description:"move to given location after extracting"` + System *string `short:"s" long:"system" description:"target system to download for (use 'all' for all choices)"` + ExtractFile *string `short:"f" long:"file" description:"glob to select files for extraction"` + All *bool ` long:"all" description:"extract all candidate files"` + Quiet *bool `short:"q" long:"quiet" description:"only print essential output"` DLOnly *bool `short:"d" long:"download-only" description:"stop after downloading the asset (no extraction)"` - UpgradeOnly *bool `long:"upgrade-only" description:"only download if release is more recent than current version"` - Asset *[]string `short:"a" long:"asset" description:"download a specific asset containing the given string; can be specified multiple times for additional filtering; use ^ for anti-match"` - Hash *bool `long:"sha256" description:"show the SHA-256 hash of the downloaded asset"` - Verify *string `long:"verify-sha256" description:"verify the downloaded asset checksum against the one provided"` - Rate bool `long:"rate" description:"show GitHub API rate limiting information"` - Remove *bool `short:"r" long:"remove" description:"remove the given file from $EGET_BIN or the current directory"` - Version bool `short:"v" long:"version" description:"show version information"` - 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"` + UpgradeOnly *bool ` long:"upgrade-only" description:"only download if release is more recent than current version"` + Asset *[]string `short:"a" long:"asset" description:"download a specific asset containing the given string; can be specified multiple times for additional filtering; use ^ for anti-match"` + Hash *bool ` long:"sha256" description:"show the SHA-256 hash of the downloaded asset"` + Verify *string ` long:"verify-sha256" description:"verify the downloaded asset checksum against the one provided"` + Rate bool ` long:"rate" description:"show GitHub API rate limiting information"` + Remove *bool `short:"r" long:"remove" description:"remove the given file from $EGET_BIN or the current directory"` + Version bool `short:"v" long:"version" description:"show version information"` + 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"` + Host *string `short:"H" long:"host" description:"host to download from"` + HostType *string `short:"T" long:"host-type" description:"type of host to download from"` }