Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit 1979a2b

Browse files
committed
PoC: support staging directory
1 parent 15e7e79 commit 1979a2b

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

gps/pkgtree/pkgtree.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ func ListPackages(fileRoot, importRoot string) (PackageTree, error) {
110110
// import paths.
111111
ip := filepath.ToSlash(filepath.Join(importRoot, strings.TrimPrefix(wp, fileRoot)))
112112

113+
// translate staging repo import path by cutting off the prefix
114+
stagingPattern := "/staging/src/"
115+
if p := strings.LastIndex(ip, stagingPattern); p != -1 {
116+
ip = ip[p+len(stagingPattern):]
117+
}
118+
113119
// Find all the imports, across all os/arch combos
114120
//p, err := fullPackageInDir(wp)
115121
p := &build.Package{
@@ -469,10 +475,10 @@ func (t PackageTree) ToReachMap(main, tests, backprop bool, ignore map[string]bo
469475
continue
470476
}
471477

472-
if !eqOrSlashedPrefix(imp, t.ImportRoot) {
473-
w.ex[imp] = true
474-
} else {
478+
if _, internal := t.Packages[imp]; internal {
475479
w.in[imp] = true
480+
} else {
481+
w.ex[imp] = true
476482
}
477483
}
478484

txn_writer.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,72 @@ func (sw SafeWriter) validate(root string, sm gps.SourceManager) error {
275275
return nil
276276
}
277277

278+
// createStagingLinksForPackage looks into <pkgPath>/staging/src and symlinks those staging
279+
// repositories into vendor/. If packages only contain subpackages, a deeper level is linked.
280+
// E.g. if <pkgPath>/staging/src/github.com has no real files and only directories the algorithm
281+
// looks at a deeper level, e.g. at pkgPath/staging/src/github.com/foo. If foo has files (for
282+
// example *.go files), a relative symlink is created:
283+
//
284+
// tempVendor/github.com/foo -> .../../../staging/src/github.com/foo
285+
//
286+
// The tempVendor directory corresponds logically to root/vendor. But, because th caller of
287+
// this func creates vendor/ dirs as temporary directories first, we have to support this
288+
// distinction.
289+
func createStagingLinksForPackage(root, pkgPath string, tempVendor string) error {
290+
stagingRoot := filepath.Join(pkgPath, "staging", "src")
291+
if _, err := os.Lstat(stagingRoot); os.IsNotExist(err) {
292+
return nil
293+
}
294+
295+
logicalVendor := filepath.Join(root, "vendor")
296+
return filepath.Walk(stagingRoot, func(wp string, fi os.FileInfo, err error) error {
297+
if err != nil && err != filepath.SkipDir {
298+
return err
299+
}
300+
if !fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
301+
return filepath.SkipDir
302+
}
303+
304+
// find out whether the directory has directories only
305+
f, err := os.Open(wp)
306+
if err != nil {
307+
return err
308+
}
309+
ffis, err := f.Readdir(0)
310+
f.Close()
311+
if err != nil {
312+
return err
313+
}
314+
filesFound := false
315+
for _, ffi := range ffis {
316+
if !ffi.IsDir() && !strings.HasPrefix(ffi.Name(), ".") {
317+
filesFound = true
318+
break
319+
}
320+
}
321+
322+
// dive deeper if no files where found, only more subdirectories
323+
if !filesFound {
324+
return nil
325+
}
326+
327+
// files were found. Let's create a symlink in the vendor dir
328+
ip := strings.TrimPrefix(wp, stagingRoot)
329+
if err := os.MkdirAll(filepath.Join(tempVendor, filepath.Dir(ip)), 0755); err != nil {
330+
return err
331+
}
332+
rel, err := filepath.Rel(filepath.Join(logicalVendor, filepath.Dir(ip)), wp)
333+
if err != nil {
334+
return err
335+
}
336+
if err := os.Symlink(rel, filepath.Join(tempVendor, ip)); err != nil {
337+
return err
338+
}
339+
340+
return filepath.SkipDir
341+
})
342+
}
343+
278344
// Write saves some combination of config yaml, lock, and a vendor tree.
279345
// root is the absolute path of root dir in which to write.
280346
// sm is only required if vendor is being written.
@@ -336,6 +402,20 @@ func (sw *SafeWriter) Write(root string, sm gps.SourceManager, noExamples bool)
336402
if err != nil {
337403
return errors.Wrap(err, "error while writing out vendor tree")
338404
}
405+
406+
// symlink staging repos of the root package
407+
if err := createStagingLinksForPackage(root, root, filepath.Join(td, "vendor")); err != nil {
408+
return errors.Wrap(err, "error creating staging symlinks")
409+
}
410+
411+
// symlink staging repos of the vendored packages. These are exported into the temporary
412+
// directory td. So we can use that as the root.
413+
for _, p := range sw.Lock.Projects() {
414+
pkgPath := filepath.Join(td, "vendor", string(p.Ident().ProjectRoot))
415+
if err := createStagingLinksForPackage(td, pkgPath, filepath.Join(td, "vendor")); err != nil {
416+
return errors.Wrap(err, fmt.Sprintf("error creating staging symlinks for vendored package %q", p.Ident().ProjectRoot))
417+
}
418+
}
339419
}
340420

341421
// Ensure vendor/.git is preserved if present

0 commit comments

Comments
 (0)