github.phpd.cn/thought-machine/please@v12.2.0+incompatible/tools/please_diff_graphs/plz_diff_graphs_main.go (about)

     1  // package main implements plz_diff_graphs, a small utility to take the JSON representation
     2  // of two build graphs (as output from 'plz query graph') and produce a list of targets
     3  // that have changed between the two.
     4  //
     5  // Note that the 'ordering' of the two graphs matters, hence their labels 'before' and 'after';
     6  // the operation is non-commutative because targets that are added appear and those deleted do not.
     7  //
     8  // It also accepts a list of filenames that have changed and invalidates targets appropriately.
     9  package main
    10  
    11  import (
    12  	"fmt"
    13  	"io/ioutil"
    14  	"os"
    15  	"strings"
    16  
    17  	"gopkg.in/op/go-logging.v1"
    18  
    19  	"cli"
    20  	"tools/please_diff_graphs/diff"
    21  )
    22  
    23  var log = logging.MustGetLogger("plz_diff_graphs")
    24  
    25  var opts = struct {
    26  	Usage        string
    27  	Verbosity    int      `short:"v" long:"verbosity" description:"Verbosity of output (higher number = more output, default 2 -> notice, warnings and errors only)" default:"2"`
    28  	Before       string   `short:"b" long:"before" required:"true" description:"File containing build graph before changes."`
    29  	After        string   `short:"a" long:"after" required:"true" description:"File containing build graph after changes."`
    30  	Include      []string `short:"i" long:"include" description:"Label of targets to include."`
    31  	Exclude      []string `short:"e" long:"exclude" description:"Label of targets to exclude." default:"manual" default:"manual:linux_amd64"`
    32  	NoRecurse    bool     `long:"norecurse" description:"Don't recurse into dependencies of rules to see if they've changed"`
    33  	ChangedFiles struct {
    34  		Files []string `positional-arg-name:"files" description:"Files that have changed. - to read from stdin."`
    35  	} `positional-args:"true"`
    36  }{
    37  	Usage: `
    38  please_diff_graphs is a small utility to calculate differences between two Please build graphs.
    39  
    40  Its inputs are two JSON graph files (produced using 'plz query graph') and any files that have changed.
    41  It will output a list of all build targets that have changed between the two.
    42  For example:
    43  
    44  please_diff_graphs -b before.json -a after.json src/core/my_file.go
    45  > //src/core:my_target
    46  > //src/elsewhere:some_other_target
    47  
    48  Note that the 'ordering' of the two graphs matters, hence their labels 'before' and 'after';
    49  the operation is non-commutative because targets that are added appear and those deleted do not.
    50  
    51  please_diff_graphs is mostly useful in conjunction with Please in a CI system; you can use it to
    52  formally determine what set of targets have changed in a diff and run the minimal set of affected tests.
    53  `,
    54  }
    55  
    56  func readStdin() []string {
    57  	stdin, err := ioutil.ReadAll(os.Stdin)
    58  	if err != nil {
    59  		fmt.Printf("%s\n", err)
    60  		os.Exit(1)
    61  	}
    62  	trimmed := strings.TrimSpace(string(stdin))
    63  	if trimmed == "" {
    64  		return []string{}
    65  	}
    66  	ret := strings.Split(trimmed, "\n")
    67  	for i, s := range ret {
    68  		ret[i] = strings.TrimSpace(s)
    69  	}
    70  	return ret
    71  }
    72  
    73  func main() {
    74  	cli.ParseFlagsOrDie("Please graph differ", "9.1.2", &opts)
    75  	cli.InitLogging(opts.Verbosity)
    76  	log.Warning("plz_diff_graphs has been deprecated in favour of 'plz query changes', consider using that instead")
    77  	before := diff.ParseGraphOrDie(opts.Before)
    78  	after := diff.ParseGraphOrDie(opts.After)
    79  	if len(opts.ChangedFiles.Files) == 1 && opts.ChangedFiles.Files[0] == "-" {
    80  		opts.ChangedFiles.Files = readStdin()
    81  	}
    82  	for _, label := range diff.Graphs(before, after, opts.ChangedFiles.Files, opts.Include, opts.Exclude, !opts.NoRecurse) {
    83  		fmt.Printf("%s\n", label)
    84  	}
    85  }