| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | |
| 3 // that can be found in the LICENSE file. | |
| 4 | |
| 5 package main | |
| 6 | |
| 7 import ( | |
| 8 "strings" | |
| 9 | |
| 10 "github.com/luci/luci-go/common/errors" | |
| 11 "github.com/luci/luci-go/deploytool/managedfs" | |
| 12 ) | |
| 13 | |
| 14 // stageGoPath creates a GOPATH-compatible directory consisting of all of the | |
| 15 // GOPATHs configured in the supplied components sources. The path begins with | |
| 16 // "src/", and is rooted in the supplied root. | |
| 17 func stageGoPath(w *work, comp *layoutDeploymentComponent, root *managedfs.Dir)
error { | |
| 18 // Build our GoPath sources. To do this, we will build subdirectories un
der | |
| 19 // "src" for the various GoPath components, then symlink the last direct
ory | |
| 20 // component to the actual GOPATH root. | |
| 21 // | |
| 22 // We need to detect path conflicts where one GOPATH checks out into the | |
| 23 // parent of another GOPATH, e.g.: | |
| 24 // /foo/bar/baz => A | |
| 25 // /foo/bar => B | |
| 26 // | |
| 27 // We do this by checking intermediate Go paths against our deployment p
lan | |
| 28 // incrementally. | |
| 29 dirs := make(map[string]struct{}) | |
| 30 build := make(map[string]string) | |
| 31 for _, src := range comp.sources { | |
| 32 if src.InitResult == nil { | |
| 33 continue | |
| 34 } | |
| 35 | |
| 36 for _, gopath := range src.InitResult.GoPath { | |
| 37 // Make sure our Go package isn't a directory. | |
| 38 if _, ok := dirs[gopath.GoPackage]; ok { | |
| 39 return errors.Reason("GOPATH %(package)q is both
a package and directory"). | |
| 40 D("package", gopath.GoPackage).Err() | |
| 41 } | |
| 42 | |
| 43 // Check intermediate paths to make sure there isn't a d
eployment | |
| 44 // conflict. | |
| 45 pkgParts := splitGoPackage(gopath.GoPackage) | |
| 46 for _, parentPkg := range pkgParts[:len(pkgParts)-1] { | |
| 47 if _, ok := build[parentPkg]; ok { | |
| 48 return errors.Reason("GOPATH %(package)q
is both a package and directory"). | |
| 49 D("package", parentPkg).Err() | |
| 50 } | |
| 51 dirs[parentPkg] = struct{}{} | |
| 52 } | |
| 53 | |
| 54 // Everything checks out, add this link. | |
| 55 build[gopath.GoPackage] = src.pathTo(gopath.Path, "") | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 srcDir, err := root.EnsureDirectory("src") | |
| 60 if err != nil { | |
| 61 return err | |
| 62 } | |
| 63 | |
| 64 for pkg, src := range build { | |
| 65 var ( | |
| 66 pkgComponents = strings.Split(pkg, "/") | |
| 67 d = srcDir | |
| 68 ) | |
| 69 for _, comp := range pkgComponents[:len(pkgComponents)-1] { | |
| 70 var err error | |
| 71 d, err = d.EnsureDirectory(comp) | |
| 72 if err != nil { | |
| 73 return errors.Annotate(err).Reason("could not cr
eate GOPATH parent directory [%(path)s]"). | |
| 74 D("path", d).Err() | |
| 75 } | |
| 76 } | |
| 77 link := d.File(pkgComponents[len(pkgComponents)-1]) | |
| 78 if err := link.SymlinkFrom(src, true); err != nil { | |
| 79 return errors.Annotate(err).Reason("failed to create GOP
ATH link").Err() | |
| 80 } | |
| 81 } | |
| 82 return nil | |
| 83 } | |
| OLD | NEW |