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