示例#1
0
// 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
}
示例#2
0
// 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
}