diff options
Diffstat (limited to 'internal/service/git.go')
-rw-r--r-- | internal/service/git.go | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/internal/service/git.go b/internal/service/git.go deleted file mode 100644 index ad3a653..0000000 --- a/internal/service/git.go +++ /dev/null @@ -1,134 +0,0 @@ -package service - -import ( - "errors" - "fmt" - "net/url" - "os" - "os/exec" - "path" - "strings" -) - -const gitDescriptionFile = "description" - -func mapExecError(err error) error { - if ee, ok := err.(*exec.ExitError); ok { - return errors.New(string(ee.Stderr)) - } - return err -} - -// Set the description for the projects repository. -func setDescription(repo string, desc string) error { - descPath := path.Join(repo, gitDescriptionFile) - - var curDesc string - buf, err := os.ReadFile(descPath) - if os.IsNotExist(err) { - // empty - } else if err != nil { - return err - } else { - curDesc = string(buf) - } - - if curDesc != desc { - err = os.WriteFile(descPath, []byte(desc), 0750) - if err != nil { - return err - } - } - - return nil -} - -// Set the remote origin's URL for the projects repository. -func setRemoteOrigin(repo string, origin *url.URL) error { - cmd := exec.Command("git", "remote", "get-url", "origin") - cmd.Dir = repo - buf, err := cmd.Output() - if err != nil { - return fmt.Errorf("getting current project remote origin: %w", err) - } - currentOrigin := strings.TrimSpace(string(buf)) - - if currentOrigin != origin.String() { - cmd = exec.Command("git", "remote", "set-url", "origin", origin.String()) - cmd.Dir = repo - err = cmd.Run() - if err != nil { - err = mapExecError(err) - return fmt.Errorf("setting project remote origin: %w", err) - } - } - - return nil -} - -func getRemoteHeadReference(repo string) (string, error) { - cmd := exec.Command("git", "ls-remote", "--symref", "origin", "HEAD") - cmd.Dir = repo - buf, err := cmd.Output() - if err != nil { - return "", mapExecError(err) - } - - for _, l := range strings.Split(string(buf), "\n") { - fields := strings.Fields(l) - if len(fields) != 3 { - return "", errors.New("unexpected output from 'git ls-remote'") - } - if fields[0] == "ref:" { - return strings.TrimPrefix(fields[1], "refs/heads/"), nil - } - } - - return "", errors.New("not found") -} - -func MirrorGit(dst *url.URL, src *url.URL, description string) error { - if dst.Scheme != "" && dst.Scheme != "file://" { - return fmt.Errorf("'%s' scheme not supported", dst.Scheme) - } - - if _, err := os.Stat(dst.Path); os.IsNotExist(err) { - err = os.MkdirAll(path.Join(dst.Path, ".."), 0750) - if err != nil { - return fmt.Errorf("creating new mirror: %w", err) - } - - cmd := exec.Command("git", "clone", "--bare", "--single-branch", src.String(), dst.String()) - cmd.Dir = path.Join(dst.Path, "..") - err := cmd.Run() - if err != nil { - err = mapExecError(err) - return fmt.Errorf("cloning: %s", err) - } - } - - err := setDescription(dst.Path, description) - if err != nil { - return err - } - - err = setRemoteOrigin(dst.Path, src) - if err != nil { - return err - } - - branch, err := getRemoteHeadReference(dst.Path) - if err != nil { - return fmt.Errorf("guessing remote default branch: %w", err) - } - - cmd := exec.Command("git", "fetch", "--tags", "origin", branch+":"+branch) - cmd.Dir = dst.Path - err = cmd.Run() - if err != nil { - err = mapExecError(err) - return fmt.Errorf("fetching project: %s", err) - } - - return nil -} |