// testTargets handles test targets which can be given in two formats; a list of targets or a single // target with a list of trailing arguments. // Alternatively they can be completely omitted in which case we test everything under the working dir. func testTargets(target core.BuildLabel, args []string) []core.BuildLabel { if target.Name == "" { return core.InitialPackage() } else if len(args) > 0 && core.LooksLikeABuildLabel(args[0]) { opts.Cover.Args.Args = []string{} opts.Test.Args.Args = []string{} return append(core.ParseBuildLabels(args), target) } else { return []core.BuildLabel{target} } }
// Replaces a single escape sequence in a command. func replaceSequence(target *core.BuildTarget, in string, runnable, multiple, dir, outPrefix, hash, test bool) string { if core.LooksLikeABuildLabel(in) { label := core.ParseBuildLabel(in, target.Label.PackageName) return replaceSequenceLabel(target, label, in, runnable, multiple, dir, outPrefix, hash, test, true) } for _, src := range target.AllSources() { if label := src.Label(); label != nil && src.String() == in { return replaceSequenceLabel(target, *label, in, runnable, multiple, dir, outPrefix, hash, test, false) } } if hash { return base64.RawURLEncoding.EncodeToString(mustPathHash(path.Join(target.Label.PackageName, in))) } return quote(path.Join(target.Label.PackageName, in)) }
//export GetLabels func GetLabels(cPackage uintptr, cTarget *C.char, cPrefix *C.char) **C.char { // Two formats are supported here: either passing just the name of a target in the current // package, or a build label referring specifically to one. lbl := C.GoString(cTarget) prefix := C.GoString(cPrefix) if core.LooksLikeABuildLabel(lbl) { label, err := core.TryParseBuildLabel(lbl, unsizep(cPackage).Name) if err != nil { log.Fatalf("%s", err) // TODO(pebers): report proper errors here and below } return stringSliceToCStringArray(getLabels(core.State.Graph.TargetOrDie(label), prefix, core.Built)) } target, err := getTargetPost(cPackage, cTarget) if err != nil { log.Fatalf("%s", err) } return stringSliceToCStringArray(getLabels(target, prefix, core.Building)) }
// Parses an incoming source label as either a file or a build label. // Identifies if the file is owned by this package and returns an error if not. func parseSource(src, packageName string, systemAllowed bool) (core.BuildInput, error) { if core.LooksLikeABuildLabel(src) { return core.TryParseBuildLabel(src, packageName) } else if src == "" { return nil, fmt.Errorf("Empty source path (in package %s)", packageName) } else if strings.Contains(src, "../") { return nil, fmt.Errorf("'%s' (in package %s) is an invalid path; build target paths can't contain ../", src, packageName) } else if src[0] == '/' || src[0] == '~' { if !systemAllowed { return nil, fmt.Errorf("'%s' (in package %s) is an absolute path; that's not allowed.", src, packageName) } return core.SystemFileLabel{Path: core.ExpandHomePath(src)}, nil } else if strings.Contains(src, "/") { // Target is in a subdirectory, check nobody else owns that. for dir := path.Dir(path.Join(packageName, src)); dir != packageName && dir != "."; dir = path.Dir(dir) { if core.IsPackage(dir) { return nil, fmt.Errorf("Package %s tries to use file %s, but that belongs to another package (%s).", packageName, src, dir) } } } return core.FileLabel{File: src, Package: packageName}, nil }
//export AddTool func AddTool(cTarget uintptr, cTool *C.char) *C.char { target := unsizet(cTarget) src := C.GoString(cTool) if !core.LooksLikeABuildLabel(src) && !strings.Contains(src, "/") { // non-specified paths like "bash" are turned into absolute ones based on plz's PATH. // awkwardly this means we can't use the builtin exec.LookPath because the current // environment variable isn't necessarily the same as what's in our config. var err error src, err = core.LookPath(src, core.State.Config.Build.Path) if err != nil { return C.CString(err.Error()) } } tool, err := parseSource(src, target.Label.PackageName, true) if err != nil { return C.CString(err.Error()) } target.Tools = append(target.Tools, tool) if label := tool.Label(); label != nil { target.AddDependency(*label) } return nil }