Resolve commit SHA1 from GitHub archive ETag header

This commit is contained in:
Benoit Gagnon 2019-07-30 22:50:39 -04:00
parent 134b21a473
commit 5e742d5339

View file

@ -19,6 +19,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -27,6 +28,7 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"github.com/fatih/color" "github.com/fatih/color"
@ -43,24 +45,40 @@ func NewGitPackage(source *spec.GitSource) Interface {
} }
} }
func DownloadFile(filepath string, url string) error { func downloadGitHubArchive(filepath string, url string) (string, error) {
// Get the data // Get the data
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return err return "", err
} }
color.Cyan("GET %s %d", url, resp.StatusCode)
// GitHub conveniently uses the commit SHA1 at the ETag
// signature for the archive. This is needed when doing `jb update`
// to resolve a ref (ie. "master") to a commit SHA1 for the lock file
etagValue := resp.Header.Get(http.CanonicalHeaderKey("ETag"))
commitShaPattern, _ := regexp.Compile("^\"([0-9a-f]{40})\"$")
m := commitShaPattern.FindStringSubmatch(etagValue)
if len(m) < 2 {
return "", errors.New(fmt.Sprintf("unexpected etag format: %s", etagValue))
}
commitSha := m[1]
defer resp.Body.Close() defer resp.Body.Close()
// Create the file // Create the file
out, err := os.Create(filepath) out, err := os.Create(filepath)
if err != nil { if err != nil {
return err return "", err
} }
defer out.Close() defer out.Close()
// Write the body to file // Write the body to file
_, err = io.Copy(out, resp.Body) _, err = io.Copy(out, resp.Body)
return err if err != nil {
return "", err
}
return commitSha, nil
} }
func gzipUntar(dst string, r io.Reader, subDir string) error { func gzipUntar(dst string, r io.Reader, subDir string) error {
@ -135,17 +153,15 @@ func (p *GitPackage) Install(ctx context.Context, dir, version string) (lockVers
if strings.HasPrefix(p.Source.Remote, "https://github.com/") { if strings.HasPrefix(p.Source.Remote, "https://github.com/") {
archiveUrl := fmt.Sprintf("%s/archive/%s.tar.gz", p.Source.Remote, version) archiveUrl := fmt.Sprintf("%s/archive/%s.tar.gz", p.Source.Remote, version)
archiveFilepath := fmt.Sprintf("%s.tar.gz", dir) archiveFilepath := fmt.Sprintf("%s.tar.gz", dir)
err := DownloadFile(archiveFilepath, archiveUrl)
defer os.Remove(archiveFilepath)
commitSha, err := downloadGitHubArchive(archiveFilepath, archiveUrl)
if err != nil { if err != nil {
return "", err return "", err
} }
color.Cyan("GET %s OK", archiveUrl)
r, err := os.Open(archiveFilepath) r, err := os.Open(archiveFilepath)
err = gzipUntar(dir, r, p.Source.Subdir) err = gzipUntar(dir, r, p.Source.Subdir)
return commitSha, nil
// TODO resolve git refs using GitHub API
commitHash := version
return commitHash, nil
} }
cmd := exec.CommandContext(ctx, "git", "init") cmd := exec.CommandContext(ctx, "git", "init")