github.com/tiagovtristao/plz@v13.4.0+incompatible/src/export/export.go (about)

     1  // Package export handles exporting parts of the repo to other directories.
     2  // This is useful if, for example, one wanted to separate out part of
     3  // their repo with all dependencies.
     4  package export
     5  
     6  import (
     7  	"os"
     8  	"path"
     9  	"strings"
    10  
    11  	"gopkg.in/op/go-logging.v1"
    12  
    13  	"github.com/thought-machine/please/src/core"
    14  	"github.com/thought-machine/please/src/fs"
    15  	"github.com/thought-machine/please/src/gc"
    16  )
    17  
    18  var log = logging.MustGetLogger("export")
    19  
    20  // ToDir exports a set of targets to the given directory.
    21  // It dies on any errors.
    22  func ToDir(state *core.BuildState, dir string, targets []core.BuildLabel) {
    23  	done := map[*core.BuildTarget]bool{}
    24  	for _, target := range targets {
    25  		export(state.Graph, dir, state.Graph.TargetOrDie(target), done)
    26  	}
    27  	// Now write all the build files
    28  	packages := map[*core.Package]bool{}
    29  	for target := range done {
    30  		packages[state.Graph.PackageOrDie(target.Label)] = true
    31  	}
    32  	for pkg := range packages {
    33  		dest := path.Join(dir, pkg.Filename)
    34  		if err := fs.RecursiveCopy(pkg.Filename, dest, 0); err != nil {
    35  			log.Fatalf("Failed to copy BUILD file: %s\n", pkg.Filename)
    36  		}
    37  		// Now rewrite the unused targets out of it
    38  		victims := []string{}
    39  		for _, target := range pkg.AllTargets() {
    40  			if !done[target] {
    41  				victims = append(victims, target.Label.Name)
    42  			}
    43  		}
    44  		if err := gc.RewriteFile(state, dest, victims); err != nil {
    45  			log.Fatalf("Failed to rewrite BUILD file: %s\n", err)
    46  		}
    47  	}
    48  }
    49  
    50  // export implements the logic of ToDir, but prevents repeating targets.
    51  func export(graph *core.BuildGraph, dir string, target *core.BuildTarget, done map[*core.BuildTarget]bool) {
    52  	if done[target] {
    53  		return
    54  	}
    55  	for _, src := range target.AllSources() {
    56  		if src.Label() == nil { // We'll handle these dependencies later
    57  			for _, p := range src.FullPaths(graph) {
    58  				if !strings.HasPrefix(p, "/") { // Don't copy system file deps.
    59  					if err := fs.RecursiveCopy(p, path.Join(dir, p), 0); err != nil {
    60  						log.Fatalf("Error copying file: %s\n", err)
    61  					}
    62  				}
    63  			}
    64  		}
    65  	}
    66  	done[target] = true
    67  	for _, dep := range target.Dependencies() {
    68  		if parent := dep.Parent(graph); parent != nil && parent != target.Parent(graph) && parent != target {
    69  			export(graph, dir, parent, done)
    70  		} else {
    71  			export(graph, dir, dep, done)
    72  		}
    73  	}
    74  	for _, subinclude := range graph.PackageOrDie(target.Label).Subincludes {
    75  		export(graph, dir, graph.TargetOrDie(subinclude), done)
    76  	}
    77  }
    78  
    79  // Outputs exports the outputs of a target.
    80  func Outputs(state *core.BuildState, dir string, targets []core.BuildLabel) {
    81  	for _, label := range targets {
    82  		target := state.Graph.TargetOrDie(label)
    83  		for _, out := range target.Outputs() {
    84  			fullPath := path.Join(dir, out)
    85  			outDir := path.Dir(fullPath)
    86  			if err := os.MkdirAll(outDir, core.DirPermissions); err != nil {
    87  				log.Fatalf("Failed to create export dir %s: %s", outDir, err)
    88  			}
    89  			if err := fs.RecursiveCopy(path.Join(target.OutDir(), out), fullPath, target.OutMode()|0200); err != nil {
    90  				log.Fatalf("Failed to copy export file: %s", err)
    91  			}
    92  		}
    93  	}
    94  }