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

Commit 82837cf

Browse files
committed
PoC: support staging directory
1 parent e93d78b commit 82837cf

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

internal/gps/pkgtree/pkgtree.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ func ListPackages(fileRoot, importRoot string) (PackageTree, error) {
122122
// import paths.
123123
ip := filepath.ToSlash(filepath.Join(importRoot, strings.TrimPrefix(wp, fileRoot)))
124124

125+
// translate staging repo import path by cutting off the prefix
126+
stagingPattern := "/staging/src/"
127+
if p := strings.LastIndex(ip, stagingPattern); p != -1 {
128+
ip = ip[p+len(stagingPattern):]
129+
}
130+
125131
// Find all the imports, across all os/arch combos
126132
//p, err := fullPackageInDir(wp)
127133
p := &build.Package{
@@ -488,10 +494,10 @@ func (t PackageTree) ToReachMap(main, tests, backprop bool, ignore map[string]bo
488494
continue
489495
}
490496

491-
if !eqOrSlashedPrefix(imp, t.ImportRoot) {
492-
w.ex[imp] = true
493-
} else {
497+
if _, internal := t.Packages[imp]; internal {
494498
w.in[imp] = true
499+
} else {
500+
w.ex[imp] = true
495501
}
496502
}
497503

txn_writer.go

+80
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,72 @@ func (sw SafeWriter) validate(root string, sm gps.SourceManager) error {
273273
return nil
274274
}
275275

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

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

0 commit comments

Comments
 (0)