diff --git a/README.md b/README.md index 5f42b2a4..8d41960f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ When a dependent package is encountered its imports are scanned to determine dependencies of dependencies (transitive dependencies). If the dependent project contains a `glide.yaml` file that information is used to help determine the dependency rules when fetching from a location or version to use. Configuration -from Godep, GB, GOM, and GPM is also imported. +from Godep, GB, GOM, GPM, and Vndr is also imported. The dependencies are exported to the `vendor/` directory where the `go` tools can find and use them. A `glide.lock` file is generated containing all the @@ -206,7 +206,7 @@ $ glide get github.com/Masterminds/cookoo ``` When `glide get` is used it will introspect the listed package to resolve its -dependencies including using Godep, GPM, Gom, and GB config files. +dependencies including using Godep, GPM, Gom, GB, and Vndr config files. ### glide update (aliased to up) @@ -219,7 +219,7 @@ $ glide up ``` This will recurse over the packages looking for other projects managed by Glide, -Godep, gb, gom, and GPM. When one is found those packages will be installed as needed. +Godep, gb, gom, GPM, and Vndr. When one is found those packages will be installed as needed. A `glide.lock` file will be created or updated with the dependencies pinned to specific versions. For example, if in the `glide.yaml` file a version was @@ -423,13 +423,13 @@ That's up to you. It's not necessary, but it may also cause you extra work and lots of extra space in your VCS. There may also be unforeseen errors ([see an example](https://github.com/mattfarina/golang-broken-vendor)). -#### Q: How do I import settings from GPM, Godep, gom or gb? +#### Q: How do I import settings from GPM, Godep, gom, gb, or Vndr? There are two parts to importing. -1. If a package you import has configuration for GPM, Godep, gom or gb Glide will +1. If a package you import has configuration for GPM, Godep, gom, gb, or Vndr Glide will recursively install the dependencies automatically. -2. If you would like to import configuration from GPM, Godep, gom or gb to Glide see +2. If you would like to import configuration from GPM, Godep, gom, gb, or Vndr to Glide see the `glide import` command. For example, you can run `glide import godep` for Glide to detect the projects Godep configuration and generate a `glide.yaml` file for you. diff --git a/action/create.go b/action/create.go index 5d421995..0b23c586 100644 --- a/action/create.go +++ b/action/create.go @@ -14,6 +14,7 @@ import ( "github.com/Masterminds/glide/msg" gpath "github.com/Masterminds/glide/path" "github.com/Masterminds/glide/util" + "github.com/Masterminds/glide/vndr" ) // Create creates/initializes a new Glide repository. @@ -204,6 +205,9 @@ func guessImportDeps(base string, config *cfg.Config) { } else if d, ok := guessImportGB(absBase); ok { msg.Info("Importing GB configuration") deps = d + } else if d, ok := guessImportVNDR(absBase); ok { + msg.Info("Importing VNDR configuration") + deps = d } for _, i := range deps { @@ -243,3 +247,12 @@ func guessImportGB(dir string) ([]*cfg.Dependency, bool) { return d, true } + +func guessImportVNDR(dir string) ([]*cfg.Dependency, bool) { + d, err := vndr.Parse(dir) + if err != nil || len(d) == 0 { + return []*cfg.Dependency{}, false + } + + return d, true +} diff --git a/action/import_vndr.go b/action/import_vndr.go new file mode 100644 index 00000000..d61a965a --- /dev/null +++ b/action/import_vndr.go @@ -0,0 +1,21 @@ +package action + +import ( + "github.com/Masterminds/glide/msg" + "github.com/Masterminds/glide/vndr" +) + +// ImportVNDR imports a vendor.conf file. +func ImportVNDR(dest string) { + base := "." + config := EnsureConfig() + if !vndr.Has(base) { + msg.Die("No VNDR data found.") + } + deps, err := vndr.Parse(base) + if err != nil { + msg.Die("Failed to extract VNDR file: %s", err) + } + appendImports(deps, config) + writeConfigToFileOrStdout(config, dest) +} diff --git a/docs/commands.md b/docs/commands.md index 7c3a53cc..65853275 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -46,7 +46,7 @@ You can download one or more packages to your `vendor` directory and have it add $ glide get github.com/Masterminds/cookoo -When `glide get` is used it will introspect the listed package to resolve its dependencies including using Godep, GPM, Gom, and GB config files. +When `glide get` is used it will introspect the listed package to resolve its dependencies including using Godep, GPM, Gom, GB, and Vndr config files. The `glide get` command can have a [version or range](versions.md) passed in with the package name. For example, @@ -63,7 +63,7 @@ dependency packages to fetch anything that's needed and read in any configuratio $ glide up This will recurse over the packages looking for other projects managed by Glide, -Godep, gb, gom, and GPM. When one is found those packages will be installed as needed. +Godep, gb, gom, GPM, and Vndr. When one is found those packages will be installed as needed. A `glide.lock` file will be created or updated with the dependencies pinned to specific versions. For example, if in the `glide.yaml` file a version was diff --git a/docs/faq.md b/docs/faq.md index 000edbac..1825ace9 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -18,12 +18,12 @@ By default, commands such as `glide update` and `glide install` install on-deman * `--strip-vcs` (aliased to `-s`) to strip VCS metadata (e.g., `.git` directories) from the `vendor` folder. * `--strip-vendor` (aliased to `-v`) to strip nested `vendor/` directories. -## Q: How do I import settings from GPM, Godep, Gom, or GB? +## Q: How do I import settings from GPM, Godep, Gom, GB, or Vndr? There are two parts to importing. -1. If a package you import has configuration for GPM, Godep, Gom, or GB Glide will recursively install the dependencies automatically. -2. If you would like to import configuration from GPM, Godep, Gom, or GB to Glide see the `glide import` command. For example, you can run `glide import godep` for Glide to detect the projects Godep configuration and generate a `glide.yaml` file for you. +1. If a package you import has configuration for GPM, Godep, Gom, GB, or Vndr Glide will recursively install the dependencies automatically. +2. If you would like to import configuration from GPM, Godep, Gom, GB, or Vndr to Glide see the `glide import` command. For example, you can run `glide import godep` for Glide to detect the projects Godep configuration and generate a `glide.yaml` file for you. Each of these will merge your existing `glide.yaml` file with the dependencies it finds for those managers, and then emit the file as diff --git a/docs/getting-started.md b/docs/getting-started.md index 1daafec8..5687ca43 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,7 +4,7 @@ This is a quick start guide to using Glide once you have it installed. ## Initially Detecting Project Dependencies -Glide can detect the dependencies in use on a project and create an initial `glide.yaml` file for you. This detection can import the configuration from Godep, GPM, Gom, and GB. To do this change into the top level directory for the project and run: +Glide can detect the dependencies in use on a project and create an initial `glide.yaml` file for you. This detection can import the configuration from Godep, GPM, Gom, GB, and Vndr. To do this change into the top level directory for the project and run: $ glide init @@ -18,7 +18,7 @@ To fetch the dependencies and set them to any versions specified in the `glide.y $ glide up -The `up` is short for `update`. This will fetch any dependencies specified in the `glide.yaml` file, walk the dependency tree to make sure any dependencies of the dependencies are fetched, and set them to the proper version. While walking the tree it will make sure versions are set and configuration from Godep, GPM, Gom, and GB is imported. +The `up` is short for `update`. This will fetch any dependencies specified in the `glide.yaml` file, walk the dependency tree to make sure any dependencies of the dependencies are fetched, and set them to the proper version. While walking the tree it will make sure versions are set and configuration from Godep, GPM, Gom, GB, and Vndr is imported. The fetched dependencies are all placed in the `vendor/` folder at the root of the project. The `go` toolchain will use the dependencies here prior to looking in the `GOPATH` or `GOROOT` if you are using Go 1.6+ or Go 1.5 with the Go 1.5 Vendor Experiment enabled. diff --git a/docs/index.md b/docs/index.md index c9791bfa..d4f7d7dc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ Glide provides the following functionality: * Supports Git, Bzr, HG, and SVN. These are the same version control systems supported by `go get`. * Utilizes `vendor/` directories, known as the Vendor Experiment, so that different projects can have differing versions of the same dependencies. * Allows for aliasing packages which is useful for working with forks. -* Import configuration from Godep, GPM, Gom, and GB. +* Import configuration from Godep, GPM, Gom, GB, and Vndr. ## Installing Glide diff --git a/docs/resolving-imports.md b/docs/resolving-imports.md index 11a857c4..786405b3 100644 --- a/docs/resolving-imports.md +++ b/docs/resolving-imports.md @@ -14,7 +14,7 @@ From this it will attempt to figure out the external packages. External packages Again, this is the same way `go` tries to determine an external location when you use `go get`. -If the project has dependency configuration stored in a Godep, GPM, Gom, or GB file that information will be used to populate the version within the `glide.yaml` file. +If the project has dependency configuration stored in a Godep, GPM, Gom, GB, or Vndr file that information will be used to populate the version within the `glide.yaml` file. ## At Update @@ -28,10 +28,10 @@ That means that only imports referenced in the source are fetched. When a version control repo is fetched it does fetch the complete repo. But, it doesn't scan all the packages in the repo for dependencies. Instead, only the packages referenced in the tree are scanned with the imports being followed. -Along the way configuration stored in Glide, Godep, GPM, Gom, and GB files are used to work out the version to set and fetched repos to. The first version found while walking the import tree wins. +Along the way configuration stored in Glide, Godep, GPM, Gom, GB, and Vndr files are used to work out the version to set and fetched repos to. The first version found while walking the import tree wins. ### All Possible Dependencies Using the `--all-dependencies` flag on `glide update` will change the behavior of the scan. Instead of walking the import tree it walks the filesystem and fetches all possible packages referenced everywhere. This downloads all packages in the tree. Even those not referenced in an applications source or in support of the applications imports. -As in other cases, Glide, Godep, GPM, Gom, and GB files are used to set the version of the fetched repo. +As in other cases, Glide, Godep, GPM, Gom, GB, and Vndr files are used to set the version of the fetched repo. diff --git a/glide.go b/glide.go index 58ab9645..eba48dda 100644 --- a/glide.go +++ b/glide.go @@ -374,6 +374,20 @@ func commands() []cli.Command { return nil }, }, + { + Name: "vndr", + Usage: "Import VNDR's vendor.conf file and display the would-be yaml file", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "file, f", + Usage: "Save all of the discovered dependencies to a Glide YAML file.", + }, + }, + Action: func(c *cli.Context) error { + action.ImportVNDR(c.String("file")) + return nil + }, + }, }, }, { diff --git a/importer/importer.go b/importer/importer.go index 9d5d2ac7..09e22cd8 100644 --- a/importer/importer.go +++ b/importer/importer.go @@ -11,6 +11,7 @@ import ( "github.com/Masterminds/glide/godep" "github.com/Masterminds/glide/gom" "github.com/Masterminds/glide/gpm" + "github.com/Masterminds/glide/vndr" ) var i = &DefaultImporter{} @@ -87,6 +88,15 @@ func (d *DefaultImporter) Import(path string) (bool, []*cfg.Dependency, error) { return true, deps, nil } + // Try importing from vndr + if vndr.Has(path) { + deps, err := vndr.Parse(path) + if err != nil { + return false, []*cfg.Dependency{}, err + } + return true, deps, nil + } + // When none are found. return false, []*cfg.Dependency{}, nil } diff --git a/vndr/vndr.go b/vndr/vndr.go new file mode 100644 index 00000000..96693509 --- /dev/null +++ b/vndr/vndr.go @@ -0,0 +1,81 @@ +// Package vndr provides basic importing of Vendor.conf dependencies. +package vndr + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/Masterminds/glide/cfg" + "github.com/Masterminds/glide/msg" + gpath "github.com/Masterminds/glide/path" + "github.com/Masterminds/glide/util" +) + +// Has is a command to detect if a package contains a vendor.conf file. +func Has(dir string) bool { + path := filepath.Join(dir, "vendor.conf") + _, err := os.Stat(path) + return err == nil +} + +// Parse parses a VNDR vendor.conf file. +// +// It returns the contents as a dependency array. +func Parse(dir string) ([]*cfg.Dependency, error) { + path := filepath.Join(dir, "vendor.conf") + msg.Info(dir) + if _, err := os.Stat(path); err != nil { + return []*cfg.Dependency{}, nil + } + msg.Info("Found vendor.conf file in %s", gpath.StripBasepath(dir)) + msg.Info("--> Parsing vndr metadata...") + + buf := []*cfg.Dependency{} + + // Get a handle to the file. + file, err := os.Open(path) + if err != nil { + return buf, err + } + defer file.Close() + + s := bufio.NewScanner(file) + for s.Scan() { + // Read and build the dependencies from the file + ln := strings.TrimSpace(s.Text()) + if strings.HasPrefix(ln, "#") || ln == "" { + continue + } + cidx := strings.Index(ln, "#") + if cidx > 0 { + ln = ln[:cidx] + } + ln = strings.TrimSpace(ln) + parts := strings.Fields(ln) + if len(parts) != 2 && len(parts) != 3 { + return []*cfg.Dependency{}, fmt.Errorf("invalid config format: %s", ln) + } + + dep := &cfg.Dependency{ + Reference: parts[1], + } + if len(parts) == 3 { + dep.Repository = parts[2] + } + pkg, sub := util.NormalizeName(parts[0]) + dep.Name = pkg + if len(sub) > 0 { + dep.Subpackages = []string{sub} + } + + buf = append(buf, dep) + } + if err := s.Err(); err != nil { + return []*cfg.Dependency{}, err + } + + return buf, nil +}