// IsBranch determines if a version (branch, commit hash, tag) is a branch (i.e. can we pull from the remote). // Assumes we are already in a sub directory of the repo func (g *Git) isBranch(name string) (result bool) { c := exec.Command("git", "branch", "-r") out, err := c.CombinedOutput() if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("git branch -r")) util.PrintIndent(colors.Red(string(out))) util.PrintIndent(colors.Red(err.Error())) return false } // get the string version but also strip the trailing newline stringOut := string(out[0 : len(out)-1]) lines := strings.Split(stringOut, "\n") for _, val := range lines { // for "origin/HEAD -> origin/master" arr := strings.Split(val, " -> ") remoteBranch := arr[0] // for normal "origin/develop" arr = strings.Split(remoteBranch, "/") branch := arr[1] if branch == name { return true } } return }
// SetupVCS configures the VCS depending on the type func (d *Dependency) SetupVCS(name string) (err error) { switch d.Type { case TypeGitClone: if d.Alias == "" { util.PrintIndent(colors.Red("Error: Dependency " + name + ": Repo '" + d.Repo + "' Type '" + d.Type + "' requires 'alias' field")) err = ErrMissingAlias return } d.VCS = new(Git) case TypeGit: d.VCS = new(Git) case TypeBzr: d.VCS = new(Bzr) case TypeHg: d.VCS = new(Hg) default: util.PrintIndent(colors.Red(d.Repo + ": Unknown repository type (" + d.Type + "), skipping...")) util.PrintIndent(colors.Red("Valid Repository types: " + TypeGit + ", " + TypeHg + ", " + TypeBzr + ", " + TypeGitClone)) err = ErrUnknownType } if d.Type != TypeGitClone && d.Alias != "" { util.Print(colors.Yellow("Warning: " + d.Repo + ": 'alias' field only allowed in dependencies with type 'git-clone', skipping...")) d.Alias = "" } return }
//GetHead - Render a revspec to a commit ID func (g *Git) GetHead(d *Dependency) (hash string, err error) { var pwd string pwd = util.Pwd() util.Cd(d.Path()) c := exec.Command("git", "rev-parse", d.Version) { var out_bytes []byte out_bytes, err = c.CombinedOutput() hash = strings.TrimSuffix(string(out_bytes), "\n") } util.Cd(pwd) if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("git rev-parse " + d.Version)) util.PrintIndent(colors.Red(string(hash))) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } return }
// LastCommit retrieves the version number of the last commit on branch // Assumes that the current working directory is in the bzr repo func (b *Bzr) LastCommit(d *Dependency, branch string) (hash string, err error) { c := exec.Command("bzr", "log", "--line") out, err := c.CombinedOutput() if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("bzr log --line")) util.PrintIndent(colors.Red(string(out))) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } hash = strings.Split(string(out), ":")[0] return }
// LastCommit retrieves the version number of the last commit on branch // Assumes that the current working directory is in the hg repo func (h *Hg) LastCommit(d *Dependency, branch string) (hash string, err error) { c := exec.Command("hg", "log", "--template='{node}\n'", "--limit=1") out, err := c.CombinedOutput() if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("hg log --template='{node}\n' --limit=1")) util.PrintIndent(colors.Red(string(out))) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } hash = strings.Replace(string(out), "\n", "", -1) return }
//Read - get top-level frozen dependencies func Read(deps dep.DependencyMap) (result string) { var err error var resultMap = make(map[string]*dep.Dependency) util.Print(colors.Yellow("NOTE: This will not reflect the state of the remote unless you have just run `depman install`.")) for k, v := range deps.Map { if v.Type == dep.TypeGitClone && v.Alias == "" { util.PrintIndent(colors.Red("Error: Repo '" + k + "' Type '" + v.Type + "' requires 'alias' field (defined in " + deps.Path + ")")) continue } v.Version, err = v.VCS.GetHead(v) if err != nil { util.Fatal(err) } resultMap[k] = v } //not changing the logic in the loop because we might want to change the print format later for _, v := range resultMap { result += fmt.Sprintf("%s %s\n", v.Repo, v.Version) } return }
// LastCommit retrieves the version number of the last commit on branch // Assumes that the current working directory is in the git repo func (g *Git) LastCommit(d *Dependency, branch string) (hash string, err error) { if !g.isBranch(branch) { err = errors.New("Branch '" + branch + "' is not a valid branch") return } c := exec.Command("git", "log", "-1", "--format=%H") out, err := c.CombinedOutput() if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("git log -1 --format=%H")) util.PrintIndent(colors.Red(string(out))) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } hash = strings.Replace(string(out), "\n", "", -1) return }
//GetHead - Render a revspec to a commit ID func (b *Bzr) GetHead(d *Dependency) (hash string, err error) { var pwd string pwd = util.Pwd() util.Cd(d.Path()) defer util.Cd(pwd) out, err := exec.Command("bzr", "revno", d.Version).CombinedOutput() hash = strings.TrimSuffix(string(out), "\n") if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("bzr revno " + d.Version)) util.PrintIndent(colors.Red(hash)) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } return }
//GetHead - Render a revspec to a commit ID func (h *Hg) GetHead(d *Dependency) (hash string, err error) { var pwd string pwd = util.Pwd() util.Cd(d.Path()) defer util.Cd(pwd) out, err := exec.Command("hg", "id", "-i").CombinedOutput() hash = strings.TrimSuffix(string(out), "\n") if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("hg id -i")) util.PrintIndent(colors.Red(hash)) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } return }
//ReadRecursively - get frozen dependencies recursively func ReadRecursively(deps dep.DependencyMap, set map[string]string) (result string) { var err error if set == nil { util.Print(colors.Yellow("NOTE: This will not reflect the state of the remote unless you have just run `depman install`.")) set = make(map[string]string) } for name, d := range deps.Map { var subPath string var depsFile string var subDeps dep.DependencyMap if _, ok := set[d.Repo]; ok { continue } if d.Type == dep.TypeGitClone && d.Alias == "" { util.PrintIndent(colors.Red("Error: Repo '" + name + "' Type '" + d.Type + "' requires 'alias' field (defined in " + deps.Path + ")")) continue } { var temp string temp, err = d.VCS.GetHead(d) if err != nil { util.Fatal(err) } set[d.Repo] = temp result += fmt.Sprintf("%s %s\n", d.Repo, temp) } subPath = d.Path() // Recursive depsFile = util.UpwardFind(subPath, dep.DepsFile) if depsFile != "" { subDeps, err = dep.Read(depsFile) if err == nil { result += ReadRecursively(subDeps, set) } else { util.Print(colors.Yellow("Error reading deps from '" + subDeps.Path + "': " + err.Error())) } } } return }
//GetHead - Render a revspec to a commit ID func (h *Hg) GetHead(d *Dependency) (hash string, err error) { var pwd string pwd = util.Pwd() util.Cd(d.Path()) { var out_bytes []byte out_bytes, err = exec.Command("hg", "id", "-i", d.Version).CombinedOutput() hash = strings.TrimSuffix(string(out_bytes), "\n") } util.Cd(pwd) if err != nil { util.Print("pwd: " + util.Pwd()) util.PrintIndent(colors.Red("hg id -i " + d.Version)) util.PrintIndent(colors.Red(hash)) util.PrintIndent(colors.Red(err.Error())) util.Fatal("") } return }
// Update rewrites Dependency name in deps.json to use the last commit in branch as version func Update(deps dep.DependencyMap, name string, branch string) { util.Print(colors.Blue("Updating:")) d, ok := deps.Map[name] if !ok { util.Fatal(colors.Red("Dependency Name '" + name + "' not found in deps.json")) } // record the old version oldVersion := d.Version // temporarily use the branch d.Version = branch pwd := util.Pwd() util.Cd(d.Path()) d.VCS.Checkout(d) d.VCS.Update(d) // get the last commit on the newly checked out branch v, err := d.VCS.LastCommit(d, branch) if err != nil { util.Fatal(err) } // set the version to be the last commit d.Version = v util.PrintIndent(colors.Blue(name) + " (" + oldVersion + " --> " + d.Version + ")") util.Cd(pwd) deps.Map[name] = d deps.Write() install.Install(deps) }
// Clean cleans a git repo: `git reset --hard HEAD ; git clean -fd` func (g *Git) Clean(d *Dependency) { util.PrintIndent(colors.Red("Cleaning:") + colors.Blue(" git reset --hard HEAD")) util.RunCommand("git reset --hard HEAD") util.RunCommand("git clean -fd") return }
func (h *Hg) Clean(d *Dependency) { util.PrintIndent(colors.Red("Cleaning:") + colors.Blue(" hg up --clean "+d.Version)) util.RunCommand("hg up --clean " + d.Version) return }