github.com/comcast/canticle@v0.0.0-20161108184242-c53cface56e8/canticles/get.go (about)

     1  package canticles
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"log"
     8  )
     9  
    10  type Get struct {
    11  	flags   *flag.FlagSet
    12  	Verbose bool
    13  	Update  bool
    14  	Source  string
    15  	Limit   int
    16  }
    17  
    18  func NewGet() *Get {
    19  	f := flag.NewFlagSet("get", flag.ExitOnError)
    20  	g := &Get{flags: f}
    21  	f.BoolVar(&g.Verbose, "v", false, "Be verbose when getting stuff")
    22  	f.BoolVar(&g.Update, "u", false, "Update branches where possible, print the results")
    23  	f.StringVar(&g.Source, "source", "", "Overide the VCS url to fetch this from")
    24  	f.IntVar(&g.Limit, "limit", 10, "Limit the number of fetches in flight at once to limit")
    25  	return g
    26  }
    27  
    28  var get = NewGet()
    29  
    30  var GetCommand = &Command{
    31  	Name:             "get",
    32  	UsageLine:        "get [-v] [-u] [-source] [-limit <n>]",
    33  	ShortDescription: "download dependencies as defined in the Canticle file",
    34  	LongDescription: `The get command fetches dependencies. When issued locally it looks...
    35  
    36  Specify -v to print out a verbose set of operations instead of just errors.
    37  
    38  Specify -u to update branches and print results.`,
    39  	Flags: get.flags,
    40  	Cmd:   get,
    41  }
    42  
    43  // Run the get command. Ignores args.
    44  func (g *Get) Run(args []string) {
    45  	if g.Verbose {
    46  		Verbose = true
    47  		defer func() { Verbose = false }()
    48  	}
    49  
    50  	pkgArgs := g.flags.Args()
    51  	if g.Source != "" && len(pkgArgs) > 1 {
    52  		log.Fatal("cant get may not be run with -source and multiple packages")
    53  	}
    54  	pkgs := ParseCmdLinePackages(pkgArgs)
    55  	for _, pkg := range pkgs {
    56  		if err := g.GetPackage(pkg); err != nil {
    57  			log.Fatal(err)
    58  		}
    59  	}
    60  }
    61  
    62  // Psuedocode
    63  // Load Canticle deps
    64  // Fetch canticle deps
    65  // Walk the dep tree and fetch anything else
    66  // Done
    67  
    68  // GetPackage fetches a package and all of it dependencies to either
    69  // the buildroot or the gopath.
    70  func (g *Get) GetPackage(path string) error {
    71  	LogVerbose("Fetching path %+v", path)
    72  	gopath, err := EnvGoPath()
    73  	if err != nil {
    74  		return err
    75  	}
    76  	resolvers := []RepoResolver{
    77  		&LocalRepoResolver{LocalPath: gopath},
    78  		&RemoteRepoResolver{gopath},
    79  		&DefaultRepoResolver{gopath},
    80  	}
    81  	resolver := NewMemoizedRepoResolver(&CompositeRepoResolver{resolvers})
    82  	depReader := &DepReader{gopath}
    83  
    84  	loader := &CanticleDepLoader{
    85  		Reader:   depReader,
    86  		Resolver: resolver,
    87  		Gopath:   gopath,
    88  		Update:   g.Update,
    89  		Limit:    g.Limit,
    90  	}
    91  	if errs := loader.FetchPath(path); len(errs) > 0 {
    92  		for _, err := range errs {
    93  			return fmt.Errorf("cant load package %s", err.Error())
    94  		}
    95  	}
    96  	if g.Update {
    97  		b, err := json.Marshal(loader.Updated())
    98  		if err != nil {
    99  			return err
   100  		}
   101  		fmt.Print("Updated packages: ", string(b))
   102  	}
   103  	return nil
   104  }