package roast import ( "errors" "fmt" "git-roast/internal/log" "git-roast/internal/util" "net/url" "os" "os/exec" "path/filepath" "time" ) func (r *Roast) Request(from string, into string) error { log.Debugf("requesting merge from %s into %s\n", from, into) sourceBranch, err := r.repo.Branch(from) if err != nil { return errors.Join(fmt.Errorf("failed to get source branch %s", from), err) } log.Debugf("branch %s found\n", sourceBranch.Name) targetBranch, err := r.repo.Branch(into) if err != nil { return errors.Join(fmt.Errorf("failed to get target branch %s", from), err) } log.Debugf("branch %s found\n", targetBranch.Name) id := url.PathEscape(fmt.Sprintf( "%016x_from_%s_into_%s", time.Now().Unix(), sourceBranch.Name, targetBranch.Name, )) initialMessage, err := util.Textedit(fmt.Sprintf( "%s is requesting merge into `%s` from `%s`\n", GitUserName(), into, from, )) if err != nil { return err } p := filepath.Join(r.dir, id) if err := os.MkdirAll(p, 0700); err != nil { return errors.Join(errors.New("failed to create directory for request"), err) } successful := false defer func() { if !successful { clean := exec.Command("git", "clean", "-xfd") clean.Path = r.dir _ = clean.Run() log.Printf("action not successful, rollback...\n") reset := exec.Command("git", "reset", "--hard") reset.Path = r.dir _ = reset.Run() } }() f, err := os.Create(filepath.Join(p, fmt.Sprintf( "%016x_%s.md", time.Now().Unix(), GitUserName(), ))) if err != nil { return errors.Join(errors.New("failed to create file for request"), err) } if _, err := f.Write([]byte(initialMessage)); err != nil { return errors.Join(errors.New("failed to write to file for request"), err) } if err := r.AddAll(); err != nil { return errors.Join(errors.New("failed to add changes before commit"), err) } if err := r.Commit(id); err != nil { return errors.Join(errors.New("failed to commit changes before push request"), err) } if err := r.Push(); err != nil { return errors.Join(errors.New("failed to push request"), err) } successful = true return nil }