// RetrieveArtifact takes in the artifact path as a parameter and checks in the base server // file directory to see if the file exists in the given path. If found, the function will // return whatever's been stored there, which might be a directory and therefore contain // multiple files to be returned. func (cache *Cache) RetrieveArtifact(artPath string) (map[string][]byte, error) { ret := map[string][]byte{} if core.IsGlob(artPath) { for _, art := range core.Glob(cache.rootPath, []string{artPath}, nil, nil, true) { fullPath := path.Join(cache.rootPath, art) lock := cache.lockFile(fullPath, false, 0) body, err := ioutil.ReadFile(fullPath) if lock != nil { lock.RUnlock() } if err != nil { return nil, err } ret[art] = body } return ret, nil } fullPath := path.Join(cache.rootPath, artPath) lock := cache.lockFile(artPath, false, 0) if lock == nil { // Can happen if artPath is a directory; we only store artifacts as files. // (This is a debatable choice; it's a bit crap either way). if info, err := os.Stat(fullPath); err == nil && info.IsDir() { return cache.retrieveDir(artPath) } return nil, os.ErrNotExist } defer lock.RUnlock() if err := filepath.Walk(fullPath, func(name string, info os.FileInfo, err error) error { if err != nil { return err } else if !info.IsDir() { body, err := ioutil.ReadFile(name) if err != nil { return err } ret[name[len(cache.rootPath)+1:]] = body } return nil }); err != nil { return nil, err } return ret, nil }
// parsePackage performs the initial parse of a package. // It's assumed that the caller used firstToParse to ascertain that they only call this once per package. func parsePackage(state *core.BuildState, label, dependor core.BuildLabel) *core.Package { packageName := label.PackageName pkg := core.NewPackage(packageName) if pkg.Filename = buildFileName(state, packageName); pkg.Filename == "" { exists := core.PathExists(packageName) // Handle quite a few cases to provide more obvious error messages. if dependor != core.OriginalTarget && exists { panic(fmt.Sprintf("%s depends on %s, but there's no BUILD file in %s/", dependor, label, packageName)) } else if dependor != core.OriginalTarget { panic(fmt.Sprintf("%s depends on %s, but the directory %s doesn't exist", dependor, label, packageName)) } else if exists { panic(fmt.Sprintf("Can't build %s; there's no BUILD file in %s/", label, packageName)) } panic(fmt.Sprintf("Can't build %s; the directory %s doesn't exist", label, packageName)) } if parsePackageFile(state, pkg.Filename, pkg) { return nil // Indicates deferral } for _, target := range pkg.Targets { state.Graph.AddTarget(target) for _, out := range target.DeclaredOutputs() { pkg.MustRegisterOutput(out, target) } for _, out := range target.TestOutputs { if !core.IsGlob(out) { pkg.MustRegisterOutput(out, target) } } } // Do this in a separate loop so we get intra-package dependencies right now. for _, target := range pkg.Targets { for _, dep := range target.DeclaredDependencies() { state.Graph.AddDependency(target.Label, dep) } } state.Graph.AddPackage(pkg) // Calling this means nobody else will add entries to pendingTargets for this package. return pkg }