package forgepb import ( "errors" "fmt" "os" "path/filepath" "strings" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) func (f *Forge) MakeDevelPatchSet() (*Patchs, error) { pset := new(Patchs) dir, err := os.MkdirTemp("", "forge") if err != nil { return nil, err } defer os.RemoveAll(dir) // clean up pset.TmpDir = dir all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() userb := repo.GetUserBranchName() develb := repo.GetDevelBranchName() if develb == "" { continue } if userb == "" { continue } pset.StartBranchName = develb pset.EndBranchName = userb err := pset.makePatchSetNew(repo) if err != nil { return nil, err } } return pset, nil } func (f *Forge) MakeMasterPatchSet() (*Patchs, error) { pset := new(Patchs) dir, err := os.MkdirTemp("", "forge") if err != nil { return nil, err } defer os.RemoveAll(dir) // clean up pset.TmpDir = dir all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() startb := repo.GetMasterBranchName() endb := repo.GetUserBranchName() if startb == "" { continue } if endb == "" { continue } // log.Info("repo", repo.GetGoPath(), startb, "..", endb) pset.StartBranchName = startb pset.EndBranchName = endb err := pset.makePatchSetNew(repo) if err != nil { return nil, err } } return pset, nil } func (pset *Patchs) makePatchSetNew(repo *gitpb.Repo) error { startBranch := pset.StartBranchName endBranch := pset.EndBranchName repoDir := filepath.Join(pset.TmpDir, repo.GetGoPath()) err := os.MkdirAll(repoDir, 0755) if err != nil { return err } // git format-patch branch1..branch2 cmd := []string{"git", "format-patch", "-o", repoDir, startBranch + ".." + endBranch} r := repo.Run(cmd) if r.Error != nil { log.Info("git format-patch", repo.FullPath) log.Info("git format-patch", cmd) log.Info("git format-patch error", r.Error) return r.Error } if r.Exit != 0 { log.Info("git format-patch", repo.FullPath) log.Info("git format-patch", cmd) log.Info("git format-patch exit", r.Exit) return errors.New(fmt.Sprintf("git returned %d", r.Exit)) } if len(r.Stdout) == 0 { // git created no files to add return nil } return pset.addPatchFiles(repo) } // process each file in pDir/ func (p *Patchs) addPatchFiles(repo *gitpb.Repo) error { psetDir := repo.GetGoPath() tmpDir := p.TmpDir log.Info("ADD PATCH FILES ADDED DIR", tmpDir) fullDir := filepath.Join(tmpDir, psetDir) var baderr error filepath.Walk(fullDir, func(path string, info os.FileInfo, err error) error { if err != nil { // Handle possible errors, like permission issues fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) baderr = err return err } if info.IsDir() { return nil } log.Info("IS THIS A FULL PATH ?", path) log.Info("trim this from path ?", fullDir) log.Info("trim this from path ?", psetDir) log.Info("trim this from path ?", tmpDir) data, err := os.ReadFile(path) if err != nil { log.Info("addPatchFile() failed", path) baderr = err return err } patch := new(Patch) patch.Filename, _ = filepath.Rel(p.TmpDir, path) patch.Data = data patch.parseData() patch.StartHash = repo.DevelHash() p.Patchs = append(p.Patchs, patch) log.Info("ADDED PATCH FILE", path) return nil }) return baderr } // looks at the git format-patch output // saves the commit Hash // saves the diff lines func (p *Patch) parseData() string { lines := strings.Split(string(p.Data), "\n") for _, line := range lines { fields := strings.Fields(line) if len(fields) < 2 { continue } switch fields[0] { case "From": p.CommitHash = fields[1] case "diff": p.Files = append(p.Files, line) } } return "" } // just an example of how to walk only directories func onlyWalkDirs(pDir string) error { log.Info("DIR", pDir) // var all []string var baderr error filepath.WalkDir(pDir, func(path string, d os.DirEntry, err error) error { if err != nil { // Handle possible errors, like permission issues fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) baderr = err return err } log.Info("TESTING DIR", path) if d.IsDir() { return filepath.SkipDir } log.Info("NEVER GETS HERE? WHAT IS THIS?", path) return nil }) return baderr }