You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dotctl/cmd/git.go

50 lines
1.5 KiB
Go

package cmd
import (
"fmt"
"os"
"github.com/go-git/go-git/v5"
"github.com/spf13/cobra"
)
// cloneOrPull clones repoURL into dotfilePath if it does not exist,
// or pulls the latest changes if it is already a git repo.
// Does nothing on disk when dryRun is true.
func cloneOrPull(cmd *cobra.Command, repoURL, dotfilePath string, dryRun bool) error {
stat, err := os.Stat(dotfilePath)
if os.IsNotExist(err) {
fmt.Fprintf(cmd.OutOrStdout(), "Cloning %s into %s...\n", repoURL, dotfilePath)
if !dryRun {
_, err = git.PlainClone(dotfilePath, false, &git.CloneOptions{
URL: repoURL,
Progress: cmd.OutOrStdout(),
})
if err != nil {
return fmt.Errorf("clone failed: %w", err)
}
}
} else if err != nil {
return fmt.Errorf("cannot stat %s: %w", dotfilePath, err)
} else if stat.IsDir() {
repo, err := git.PlainOpen(dotfilePath)
if err != nil {
return fmt.Errorf("%s exists but is not a git repository\nRemove it or use a different --dotfile-path", dotfilePath)
}
fmt.Fprintf(cmd.OutOrStdout(), "Pulling latest changes in %s...\n", dotfilePath)
if !dryRun {
w, err := repo.Worktree()
if err != nil {
return fmt.Errorf("cannot get worktree: %w", err)
}
err = w.Pull(&git.PullOptions{RemoteName: "origin"})
if err != nil && err != git.NoErrAlreadyUpToDate {
fmt.Fprintf(cmd.OutOrStdout(), "Warning: git pull failed (%v), continuing with local state\n", err)
} else if err == git.NoErrAlreadyUpToDate {
fmt.Fprintln(cmd.OutOrStdout(), "Already up to date.")
}
}
}
return nil
}