func()

in go/pkg/client/tree.go [513:581]


func (c *Client) ComputeOutputsToUpload(execRoot, workingDir string, paths []string, cache filemetadata.Cache, sb command.SymlinkBehaviorType) (map[digest.Digest]*uploadinfo.Entry, *repb.ActionResult, error) {
	outs := make(map[digest.Digest]*uploadinfo.Entry)
	resPb := &repb.ActionResult{}
	for _, path := range paths {
		absPath := filepath.Join(execRoot, workingDir, path)
		if _, err := getRelPath(execRoot, absPath); err != nil {
			return nil, nil, err
		}
		meta := cache.Get(absPath)
		if meta.Err != nil {
			if e, ok := meta.Err.(*filemetadata.FileError); ok && e.IsNotFound {
				continue // Ignore missing outputs.
			}
			return nil, nil, meta.Err
		}
		normPath, err := filepath.Rel(filepath.Join(execRoot, workingDir), absPath)
		if err != nil {
			return nil, nil, err
		}
		if !meta.IsDirectory {
			// A regular file.
			ue := uploadinfo.EntryFromFile(meta.Digest, absPath)
			outs[meta.Digest] = ue
			resPb.OutputFiles = append(resPb.OutputFiles, &repb.OutputFile{Path: normPath, Digest: meta.Digest.ToProto(), IsExecutable: meta.IsExecutable})
			continue
		}
		// A directory.
		fs := make(map[string]*fileSysNode)
		if e := loadFiles(absPath, "", "", nil, []string{"."}, fs, cache, treeSymlinkOpts(c.TreeSymlinkOpts, sb)); e != nil {
			return nil, nil, e
		}
		ft, err := buildTree(fs)
		if err != nil {
			return nil, nil, err
		}

		treePb := &repb.Tree{}
		rootDir, childDirs, files, err := packageDirectories(ft)
		if err != nil {
			return nil, nil, err
		}
		ue, err := uploadinfo.EntryFromProto(rootDir)
		if err != nil {
			return nil, nil, err
		}
		outs[ue.Digest] = ue
		treePb.Root = rootDir
		for _, c := range childDirs {
			treePb.Children = append(treePb.Children, c)
		}
		ue, err = uploadinfo.EntryFromProto(treePb)
		if err != nil {
			return nil, nil, err
		}
		outs[ue.Digest] = ue
		for _, ue := range files {
			outs[ue.Digest] = ue
		}
		resPb.OutputDirectories = append(resPb.OutputDirectories, &repb.OutputDirectory{Path: normPath, TreeDigest: ue.Digest.ToProto()})
		// Upload the child directories individually as well
		ueRoot, _ := uploadinfo.EntryFromProto(treePb.Root)
		outs[ueRoot.Digest] = ueRoot
		for _, child := range treePb.Children {
			ueChild, _ := uploadinfo.EntryFromProto(child)
			outs[ueChild.Digest] = ueChild
		}
	}
	return outs, resPb, nil
}