pinning binary exts
This commit is contained in:
parent
eaa64df801
commit
fe5eca1dd5
5 changed files with 90 additions and 40 deletions
|
|
@ -70,10 +70,12 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
return t.Render()
|
||||
},
|
||||
},
|
||||
&cobra.Command{
|
||||
Use: "install <repository>",
|
||||
Short: "Install a gh extension from a repository",
|
||||
Long: heredoc.Doc(`
|
||||
func() *cobra.Command {
|
||||
var pinFlag string
|
||||
cmd := &cobra.Command{
|
||||
Use: "install <repository>",
|
||||
Short: "Install a gh extension from a repository",
|
||||
Long: heredoc.Doc(`
|
||||
Install a GitHub repository locally as a GitHub CLI extension.
|
||||
|
||||
The repository argument can be specified in "owner/repo" format as well as a full URL.
|
||||
|
|
@ -84,41 +86,44 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
|
||||
See the list of available extensions at <https://github.com/topics/gh-extension>
|
||||
`),
|
||||
Example: heredoc.Doc(`
|
||||
Example: heredoc.Doc(`
|
||||
$ gh extension install owner/gh-extension
|
||||
$ gh extension install https://git.example.com/owner/gh-extension
|
||||
$ gh extension install .
|
||||
`),
|
||||
Args: cmdutil.MinimumArgs(1, "must specify a repository to install from"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if args[0] == "." {
|
||||
wd, err := os.Getwd()
|
||||
Args: cmdutil.MinimumArgs(1, "must specify a repository to install from"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if args[0] == "." {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.InstallLocal(wd)
|
||||
}
|
||||
|
||||
repo, err := ghrepo.FromFullName(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.InstallLocal(wd)
|
||||
}
|
||||
|
||||
repo, err := ghrepo.FromFullName(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkValidExtension(cmd.Root(), m, repo.RepoName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkValidExtension(cmd.Root(), m, repo.RepoName()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.Install(repo, pinFlag); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.Install(repo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if io.IsStdoutTTY() {
|
||||
cs := io.ColorScheme()
|
||||
fmt.Fprintf(io.Out, "%s Installed extension %s\n", cs.SuccessIcon(), args[0])
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
if io.IsStdoutTTY() {
|
||||
cs := io.ColorScheme()
|
||||
fmt.Fprintf(io.Out, "%s Installed extension %s\n", cs.SuccessIcon(), args[0])
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&pinFlag, "pin", "", "pin extension to a release tag or commit sha")
|
||||
return cmd
|
||||
}(),
|
||||
func() *cobra.Command {
|
||||
var flagAll bool
|
||||
var flagForce bool
|
||||
|
|
|
|||
|
|
@ -112,3 +112,37 @@ func fetchLatestRelease(httpClient *http.Client, baseRepo ghrepo.Interface) (*re
|
|||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// fetchRelease finds release by tag name for a repository
|
||||
func fetchReleaseFromTag(httpClient *http.Client, baseRepo ghrepo.Interface, tagName string) (*release, error) {
|
||||
fullRepoName := fmt.Sprintf("%s/%s", baseRepo.RepoOwner(), baseRepo.RepoName())
|
||||
path := fmt.Sprintf("repos/%s/releases/tags/%s", fullRepoName, tagName)
|
||||
url := ghinstance.RESTPrefix(baseRepo.RepoHost()) + path
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
return nil, api.HandleHTTPError(resp)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var r release
|
||||
err = json.Unmarshal(b, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,13 +320,13 @@ type binManifest struct {
|
|||
Path string
|
||||
}
|
||||
|
||||
func (m *Manager) Install(repo ghrepo.Interface) error {
|
||||
func (m *Manager) Install(repo ghrepo.Interface, targetCommitish string) error {
|
||||
isBin, err := isBinExtension(m.client, repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not check for binary extension: %w", err)
|
||||
}
|
||||
if isBin {
|
||||
return m.installBin(repo)
|
||||
return m.installBin(repo, targetCommitish)
|
||||
}
|
||||
|
||||
hs, err := hasScript(m.client, repo)
|
||||
|
|
@ -341,9 +341,14 @@ func (m *Manager) Install(repo ghrepo.Interface) error {
|
|||
return m.installGit(ghrepo.FormatRemoteURL(repo, protocol), m.io.Out, m.io.ErrOut)
|
||||
}
|
||||
|
||||
func (m *Manager) installBin(repo ghrepo.Interface) error {
|
||||
func (m *Manager) installBin(repo ghrepo.Interface, targetCommitish string) error {
|
||||
var r *release
|
||||
r, err := fetchLatestRelease(m.client, repo)
|
||||
var err error
|
||||
if targetCommitish == "" {
|
||||
r, err = fetchLatestRelease(m.client, repo)
|
||||
} else {
|
||||
r, err = fetchReleaseFromTag(m.client, repo, targetCommitish)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -498,7 +503,7 @@ func (m *Manager) upgradeExtension(ext Extension, force bool) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to migrate to new precompiled extension format: %w", err)
|
||||
}
|
||||
return m.installBin(repo)
|
||||
return m.installBin(repo, "")
|
||||
}
|
||||
err = m.upgradeGitExtension(ext, force)
|
||||
}
|
||||
|
|
@ -525,7 +530,7 @@ func (m *Manager) upgradeBinExtension(ext Extension) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to parse URL %s: %w", ext.url, err)
|
||||
}
|
||||
return m.installBin(repo)
|
||||
return m.installBin(repo, "")
|
||||
}
|
||||
|
||||
func (m *Manager) Remove(name string) error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue