func Read() { cacheFile = filepath.Join(os.Getenv("GOPATH"), cacheFileName) cache = make(map[string]time.Time) if !util.Exists(cacheFile) { return } if clear { err := os.Remove(cacheFile) if err != nil { util.Fatal(err) } return } util.Verbose("Reading cache file from " + cacheFile) data, err := ioutil.ReadFile(cacheFile) if err != nil { util.Fatal(err) } err = json.Unmarshal(data, &cache) if err != nil { return } }
// Create writes an empty deps.json at the location specified by path func Create(path string) { if util.Exists(path) { util.Fatal(colors.Red(dep.DepsFile + " already exists!")) } util.Print(colors.Blue("Initializing:")) err := ioutil.WriteFile(path, []byte(template), 0644) if err == nil { util.Print("Empty " + dep.DepsFile + " created (" + path + ")") } else { util.Fatal(colors.Red("Error creating "+dep.DepsFile+": "), err) } 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 }
//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 }
// Add interactively prompts the user for details of a dependency, adds it to deps.json, and writes out the file func Add(deps dep.DependencyMap, name string) { var cont = true _, exists := deps.Map[name] if exists { util.Fatal(colors.Red("Dependency '" + name + "'' is already defined, pick another name.")) } util.Print(colors.Blue("Adding: ") + name) for cont { d := new(dep.Dependency) d.Type = promptType("Type", "git, git-clone, hg, bzr") if d.Type == dep.TypeGitClone { d.Repo = promptString("Repo", "git url") } else { d.Repo = promptString("Repo", "go import") } d.Version = promptString("Version", "hash, branch, or tag") if d.Type == dep.TypeGitClone { d.Alias = promptString("Alias", "where to install the repo") } deps.Map[name] = d cont = promptBool("Add another", "y/N") } for name, d := range deps.Map { err := d.SetupVCS(name) if err != nil { delete(deps.Map, name) } } err := deps.Write() if err != nil { util.Fatal(colors.Red("Error Writing " + deps.Path + ": " + err.Error())) } install.Install(deps) 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 }
// Check for duplicate dependency // if same name and same version, skip // if same name and different version, exit // if different name, add to set, don't skip func duplicate(d dep.Dependency, set map[string]string) (skip bool) { version, installed := set[d.Repo] if installed && version != d.Version { util.Print(colors.Red("ERROR : Duplicate dependency with different versions detected")) util.Print(colors.Red("Repo : " + d.Repo)) util.Fatal(colors.Red("Versions : " + d.Version + "\t" + version)) } else if installed { util.VerboseIndent(colors.Yellow("Skipping previously installed dependency: ") + d.Repo) skip = true } else { set[d.Repo] = d.Version } 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) }
// 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 }
//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 }
// Print displays a message if a newer version of depman is available // this should only be called after Check() func Print() { if !checkCalled { util.Fatal(colors.Red("You must call upgrade.Check() before upgrade.Print()")) } // if the command used was self-upgrade, we can just return if selfCalled { return } ref := <-channel if checkError != nil { util.Verbose(colors.Yellow("Upgrade Check Error: " + checkError.Error())) } if ref != none { fmt.Println(colors.Yellow(fmt.Sprintf(message, ref))) } }
// 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 (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 }
// Write writes the cache out to disk func Write() { if skip { return } var buf bytes.Buffer str, err := json.Marshal(cache) if err == nil { json.Indent(&buf, str, "", " ") data := []byte(buf.String() + "\n") util.Verbose("Writing cache file to " + cacheFile) err = ioutil.WriteFile(cacheFile, data, 0644) if err != nil { util.Fatal(err) } } return }
// Read reads the cache from disk func Read() { parts := strings.Split(os.Getenv("GOPATH"), ":") cacheFile = filepath.Join(parts[0], cacheFileName) cache = make(map[string]time.Time) if !util.Exists(cacheFile) { return } util.Verbose("Reading cache file from " + cacheFile) data, err := ioutil.ReadFile(cacheFile) if err != nil { util.Fatal(err) } err = json.Unmarshal(data, &cache) if err != nil { return } }
// Clear clears the cache, returns true if the cache was cleared func Clear() (cleared bool) { cleared = clear if clear { parts := strings.Split(os.Getenv("GOPATH"), ":") cacheFile = filepath.Join(parts[0], cacheFileName) util.Print(colors.Yellow("Clearing cache file: " + cacheFile)) _, err := os.Stat(cacheFile) if err != nil { return } err = os.Remove(cacheFile) if err != nil { util.Fatal(err) } } 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 }
func main() { var help bool var path string var command string var arguments []string var deps dep.DependencyMap var err error log.SetFlags(0) flag.BoolVar(&help, "help", false, "Display help") flag.StringVar(&path, "path", ".", "Directory or full path to deps.json") util.Parse() util.Version(VERSION) fmt.Println(colors.Red("Depman was deprecated on 25 February 2015")) fmt.Println(colors.Red("We recommend using 'godep' instead: https://github.com/tools/godep")) util.GoPathIsSet() if timelock.Clear() { return } timelock.Read() // check for a new version of depman go upgrade.Check(VERSION) runtime.Gosched() defer upgrade.Print() path = dep.GetPath(path) if flag.NArg() > 0 { command = strings.ToLower(flag.Arg(0)) } if flag.NArg() > 1 { arguments = flag.Args()[1:] } if help { command = "help" } // switch to check for deps.json switch command { case "add", "", "install", "update", "show-frozen": // check for deps.json util.CheckPath(path) deps, err = dep.Read(path) if err != nil { util.Fatal(colors.Red("Error Reading deps.json: " + err.Error())) } } // switch to exec the sub command switch command { case "init", "create": create.Create(path) case "add": if len(arguments) < 1 { util.Print(colors.Red("Add command requires 1 argument: Add [nickname]")) Help() } else { add.Add(deps, arguments[0]) } case "update": if len(arguments) < 2 { util.Print(colors.Red("Update command requires 2 arguments: Update [nickname] [branch]")) Help() } else { update.Update(deps, arguments[0], arguments[1]) } case "install", "": install.Install(deps) case "self-upgrade": upgrade.Self(VERSION) case "show-frozen": var recursive bool flagset := flag.NewFlagSet("show-frozen", flag.ExitOnError) flagset.BoolVar(&recursive, "recursive", false, "descend recursively (depth-first) into dependencies") flagset.Parse(flag.Args()[1:]) if recursive { fmt.Println(showfrozen.ReadRecursively(deps, nil)) } else { fmt.Print(showfrozen.Read(deps)) } default: result.RegisterError() log.Println(colors.Red("Unknown Command: " + command)) fallthrough case "help": Help() } timelock.Write() if result.ShouldExitWithError() { os.Exit(1) } else { util.Print("Success") } }