github.com/ngdinhtoan/glide@v0.12.3/glide.go (about)

     1  // Glide is a command line utility that manages Go project dependencies.
     2  //
     3  // Configureation of where to start is managed via a glide.yaml in the root of a
     4  // project. The yaml
     5  //
     6  // A glide.yaml file looks like:
     7  //
     8  //		package: github.com/Masterminds/glide
     9  //		imports:
    10  //		- package: github.com/Masterminds/cookoo
    11  //		- package: github.com/kylelemons/go-gypsy
    12  //		  subpackages:
    13  //		  - yaml
    14  //
    15  // Glide puts dependencies in a vendor directory. Go utilities require this to
    16  // be in your GOPATH. Glide makes this easy.
    17  //
    18  // For more information use the `glide help` command or see https://glide.sh
    19  package main
    20  
    21  import (
    22  	"path/filepath"
    23  
    24  	"github.com/Masterminds/glide/action"
    25  	"github.com/Masterminds/glide/cache"
    26  	"github.com/Masterminds/glide/msg"
    27  	gpath "github.com/Masterminds/glide/path"
    28  	"github.com/Masterminds/glide/repo"
    29  	"github.com/Masterminds/glide/util"
    30  
    31  	"github.com/codegangsta/cli"
    32  
    33  	"fmt"
    34  	"os"
    35  )
    36  
    37  var version = "0.12.0-dev"
    38  
    39  const usage = `Vendor Package Management for your Go projects.
    40  
    41     Each project should have a 'glide.yaml' file in the project directory. Files
    42     look something like this:
    43  
    44         package: github.com/Masterminds/glide
    45         imports:
    46         - package: github.com/Masterminds/cookoo
    47           version: 1.1.0
    48         - package: github.com/kylelemons/go-gypsy
    49           subpackages:
    50           - yaml
    51  
    52     For more details on the 'glide.yaml' files see the documentation at
    53     https://glide.sh/docs/glide.yaml
    54  `
    55  
    56  // VendorDir default vendor directory name
    57  var VendorDir = "vendor"
    58  
    59  func main() {
    60  	app := cli.NewApp()
    61  	app.Name = "glide"
    62  	app.Usage = usage
    63  	app.Version = version
    64  	app.Flags = []cli.Flag{
    65  		cli.StringFlag{
    66  			Name:  "yaml, y",
    67  			Value: "glide.yaml",
    68  			Usage: "Set a YAML configuration file.",
    69  		},
    70  		cli.BoolFlag{
    71  			Name:  "quiet, q",
    72  			Usage: "Quiet (no info or debug messages)",
    73  		},
    74  		cli.BoolFlag{
    75  			Name:   "verbose",
    76  			Usage:  "Print detailed informational messages",
    77  			Hidden: true,
    78  		},
    79  		cli.BoolFlag{
    80  			Name:  "debug",
    81  			Usage: "Print debug verbose informational messages",
    82  		},
    83  		cli.StringFlag{
    84  			Name:   "home",
    85  			Value:  gpath.Home(),
    86  			Usage:  "The location of Glide files",
    87  			EnvVar: "GLIDE_HOME",
    88  		},
    89  		cli.StringFlag{
    90  			Name:   "tmp",
    91  			Value:  "",
    92  			Usage:  "The temp directory to use. Defaults to systems temp",
    93  			EnvVar: "GLIDE_TMP",
    94  		},
    95  		cli.BoolFlag{
    96  			Name:  "no-color",
    97  			Usage: "Turn off colored output for log messages",
    98  		},
    99  	}
   100  	app.CommandNotFound = func(c *cli.Context, command string) {
   101  		// TODO: Set some useful env vars.
   102  		action.Plugin(command, os.Args)
   103  	}
   104  	app.Before = startup
   105  	app.After = shutdown
   106  	app.Commands = commands()
   107  
   108  	// Detect errors from the Before and After calls and exit on them.
   109  	if err := app.Run(os.Args); err != nil {
   110  		msg.Err(err.Error())
   111  		os.Exit(1)
   112  	}
   113  
   114  	// If there was a Error message exit non-zero.
   115  	if msg.HasErrored() {
   116  		m := msg.Color(msg.Red, "An Error has occurred")
   117  		msg.Msg(m)
   118  		os.Exit(2)
   119  	}
   120  }
   121  
   122  func commands() []cli.Command {
   123  	return []cli.Command{
   124  		{
   125  			Name:      "create",
   126  			ShortName: "init",
   127  			Usage:     "Initialize a new project, creating a glide.yaml file",
   128  			Description: `This command starts from a project without Glide and
   129     sets it up. It generates a glide.yaml file, parsing your codebase to guess
   130     the dependencies to include. Once this step is done you may edit the
   131     glide.yaml file to update imported dependency properties such as the version
   132     or version range to include.
   133  
   134     To fetch the dependencies you may run 'glide install'.`,
   135  			Flags: []cli.Flag{
   136  				cli.BoolFlag{
   137  					Name:  "skip-import",
   138  					Usage: "When initializing skip importing from other package managers.",
   139  				},
   140  				cli.BoolFlag{
   141  					Name:  "non-interactive",
   142  					Usage: "Disable interactive prompts.",
   143  				},
   144  			},
   145  			Action: func(c *cli.Context) error {
   146  				action.Create(".", c.Bool("skip-import"), c.Bool("non-interactive"))
   147  				return nil
   148  			},
   149  		},
   150  		{
   151  			Name:      "config-wizard",
   152  			ShortName: "cw",
   153  			Usage:     "Wizard that makes optional suggestions to improve config in a glide.yaml file.",
   154  			Description: `Glide will analyze a projects glide.yaml file and the imported
   155  		projects to find ways the glide.yaml file can potentially be improved. It
   156  		will then interactively make suggestions that you can skip or accept.`,
   157  			Action: func(c *cli.Context) error {
   158  				action.ConfigWizard(".")
   159  				return nil
   160  			},
   161  		},
   162  		{
   163  			Name:  "get",
   164  			Usage: "Install one or more packages into `vendor/` and add dependency to glide.yaml.",
   165  			Description: `Gets one or more package (like 'go get') and then adds that file
   166     to the glide.yaml file. Multiple package names can be specified on one line.
   167  
   168         $ glide get github.com/Masterminds/cookoo/web
   169  
   170     The above will install the project github.com/Masterminds/cookoo and add
   171     the subpackage 'web'.
   172  
   173     If a fetched dependency has a glide.yaml file, configuration from Godep,
   174     GPM, GOM, or GB Glide that configuration will be used to find the dependencies
   175     and versions to fetch. If those are not available the dependent packages will
   176     be fetched as either a version specified elsewhere or the latest version.
   177  
   178     When adding a new dependency Glide will perform an update to work out the
   179     the versions for the dependencies of this dependency (transitive ones). This
   180     will generate an updated glide.lock file with specific locked versions to use.
   181  
   182     The '--strip-vendor' flag will remove any nested 'vendor' folders and
   183     'Godeps/_workspace' folders after an update (along with undoing any Godep
   184     import rewriting). Note, The Godeps specific functionality is deprecated and
   185     will be removed when most Godeps users have migrated to using the vendor
   186     folder.`,
   187  			Flags: []cli.Flag{
   188  				cli.BoolFlag{
   189  					Name:  "test",
   190  					Usage: "Add test dependencies.",
   191  				},
   192  				cli.BoolFlag{
   193  					Name:  "insecure",
   194  					Usage: "Use http:// rather than https:// to retrieve pacakges.",
   195  				},
   196  				cli.BoolFlag{
   197  					Name:  "no-recursive, quick",
   198  					Usage: "Disable updating dependencies' dependencies.",
   199  				},
   200  				cli.BoolFlag{
   201  					Name:  "force",
   202  					Usage: "If there was a change in the repo or VCS switch to new one. Warning, changes will be lost.",
   203  				},
   204  				cli.BoolFlag{
   205  					Name:  "all-dependencies",
   206  					Usage: "This will resolve all dependencies for all packages, not just those directly used.",
   207  				},
   208  				cli.BoolFlag{
   209  					Name:   "update-vendored, u",
   210  					Usage:  "Update vendored packages (without local VCS repo). Warning, changes will be lost.",
   211  					Hidden: true,
   212  				},
   213  				cli.BoolFlag{
   214  					Name:   "cache",
   215  					Usage:  "When downloading dependencies attempt to cache them.",
   216  					Hidden: true,
   217  				},
   218  				cli.BoolFlag{
   219  					Name:   "cache-gopath",
   220  					Usage:  "When downloading dependencies attempt to put them in the GOPATH, too.",
   221  					Hidden: true,
   222  				},
   223  				cli.BoolFlag{
   224  					Name:   "use-gopath",
   225  					Usage:  "Copy dependencies from the GOPATH if they exist there.",
   226  					Hidden: true,
   227  				},
   228  				cli.BoolFlag{
   229  					Name:  "resolve-current",
   230  					Usage: "Resolve dependencies for only the current system rather than all build modes.",
   231  				},
   232  				cli.BoolFlag{
   233  					Name:   "strip-vcs, s",
   234  					Usage:  "Removes version control metadata (e.g, .git directory) from the vendor folder.",
   235  					Hidden: true,
   236  				},
   237  				cli.BoolFlag{
   238  					Name:  "strip-vendor, v",
   239  					Usage: "Removes nested vendor and Godeps/_workspace directories.",
   240  				},
   241  				cli.BoolFlag{
   242  					Name:  "non-interactive",
   243  					Usage: "Disable interactive prompts.",
   244  				},
   245  				cli.BoolFlag{
   246  					Name:  "skip-test",
   247  					Usage: "Resolve dependencies in test files.",
   248  				},
   249  			},
   250  			Action: func(c *cli.Context) error {
   251  				if c.Bool("delete") {
   252  					msg.Warn("The --delete flag is deprecated. This now works by default.")
   253  				}
   254  				if c.Bool("update-vendored") {
   255  					msg.Warn("The --update-vendored flag is deprecated. This now works by default.")
   256  				}
   257  				if c.String("file") != "" {
   258  					msg.Warn("The --flag flag is deprecated.")
   259  				}
   260  				if c.Bool("cache") {
   261  					msg.Warn("The --cache flag is deprecated. This now works by default.")
   262  				}
   263  				if c.Bool("cache-gopath") {
   264  					msg.Warn("The --cache-gopath flag is deprecated.")
   265  				}
   266  				if c.Bool("use-gopath") {
   267  					msg.Warn("The --use-gopath flag is deprecated. Please see overrides.")
   268  				}
   269  				if c.Bool("strip-vcs") {
   270  					msg.Warn("The --strip-vcs flag is deprecated. This now works by default.")
   271  				}
   272  
   273  				if len(c.Args()) < 1 {
   274  					fmt.Println("Oops! Package name is required.")
   275  					os.Exit(1)
   276  				}
   277  
   278  				if c.Bool("resolve-current") {
   279  					util.ResolveCurrent = true
   280  					msg.Warn("Only resolving dependencies for the current OS/Arch")
   281  				}
   282  
   283  				inst := repo.NewInstaller()
   284  				inst.Force = c.Bool("force")
   285  				inst.ResolveAllFiles = c.Bool("all-dependencies")
   286  				inst.ResolveTest = !c.Bool("skip-test")
   287  				packages := []string(c.Args())
   288  				insecure := c.Bool("insecure")
   289  				action.Get(packages, inst, insecure, c.Bool("no-recursive"), c.Bool("strip-vendor"), c.Bool("non-interactive"), c.Bool("test"))
   290  				return nil
   291  			},
   292  		},
   293  		{
   294  			Name:      "remove",
   295  			ShortName: "rm",
   296  			Usage:     "Remove a package from the glide.yaml file, and regenerate the lock file.",
   297  			Description: `This takes one or more package names, and removes references from the glide.yaml file.
   298     This will rebuild the glide lock file re-resolving the depencies.`,
   299  			Flags: []cli.Flag{
   300  				cli.BoolFlag{
   301  					Name:  "delete,d",
   302  					Usage: "Also delete from vendor/ any packages that are no longer used.",
   303  				},
   304  			},
   305  			Action: func(c *cli.Context) error {
   306  				if len(c.Args()) < 1 {
   307  					fmt.Println("Oops! At least one package name is required.")
   308  					os.Exit(1)
   309  				}
   310  
   311  				if c.Bool("delete") {
   312  					// FIXME: Implement this in the installer.
   313  					fmt.Println("Delete is not currently implemented.")
   314  				}
   315  				inst := repo.NewInstaller()
   316  				inst.Force = c.Bool("force")
   317  				packages := []string(c.Args())
   318  				action.Remove(packages, inst)
   319  				return nil
   320  			},
   321  		},
   322  		{
   323  			Name:  "import",
   324  			Usage: "Import files from other dependency management systems.",
   325  			Subcommands: []cli.Command{
   326  				{
   327  					Name:  "godep",
   328  					Usage: "Import Godep's Godeps.json files and display the would-be yaml file",
   329  					Flags: []cli.Flag{
   330  						cli.StringFlag{
   331  							Name:  "file, f",
   332  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   333  						},
   334  					},
   335  					Action: func(c *cli.Context) error {
   336  						action.ImportGodep(c.String("file"))
   337  						return nil
   338  					},
   339  				},
   340  				{
   341  					Name:  "gpm",
   342  					Usage: "Import GPM's Godeps and Godeps-Git files and display the would-be yaml file",
   343  					Flags: []cli.Flag{
   344  						cli.StringFlag{
   345  							Name:  "file, f",
   346  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   347  						},
   348  					},
   349  					Action: func(c *cli.Context) error {
   350  						action.ImportGPM(c.String("file"))
   351  						return nil
   352  					},
   353  				},
   354  				{
   355  					Name:  "gb",
   356  					Usage: "Import gb's manifest file and display the would-be yaml file",
   357  					Flags: []cli.Flag{
   358  						cli.StringFlag{
   359  							Name:  "file, f",
   360  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   361  						},
   362  					},
   363  					Action: func(c *cli.Context) error {
   364  						action.ImportGB(c.String("file"))
   365  						return nil
   366  					},
   367  				},
   368  				{
   369  					Name:  "gom",
   370  					Usage: "Import Gomfile and display the would-be yaml file",
   371  					Flags: []cli.Flag{
   372  						cli.StringFlag{
   373  							Name:  "file, f",
   374  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   375  						},
   376  					},
   377  					Action: func(c *cli.Context) error {
   378  						action.ImportGom(c.String("file"))
   379  						return nil
   380  					},
   381  				},
   382  			},
   383  		},
   384  		{
   385  			Name:        "name",
   386  			Usage:       "Print the name of this project.",
   387  			Description: `Read the glide.yaml file and print the name given on the 'package' line.`,
   388  			Action: func(c *cli.Context) error {
   389  				action.Name()
   390  				return nil
   391  			},
   392  		},
   393  		{
   394  			Name:      "novendor",
   395  			ShortName: "nv",
   396  			Usage:     "List all non-vendor paths in a directory.",
   397  			Description: `Given a directory, list all the relevant Go paths that are not vendored.
   398  
   399  Example:
   400     $ go test $(glide novendor)`,
   401  			Flags: []cli.Flag{
   402  				cli.StringFlag{
   403  					Name:  "dir,d",
   404  					Usage: "Specify a directory to run novendor against.",
   405  					Value: ".",
   406  				},
   407  				cli.BoolFlag{
   408  					Name:  "no-subdir,x",
   409  					Usage: "Specify this to prevent nv from append '/...' to all directories.",
   410  				},
   411  			},
   412  			Action: func(c *cli.Context) error {
   413  				action.NoVendor(c.String("dir"), true, !c.Bool("no-subdir"))
   414  				return nil
   415  			},
   416  		},
   417  		{
   418  			Name:  "rebuild",
   419  			Usage: "Rebuild ('go build') the dependencies",
   420  			Description: `(Deprecated) This rebuilds the packages' '.a' files. On some systems
   421  	this can improve performance on subsequent 'go run' and 'go build' calls.`,
   422  			Action: func(c *cli.Context) error {
   423  				action.Rebuild()
   424  				return nil
   425  			},
   426  		},
   427  		{
   428  			Name:      "install",
   429  			ShortName: "i",
   430  			Usage:     "Install a project's dependencies",
   431  			Description: `This uses the native VCS of each packages to install
   432     the appropriate version. There are two ways a projects dependencies can
   433     be installed. When there is a glide.yaml file defining the dependencies but
   434     no lock file (glide.lock) the dependencies are installed using the "update"
   435     command and a glide.lock file is generated pinning all dependencies. If a
   436     glide.lock file is already present the dependencies are installed or updated
   437     from the lock file.`,
   438  			Flags: []cli.Flag{
   439  				cli.BoolFlag{
   440  					Name:   "delete",
   441  					Usage:  "Delete vendor packages not specified in config.",
   442  					Hidden: true,
   443  				},
   444  				cli.BoolFlag{
   445  					Name:  "force",
   446  					Usage: "If there was a change in the repo or VCS switch to new one. Warning: changes will be lost.",
   447  				},
   448  				cli.BoolFlag{
   449  					Name:   "update-vendored, u",
   450  					Usage:  "Update vendored packages (without local VCS repo). Warning: this may destroy local modifications to vendor/.",
   451  					Hidden: true,
   452  				},
   453  				cli.StringFlag{
   454  					Name:   "file, f",
   455  					Usage:  "Save all of the discovered dependencies to a Glide YAML file. (DEPRECATED: This has no impact.)",
   456  					Hidden: true,
   457  				},
   458  				cli.BoolFlag{
   459  					Name:   "cache",
   460  					Usage:  "When downloading dependencies attempt to cache them.",
   461  					Hidden: true,
   462  				},
   463  				cli.BoolFlag{
   464  					Name:   "cache-gopath",
   465  					Usage:  "When downloading dependencies attempt to put them in the GOPATH, too.",
   466  					Hidden: true,
   467  				},
   468  				cli.BoolFlag{
   469  					Name:   "use-gopath",
   470  					Usage:  "Copy dependencies from the GOPATH if they exist there.",
   471  					Hidden: true,
   472  				},
   473  				cli.BoolFlag{
   474  					Name:   "strip-vcs, s",
   475  					Usage:  "Removes version control metadata (e.g, .git directory) from the vendor folder.",
   476  					Hidden: true,
   477  				},
   478  				cli.BoolFlag{
   479  					Name:  "strip-vendor, v",
   480  					Usage: "Removes nested vendor and Godeps/_workspace directories.",
   481  				},
   482  				cli.BoolFlag{
   483  					Name:  "skip-test",
   484  					Usage: "Resolve dependencies in test files.",
   485  				},
   486  			},
   487  			Action: func(c *cli.Context) error {
   488  				if c.Bool("delete") {
   489  					msg.Warn("The --delete flag is deprecated. This now works by default.")
   490  				}
   491  				if c.Bool("update-vendored") {
   492  					msg.Warn("The --update-vendored flag is deprecated. This now works by default.")
   493  				}
   494  				if c.String("file") != "" {
   495  					msg.Warn("The --flag flag is deprecated.")
   496  				}
   497  				if c.Bool("cache") {
   498  					msg.Warn("The --cache flag is deprecated. This now works by default.")
   499  				}
   500  				if c.Bool("cache-gopath") {
   501  					msg.Warn("The --cache-gopath flag is deprecated.")
   502  				}
   503  				if c.Bool("use-gopath") {
   504  					msg.Warn("The --use-gopath flag is deprecated. Please see overrides.")
   505  				}
   506  				if c.Bool("strip-vcs") {
   507  					msg.Warn("The --strip-vcs flag is deprecated. This now works by default.")
   508  				}
   509  
   510  				installer := repo.NewInstaller()
   511  				installer.Force = c.Bool("force")
   512  				installer.Home = c.GlobalString("home")
   513  				installer.ResolveTest = !c.Bool("skip-test")
   514  
   515  				action.Install(installer, c.Bool("strip-vendor"))
   516  				return nil
   517  			},
   518  		},
   519  		{
   520  			Name:      "update",
   521  			ShortName: "up",
   522  			Usage:     "Update a project's dependencies",
   523  			Description: `This updates the dependencies by scanning the codebase
   524     to determine the needed dependencies and fetching them following the rules
   525     in the glide.yaml file. When no rules exist the tip of the default branch
   526     is used. For more details see https://glide.sh/docs/glide.yaml
   527  
   528     If a dependency has a glide.yaml file, update will read that file and
   529     use the information contained there. Those dependencies are maintained in
   530     a the top level 'vendor/' directory. 'vendor/foo/bar' will have its
   531     dependencies stored in 'vendor/'. This behavior can be disabled with
   532     '--no-recursive'. When this behavior is skipped a glide.lock file is not
   533     generated because the full dependency tree cannot be known.
   534  
   535     Glide will also import Godep, GB, GOM, and GPM files as it finds them in dependencies.
   536     It will create a glide.yaml file from the Godeps data, and then update. This
   537     has no effect if '--no-recursive' is set.
   538  
   539     The '--strip-vendor' flag will remove any nested 'vendor' folders and
   540     'Godeps/_workspace' folders after an update (along with undoing any Godep
   541     import rewriting). Note, The Godeps specific functionality is deprecated and
   542     will be removed when most Godeps users have migrated to using the vendor
   543     folder.`,
   544  			Flags: []cli.Flag{
   545  				cli.BoolFlag{
   546  					Name:   "delete",
   547  					Usage:  "Delete vendor packages not specified in config.",
   548  					Hidden: true,
   549  				},
   550  				cli.BoolFlag{
   551  					Name:  "no-recursive, quick",
   552  					Usage: "Disable updating dependencies' dependencies. Only update things in glide.yaml.",
   553  				},
   554  				cli.BoolFlag{
   555  					Name:  "force",
   556  					Usage: "If there was a change in the repo or VCS switch to new one. Warning, changes will be lost.",
   557  				},
   558  				cli.BoolFlag{
   559  					Name:  "all-dependencies",
   560  					Usage: "This will resolve all dependencies for all packages, not just those directly used.",
   561  				},
   562  				cli.BoolFlag{
   563  					Name:   "update-vendored, u",
   564  					Usage:  "Update vendored packages (without local VCS repo). Warning, changes will be lost.",
   565  					Hidden: true,
   566  				},
   567  				cli.StringFlag{
   568  					Name:   "file, f",
   569  					Usage:  "Save all of the discovered dependencies to a Glide YAML file.",
   570  					Hidden: true,
   571  				},
   572  				cli.BoolFlag{
   573  					Name:   "cache",
   574  					Usage:  "When downloading dependencies attempt to cache them.",
   575  					Hidden: true,
   576  				},
   577  				cli.BoolFlag{
   578  					Name:   "cache-gopath",
   579  					Usage:  "When downloading dependencies attempt to put them in the GOPATH, too.",
   580  					Hidden: true,
   581  				},
   582  				cli.BoolFlag{
   583  					Name:   "use-gopath",
   584  					Usage:  "Copy dependencies from the GOPATH if they exist there.",
   585  					Hidden: true,
   586  				},
   587  				cli.BoolFlag{
   588  					Name:  "resolve-current",
   589  					Usage: "Resolve dependencies for only the current system rather than all build modes.",
   590  				},
   591  				cli.BoolFlag{
   592  					Name:   "strip-vcs, s",
   593  					Usage:  "Removes version control metadata (e.g, .git directory) from the vendor folder.",
   594  					Hidden: true,
   595  				},
   596  				cli.BoolFlag{
   597  					Name:  "strip-vendor, v",
   598  					Usage: "Removes nested vendor and Godeps/_workspace directories.",
   599  				},
   600  				cli.BoolFlag{
   601  					Name:  "skip-test",
   602  					Usage: "Resolve dependencies in test files.",
   603  				},
   604  			},
   605  			Action: func(c *cli.Context) error {
   606  				if c.Bool("delete") {
   607  					msg.Warn("The --delete flag is deprecated. This now works by default.")
   608  				}
   609  				if c.Bool("update-vendored") {
   610  					msg.Warn("The --update-vendored flag is deprecated. This now works by default.")
   611  				}
   612  				if c.String("file") != "" {
   613  					msg.Warn("The --flag flag is deprecated.")
   614  				}
   615  				if c.Bool("cache") {
   616  					msg.Warn("The --cache flag is deprecated. This now works by default.")
   617  				}
   618  				if c.Bool("cache-gopath") {
   619  					msg.Warn("The --cache-gopath flag is deprecated.")
   620  				}
   621  				if c.Bool("use-gopath") {
   622  					msg.Warn("The --use-gopath flag is deprecated. Please see overrides.")
   623  				}
   624  				if c.Bool("strip-vcs") {
   625  					msg.Warn("The --strip-vcs flag is deprecated. This now works by default.")
   626  				}
   627  
   628  				if c.Bool("resolve-current") {
   629  					util.ResolveCurrent = true
   630  					msg.Warn("Only resolving dependencies for the current OS/Arch")
   631  				}
   632  
   633  				installer := repo.NewInstaller()
   634  				installer.Force = c.Bool("force")
   635  				installer.ResolveAllFiles = c.Bool("all-dependencies")
   636  				installer.Home = c.GlobalString("home")
   637  				installer.ResolveTest = !c.Bool("skip-test")
   638  
   639  				action.Update(installer, c.Bool("no-recursive"), c.Bool("strip-vendor"))
   640  
   641  				return nil
   642  			},
   643  		},
   644  		{
   645  			Name:  "tree",
   646  			Usage: "(Deprecated) Tree prints the dependencies of this project as a tree.",
   647  			Description: `This scans a project's source files and builds a tree
   648     representation of the import graph.
   649  
   650     It ignores testdata/ and directories that begin with . or _. Packages in
   651     vendor/ are only included if they are referenced by the main project or
   652     one of its dependencies.
   653  
   654     Note, for large projects this can display a large list tens of thousands of
   655     lines long.`,
   656  			Action: func(c *cli.Context) error {
   657  				action.Tree(".", false)
   658  				return nil
   659  			},
   660  		},
   661  		{
   662  			Name:  "list",
   663  			Usage: "List prints all dependencies that the present code references.",
   664  			Description: `List scans your code and lists all of the packages that are used.
   665  
   666     It does not use the glide.yaml. Instead, it inspects the code to determine what packages are
   667     imported.
   668  
   669     Directories that begin with . or _ are ignored, as are testdata directories. Packages in
   670     vendor are only included if they are used by the project.`,
   671  			Action: func(c *cli.Context) error {
   672  				action.List(".", true, c.String("output"))
   673  				return nil
   674  			},
   675  			Flags: []cli.Flag{
   676  				cli.StringFlag{
   677  					Name:  "output, o",
   678  					Usage: "Output format. One of: json|json-pretty|text",
   679  					Value: "text",
   680  				},
   681  			},
   682  		},
   683  		{
   684  			Name:  "info",
   685  			Usage: "Info prints information about this project",
   686  			Flags: []cli.Flag{
   687  				cli.StringFlag{
   688  					Name:  "format, f",
   689  					Usage: `Format of the information wanted (required).`,
   690  				},
   691  			},
   692  			Description: `A format containing the text with replacement variables
   693     has to be passed in. Those variables are:
   694  
   695         %n - name
   696         %d - description
   697         %h - homepage
   698         %l - license
   699  
   700     For example, given a project with the following glide.yaml:
   701  
   702         package: foo
   703         homepage: https://example.com
   704         license: MIT
   705         description: Some example description
   706  
   707     Then running the following commands:
   708  
   709         glide info -f %n
   710            prints 'foo'
   711  
   712         glide info -f "License: %l"
   713            prints 'License: MIT'
   714  
   715         glide info -f "%n - %d - %h - %l"
   716            prints 'foo - Some example description - https://example.com - MIT'`,
   717  			Action: func(c *cli.Context) error {
   718  				if c.IsSet("format") {
   719  					action.Info(c.String("format"))
   720  				} else {
   721  					cli.ShowCommandHelp(c, c.Command.Name)
   722  				}
   723  				return nil
   724  			},
   725  		},
   726  		{
   727  			Name:      "cache-clear",
   728  			ShortName: "cc",
   729  			Usage:     "Clears the Glide cache.",
   730  			Action: func(c *cli.Context) error {
   731  				action.CacheClear()
   732  				return nil
   733  			},
   734  		},
   735  		{
   736  			Name:  "about",
   737  			Usage: "Learn about Glide",
   738  			Action: func(c *cli.Context) error {
   739  				action.About()
   740  				return nil
   741  			},
   742  		},
   743  		{
   744  			Name:  "mirror",
   745  			Usage: "Manage mirrors",
   746  			Description: `Mirrors provide the ability to replace a repo location with
   747     another location that's a mirror of the original. This is useful when you want
   748     to have a cache for your continuous integration (CI) system or if you want to
   749     work on a dependency in a local location.
   750  
   751     The mirrors are stored in an mirrors.yaml file in your GLIDE_HOME.
   752  
   753     The three commands to manager mirrors are 'list', 'set', and 'remove'.
   754  
   755     Use 'set' in the form:
   756  
   757         glide mirror set [original] [replacement]
   758  
   759     or
   760  
   761         glide mirror set [original] [replacement] --vcs [type]
   762  
   763     for example,
   764  
   765         glide mirror set https://github.com/example/foo https://git.example.com/example/foo.git
   766  
   767         glide mirror set https://github.com/example/foo file:///path/to/local/repo --vcs git
   768  
   769     Use 'remove' in the form:
   770  
   771         glide mirror remove [original]
   772  
   773     for example,
   774  
   775         glide mirror remove https://github.com/example/foo`,
   776  			Subcommands: []cli.Command{
   777  				{
   778  					Name:  "list",
   779  					Usage: "List the current mirrors",
   780  					Action: func(c *cli.Context) error {
   781  						return action.MirrorsList()
   782  					},
   783  				},
   784  				{
   785  					Name:  "set",
   786  					Usage: "Set a mirror. This overwrites an existing entry if one exists",
   787  					Description: `Use 'set' in the form:
   788  
   789         glide mirror set [original] [replacement]
   790  
   791     or
   792  
   793         glide mirror set [original] [replacement] --vcs [type]
   794  
   795     for example,
   796  
   797         glide mirror set https://github.com/example/foo https://git.example.com/example/foo.git
   798  
   799         glide mirror set https://github.com/example/foo file:///path/to/local/repo --vcs git`,
   800  					Flags: []cli.Flag{
   801  						cli.StringFlag{
   802  							Name:  "vcs",
   803  							Usage: "The VCS type to use. Autodiscovery is attempted when not supplied. Can be one of git, svn, bzr, or hg",
   804  						},
   805  					},
   806  					Action: func(c *cli.Context) error {
   807  						return action.MirrorsSet(c.Args().Get(0), c.Args().Get(1), c.String("vcs"))
   808  					},
   809  				},
   810  				{
   811  					Name:      "remove",
   812  					ShortName: "rm",
   813  					Usage:     "Remove an mirror",
   814  					Description: `Use 'remove' in the form:
   815  
   816         glide mirror remove [original]
   817  
   818     for example,
   819  
   820         glide mirror remove https://github.com/example/foo`,
   821  					Action: func(c *cli.Context) error {
   822  						return action.MirrorsRemove(c.Args().Get(0))
   823  					},
   824  				},
   825  			},
   826  		},
   827  	}
   828  }
   829  
   830  // startup sets up the base environment.
   831  //
   832  // It does not assume the presence of a Glide.yaml file or vendor/ directory,
   833  // so it can be used by any Glide command.
   834  func startup(c *cli.Context) error {
   835  	action.Debug(c.Bool("debug"))
   836  	action.Verbose(c.Bool("verbose"))
   837  	action.NoColor(c.Bool("no-color"))
   838  	action.Quiet(c.Bool("quiet"))
   839  	action.Init(c.String("yaml"), c.String("home"))
   840  	action.EnsureGoVendor()
   841  	gpath.Tmp = c.String("tmp")
   842  	return nil
   843  }
   844  
   845  func shutdown(c *cli.Context) error {
   846  	cache.SystemUnlock()
   847  	return nil
   848  }
   849  
   850  // Get the path to the glide.yaml file.
   851  //
   852  // This returns the name of the path, even if the file does not exist. The value
   853  // may be set by the user, or it may be the default.
   854  func glidefile(c *cli.Context) string {
   855  	path := c.String("file")
   856  	if path == "" {
   857  		// For now, we construct a basic assumption. In the future, we could
   858  		// traverse backward to see if a glide.yaml exists in a parent.
   859  		path = "./glide.yaml"
   860  	}
   861  	a, err := filepath.Abs(path)
   862  	if err != nil {
   863  		// Underlying fs didn't provide working dir.
   864  		return path
   865  	}
   866  	return a
   867  }