github.com/sc0rp1us/gb@v0.4.1-0.20160319180011-4ba8cf1baa5a/cmd/gb-vendor/update.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"path/filepath"
     7  
     8  	"github.com/constabulary/gb"
     9  	"github.com/constabulary/gb/cmd"
    10  	"github.com/constabulary/gb/fileutils"
    11  	"github.com/constabulary/gb/vendor"
    12  )
    13  
    14  var (
    15  	// gb vendor update flags
    16  
    17  	// update all dependencies
    18  	updateAll bool
    19  )
    20  
    21  func addUpdateFlags(fs *flag.FlagSet) {
    22  	fs.BoolVar(&updateAll, "all", false, "update all dependencies")
    23  	fs.BoolVar(&insecure, "precaire", false, "allow the use of insecure protocols")
    24  }
    25  
    26  var cmdUpdate = &cmd.Command{
    27  	Name:      "update",
    28  	UsageLine: "update [-all] import",
    29  	Short:     "update a local dependency",
    30  	Long: `gb vendor update will replaces the source with the latest available from the head of the master branch.
    31  
    32  Updating from one copy of a dependency to another comes with several restrictions.
    33  The first is you can only update to the head of the branch your dependency was vendered from, switching branches is not supported.
    34  The second restriction is if you have used -tag or -revision while vendoring a dependency, your dependency is "headless"
    35  (to borrow a term from git) and cannot be updated.
    36  
    37  To update across branches, or from one tag/revision to another, you must first use gb vendor delete to remove the dependency, then
    38  gb vendor fetch [-tag | -revision | -branch ] [-precaire] to replace it.
    39  
    40  Flags:
    41  	-all
    42  		will update all dependencies in the manifest, otherwise only the dependency supplied.
    43  	-precaire
    44  		allow the use of insecure protocols.
    45  
    46  `,
    47  	Run: func(ctx *gb.Context, args []string) error {
    48  		if len(args) != 1 && !updateAll {
    49  			return fmt.Errorf("update: import path or --all flag is missing")
    50  		} else if len(args) == 1 && updateAll {
    51  			return fmt.Errorf("update: you cannot specify path and --all flag at once")
    52  		}
    53  
    54  		m, err := vendor.ReadManifest(manifestFile(ctx))
    55  		if err != nil {
    56  			return fmt.Errorf("could not load manifest: %v", err)
    57  		}
    58  
    59  		var dependencies []vendor.Dependency
    60  		if updateAll {
    61  			dependencies = make([]vendor.Dependency, len(m.Dependencies))
    62  			copy(dependencies, m.Dependencies)
    63  		} else {
    64  			p := args[0]
    65  			dependency, err := m.GetDependencyForImportpath(p)
    66  			if err != nil {
    67  				return fmt.Errorf("could not get dependency: %v", err)
    68  			}
    69  			dependencies = append(dependencies, dependency)
    70  		}
    71  
    72  		for _, d := range dependencies {
    73  			err = m.RemoveDependency(d)
    74  			if err != nil {
    75  				return fmt.Errorf("dependency could not be deleted from manifest: %v", err)
    76  			}
    77  
    78  			repo, extra, err := vendor.DeduceRemoteRepo(d.Importpath, insecure)
    79  			if err != nil {
    80  				return fmt.Errorf("could not determine repository for import %q", d.Importpath)
    81  			}
    82  
    83  			wc, err := repo.Checkout(d.Branch, "", "")
    84  			if err != nil {
    85  				return err
    86  			}
    87  
    88  			rev, err := wc.Revision()
    89  			if err != nil {
    90  				return err
    91  			}
    92  
    93  			branch, err := wc.Branch()
    94  			if err != nil {
    95  				return err
    96  			}
    97  
    98  			dep := vendor.Dependency{
    99  				Importpath: d.Importpath,
   100  				Repository: repo.URL(),
   101  				Revision:   rev,
   102  				Branch:     branch,
   103  				Path:       extra,
   104  			}
   105  
   106  			if err := fileutils.RemoveAll(filepath.Join(ctx.Projectdir(), "vendor", "src", filepath.FromSlash(d.Importpath))); err != nil {
   107  				// TODO(dfc) need to apply vendor.cleanpath here to remove indermediate directories.
   108  				return fmt.Errorf("dependency could not be deleted: %v", err)
   109  			}
   110  
   111  			dst := filepath.Join(ctx.Projectdir(), "vendor", "src", filepath.FromSlash(dep.Importpath))
   112  			src := filepath.Join(wc.Dir(), dep.Path)
   113  
   114  			if err := fileutils.Copypath(dst, src); err != nil {
   115  				return err
   116  			}
   117  
   118  			if err := m.AddDependency(dep); err != nil {
   119  				return err
   120  			}
   121  
   122  			if err := vendor.WriteManifest(manifestFile(ctx), m); err != nil {
   123  				return err
   124  			}
   125  
   126  			if err := wc.Destroy(); err != nil {
   127  				return err
   128  			}
   129  		}
   130  
   131  		return nil
   132  	},
   133  	AddFlags: addUpdateFlags,
   134  }