gopkg.in/tools/godep.v67@v67.0.0-20160513230433-2d182dfe781d/godepfile.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "log" 8 "os" 9 "path/filepath" 10 ) 11 12 var ( 13 godepsFile = filepath.Join("Godeps", "Godeps.json") 14 oldGodepsFile = filepath.Join("Godeps") 15 ) 16 17 // Godeps describes what a package needs to be rebuilt reproducibly. 18 // It's the same information stored in file Godeps. 19 type Godeps struct { 20 ImportPath string 21 GoVersion string 22 GodepVersion string 23 Packages []string `json:",omitempty"` // Arguments to save, if any. 24 Deps []Dependency 25 isOldFile bool 26 } 27 28 func createGodepsFile() (*os.File, error) { 29 return os.Create(godepsFile) 30 } 31 32 func loadGodepsFile(path string) (Godeps, error) { 33 var g Godeps 34 f, err := os.Open(path) 35 if err != nil { 36 return g, err 37 } 38 defer f.Close() 39 err = json.NewDecoder(f).Decode(&g) 40 if err != nil { 41 err = fmt.Errorf("Unable to parse %s: %s", path, err.Error()) 42 } 43 return g, err 44 } 45 46 func loadDefaultGodepsFile() (Godeps, error) { 47 var g Godeps 48 var err error 49 g, err = loadGodepsFile(godepsFile) 50 if err != nil { 51 if os.IsNotExist(err) { 52 var err1 error 53 g, err1 = loadGodepsFile(oldGodepsFile) 54 if err1 != nil { 55 if os.IsNotExist(err1) { 56 return g, err 57 } 58 return g, err1 59 } 60 g.isOldFile = true 61 return g, nil 62 } 63 } 64 return g, err 65 } 66 67 // pkgs is the list of packages to read dependencies for 68 func (g *Godeps) fill(pkgs []*Package, destImportPath string) error { 69 debugln("fill", destImportPath) 70 ppln(pkgs) 71 var err1 error 72 var path, testImports []string 73 dipp := []string{destImportPath} 74 for _, p := range pkgs { 75 if p.Standard { 76 log.Println("ignoring stdlib package:", p.ImportPath) 77 continue 78 } 79 if p.Error.Err != "" { 80 log.Println(p.Error.Err) 81 err1 = errorLoadingPackages 82 continue 83 } 84 path = append(path, p.ImportPath) 85 path = append(path, p.Deps...) 86 testImports = append(testImports, p.TestImports...) 87 testImports = append(testImports, p.XTestImports...) 88 } 89 ps, err := LoadPackages(testImports...) 90 if err != nil { 91 return err 92 } 93 for _, p := range ps { 94 if p.Standard { 95 continue 96 } 97 if p.Error.Err != "" { 98 log.Println(p.Error.Err) 99 err1 = errorLoadingPackages 100 continue 101 } 102 path = append(path, p.ImportPath) 103 path = append(path, p.Deps...) 104 } 105 debugln("path", path) 106 for i, p := range path { 107 path[i] = unqualify(p) 108 } 109 path = uniq(path) 110 debugln("uniq, unqualify'd path", path) 111 ps, err = LoadPackages(path...) 112 if err != nil { 113 return err 114 } 115 for _, pkg := range ps { 116 if pkg.Error.Err != "" { 117 log.Println(pkg.Error.Err) 118 err1 = errorLoadingDeps 119 continue 120 } 121 if pkg.Standard || containsPathPrefix(dipp, pkg.ImportPath) { 122 debugln("standard or dest skipping", pkg.ImportPath) 123 continue 124 } 125 vcs, reporoot, err := VCSFromDir(pkg.Dir, filepath.Join(pkg.Root, "src")) 126 if err != nil { 127 log.Println(err) 128 err1 = errorLoadingDeps 129 continue 130 } 131 id, err := vcs.identify(pkg.Dir) 132 if err != nil { 133 log.Println(err) 134 err1 = errorLoadingDeps 135 continue 136 } 137 if vcs.isDirty(pkg.Dir, id) { 138 log.Println("dirty working tree (please commit changes):", pkg.Dir) 139 err1 = errorLoadingDeps 140 continue 141 } 142 comment := vcs.describe(pkg.Dir, id) 143 g.Deps = append(g.Deps, Dependency{ 144 ImportPath: pkg.ImportPath, 145 Rev: id, 146 Comment: comment, 147 dir: pkg.Dir, 148 ws: pkg.Root, 149 root: filepath.ToSlash(reporoot), 150 vcs: vcs, 151 }) 152 } 153 return err1 154 } 155 156 func (g *Godeps) copy() *Godeps { 157 h := *g 158 h.Deps = make([]Dependency, len(g.Deps)) 159 copy(h.Deps, g.Deps) 160 return &h 161 } 162 163 func (g *Godeps) file() string { 164 if g.isOldFile { 165 return oldGodepsFile 166 } 167 return godepsFile 168 } 169 170 func (g *Godeps) save() (int64, error) { 171 f, err := os.Create(g.file()) 172 if err != nil { 173 return 0, err 174 } 175 defer f.Close() 176 return g.writeTo(f) 177 } 178 179 func (g *Godeps) writeTo(w io.Writer) (int64, error) { 180 g.GodepVersion = fmt.Sprintf("v%d", version) // godep always writes its current version. 181 b, err := json.MarshalIndent(g, "", "\t") 182 if err != nil { 183 return 0, err 184 } 185 n, err := w.Write(append(b, '\n')) 186 return int64(n), err 187 } 188 189 func (g *Godeps) addOrUpdateDeps(deps []Dependency) { 190 var missing []Dependency 191 for _, d := range deps { 192 var found bool 193 for i := range g.Deps { 194 if g.Deps[i].ImportPath == d.ImportPath { 195 g.Deps[i] = d 196 found = true 197 break 198 } 199 } 200 if !found { 201 missing = append(missing, d) 202 } 203 } 204 for _, d := range missing { 205 g.Deps = append(g.Deps, d) 206 } 207 } 208 209 func (g *Godeps) removeDeps(deps []Dependency) { 210 var f []Dependency 211 for i := range g.Deps { 212 var found bool 213 for _, d := range deps { 214 if g.Deps[i].ImportPath == d.ImportPath { 215 found = true 216 break 217 } 218 } 219 if !found { 220 f = append(f, g.Deps[i]) 221 } 222 } 223 g.Deps = f 224 }