pinning script exts
This commit is contained in:
parent
d7277e396c
commit
db53df102c
3 changed files with 78 additions and 7 deletions
|
|
@ -116,18 +116,28 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
cs := io.ColorScheme()
|
||||
if err := m.Install(repo, pinFlag); err != nil {
|
||||
if errors.Is(err, releaseNotFoundErr) {
|
||||
return fmt.Errorf("%s Could not find a release of %s for %s",
|
||||
cs.FailureIcon(), args[0], cs.Cyan(pinFlag))
|
||||
} else if errors.Is(err, commitNotFoundErr) {
|
||||
return fmt.Errorf("%s %s does not exist in %s",
|
||||
cs.FailureIcon(), cs.Cyan(pinFlag), args[0])
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if io.IsStdoutTTY() {
|
||||
cs := io.ColorScheme()
|
||||
fmt.Fprintf(io.Out, "%s Installed extension %s\n", cs.SuccessIcon(), args[0])
|
||||
if pinFlag != "" {
|
||||
fmt.Fprintf(io.Out, "%s Pinned extension at %s\n", cs.SuccessIcon(), cs.Cyan(pinFlag))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&pinFlag, "pin", "", "pin extension to a release tag or commit sha")
|
||||
cmd.Flags().StringVar(&pinFlag, "pin", "", "pin extension to a release tag or commit ref")
|
||||
return cmd
|
||||
}(),
|
||||
func() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package extension
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -80,6 +81,9 @@ func downloadAsset(httpClient *http.Client, asset releaseAsset, destPath string)
|
|||
return err
|
||||
}
|
||||
|
||||
var releaseNotFoundErr = errors.New("release not found")
|
||||
var commitNotFoundErr = errors.New("commit not found")
|
||||
|
||||
// fetchLatestRelease finds the latest published release for a repository.
|
||||
func fetchLatestRelease(httpClient *http.Client, baseRepo ghrepo.Interface) (*release, error) {
|
||||
path := fmt.Sprintf("repos/%s/%s/releases/latest", baseRepo.RepoOwner(), baseRepo.RepoName())
|
||||
|
|
@ -113,7 +117,7 @@ func fetchLatestRelease(httpClient *http.Client, baseRepo ghrepo.Interface) (*re
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
// fetchRelease finds release by tag name for a repository
|
||||
// fetchReleaseFromTag 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)
|
||||
|
|
@ -129,6 +133,9 @@ func fetchReleaseFromTag(httpClient *http.Client, baseRepo ghrepo.Interface, tag
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode == 404 {
|
||||
return nil, releaseNotFoundErr
|
||||
}
|
||||
if resp.StatusCode > 299 {
|
||||
return nil, api.HandleHTTPError(resp)
|
||||
}
|
||||
|
|
@ -146,3 +153,34 @@ func fetchReleaseFromTag(httpClient *http.Client, baseRepo ghrepo.Interface, tag
|
|||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// fetchCommitSHA finds full commit SHA from a target ref in a repo
|
||||
func fetchCommitSHA(httpClient *http.Client, baseRepo ghrepo.Interface, targetRef string) (string, error) {
|
||||
path := fmt.Sprintf("repos/%s/%s/commits/%s", baseRepo.RepoOwner(), baseRepo.RepoName(), targetRef)
|
||||
url := ghinstance.RESTPrefix(baseRepo.RepoHost()) + path
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/vnd.github.VERSION.sha")
|
||||
resp, err := httpClient.Do(req)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.StatusCode == 422 {
|
||||
return "", commitNotFoundErr
|
||||
}
|
||||
if resp.StatusCode > 299 {
|
||||
return "", api.HandleHTTPError(resp)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -320,6 +321,7 @@ type binManifest struct {
|
|||
Path string
|
||||
}
|
||||
|
||||
// Install an extension from repo, and pin to commitish if provided
|
||||
func (m *Manager) Install(repo ghrepo.Interface, targetCommitish string) error {
|
||||
isBin, err := isBinExtension(m.client, repo)
|
||||
if err != nil {
|
||||
|
|
@ -337,11 +339,11 @@ func (m *Manager) Install(repo ghrepo.Interface, targetCommitish string) error {
|
|||
return errors.New("extension is not installable: missing executable")
|
||||
}
|
||||
|
||||
protocol, _ := m.config.GetOrDefault(repo.RepoHost(), "git_protocol")
|
||||
return m.installGit(ghrepo.FormatRemoteURL(repo, protocol), m.io.Out, m.io.ErrOut)
|
||||
return m.installGit(repo, targetCommitish, m.io.Out, m.io.ErrOut)
|
||||
}
|
||||
|
||||
func (m *Manager) installBin(repo ghrepo.Interface, targetCommitish string) error {
|
||||
log.Println("Installing binary extension")
|
||||
var r *release
|
||||
var err error
|
||||
if targetCommitish == "" {
|
||||
|
|
@ -413,19 +415,40 @@ func (m *Manager) installBin(repo ghrepo.Interface, targetCommitish string) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) installGit(cloneURL string, stdout, stderr io.Writer) error {
|
||||
func (m *Manager) installGit(repo ghrepo.Interface, targetCommitish string, stdout, stderr io.Writer) error {
|
||||
protocol, _ := m.config.GetOrDefault(repo.RepoHost(), "git_protocol")
|
||||
cloneURL := ghrepo.FormatRemoteURL(repo, protocol)
|
||||
|
||||
exe, err := m.lookPath("git")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var commitSHA string
|
||||
if targetCommitish != "" {
|
||||
commitSHA, err = fetchCommitSHA(m.client, repo, targetCommitish)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
name := strings.TrimSuffix(path.Base(cloneURL), ".git")
|
||||
targetDir := filepath.Join(m.installDir(), name)
|
||||
|
||||
externalCmd := m.newCommand(exe, "clone", cloneURL, targetDir)
|
||||
externalCmd.Stdout = stdout
|
||||
externalCmd.Stderr = stderr
|
||||
return externalCmd.Run()
|
||||
if err := externalCmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if commitSHA == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
checkoutCmd := m.newCommand(exe, "-C", targetDir, "checkout", commitSHA)
|
||||
checkoutCmd.Stdout = stdout
|
||||
checkoutCmd.Stderr = stderr
|
||||
return checkoutCmd.Run()
|
||||
}
|
||||
|
||||
var localExtensionUpgradeError = errors.New("local extensions can not be upgraded")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue