github.com/kngu9/glide@v0.0.0-20160505135211-e73500c73591/glide.go (about)

     1  // Glide is a command line utility that manages Go project dependencies and
     2  // your GOPATH.
     3  //
     4  // Dependencies are managed via a glide.yaml in the root of a project. The yaml
     5  //
     6  // Params:
     7  // 	- filename (string): The name of the glide YAML file. Default is glide.yaml.
     8  // 	- project (string): The name of the project. Default is 'main'.
     9  // file lets you specify projects, versions (tags, branches, or references),
    10  // and even alias one location in as other one. Aliasing is useful when supporting
    11  // forks without needing to rewrite the imports in a codebase.
    12  //
    13  // A glide.yaml file looks like:
    14  //
    15  //		package: github.com/Masterminds/glide
    16  //		imports:
    17  //			- package: github.com/Masterminds/cookoo
    18  //			  vcs: git
    19  //			  ref: 1.1.0
    20  //			  subpackages: **
    21  //			- package: github.com/kylelemons/go-gypsy
    22  //			  subpackages: yaml
    23  //
    24  // Glide puts dependencies in a vendor directory. Go utilities require this to
    25  // be in your GOPATH. Glide makes this easy. Use the `glide in` command to enter
    26  // a shell (your default) with the GOPATH set to the projects vendor directory.
    27  // To leave this shell simply exit it.
    28  //
    29  // If your .bashrc, .zshrc, or other startup shell sets your GOPATH you many need
    30  // to optionally set it using something like:
    31  //
    32  //		if [ "" = "${GOPATH}" ]; then
    33  //		  export GOPATH="/some/dir"
    34  //		fi
    35  //
    36  // For more information use the `glide help` command or see https://github.com/Masterminds/glide
    37  package main
    38  
    39  import (
    40  	"path/filepath"
    41  
    42  	"github.com/Masterminds/glide/action"
    43  	"github.com/Masterminds/glide/msg"
    44  	gpath "github.com/Masterminds/glide/path"
    45  	"github.com/Masterminds/glide/repo"
    46  	"github.com/Masterminds/glide/util"
    47  
    48  	"github.com/codegangsta/cli"
    49  
    50  	"fmt"
    51  	"os"
    52  	"os/user"
    53  )
    54  
    55  var version = "0.11.0-dev"
    56  
    57  const usage = `The lightweight vendor package manager for your Go projects.
    58  
    59  Each project should have a 'glide.yaml' file in the project directory. Files
    60  look something like this:
    61  
    62  	package: github.com/Masterminds/glide
    63  	imports:
    64  		- package: github.com/Masterminds/cookoo
    65  		  vcs: git
    66  		  ref: 1.1.0
    67  		  subpackages: **
    68  		- package: github.com/kylelemons/go-gypsy
    69  		  subpackages: yaml
    70  			flatten: true
    71  
    72  NOTE: As of Glide 0.5, the commands 'into', 'gopath', 'status', and 'env'
    73  no longer exist.
    74  `
    75  
    76  // VendorDir default vendor directory name
    77  var VendorDir = "vendor"
    78  
    79  func main() {
    80  	app := cli.NewApp()
    81  	app.Name = "glide"
    82  	app.Usage = usage
    83  	app.Version = version
    84  	app.Flags = []cli.Flag{
    85  		cli.StringFlag{
    86  			Name:  "yaml, y",
    87  			Value: "glide.yaml",
    88  			Usage: "Set a YAML configuration file.",
    89  		},
    90  		cli.BoolFlag{
    91  			Name:  "quiet, q",
    92  			Usage: "Quiet (no info or debug messages)",
    93  		},
    94  		cli.BoolFlag{
    95  			Name:  "debug",
    96  			Usage: "Print Debug messages (verbose)",
    97  		},
    98  		cli.StringFlag{
    99  			Name:   "home",
   100  			Value:  defaultGlideDir(),
   101  			Usage:  "The location of Glide files",
   102  			EnvVar: "GLIDE_HOME",
   103  		},
   104  		cli.BoolFlag{
   105  			Name:  "no-color",
   106  			Usage: "Turn off colored output for log messages",
   107  		},
   108  	}
   109  	app.CommandNotFound = func(c *cli.Context, command string) {
   110  		// TODO: Set some useful env vars.
   111  		action.Plugin(command, os.Args)
   112  	}
   113  	app.Before = startup
   114  	app.Commands = commands()
   115  
   116  	// Detect errors from the Before and After calls and exit on them.
   117  	if err := app.Run(os.Args); err != nil {
   118  		msg.Err(err.Error())
   119  		os.Exit(1)
   120  	}
   121  
   122  	// If there was a Error message exit non-zero.
   123  	if msg.HasErrored() {
   124  		m := msg.Color(msg.Red, "An Error has occurred")
   125  		msg.Msg(m)
   126  		os.Exit(2)
   127  	}
   128  }
   129  
   130  func commands() []cli.Command {
   131  	return []cli.Command{
   132  		{
   133  			Name:      "create",
   134  			ShortName: "init",
   135  			Usage:     "Initialize a new project, creating a glide.yaml file",
   136  			Description: `This command starts from a project without Glide and
   137     sets it up. It generates a glide.yaml file, parsing your codebase to guess
   138     the dependencies to include. Once this step is done you may edit the
   139     glide.yaml file to update imported dependency properties such as the version
   140     or version range to include.
   141  
   142     To fetch the dependencies you may run 'glide install'.`,
   143  			Flags: []cli.Flag{
   144  				cli.BoolFlag{
   145  					Name:  "skip-import",
   146  					Usage: "When initializing skip importing from other package managers.",
   147  				},
   148  			},
   149  			Action: func(c *cli.Context) {
   150  				action.Create(".", c.Bool("skip-import"))
   151  			},
   152  		},
   153  		{
   154  			Name:  "get",
   155  			Usage: "Install one or more packages into `vendor/` and add dependency to glide.yaml.",
   156  			Description: `Gets one or more package (like 'go get') and then adds that file
   157     to the glide.yaml file. Multiple package names can be specified on one line.
   158  
   159     	$ glide get github.com/Masterminds/cookoo/web
   160  
   161     The above will install the project github.com/Masterminds/cookoo and add
   162     the subpackage 'web'.
   163  
   164     If a fetched dependency has a glide.yaml file, configuration from Godep,
   165     GPM, or GB Glide that configuration will be used to find the dependencies
   166     and versions to fetch. If those are not available the dependent packages will
   167     be fetched as either a version specified elsewhere or the latest version.
   168  
   169     When adding a new dependency Glide will perform an update to work out the
   170     the versions to use from the dependency tree. This will generate an updated
   171     glide.lock file with specific locked versions to use.
   172  
   173     If you are storing the outside dependencies in your version control system
   174     (VCS), also known as vendoring, there are a few flags that may be useful.
   175     The '--update-vendored' flag will cause Glide to update packages when VCS
   176     information is unavailable. This can be used with the '--strip-vcs' flag which
   177     will strip VCS data found in the vendor directory. This is useful for
   178     removing VCS data from transitive dependencies and initial setups. The
   179     '--strip-vendor' flag will remove any nested 'vendor' folders and
   180     'Godeps/_workspace' folders after an update (along with undoing any Godep
   181     import rewriting). Note, The Godeps specific functionality is deprecated and
   182     will be removed when most Godeps users have migrated to using the vendor
   183     folder.`,
   184  			Flags: []cli.Flag{
   185  				cli.BoolFlag{
   186  					Name:  "insecure",
   187  					Usage: "Use http:// rather than https:// to retrieve pacakges.",
   188  				},
   189  				cli.BoolFlag{
   190  					Name:  "no-recursive, quick",
   191  					Usage: "Disable updating dependencies' dependencies.",
   192  				},
   193  				cli.BoolFlag{
   194  					Name:  "force",
   195  					Usage: "If there was a change in the repo or VCS switch to new one. Warning, changes will be lost.",
   196  				},
   197  				cli.BoolFlag{
   198  					Name:  "all-dependencies",
   199  					Usage: "This will resolve all dependencies for all packages, not just those directly used.",
   200  				},
   201  				cli.BoolFlag{
   202  					Name:  "update-vendored, u",
   203  					Usage: "Update vendored packages (without local VCS repo). Warning, changes will be lost.",
   204  				},
   205  				cli.BoolFlag{
   206  					Name:  "cache",
   207  					Usage: "When downloading dependencies attempt to cache them.",
   208  				},
   209  				cli.BoolFlag{
   210  					Name:  "cache-gopath",
   211  					Usage: "When downloading dependencies attempt to put them in the GOPATH, too.",
   212  				},
   213  				cli.BoolFlag{
   214  					Name:  "use-gopath",
   215  					Usage: "Copy dependencies from the GOPATH if they exist there.",
   216  				},
   217  				cli.BoolFlag{
   218  					Name:  "resolve-current",
   219  					Usage: "Resolve dependencies for only the current system rather than all build modes.",
   220  				},
   221  				cli.BoolFlag{
   222  					Name:  "strip-vcs, s",
   223  					Usage: "Removes version control metada (e.g, .git directory) from the vendor folder.",
   224  				},
   225  				cli.BoolFlag{
   226  					Name:  "strip-vendor, v",
   227  					Usage: "Removes nested vendor and Godeps/_workspace directories. Requires --strip-vcs.",
   228  				},
   229  			},
   230  			Action: func(c *cli.Context) {
   231  				if c.Bool("strip-vendor") && !c.Bool("strip-vcs") {
   232  					msg.Die("--strip-vendor cannot be used without --strip-vcs")
   233  				}
   234  
   235  				if len(c.Args()) < 1 {
   236  					fmt.Println("Oops! Package name is required.")
   237  					os.Exit(1)
   238  				}
   239  
   240  				if c.Bool("resolve-current") {
   241  					util.ResolveCurrent = true
   242  					msg.Warn("Only resolving dependencies for the current OS/Arch")
   243  				}
   244  
   245  				inst := repo.NewInstaller()
   246  				inst.Force = c.Bool("force")
   247  				inst.UseCache = c.Bool("cache")
   248  				inst.UseGopath = c.Bool("use-gopath")
   249  				inst.UseCacheGopath = c.Bool("cache-gopath")
   250  				inst.UpdateVendored = c.Bool("update-vendored")
   251  				inst.ResolveAllFiles = c.Bool("all-dependencies")
   252  				packages := []string(c.Args())
   253  				insecure := c.Bool("insecure")
   254  				action.Get(packages, inst, insecure, c.Bool("no-recursive"), c.Bool("strip-vcs"), c.Bool("strip-vendor"))
   255  			},
   256  		},
   257  		{
   258  			Name:      "remove",
   259  			ShortName: "rm",
   260  			Usage:     "Remove a package from the glide.yaml file, and regenerate the lock file.",
   261  			Description: `This takes one or more package names, and removes references from the glide.yaml file.
   262     This will rebuild the glide lock file with the following constraints:
   263  
   264     - Dependencies are re-negotiated. Any that are no longer used are left out of the lock.
   265     - Minor version re-nogotiation is performed on remaining dependencies.
   266     - No updates are peformed. You may want to run 'glide up' to accomplish that.`,
   267  			Flags: []cli.Flag{
   268  				cli.BoolFlag{
   269  					Name:  "delete,d",
   270  					Usage: "Also delete from vendor/ any packages that are no longer used.",
   271  				},
   272  			},
   273  			Action: func(c *cli.Context) {
   274  				if len(c.Args()) < 1 {
   275  					fmt.Println("Oops! At least one package name is required.")
   276  					os.Exit(1)
   277  				}
   278  
   279  				if c.Bool("delete") {
   280  					// FIXME: Implement this in the installer.
   281  					fmt.Println("Delete is not currently implemented.")
   282  				}
   283  				inst := repo.NewInstaller()
   284  				inst.Force = c.Bool("force")
   285  				packages := []string(c.Args())
   286  				action.Remove(packages, inst)
   287  			},
   288  		},
   289  		{
   290  			Name:  "import",
   291  			Usage: "Import files from other dependency management systems.",
   292  			Subcommands: []cli.Command{
   293  				{
   294  					Name:  "godep",
   295  					Usage: "Import Godep's Godeps.json files and display the would-be yaml file",
   296  					Flags: []cli.Flag{
   297  						cli.StringFlag{
   298  							Name:  "file, f",
   299  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   300  						},
   301  					},
   302  					Action: func(c *cli.Context) {
   303  						action.ImportGodep(c.String("file"))
   304  					},
   305  				},
   306  				{
   307  					Name:  "gpm",
   308  					Usage: "Import GPM's Godeps and Godeps-Git files and display the would-be yaml file",
   309  					Flags: []cli.Flag{
   310  						cli.StringFlag{
   311  							Name:  "file, f",
   312  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   313  						},
   314  					},
   315  					Action: func(c *cli.Context) {
   316  						action.ImportGPM(c.String("file"))
   317  					},
   318  				},
   319  				{
   320  					Name:  "gb",
   321  					Usage: "Import gb's manifest file and display the would-be yaml file",
   322  					Flags: []cli.Flag{
   323  						cli.StringFlag{
   324  							Name:  "file, f",
   325  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   326  						},
   327  					},
   328  					Action: func(c *cli.Context) {
   329  						action.ImportGB(c.String("file"))
   330  					},
   331  				},
   332  				{
   333  					Name:  "gom",
   334  					Usage: "Import Gomfile and display the would-be yaml file",
   335  					Flags: []cli.Flag{
   336  						cli.StringFlag{
   337  							Name:  "file, f",
   338  							Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   339  						},
   340  					},
   341  					Action: func(c *cli.Context) {
   342  						action.ImportGom(c.String("file"))
   343  					},
   344  				},
   345  			},
   346  		},
   347  		{
   348  			Name:        "name",
   349  			Usage:       "Print the name of this project.",
   350  			Description: `Read the glide.yaml file and print the name given on the 'package' line.`,
   351  			Action: func(c *cli.Context) {
   352  				action.Name()
   353  			},
   354  		},
   355  		{
   356  			Name:      "novendor",
   357  			ShortName: "nv",
   358  			Usage:     "List all non-vendor paths in a directory.",
   359  			Description: `Given a directory, list all the relevant Go paths that are not vendored.
   360  
   361  Example:
   362     $ go test $(glide novendor)`,
   363  			Flags: []cli.Flag{
   364  				cli.StringFlag{
   365  					Name:  "dir,d",
   366  					Usage: "Specify a directory to run novendor against.",
   367  					Value: ".",
   368  				},
   369  				cli.BoolFlag{
   370  					Name:  "no-subdir,x",
   371  					Usage: "Specify this to prevent nv from append '/...' to all directories.",
   372  				},
   373  			},
   374  			Action: func(c *cli.Context) {
   375  				action.NoVendor(c.String("dir"), true, !c.Bool("no-subdir"))
   376  			},
   377  		},
   378  		{
   379  			Name:  "rebuild",
   380  			Usage: "Rebuild ('go build') the dependencies",
   381  			Description: `This rebuilds the packages' '.a' files. On some systems
   382  	this can improve performance on subsequent 'go run' and 'go build' calls.`,
   383  			Action: func(c *cli.Context) {
   384  				action.Rebuild()
   385  			},
   386  		},
   387  		{
   388  			Name:      "install",
   389  			ShortName: "i",
   390  			Usage:     "Install a project's dependencies",
   391  			Description: `This uses the native VCS of each packages to install
   392     the appropriate version. There are two ways a projects dependencies can
   393     be installed. When there is a glide.yaml file defining the dependencies but
   394     no lock file (glide.lock) the dependencies are installed using the "update"
   395     command and a glide.lock file is generated pinning all dependencies. If a
   396     glide.lock file is already present the dependencies are installed or updated
   397     from the lock file.`,
   398  			Flags: []cli.Flag{
   399  				cli.BoolFlag{
   400  					Name:  "delete",
   401  					Usage: "Delete vendor packages not specified in config.",
   402  				},
   403  				cli.BoolFlag{
   404  					Name:  "force",
   405  					Usage: "If there was a change in the repo or VCS switch to new one. Warning: changes will be lost.",
   406  				},
   407  				cli.BoolFlag{
   408  					Name:  "update-vendored, u",
   409  					Usage: "Update vendored packages (without local VCS repo). Warning: this may destroy local modifications to vendor/.",
   410  				},
   411  				cli.StringFlag{
   412  					Name:  "file, f",
   413  					Usage: "Save all of the discovered dependencies to a Glide YAML file. (DEPRECATED: This has no impact.)",
   414  				},
   415  				cli.BoolFlag{
   416  					Name:  "cache",
   417  					Usage: "When downloading dependencies attempt to cache them.",
   418  				},
   419  				cli.BoolFlag{
   420  					Name:  "cache-gopath",
   421  					Usage: "When downloading dependencies attempt to put them in the GOPATH, too.",
   422  				},
   423  				cli.BoolFlag{
   424  					Name:  "use-gopath",
   425  					Usage: "Copy dependencies from the GOPATH if they exist there.",
   426  				},
   427  				cli.BoolFlag{
   428  					Name:  "strip-vcs, s",
   429  					Usage: "Removes version control metada (e.g, .git directory) from the vendor folder.",
   430  				},
   431  				cli.BoolFlag{
   432  					Name:  "strip-vendor, v",
   433  					Usage: "Removes nested vendor and Godeps/_workspace directories. Requires --strip-vcs.",
   434  				},
   435  			},
   436  			Action: func(c *cli.Context) {
   437  				if c.Bool("strip-vendor") && !c.Bool("strip-vcs") {
   438  					msg.Die("--strip-vendor cannot be used without --strip-vcs")
   439  				}
   440  
   441  				installer := repo.NewInstaller()
   442  				installer.Force = c.Bool("force")
   443  				installer.UseCache = c.Bool("cache")
   444  				installer.UseGopath = c.Bool("use-gopath")
   445  				installer.UseCacheGopath = c.Bool("cache-gopath")
   446  				installer.UpdateVendored = c.Bool("update-vendored")
   447  				installer.Home = gpath.Home()
   448  				installer.DeleteUnused = c.Bool("deleteOptIn")
   449  
   450  				action.Install(installer, c.Bool("strip-vcs"), c.Bool("strip-vendor"))
   451  			},
   452  		},
   453  		{
   454  			Name:      "update",
   455  			ShortName: "up",
   456  			Usage:     "Update a project's dependencies",
   457  			Description: `This uses the native VCS of each package to try to
   458     pull the most applicable updates. Packages with fixed refs (Versions or
   459     tags) will not be updated. Packages with no ref or with a branch ref will
   460     be updated as expected.
   461  
   462     If a dependency has a glide.yaml file, update will read that file and
   463     update those dependencies accordingly. Those dependencies are maintained in
   464     a the top level 'vendor/' directory. 'vendor/foo/bar' will have its
   465     dependencies stored in 'vendor/'. This behavior can be disabled with
   466     '--no-recursive'. When this behavior is skipped a glide.lock file is not
   467     generated because the full dependency tree cannot be known.
   468  
   469     Glide will also import Godep, GB, and GPM files as it finds them in dependencies.
   470     It will create a glide.yaml file from the Godeps data, and then update. This
   471     has no effect if '--no-recursive' is set.
   472  
   473     If you are storing the outside dependencies in your version control system
   474     (VCS), also known as vendoring, there are a few flags that may be useful.
   475     The '--update-vendored' flag will cause Glide to update packages when VCS
   476     information is unavailable. This can be used with the '--strip-vcs' flag which
   477     will strip VCS data found in the vendor directory. This is useful for
   478     removing VCS data from transitive dependencies and initial setups. The
   479     '--strip-vendor' flag will remove any nested 'vendor' folders and
   480     'Godeps/_workspace' folders after an update (along with undoing any Godep
   481     import rewriting). Note, The Godeps specific functionality is deprecated and
   482     will be removed when most Godeps users have migrated to using the vendor
   483     folder.
   484  
   485     Note, Glide detects vendored dependencies. With the '--update-vendored' flag
   486     Glide will update vendored dependencies leaving them in a vendored state.
   487     Tertiary dependencies will not be vendored automatically unless the
   488     '--strip-vcs' flag is used along with it.
   489  
   490     By default, packages that are discovered are considered transient, and are
   491     not stored in the glide.yaml file. The --file=NAME.yaml flag allows you
   492     to save the discovered dependencies to a YAML file.`,
   493  			Flags: []cli.Flag{
   494  				cli.BoolFlag{
   495  					Name:  "delete",
   496  					Usage: "Delete vendor packages not specified in config.",
   497  				},
   498  				cli.BoolFlag{
   499  					Name:  "no-recursive, quick",
   500  					Usage: "Disable updating dependencies' dependencies. Only update things in glide.yaml.",
   501  				},
   502  				cli.BoolFlag{
   503  					Name:  "force",
   504  					Usage: "If there was a change in the repo or VCS switch to new one. Warning, changes will be lost.",
   505  				},
   506  				cli.BoolFlag{
   507  					Name:  "all-dependencies",
   508  					Usage: "This will resolve all dependencies for all packages, not just those directly used.",
   509  				},
   510  				cli.BoolFlag{
   511  					Name:  "update-vendored, u",
   512  					Usage: "Update vendored packages (without local VCS repo). Warning, changes will be lost.",
   513  				},
   514  				cli.StringFlag{
   515  					Name:  "file, f",
   516  					Usage: "Save all of the discovered dependencies to a Glide YAML file.",
   517  				},
   518  				cli.BoolFlag{
   519  					Name:  "cache",
   520  					Usage: "When downloading dependencies attempt to cache them.",
   521  				},
   522  				cli.BoolFlag{
   523  					Name:  "cache-gopath",
   524  					Usage: "When downloading dependencies attempt to put them in the GOPATH, too.",
   525  				},
   526  				cli.BoolFlag{
   527  					Name:  "use-gopath",
   528  					Usage: "Copy dependencies from the GOPATH if they exist there.",
   529  				},
   530  				cli.BoolFlag{
   531  					Name:  "resolve-current",
   532  					Usage: "Resolve dependencies for only the current system rather than all build modes.",
   533  				},
   534  				cli.BoolFlag{
   535  					Name:  "strip-vcs, s",
   536  					Usage: "Removes version control metada (e.g, .git directory) from the vendor folder.",
   537  				},
   538  				cli.BoolFlag{
   539  					Name:  "strip-vendor, v",
   540  					Usage: "Removes nested vendor and Godeps/_workspace directories. Requires --strip-vcs.",
   541  				},
   542  			},
   543  			Action: func(c *cli.Context) {
   544  				if c.Bool("strip-vendor") && !c.Bool("strip-vcs") {
   545  					msg.Die("--strip-vendor cannot be used without --strip-vcs")
   546  				}
   547  
   548  				if c.Bool("resolve-current") {
   549  					util.ResolveCurrent = true
   550  					msg.Warn("Only resolving dependencies for the current OS/Arch")
   551  				}
   552  
   553  				installer := repo.NewInstaller()
   554  				installer.Force = c.Bool("force")
   555  				installer.UseCache = c.Bool("cache")
   556  				installer.UseGopath = c.Bool("use-gopath")
   557  				installer.UseCacheGopath = c.Bool("cache-gopath")
   558  				installer.UpdateVendored = c.Bool("update-vendored")
   559  				installer.ResolveAllFiles = c.Bool("all-dependencies")
   560  				installer.Home = gpath.Home()
   561  				installer.DeleteUnused = c.Bool("deleteOptIn")
   562  
   563  				action.Update(installer, c.Bool("no-recursive"), c.Bool("strip-vcs"), c.Bool("strip-vendor"))
   564  			},
   565  		},
   566  		{
   567  			Name:  "tree",
   568  			Usage: "Tree prints the dependencies of this project as a tree.",
   569  			Description: `This scans a project's source files and builds a tree
   570     representation of the import graph.
   571  
   572     It ignores testdata/ and directories that begin with . or _. Packages in
   573     vendor/ are only included if they are referenced by the main project or
   574     one of its dependencies.`,
   575  			Action: func(c *cli.Context) {
   576  				action.Tree(".", false)
   577  			},
   578  		},
   579  		{
   580  			Name:  "list",
   581  			Usage: "List prints all dependencies that the present code references.",
   582  			Description: `List scans your code and lists all of the packages that are used.
   583  
   584     It does not use the glide.yaml. Instead, it inspects the code to determine what packages are
   585     imported.
   586  
   587     Directories that begin with . or _ are ignored, as are testdata directories. Packages in
   588     vendor are only included if they are used by the project.`,
   589  			Action: func(c *cli.Context) {
   590  				action.List(".", true, c.String("output"))
   591  			},
   592  			Flags: []cli.Flag{
   593  				cli.StringFlag{
   594  					Name:  "output, o",
   595  					Usage: "Output format. One of: json|json-pretty|text",
   596  					Value: "text",
   597  				},
   598  			},
   599  		},
   600  		{
   601  			Name:  "info",
   602  			Usage: "Info prints information about this project",
   603  			Flags: []cli.Flag{
   604  				cli.StringFlag{
   605  					Name:  "format, f",
   606  					Usage: `Format of the information wanted (required).`,
   607  				},
   608  			},
   609  			Description: `A format containing the text with replacement variables
   610     has to be passed in. Those variables are:
   611  
   612         %n - name
   613         %d - description
   614         %h - homepage
   615         %l - license
   616  
   617     For example, given a project with the following glide.yaml:
   618  
   619         package: foo
   620         homepage: https://example.com
   621         license: MIT
   622         description: Some example description
   623  
   624     Then running the following commands:
   625  
   626         glide info -f %n
   627            prints 'foo'
   628  
   629         glide info -f "License: %l"
   630            prints 'License: MIT'
   631  
   632         glide info -f "%n - %d - %h - %l"
   633            prints 'foo - Some example description - https://example.com - MIT'`,
   634  			Action: func(c *cli.Context) {
   635  				if c.IsSet("format") {
   636  					action.Info(c.String("format"))
   637  				} else {
   638  					cli.ShowCommandHelp(c, c.Command.Name)
   639  				}
   640  			},
   641  		},
   642  		{
   643  			Name:  "about",
   644  			Usage: "Learn about Glide",
   645  			Action: func(c *cli.Context) {
   646  				action.About()
   647  			},
   648  		},
   649  	}
   650  }
   651  
   652  func defaultGlideDir() string {
   653  	c, err := user.Current()
   654  	if err != nil {
   655  		return ""
   656  	}
   657  	return filepath.Join(c.HomeDir, ".glide")
   658  }
   659  
   660  // startup sets up the base environment.
   661  //
   662  // It does not assume the presence of a Glide.yaml file or vendor/ directory,
   663  // so it can be used by any Glide command.
   664  func startup(c *cli.Context) error {
   665  	action.Debug(c.Bool("debug"))
   666  	action.NoColor(c.Bool("no-color"))
   667  	action.Quiet(c.Bool("quiet"))
   668  	action.Init(c.String("yaml"), c.String("home"))
   669  	action.EnsureGoVendor()
   670  	return nil
   671  }
   672  
   673  // Get the path to the glide.yaml file.
   674  //
   675  // This returns the name of the path, even if the file does not exist. The value
   676  // may be set by the user, or it may be the default.
   677  func glidefile(c *cli.Context) string {
   678  	path := c.String("file")
   679  	if path == "" {
   680  		// For now, we construct a basic assumption. In the future, we could
   681  		// traverse backward to see if a glide.yaml exists in a parent.
   682  		path = "./glide.yaml"
   683  	}
   684  	a, err := filepath.Abs(path)
   685  	if err != nil {
   686  		// Underlying fs didn't provide working dir.
   687  		return path
   688  	}
   689  	return a
   690  }