mirror of
				https://github.com/packwiz/packwiz.git
				synced 2025-10-31 02:34:31 +01:00 
			
		
		
		
	github: standardize language + fix api requests
language: - funcs, vars, log messages, etc. api requests: - make all requests use the makeGet() function - include packwiz user agent Signed-off-by: unilock <unilock@fennet.rentals>
This commit is contained in:
		| @@ -3,9 +3,7 @@ package github | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" |  | ||||||
|  |  | ||||||
| 	"github.com/mitchellh/mapstructure" | 	"github.com/mitchellh/mapstructure" | ||||||
| 	"github.com/packwiz/packwiz/cmd" | 	"github.com/packwiz/packwiz/cmd" | ||||||
| @@ -16,7 +14,7 @@ import ( | |||||||
| var githubCmd = &cobra.Command{ | var githubCmd = &cobra.Command{ | ||||||
| 	Use:     "github", | 	Use:     "github", | ||||||
| 	Aliases: []string{"gh"}, | 	Aliases: []string{"gh"}, | ||||||
| 	Short:   "Manage github-based mods", | 	Short:   "Manage projects released on GitHub", | ||||||
| } | } | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| @@ -27,7 +25,7 @@ func init() { | |||||||
| func fetchRepo(slug string) (Repo, error) { | func fetchRepo(slug string) (Repo, error) { | ||||||
| 	var repo Repo | 	var repo Repo | ||||||
|  |  | ||||||
| 	res, err := http.Get(githubApiUrl + "repos/" + slug) | 	res, err := ghDefaultClient.getRepo(slug) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return repo, err | 		return repo, err | ||||||
| 	} | 	} | ||||||
| @@ -45,7 +43,7 @@ func fetchRepo(slug string) (Repo, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if repo.FullName == "" { | 	if repo.FullName == "" { | ||||||
| 		return repo, errors.New("invalid json while fetching mod: " + slug) | 		return repo, errors.New("invalid json while fetching project: " + slug) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return repo, nil | 	return repo, nil | ||||||
| @@ -53,14 +51,12 @@ func fetchRepo(slug string) (Repo, error) { | |||||||
|  |  | ||||||
| type Repo struct { | type Repo struct { | ||||||
| 	ID       int    `json:"id"` | 	ID       int    `json:"id"` | ||||||
| 	NodeID   string `json:"node_id"`   // TODO: use this with GH API, instead of name (to acct. for repo renames?) + store in mod.pw.toml |  | ||||||
| 	Name     string `json:"name"`      // "hello_world" | 	Name     string `json:"name"`      // "hello_world" | ||||||
| 	FullName string `json:"full_name"` // "owner/hello_world" | 	FullName string `json:"full_name"` // "owner/hello_world" | ||||||
| } | } | ||||||
|  |  | ||||||
| type Release struct { | type Release struct { | ||||||
| 	URL             string  `json:"url"` | 	URL             string  `json:"url"` | ||||||
| 	NodeID          string  `json:"node_id"` // TODO: probably also use this with GH API |  | ||||||
| 	TagName         string  `json:"tag_name"` | 	TagName         string  `json:"tag_name"` | ||||||
| 	TargetCommitish string  `json:"target_commitish"` // The branch of the release | 	TargetCommitish string  `json:"target_commitish"` // The branch of the release | ||||||
| 	Name            string  `json:"name"` | 	Name            string  `json:"name"` | ||||||
| @@ -87,13 +83,10 @@ func (u Asset) getSha256() (string, error) { | |||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp, err := http.Get(u.BrowserDownloadURL) | 	resp, err := ghDefaultClient.makeGet(u.BrowserDownloadURL) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	if resp.StatusCode != 200 { |  | ||||||
| 		return "", fmt.Errorf("invalid response status: %v", resp.StatusCode) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	defer resp.Body.Close() | 	defer resp.Body.Close() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ var GithubRegex = regexp.MustCompile(`^https?://(?:www\.)?github\.com/([^/]+/[^/ | |||||||
|  |  | ||||||
| // installCmd represents the install command | // installCmd represents the install command | ||||||
| var installCmd = &cobra.Command{ | var installCmd = &cobra.Command{ | ||||||
| 	Use:     "add [URL]", | 	Use:     "add [URL|slug]", | ||||||
| 	Short:   "Add a project from a GitHub repository URL", | 	Short:   "Add a project from a GitHub repository URL or slug", | ||||||
| 	Aliases: []string{"install", "get"}, | 	Aliases: []string{"install", "get"}, | ||||||
| 	Args:    cobra.ArbitraryArgs, | 	Args:    cobra.ArbitraryArgs, | ||||||
| 	Run: func(cmd *cobra.Command, args []string) { | 	Run: func(cmd *cobra.Command, args []string) { | ||||||
| @@ -50,7 +50,7 @@ var installCmd = &cobra.Command{ | |||||||
| 		repo, err := fetchRepo(slug) | 		repo, err := fetchRepo(slug) | ||||||
|  |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			fmt.Println("Failed to get the mod ", err) | 			fmt.Printf("Failed to add project: %s\n", err) | ||||||
| 			os.Exit(1) | 			os.Exit(1) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -62,25 +62,20 @@ func init() { | |||||||
| 	githubCmd.AddCommand(installCmd) | 	githubCmd.AddCommand(installCmd) | ||||||
| } | } | ||||||
|  |  | ||||||
| const githubApiUrl = "https://api.github.com/" |  | ||||||
|  |  | ||||||
| func installMod(repo Repo, pack core.Pack) error { | func installMod(repo Repo, pack core.Pack) error { | ||||||
| 	latestVersion, err := getLatestVersion(repo.FullName, "") | 	latestRelease, err := getLatestRelease(repo.FullName, "") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("failed to get latest version: %v", err) | 		return fmt.Errorf("failed to get latest release: %v", err) | ||||||
| 	} |  | ||||||
| 	if latestVersion.URL == "" { |  | ||||||
| 		return errors.New("mod is not available for this Minecraft version (use the acceptable-game-versions option to accept more) or mod loader") |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return installVersion(repo, latestVersion, pack) | 	return installRelease(repo, latestRelease, pack) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getLatestVersion(slug string, branch string) (Release, error) { | func getLatestRelease(slug string, branch string) (Release, error) { | ||||||
| 	var modReleases []Release | 	var releases []Release | ||||||
| 	var release Release | 	var release Release | ||||||
|  |  | ||||||
| 	resp, err := ghDefaultClient.makeGet(slug) | 	resp, err := ghDefaultClient.getReleases(slug) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return release, err | 		return release, err | ||||||
| 	} | 	} | ||||||
| @@ -90,20 +85,20 @@ func getLatestVersion(slug string, branch string) (Release, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return release, err | 		return release, err | ||||||
| 	} | 	} | ||||||
| 	err = json.Unmarshal(body, &modReleases) | 	err = json.Unmarshal(body, &releases) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return release, err | 		return release, err | ||||||
| 	} | 	} | ||||||
| 	for _, r := range modReleases { | 	for _, r := range releases { | ||||||
| 		if r.TargetCommitish == branch { | 		if r.TargetCommitish == branch { | ||||||
| 			return r, nil | 			return r, nil | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return modReleases[0], nil | 	return releases[0], nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func installVersion(repo Repo, release Release, pack core.Pack) error { | func installRelease(repo Repo, release Release, pack core.Pack) error { | ||||||
| 	var files = release.Assets | 	var files = release.Assets | ||||||
|  |  | ||||||
| 	if len(files) == 0 { | 	if len(files) == 0 { | ||||||
| @@ -157,7 +152,7 @@ func installVersion(repo Repo, release Release, pack core.Pack) error { | |||||||
| 	if folder == "" { | 	if folder == "" { | ||||||
| 		folder = "mods" | 		folder = "mods" | ||||||
| 	} | 	} | ||||||
| 	path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, repo.Name+core.MetaExtension)) | 	path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, core.SlugifyName(repo.Name)+core.MetaExtension)) | ||||||
|  |  | ||||||
| 	// If the file already exists, this will overwrite it!!! | 	// If the file already exists, this will overwrite it!!! | ||||||
| 	// TODO: Should this be improved? | 	// TODO: Should this be improved? | ||||||
| @@ -168,21 +163,5 @@ func installVersion(repo Repo, release Release, pack core.Pack) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	err = index.RefreshFileWithHash(path, format, hash, true) | 	return index.RefreshFileWithHash(path, format, hash, true) | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	err = index.Write() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	err = pack.UpdateIndexHash() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	err = pack.Write() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ package github | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"github.com/packwiz/packwiz/core" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ghApiServer = "api.github.com" | const ghApiServer = "api.github.com" | ||||||
| @@ -13,21 +15,40 @@ type ghApiClient struct { | |||||||
|  |  | ||||||
| var ghDefaultClient = ghApiClient{&http.Client{}} | var ghDefaultClient = ghApiClient{&http.Client{}} | ||||||
|  |  | ||||||
| func (c *ghApiClient) makeGet(slug string) (*http.Response, error) { | func (c *ghApiClient) makeGet(url string) (*http.Response, error) { | ||||||
| 	req, err := http.NewRequest("GET", "https://" + ghApiServer + "/repos/" + slug + "/releases", nil) | 	req, err := http.NewRequest("GET", url, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	req.Header.Set("User-Agent", core.UserAgent) | ||||||
| 	req.Header.Set("Accept", "application/vnd.github+json") | 	req.Header.Set("Accept", "application/vnd.github+json") | ||||||
|  |  | ||||||
| 	resp, err := c.httpClient.Do(req) | 	resp, err := c.httpClient.Do(req) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if resp.StatusCode != 200 { | 	if resp.StatusCode != 200 { | ||||||
| 		return nil, fmt.Errorf("invalid response status: %v", resp.Status) | 		return nil, fmt.Errorf("invalid response status: %v", resp.Status) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *ghApiClient) getRepo(slug string) (*http.Response, error) { | ||||||
|  | 	resp, err := c.makeGet("https://" + ghApiServer + "/repos/" + slug) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return resp, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *ghApiClient) getReleases(slug string) (*http.Response, error) { | ||||||
|  | 	resp, err := c.getRepo(slug + "/releases") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return resp, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ func (u ghUpdater) ParseUpdate(updateUnparsed map[string]interface{}) (interface | |||||||
| } | } | ||||||
|  |  | ||||||
| type cachedStateStore struct { | type cachedStateStore struct { | ||||||
| 	ModID   string | 	Slug    string | ||||||
| 	Version Release | 	Release Release | ||||||
| } | } | ||||||
|  |  | ||||||
| func (u ghUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateCheck, error) { | func (u ghUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateCheck, error) { | ||||||
| @@ -40,28 +40,33 @@ func (u ghUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateC | |||||||
|  |  | ||||||
| 		data := rawData.(ghUpdateData) | 		data := rawData.(ghUpdateData) | ||||||
|  |  | ||||||
| 		newVersion, err := getLatestVersion(data.Slug, data.Branch) | 		newRelease, err := getLatestRelease(data.Slug, data.Branch) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			results[i] = core.UpdateCheck{Error: fmt.Errorf("failed to get latest version: %v", err)} | 			results[i] = core.UpdateCheck{Error: fmt.Errorf("failed to get latest release: %v", err)} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if newVersion.TagName == data.Tag { // The latest version from the site is the same as the installed one | 		if newRelease.TagName == data.Tag { // The latest release is the same as the installed one | ||||||
| 			results[i] = core.UpdateCheck{UpdateAvailable: false} | 			results[i] = core.UpdateCheck{UpdateAvailable: false} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if len(newVersion.Assets) == 0 { | 		if len(newRelease.Assets) == 0 { | ||||||
| 			results[i] = core.UpdateCheck{Error: errors.New("new version doesn't have any assets")} | 			results[i] = core.UpdateCheck{Error: errors.New("new release doesn't have any assets")} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		newFilename := newVersion.Assets[0].Name | 		newFile := newRelease.Assets[0] | ||||||
|  | 		for _, v := range newRelease.Assets { | ||||||
|  | 			if strings.HasSuffix(v.Name, ".jar") { | ||||||
|  | 				newFile = v | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		results[i] = core.UpdateCheck{ | 		results[i] = core.UpdateCheck{ | ||||||
| 			UpdateAvailable: true, | 			UpdateAvailable: true, | ||||||
| 			UpdateString:    mod.FileName + " -> " + newFilename, | 			UpdateString:    mod.FileName + " -> " + newFile.Name, | ||||||
| 			CachedState:     cachedStateStore{data.Slug, newVersion}, | 			CachedState:     cachedStateStore{data.Slug, newRelease}, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -71,10 +76,11 @@ func (u ghUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateC | |||||||
| func (u ghUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error { | func (u ghUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error { | ||||||
| 	for i, mod := range mods { | 	for i, mod := range mods { | ||||||
| 		modState := cachedState[i].(cachedStateStore) | 		modState := cachedState[i].(cachedStateStore) | ||||||
| 		var version = modState.Version | 		var release = modState.Release | ||||||
|  |  | ||||||
| 		var file = version.Assets[0] | 		// yes, this is duplicated - i guess we should just cache asset + tag instead of entire release...? | ||||||
| 		for _, v := range version.Assets { | 		var file = release.Assets[0] | ||||||
|  | 		for _, v := range release.Assets { | ||||||
| 			if strings.HasSuffix(v.Name, ".jar") { | 			if strings.HasSuffix(v.Name, ".jar") { | ||||||
| 				file = v | 				file = v | ||||||
| 			} | 			} | ||||||
| @@ -91,7 +97,7 @@ func (u ghUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error { | |||||||
| 			HashFormat: "sha256", | 			HashFormat: "sha256", | ||||||
| 			Hash:       hash, | 			Hash:       hash, | ||||||
| 		} | 		} | ||||||
| 		mod.Update["github"]["tag"] = version.TagName | 		mod.Update["github"]["tag"] = release.TagName | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user