예제 #1
0
//export Glob
func Glob(cPackage *C.char, cIncludes **C.char, numIncludes int, cExcludes **C.char, numExcludes int, includeHidden bool) **C.char {
	packageName := C.GoString(cPackage)
	includes := cStringArrayToStringSlice(cIncludes, numIncludes, "")
	prefixedExcludes := cStringArrayToStringSlice(cExcludes, numExcludes, packageName)
	excludes := cStringArrayToStringSlice(cExcludes, numExcludes, "")
	filenames := core.Glob(packageName, includes, prefixedExcludes, excludes, includeHidden)
	return stringSliceToCStringArray(filenames)
}
예제 #2
0
func moveOutputs(state *core.BuildState, target *core.BuildTarget) ([]string, bool, error) {
	// Before we write any outputs, we must remove the old hash file to avoid it being
	// left in an inconsistent state.
	if err := os.RemoveAll(ruleHashFileName(target)); err != nil {
		return nil, true, err
	}
	changed := false
	tmpDir := target.TmpDir()
	outDir := target.OutDir()
	for _, output := range target.Outputs() {
		tmpOutput := path.Join(tmpDir, output)
		realOutput := path.Join(outDir, output)
		if !core.PathExists(tmpOutput) {
			return nil, true, fmt.Errorf("Rule %s failed to create output %s", target.Label, tmpOutput)
		}
		// If output is a symlink, dereference it. Otherwise, for efficiency,
		// we can just move it without a full copy (saves copying large .jar files etc).
		dereferencedPath, err := filepath.EvalSymlinks(tmpOutput)
		if err != nil {
			return nil, true, err
		}
		// NB. false -> not filegroup, we wouldn't be here if it was.
		outputChanged, err := moveOutput(target, dereferencedPath, realOutput, false)
		if err != nil {
			return nil, true, err
		}
		changed = changed || outputChanged
	}
	if changed {
		log.Debug("Outputs for %s have changed", target.Label)
	} else {
		log.Debug("Outputs for %s are unchanged", target.Label)
	}
	// Optional outputs get moved but don't contribute to the hash or for incrementality.
	// Glob patterns are supported on these.
	extraOuts := []string{}
	for _, output := range core.Glob(tmpDir, target.OptionalOutputs, nil, nil, true) {
		log.Debug("Discovered optional output %s", output)
		tmpOutput := path.Join(tmpDir, output)
		realOutput := path.Join(outDir, output)
		if _, err := moveOutput(target, tmpOutput, realOutput, false); err != nil {
			return nil, changed, err
		}
		extraOuts = append(extraOuts, output)
	}
	return extraOuts, changed, nil
}
예제 #3
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
}