mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-24 11:25:40 +00:00
Merge pull request #2627 from ijc/linuxkit-pkg-no-git
Improve `linuxkit pkg` handling of git
This commit is contained in:
commit
fc8e393feb
@ -70,8 +70,8 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
|||||||
return fmt.Errorf("Unknown arch %q", arch)
|
return fmt.Errorf("Unknown arch %q", arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bo.release == "" {
|
if p.git != nil && bo.release == "" {
|
||||||
r, err := gitCommitTag("HEAD")
|
r, err := p.git.commitTag("HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -97,11 +97,11 @@ func (p Pkg) Build(bos ...BuildOpt) error {
|
|||||||
|
|
||||||
var args []string
|
var args []string
|
||||||
|
|
||||||
if p.gitRepo != "" {
|
if p.git != nil && p.gitRepo != "" {
|
||||||
args = append(args, "--label", "org.opencontainers.image.source="+p.gitRepo)
|
args = append(args, "--label", "org.opencontainers.image.source="+p.gitRepo)
|
||||||
}
|
}
|
||||||
if !p.dirty {
|
if p.git != nil && !p.dirty {
|
||||||
commit, err := gitCommitHash("HEAD")
|
commit, err := p.git.commitHash("HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ package pkglib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -19,9 +20,32 @@ func init() {
|
|||||||
treeHashRe = regexp.MustCompile("^[0-7]{6} [^ ]+ ([0-9a-f]{40})\t.+\n$")
|
treeHashRe = regexp.MustCompile("^[0-7]{6} [^ ]+ ([0-9a-f]{40})\t.+\n$")
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCommandStdout(args ...string) (string, error) {
|
type git struct {
|
||||||
cmd := exec.Command("git", args...)
|
dir string
|
||||||
cmd.Stderr = os.Stderr
|
}
|
||||||
|
|
||||||
|
// Returns git==nil and no error if the path is not within a git repository
|
||||||
|
func newGit(dir string) (*git, error) {
|
||||||
|
g := &git{dir}
|
||||||
|
|
||||||
|
// Check if dir really is within a git directory
|
||||||
|
ok, err := g.isWorkTree(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g git) mkCmd(args ...string) *exec.Cmd {
|
||||||
|
return exec.Command("git", append([]string{"-C", g.dir}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g git) commandStdout(stderr io.Writer, args ...string) (string, error) {
|
||||||
|
cmd := g.mkCmd(args...)
|
||||||
|
cmd.Stderr = stderr
|
||||||
|
|
||||||
if debugGitCommands {
|
if debugGitCommands {
|
||||||
fmt.Fprintf(os.Stderr, "+ %v\n", cmd.Args)
|
fmt.Fprintf(os.Stderr, "+ %v\n", cmd.Args)
|
||||||
@ -33,8 +57,8 @@ func gitCommandStdout(args ...string) (string, error) {
|
|||||||
return string(out), nil
|
return string(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCommand(args ...string) error {
|
func (g git) command(args ...string) error {
|
||||||
cmd := exec.Command("git", args...)
|
cmd := g.mkCmd(args...)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
if debugGitCommands {
|
if debugGitCommands {
|
||||||
@ -43,8 +67,27 @@ func gitCommand(args ...string) error {
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitTreeHash(pkg, commit string) (string, error) {
|
func (g git) isWorkTree(pkg string) (bool, error) {
|
||||||
out, err := gitCommandStdout("ls-tree", "--full-tree", commit, "--", pkg)
|
tf, err := g.commandStdout(nil, "rev-parse", "--is-inside-work-tree")
|
||||||
|
if err != nil {
|
||||||
|
// If we executed git ok but it errored then that's because this isn't a git repo
|
||||||
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tf = strings.TrimSpace(tf)
|
||||||
|
|
||||||
|
if tf == "true" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, fmt.Errorf("unexpected output from git rev-parse --is-inside-work-tree: %s", tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g git) treeHash(pkg, commit string) (string, error) {
|
||||||
|
out, err := g.commandStdout(os.Stderr, "ls-tree", "--full-tree", commit, "--", pkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -57,8 +100,8 @@ func gitTreeHash(pkg, commit string) (string, error) {
|
|||||||
return matches[1], nil
|
return matches[1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCommitHash(commit string) (string, error) {
|
func (g git) commitHash(commit string) (string, error) {
|
||||||
out, err := gitCommandStdout("rev-parse", commit)
|
out, err := g.commandStdout(os.Stderr, "rev-parse", commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -66,8 +109,8 @@ func gitCommitHash(commit string) (string, error) {
|
|||||||
return strings.TrimSpace(out), nil
|
return strings.TrimSpace(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCommitTag(commit string) (string, error) {
|
func (g git) commitTag(commit string) (string, error) {
|
||||||
out, err := gitCommandStdout("tag", "-l", "--points-at", commit)
|
out, err := g.commandStdout(os.Stderr, "tag", "-l", "--points-at", commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -75,7 +118,7 @@ func gitCommitTag(commit string) (string, error) {
|
|||||||
return strings.TrimSpace(out), nil
|
return strings.TrimSpace(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitIsDirty(pkg, commit string) (bool, error) {
|
func (g git) isDirty(pkg, commit string) (bool, error) {
|
||||||
// If it isn't HEAD it can't be dirty
|
// If it isn't HEAD it can't be dirty
|
||||||
if commit != "HEAD" {
|
if commit != "HEAD" {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -86,11 +129,11 @@ func gitIsDirty(pkg, commit string) (bool, error) {
|
|||||||
// because `git diff-index` only uses the `lstat` result and
|
// because `git diff-index` only uses the `lstat` result and
|
||||||
// not the actual file contents. Running `git update-index
|
// not the actual file contents. Running `git update-index
|
||||||
// --refresh` updates the cache.
|
// --refresh` updates the cache.
|
||||||
if err := gitCommand("update-index", "-q", "--refresh"); err != nil {
|
if err := g.command("update-index", "-q", "--refresh"); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := gitCommand("diff-index", "--quiet", commit, "--", pkg)
|
err := g.command("diff-index", "--quiet", commit, "--", pkg)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ type Pkg struct {
|
|||||||
hash string
|
hash string
|
||||||
dirty bool
|
dirty bool
|
||||||
commitHash string
|
commitHash string
|
||||||
|
git *git
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFromCLI creates a Pkg from a set of CLI arguments. Calls fs.Parse()
|
// NewFromCLI creates a Pkg from a set of CLI arguments. Calls fs.Parse()
|
||||||
@ -138,20 +139,27 @@ func NewFromCLI(fs *flag.FlagSet, args ...string) (Pkg, error) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
gitDirty, err := gitIsDirty(hashPath, hashCommit)
|
git, err := newGit(pkgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Pkg{}, err
|
return Pkg{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty = dirty || gitDirty
|
if git != nil {
|
||||||
|
gitDirty, err := git.isDirty(hashPath, hashCommit)
|
||||||
if hash == "" {
|
if err != nil {
|
||||||
if hash, err = gitTreeHash(hashPath, hashCommit); err != nil {
|
|
||||||
return Pkg{}, err
|
return Pkg{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dirty {
|
dirty = dirty || gitDirty
|
||||||
hash += "-dirty"
|
|
||||||
|
if hash == "" {
|
||||||
|
if hash, err = git.treeHash(hashPath, hashCommit); err != nil {
|
||||||
|
return Pkg{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if dirty {
|
||||||
|
hash += "-dirty"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +175,7 @@ func NewFromCLI(fs *flag.FlagSet, args ...string) (Pkg, error) {
|
|||||||
cache: !pi.DisableCache,
|
cache: !pi.DisableCache,
|
||||||
dirty: dirty,
|
dirty: dirty,
|
||||||
pkgPath: pkgPath,
|
pkgPath: pkgPath,
|
||||||
|
git: git,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +198,11 @@ func (p Pkg) ReleaseTag(release string) (string, error) {
|
|||||||
|
|
||||||
// Tag returns the tag to use for the package
|
// Tag returns the tag to use for the package
|
||||||
func (p Pkg) Tag() string {
|
func (p Pkg) Tag() string {
|
||||||
return p.org + "/" + p.image + ":" + p.hash
|
t := p.hash
|
||||||
|
if t == "" {
|
||||||
|
t = "latest"
|
||||||
|
}
|
||||||
|
return p.org + "/" + p.image + ":" + t
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrustEnabled returns true if trust is enabled
|
// TrustEnabled returns true if trust is enabled
|
||||||
|
Loading…
Reference in New Issue
Block a user