From eb9f6c92bd333537150bc9fb5cce5ef88cf9f01b Mon Sep 17 00:00:00 2001 From: Oscar Ward Date: Fri, 13 Oct 2023 11:30:49 -0700 Subject: [PATCH] swap to git cli Signed-off-by: Oscar Ward --- pkg/cli/dev.go | 2 +- pkg/vcs/vcs.go | 78 ++++++++++++++++++++++---------------------------- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/pkg/cli/dev.go b/pkg/cli/dev.go index 2be5de238..a15732187 100644 --- a/pkg/cli/dev.go +++ b/pkg/cli/dev.go @@ -68,7 +68,7 @@ func (s *Dev) Run(cmd *cobra.Command, args []string) error { if !s.Clone { imageSource = imagesource.NewImageSource(s.client.AcornConfigFile(), s.File, s.ArgsFile, args, nil, z.Dereference(s.AutoUpgrade)) } else if s.Name == "" { - return fmt.Errorf("clone option must be used when running dev on an existing app") + return fmt.Errorf("clone option can only be used when running dev on an existing app") } else { // Get info from the running app app, err := c.AppGet(cmd.Context(), s.Name) diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go index 59cbe9924..4a72f95ea 100644 --- a/pkg/vcs/vcs.go +++ b/pkg/vcs/vcs.go @@ -3,16 +3,14 @@ package vcs import ( "context" "fmt" - "net/url" "os" + "os/exec" "path/filepath" "strings" apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1" v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" ) func VCS(filePath, buildContextPath string) (result v1.VCS) { @@ -97,22 +95,7 @@ func ImageInfoFromApp(ctx context.Context, app *apiv1.App, cloneDir string) (str return "", "", fmt.Errorf("app is missing required vcs information, image must be rebuilt with a newer acorn cli") } - // Create auth object to use when fetching and cloning git repos - auth, err := ssh.NewSSHAgentAuth("git") - if err != nil { - return "", "", err - } - for _, remote := range vcs.Remotes { - // Since we use ssh auth to clone the repo we need a git url but will sometimes get http urls - var gitUrl string - httpUrl, err := url.Parse(remote) - if err == nil { - gitUrl = fmt.Sprintf("git@%s:%s", httpUrl.Host, httpUrl.Path[1:]) - } else { - gitUrl = remote - } - // Determine the repository name from the repo url idx := strings.LastIndex(remote, "/") if idx < 0 || idx >= len(remote)-1 { @@ -121,27 +104,36 @@ func ImageInfoFromApp(ctx context.Context, app *apiv1.App, cloneDir string) (str } workdir := filepath.Join(cloneDir, strings.TrimSuffix(remote[idx+1:], ".git")) - // Clone git repo and checkout revision - fmt.Printf("# Cloning repository %q into directory %q\n", gitUrl, workdir) - repo, err := git.PlainCloneContext(ctx, workdir, false, &git.CloneOptions{ - URL: gitUrl, - Auth: auth, - Progress: os.Stderr, - }) - if err != nil { - fmt.Printf("failed to clone repository %q: %s\n", gitUrl, err.Error()) - continue - } - w, err := repo.Worktree() - if err != nil { - fmt.Printf("failed to get worktree from repository %q: %s\n", workdir, err.Error()) + // Check if we've cloned the repo already + if _, err := os.Stat(workdir); os.IsNotExist(err) { + // Clone the repo + args := []string{"clone", remote, workdir} + cmd := exec.CommandContext(ctx, "git", args...) + err = cmd.Run() + if err != nil { + fmt.Printf("failed to clone repository %q: %v", remote, err) + continue + } + } else if os.IsExist(err) { + // Fetch the remote in the repo + args := []string{"-C", workdir, "fetch", remote} + cmd := exec.CommandContext(ctx, "git", args...) + err = cmd.Run() + if err != nil { + fmt.Printf("failed to fetch remote %q in repository %q: %v", remote, workdir, err) + continue + } + } else if err != nil { + fmt.Printf("failed to check for the existence of directory %q: %v", workdir, err) continue } - err = w.Checkout(&git.CheckoutOptions{ - Hash: plumbing.NewHash(vcs.Revision), - }) + + // Try to checkout the revision + args := []string{"-C", workdir, "checkout", vcs.Revision} + cmd := exec.CommandContext(ctx, "git", args...) + err := cmd.Run() if err != nil { - fmt.Printf("failed to checkout revision %q for repository %q: %s\n", vcs.Revision, workdir, err.Error()) + fmt.Printf("failed to checkout revision %q: %v", vcs.Revision, err) continue } @@ -149,18 +141,16 @@ func ImageInfoFromApp(ctx context.Context, app *apiv1.App, cloneDir string) (str acornfile := filepath.Join(workdir, vcs.Acornfile) err = os.WriteFile(acornfile, []byte(app.Status.AppImage.Acornfile), 0666) if err != nil { - fmt.Printf("failed to create file %q in repository %q: %s\n", acornfile, workdir, err.Error()) + fmt.Printf("failed to create file %q in repository %q: %v\n", acornfile, workdir, err) continue } // Determine if the Acornfile is dirty or not - s, err := w.Status() - if err == nil { - if !s.IsClean() { - fmt.Printf("running with a dirty Acornfile %q\n", acornfile) - } - } else { - fmt.Printf("failed to get status from worktree %q: %s\n", workdir, err.Error()) + args = []string{"-C", workdir, "diff", "--quiet"} + cmd = exec.CommandContext(ctx, "git", args...) + err = cmd.Run() + if err != nil { + fmt.Printf("running with a dirty Acornfile %q\n", acornfile) } // Get the build context