/
install.go
123 lines (102 loc) · 2.67 KB
/
install.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Package install provides functions to recursively install dependencies
// Cleaning of existing changes in dependency repositories is controlled by the --clean flag
package install
// Copyright 2013-2014 Vubeology, Inc.
import (
"flag"
"fmt"
"time"
"github.com/vube/depman/colors"
"github.com/vube/depman/dep"
"github.com/vube/depman/result"
"github.com/vube/depman/timelock"
"github.com/vube/depman/util"
)
var (
clean bool
)
// Whether to install recursively
var Recurse = true
func init() {
flag.BoolVar(&clean, "clean", false, "Remove changes to code in dependencies")
}
// Install a DependencyMap
func Install(deps dep.DependencyMap) error {
util.Print(colors.Blue("Installing:"))
set := make(map[string]string)
return recursiveInstall(deps, set)
}
// recursively install a DependencyMap
func recursiveInstall(deps dep.DependencyMap, set map[string]string) (err error) {
for name, d := range deps.Map {
start := time.Now()
if duplicate(*d, set) {
continue
}
stale := timelock.IsStale(d)
util.PrintDep(name, d.Version, d.Repo, stale)
subPath := d.Path()
err = d.VCS.Clone(d)
if err != nil {
continue
}
util.Cd(subPath)
if clean {
d.VCS.Clean(d)
}
if stale {
util.VerboseIndent("# repo is stale, fetching")
err = d.VCS.Fetch(d)
if err != nil {
continue
}
}
err = d.VCS.Checkout(d)
if err != nil {
continue
}
if stale {
err = d.VCS.Update(d)
if err != nil {
continue
}
}
util.VerboseIndent(fmt.Sprintf("# time to install: %.3fs", time.Since(start).Seconds()))
// Recursive
depsFile := util.UpwardFind(subPath, dep.DepsFile)
if depsFile != "" && Recurse {
subDeps, err := dep.Read(depsFile)
if err != nil {
util.Print(colors.Red("Error reading deps from '" + depsFile + "': " + err.Error()))
result.RegisterError()
} else {
util.IncreaseIndent()
recursiveInstall(subDeps, set)
util.DecreaseIndent()
}
}
}
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
}
// Mock sets clean to true for testing
func Mock() {
clean = true
}