From 02616e64ec7430379cccb5d2fadccd8569e7285a Mon Sep 17 00:00:00 2001 From: blacktop Date: Sat, 27 Apr 2024 10:54:44 -0600 Subject: [PATCH] fix: `ipsw dl appledb` cmd which defaults to using git will use the bin if installed othewise will use a pure Go git implementation --- internal/download/appledb.go | 23 ++------------- internal/utils/git.go | 57 +++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/internal/download/appledb.go b/internal/download/appledb.go index c732b0a56e..5b64c29270 100644 --- a/internal/download/appledb.go +++ b/internal/download/appledb.go @@ -17,8 +17,6 @@ import ( "github.com/apex/log" "github.com/blacktop/ipsw/internal/utils" - "github.com/go-git/go-git/v5" - "github.com/pkg/errors" ) const ( @@ -230,27 +228,12 @@ func LocalAppleDBQuery(q *ADBQuery) ([]OsFileSource, error) { if _, err := os.Stat(filepath.Join(q.ConfigDir, "appledb")); os.IsNotExist(err) { utils.Indent(log.Info, 2)(fmt.Sprintf("Git cloning local 'appledb' to %s", filepath.Join(q.ConfigDir, "appledb"))) - if _, err := git.PlainClone(filepath.Join(q.ConfigDir, "appledb"), false, &git.CloneOptions{ - URL: AppleDBGitURL, - Depth: 1, - Progress: os.Stderr, - }); err != nil { + if _, err := utils.GitClone(AppleDBGitURL, filepath.Join(q.ConfigDir, "appledb")); err != nil { return nil, fmt.Errorf("failed to create local copy of 'appledb' repo: %v", err) } } else { - r, err := git.PlainOpen(filepath.Join(q.ConfigDir, "appledb")) - if err != nil { - return nil, fmt.Errorf("failed to open local copy of 'appledb' repo: %v", err) - } - - w, err := r.Worktree() - if err != nil { - return nil, fmt.Errorf("failed to get worktree of local copy of 'appledb' repo: %v", err) - } - - if err = w.Pull(&git.PullOptions{ - Progress: os.Stderr, - }); err != nil && errors.Is(err, git.NoErrAlreadyUpToDate) { + utils.Indent(log.Info, 2)(fmt.Sprintf("Updating 'appledb' repo %s", filepath.Join(q.ConfigDir, "appledb"))) + if _, err := utils.GitRefresh(filepath.Join(q.ConfigDir, "appledb")); err != nil { return nil, fmt.Errorf("failed to update local copy of 'appledb' repo: %v", err) } } diff --git a/internal/utils/git.go b/internal/utils/git.go index b0bae9b9e6..8466a293aa 100644 --- a/internal/utils/git.go +++ b/internal/utils/git.go @@ -1,6 +1,7 @@ package utils import ( + "errors" "fmt" "io" "os" @@ -10,29 +11,63 @@ import ( "strings" "github.com/alecthomas/chroma/v2/quick" + "github.com/go-git/go-git/v5" "github.com/sergi/go-diff/diffmatchpatch" + "golang.org/x/sys/execabs" "golang.org/x/term" ) // GitClone clones a git repo func GitClone(repo, dst string) (string, error) { - cmd := exec.Command("git", "clone", "--depth", "1", repo, dst) - dat, err := cmd.CombinedOutput() - if err != nil { - return "", fmt.Errorf("failed to clone repo '%s' to %s: %v", repo, dst, err) + if _, err := execabs.LookPath("git"); err == nil { + cmd := exec.Command("git", "clone", "--depth", "1", repo, dst) + dat, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("failed to clone repo '%s' to %s: %v", repo, dst, err) + } + return string(dat), nil + } else { // use pure Go version of git + if _, err := git.PlainClone(dst, false, &git.CloneOptions{ + URL: repo, + Depth: 1, + Progress: os.Stderr, + }); err != nil { + return "", fmt.Errorf("failed to create local copy of 'appledb' repo: %v", err) + } + return "", nil } - return string(dat), nil } // GitRefresh refreshes a git repo func GitRefresh(repoPath string) (string, error) { - cmd := exec.Command("git", "pull", "--rebase") - cmd.Dir = repoPath - dat, err := cmd.CombinedOutput() - if err != nil { - return "", fmt.Errorf("failed to refresh repo '%s': %v", repoPath, err) + if _, err := execabs.LookPath("git"); err == nil { + cmd := exec.Command("git", "pull", "--rebase") + cmd.Dir = repoPath + dat, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("failed to refresh repo '%s': %v", repoPath, err) + } + return string(dat), nil + } else { // use pure Go version of git + r, err := git.PlainOpen(repoPath) + if err != nil { + return "", fmt.Errorf("failed to open local copy of 'appledb' repo: %v", err) + } + w, err := r.Worktree() + if err != nil { + return "", fmt.Errorf("failed to get worktree of local copy of 'appledb' repo: %v", err) + } + if err = w.Pull(&git.PullOptions{ + RemoteName: "origin", + // Force: true, + Progress: os.Stderr, + }); err != nil { + if !errors.Is(err, git.NoErrAlreadyUpToDate) { + return "", fmt.Errorf("failed to update local copy of 'appledb' repo: %v", err) + } + } + return "", nil } - return string(dat), nil } type GitDiffConfig struct {