//dorefresh actually run the refresh command, it is unsafe to call it without caution. It should only update errcode, and result func (j *job) dorefresh(w io.Writer) error { // NB: this is a mammoth function. I know it, but I wasn't able to // split it down before having done everything. // // Step by step I will extract subffunctions to appropriate set of objects // wd, err := os.Getwd() if err != nil { return err } _, err = os.Stat(j.name) if os.IsNotExist(err) { // target does not exist, make it. fmt.Fprintf(w, "%s dir does not exists. Will create one.\n", j.name) result, err := git.Clone(wd, j.name, j.remote, j.branch) fmt.Fprintln(w, result) if err != nil { return err } } wk := sbr.NewWorkspace(filepath.Join(wd, j.name)) ch := sbr.NewCheckouter(wk, w) ch.SetFastForwardOnly(true) ch.SetPrune(true) digest, err := ch.Checkout() if err != nil { return err } copy(j.refresh.version[:], digest) return nil }
func (c *CloneCmd) Run(args []string) { // use wd by default wd, err := os.Getwd() if err != nil { fmt.Printf("Error, cannot determine the current directory. %s\n", err.Error()) os.Exit(CodeNoWorkingDir) } var rel, remote string switch len(args) { case 0: fmt.Printf("Usage sbr clone [-b branch] <remote> [target]\n") os.Exit(-1) case 1: remote = args[0] rel = strings.TrimSuffix(filepath.Base(remote), ".git") case 2: remote = args[0] rel = args[1] } res, err := git.Clone(wd, rel, remote, *c.branch) fmt.Println(res) if err != nil { fmt.Printf("Error, cannot clone %s: %s\n", remote, err.Error()) os.Exit(-1) } //creates a workspace to be able to read from/to sets workspace := sbr.NewWorkspace(filepath.Join(wd, rel)) ch := sbr.NewCheckouter(workspace, os.Stdout) _, err = ch.Checkout() if err != nil { fmt.Printf("checkout error: %s", err.Error()) os.Exit(-1) } }
//applychanges computes ins, del, upd , and try to apply them on the workspace func (ch *Checkouter) patchDisk() (cloned map[string]bool, err error) { wds, err := ch.wk.Scan() if err != nil { return } sbrs, err := ch.wk.Read() if err != nil { return } ins, del, upd := Diff(wds, sbrs) // map to keep track of cloned repo (that don't need refresh) cloned = make(map[string]bool) var refresherrors []error // we keep track of all errors, but we still go on. var waiter sync.WaitGroup // to wait for all commands to return var delCount, cloneCount, changeCount int if len(ins) > 0 || len(del) > 0 || len(upd) > 0 { for _, sbr := range ins { waiter.Add(1) go func(d Sub) { defer waiter.Done() res, err := git.Clone(ch.wk.Wd(), d.Rel(), d.Remote(), d.Branch()) if err != nil { fmt.Fprintf(ch.w, "ERR Cloning into '%s' : %q\n%s\n", d.Rel(), err.Error(), res) refresherrors = append(refresherrors, err) } else { cloneCount++ fmt.Fprintf(ch.w, " Cloning into '%s'...\n", d.Rel()) } }(sbr) } for _, delta := range upd { u, err := ch.UpdateRepository(delta) if err != nil { fmt.Fprintf(ch.w, "ERR Changing '%s' : %s\n%s\n", delta.Rel(), err.Error(), delta.String()) refresherrors = append(refresherrors, err) } else { if u { fmt.Fprintf(ch.w, " Changing %s\n", delta.String()) changeCount++ } } } if ch.prune { for _, sbr := range del { waiter.Add(1) go func(d Sub) { defer waiter.Done() err = ch.Prune(sbr) if err != nil { fmt.Fprintf(ch.w, "ERR Pruning '%s' : %q\n", d.Rel(), err.Error()) refresherrors = append(refresherrors, err) } else { delCount++ fmt.Fprintf(ch.w, " Pruning '%s'...\n", d.Rel()) } }(sbr) } } // no prune at all waiter.Wait() //print out some report if ch.prune { fmt.Fprintf(ch.w, "%v CLONE, %v PRUNE %v CHANGED\n\n", cloneCount, delCount, changeCount) } else { //fake prune with a specific message for _, sbr := range del { fmt.Fprintf(ch.w, " Would Prune %s %s %s\n", sbr.Rel(), sbr.Remote(), sbr.Branch()) delCount++ } fmt.Fprintf(ch.w, "%v CLONE, %v REQUIRED PRUNE %v CHANGED\n\n", cloneCount, delCount, changeCount) } } if len(refresherrors) > 0 { // todo print those errors if there are not too many err = fmt.Errorf("Errors occured (%v) during operations", len(refresherrors)) } return }