Catch gps back up with master
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a76e7d3..9c1187a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,47 @@
+# Release 0.11.0 (2016-07-05)
+
+## Added
+- #461: Resolve test imports
+- #458: Wizard and version detection are now on `glide get`
+- #444: New config wizard helps you find versions and set ranges. Can be run from
+ `glide init` or as separate command
+- #438: Added ability to read symlink basedirs (thanks @klnusbaum)
+- #436: Added .idea to .gitignore
+- #393 and #401: Added a PPA (https://github.com/Masterminds/glide-ppa) and instructions
+ on using it (thanks @franciscocpg)
+- #390: Added support for custom Go executable name. Needed for environments like
+ appengine. Environment variable GLIDE_GO_EXECUTABLE (thanks @dpmcnevin)
+- #382: `glide info` command takes a format string and returns info (thanks @franciscocpg)
+- #365: glide list: support json output format (thanks @chancez)
+
+## Changed
+- Tags are now in the form v[SemVer]. The change is the initial v on the tag.
+ This is to conform with other Go tools that require this.
+- #501: Updating the plugins documentation and adding listing
+- #500: Log an error if stripping version control data fails (thanks @alexbrand)
+- #496: Updated to github.com/Masterminds/semver 1.1.1
+- #495: Updated to github.com/Masterminds/vcs 1.8.0
+- #494: Glide install skips fetch when it is up to date
+- #489: Make shared funcs for lockfile usage (thanks @heewa)
+- #459: When a conflict occurs output the tag, if one exists, for the commit
+- #443: Updating message indentation to be uniform
+- #431: Updated the docs on subpackages
+- #433: The global shared cache was reworked in prep for future uses
+- #396: Don't update the lock file if nothing has changed
+
+## Fixed
+- #460: Sometimes ignored packages were written to lock file. Fixed.
+- #463: Fixed possible nil pointer issues
+- #453: Fix DeleteUnused flag which was not working (thanks @s-urbaniak)
+- #432: Fixed issue with new net/http/httptrace std lib package
+- #392: Correctly normalize Windows package paths (thanks @jrick)
+- #395: Creating the cache key did not handle SCP properly
+- #386: Fixed help text indentation
+- #383: Failed `glide get` had been updating files. No longer does this
+
+And thanks to @derelk, @franciscocpg, @shawnps, @kngu9, @tugberkugurlu, @rhcarvalho,
+@gyuho, and @7imon7ays for documentation updates.
+
# Release 0.10.2 (2016-04-06)
- Issue #362: Updated docs on how -update-vendored works to help avoid confusion.
diff --git a/README.md b/README.md
index 566bd30..39ef0e8 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
installed by a tool (e.g. glide), similar to `go get` or they can be vendored and
distributed with the package.
-[](https://travis-ci.org/Masterminds/glide) [](http://goreportcard.com/report/Masterminds/glide) [](https://godoc.org/github.com/Masterminds/glide) [](http://glide.readthedocs.org/en/stable/?badge=stable) [](http://glide.readthedocs.org/en/latest/?badge=latest) [](https://gitter.im/Masterminds/glide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://travis-ci.org/Masterminds/glide) [](https://goreportcard.com/report/github.com/Masterminds/glide) [](https://godoc.org/github.com/Masterminds/glide) [](http://glide.readthedocs.org/en/stable/?badge=stable) [](http://glide.readthedocs.org/en/latest/?badge=latest) [](https://gitter.im/Masterminds/glide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
### Features
@@ -76,7 +76,13 @@
## Install
-On Mac OS X you can install the latest release via [Homebrew](https://github.com/Homebrew/homebrew):
+The easiest way to install the latest release on Mac or Linux is with the following script:
+
+```
+curl https://glide.sh/get | sh
+```
+
+On Mac OS X you can also install the latest release via [Homebrew](https://github.com/Homebrew/homebrew):
```
$ brew install glide
diff --git a/action/get.go b/action/get.go
index d4e9a50..ff9ed7d 100644
--- a/action/get.go
+++ b/action/get.go
@@ -50,7 +50,7 @@
// don't want a get to just update all deps without the user explictly
// making that choice.
if gpath.HasLock(base) {
- params.Lock, err = LoadLockfile(base, conf)
+ params.Lock, err = loadLockfile(base, conf)
if err != nil {
msg.Err("Could not load lockfile; aborting get. Existing dependency versions cannot be safely preserved without a lock file. Error was: %s", err)
return
diff --git a/action/install.go b/action/install.go
index 53599af..c10f5d3 100644
--- a/action/install.go
+++ b/action/install.go
@@ -49,7 +49,7 @@
var s gps.Solver
if gpath.HasLock(base) {
- params.Lock, err = LoadLockfile(base, conf)
+ params.Lock, err = loadLockfile(base, conf)
if err != nil {
msg.Err("Could not load lockfile.")
return
@@ -334,10 +334,8 @@
return nil
}
-// LoadLockfile loads the contents of a glide.lock file.
-//
-// TODO: This should go in another package.
-func LoadLockfile(base string, conf *cfg.Config) (*cfg.Lockfile, error) {
+// loadLockfile loads the contents of a glide.lock file.
+func loadLockfile(base string, conf *cfg.Config) (*cfg.Lockfile, error) {
yml, err := ioutil.ReadFile(filepath.Join(base, gpath.LockFile))
if err != nil {
return nil, err
diff --git a/action/project_info.go b/action/project_info.go
index 0662bbc..b82b41c 100644
--- a/action/project_info.go
+++ b/action/project_info.go
@@ -6,13 +6,14 @@
"github.com/Masterminds/glide/msg"
)
+// Info prints information about a project based on a passed in format.
func Info(format string) {
conf := EnsureConfig()
var buffer bytes.Buffer
varInit := false
- for _, var_format := range format {
+ for _, varfmt := range format {
if varInit {
- switch var_format {
+ switch varfmt {
case 'n':
buffer.WriteString(conf.ProjectRoot)
case 'd':
@@ -22,15 +23,15 @@
case 'l':
buffer.WriteString(conf.License)
default:
- msg.Die("Invalid format %s", string(var_format))
+ msg.Die("Invalid format %s", string(varfmt))
}
} else {
- switch var_format {
+ switch varfmt {
case '%':
varInit = true
continue
default:
- buffer.WriteString(string(var_format))
+ buffer.WriteString(string(varfmt))
}
}
varInit = false
diff --git a/action/rebuild.go b/action/rebuild.go
index f76d948..dffde39 100644
--- a/action/rebuild.go
+++ b/action/rebuild.go
@@ -98,4 +98,3 @@
}
return err
}
-
diff --git a/action/update.go b/action/update.go
index 33d616a..c008f98 100644
--- a/action/update.go
+++ b/action/update.go
@@ -52,7 +52,7 @@
}
if gpath.HasLock(base) {
- params.Lock, err = LoadLockfile(base, conf)
+ params.Lock, err = loadLockfile(base, conf)
if err != nil {
msg.Err("Could not load lockfile, aborting: %s", err)
return
diff --git a/cfg/config.go b/cfg/config.go
index 54e60be..3046a74 100644
--- a/cfg/config.go
+++ b/cfg/config.go
@@ -465,6 +465,19 @@
Os []string `yaml:"os,omitempty"`
}
+// DependencyFromLock converts a Lock to a Dependency
+func DependencyFromLock(lock *Lock) *Dependency {
+ return &Dependency{
+ Name: lock.Name,
+ Reference: lock.Version,
+ Repository: lock.Repository,
+ VcsType: lock.VcsType,
+ Subpackages: lock.Subpackages,
+ Arch: lock.Arch,
+ Os: lock.Os,
+ }
+}
+
// UnmarshalYAML is a hook for gopkg.in/yaml.v2 in the unmarshaling process
func (d *Dependency) UnmarshalYAML(unmarshal func(interface{}) error) error {
newDep := &dep{}
diff --git a/cfg/lock.go b/cfg/lock.go
index 0c798a6..ac03f91 100644
--- a/cfg/lock.go
+++ b/cfg/lock.go
@@ -153,6 +153,19 @@
return sha256.Sum256(yml), nil
}
+// ReadLockFile loads the contents of a glide.lock file.
+func ReadLockFile(lockpath string) (*Lockfile, error) {
+ yml, err := ioutil.ReadFile(lockpath)
+ if err != nil {
+ return nil, err
+ }
+ lock, err := LockfileFromYaml(yml)
+ if err != nil {
+ return nil, err
+ }
+ return lock, nil
+}
+
// Locks is a slice of locked dependencies.
type Locks []*Lock
@@ -211,6 +224,19 @@
}
}
+// LockFromDependency converts a Dependency to a Lock
+func LockFromDependency(dep *Dependency) *Lock {
+ return &Lock{
+ Name: dep.Name,
+ Version: dep.Pin,
+ Repository: dep.Repository,
+ VcsType: dep.VcsType,
+ Subpackages: dep.Subpackages,
+ Arch: dep.Arch,
+ Os: dep.Os,
+ }
+}
+
// NewLockfile is used to create an instance of Lockfile.
func NewLockfile(ds, tds Dependencies, hash string) *Lockfile {
lf := &Lockfile{
@@ -221,29 +247,13 @@
}
for i := 0; i < len(ds); i++ {
- lf.Imports[i] = &Lock{
- Name: ds[i].Name,
- Version: ds[i].Pin,
- Repository: ds[i].Repository,
- VcsType: ds[i].VcsType,
- Subpackages: ds[i].Subpackages,
- Arch: ds[i].Arch,
- Os: ds[i].Os,
- }
+ lf.Imports[i] = LockFromDependency(ds[i])
}
sort.Sort(lf.Imports)
for i := 0; i < len(tds); i++ {
- lf.DevImports[i] = &Lock{
- Name: tds[i].Name,
- Version: tds[i].Pin,
- Repository: tds[i].Repository,
- VcsType: tds[i].VcsType,
- Subpackages: tds[i].Subpackages,
- Arch: tds[i].Arch,
- Os: tds[i].Os,
- }
+ lf.DevImports[i] = LockFromDependency(tds[i])
}
sort.Sort(lf.DevImports)
@@ -261,15 +271,8 @@
i := 0
for name, dep := range ds {
- lf.Imports[i] = &Lock{
- Name: name,
- Version: dep.Pin,
- Repository: dep.Repository,
- VcsType: dep.VcsType,
- Subpackages: dep.Subpackages,
- Arch: dep.Arch,
- Os: dep.Os,
- }
+ lf.Imports[i] = LockFromDependency(dep)
+ lf.Imports[i].Name = name
i++
}
diff --git a/docs/plugins.md b/docs/plugins.md
index 98f24ae..bc3b596 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -1,44 +1,47 @@
# Glide Plugins
-(Not to be confused with Glade Plugins. Pew.)
+Glide supports a simple plugin system similar to Git.
-Glide supports a simple plugin system similar to Git. When Glide
-encounters a subcommand that it does not know, it will try to delegate
-it to another executable according to the following rules.
+## Existing Plugins
+
+Some plugins exist today for Glide including:
+
+* [glide-vc](https://github.com/sgotti/glide-vc) - The vendor cleaner allows you to strip files files not needed for building your application from the `vendor/` directory.
+* [glide-brew](https://github.com/heewa/glide-brew) - Convert Go deps managed by glide to Homebrew resources to help you make brew formulas for you Go programs.
+* [glide-hash](https://github.com/mattfarina/glide-hash) - Generates a hash of the `glide.yaml` file compatible with Glides internal hash.
+
+_Note, to add plugins to this list please create a pull request._
+
+## How Plugins Work
+
+When Glide encounters a subcommand that it does not know, it will try to delegate it to another executable according to the following rules.
Example:
```
-$ glide in # We know this command, so we execute it
-$ glide foo # We don't know this command, so we look for a suitable
- # plugin.
+$ glide install # We know this command, so we execute it
+$ glide foo # We don't know this command, so we look for a suitable
+ # plugin.
```
-In the example above, when glide receives the command `foo`, which it
-does not know, it will do the following:
+In the example above, when glide receives the command `foo`, which it does not know, it will do the following:
1. Transform the name from `foo` to `glide-foo`
-2. Look on the system `$PATH` for `glide-foo`. If it finds a program by
- that name, execute it...
-3. Or else, look at the current project's root for `glide-foo`. (That
- is, look in the same directory as glide.yaml). If found, execute it.
+2. Look on the system `$PATH` for `glide-foo`. If it finds a program by that name, execute it...
+3. Or else, look at the current project's root for `glide-foo`. (That is, look in the same directory as `glide.yaml`). If found, execute it.
4. If no suitable command is found, exit with an error.
## Writing a Glide Plugin
-A Glide plugin can be written in any language you wish, provided that it
-can be executed from the command line as a subprocess of Glide. The
-example included with Glide is a simple Bash script. We could just as
-easily write Go, Python, Perl, or even Java code (with a wrapper) to
+A Glide plugin can be written in any language you wish, provided that it can be executed from the command line as a subprocess of Glide. The example included with Glide is a simple Bash script. We could just as easily write Go, Python, Perl, or even Java code (with a wrapper) to
execute.
A glide plugin must be in one of two locations:
-1. Somewhere on the PATH (including `$GLIDE_PATH/_vendor/bin`)
+1. Somewhere on the PATH
2. In the same directory as `glide.yaml`
-It is recommended that system-wide Glide plugins go in `/usr/local/bin`
-while project-specific plugins go in the same directory as `glide.yaml`.
+It is recommended that system-wide Glide plugins go in `/usr/local/bin` or `$GOPATH/bin` while project-specific plugins go in the same directory as `glide.yaml`.
### Arguments and Flags
@@ -48,32 +51,15 @@
$ glide foo -name=Matt myfile.txt
```
-Glide will interpret this as a request to execute `glide-foo` with the
-arguments `-name=Matt myfile.txt`. It will not attempt to interpret
-those arguments or modify them in any way.
+Glide will interpret this as a request to execute `glide-foo` with the arguments `-name=Matt myfile.txt`. It will not attempt to interpret those arguments or modify them in any way.
-Hypothetically, if Glide had a `-x` flag of its own, you could call
-this:
+Hypothetically, if Glide had a `-x` flag of its own, you could call this:
```
$ glide -x foo -name=Matt myfile.txt
```
-In this case, glide would interpret and swollow the -x and pass the rest
-on to glide-foo as in the example above.
-
-### Environment Variables
-
-When Glide executes a plugin, it passes through all of its environment
-variables, including...
-
-- GOPATH: Gopath
-- PATH: Executable paths
-- GLIDE_GOPATH: Gopath (in case GOPATH gets overridden by another
- script)
-- GLIDE_PROJECT: The path to the project
-- GLIDE_YAML: The path to the project's YAML
-- ALREADY_GLIDING: 1 if we are in a `glide in` session.
+In this case, glide would interpret and swollow the -x and pass the rest on to `glide-foo` as in the example above.
## Example Plugin
@@ -84,5 +70,3 @@
echo "Hello"
```
-
-Yup, that's it. Also see `glide-example-plugin` for a bigger example.
diff --git a/docs/versions.md b/docs/versions.md
index a323fb2..047a5ce 100644
--- a/docs/versions.md
+++ b/docs/versions.md
@@ -27,7 +27,7 @@
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
-* `<= 2.x` is equivalent to `<= 3`
+* `<= 2.x` is equivalent to `< 3`
* `*` is equivalent to `>= 0.0.0`
## Tilde Range Comparisons (Patch)
diff --git a/glide.lock b/glide.lock
index 951824d..e46c890 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: 607480f548198f86c4f4a5946960053afa74db4cd2d5c62b51d5954470922d3a
-updated: 2016-06-24T15:23:14.128213581-04:00
+hash: 0653c17bcbf6f1df79990f3d2211dbcbc920ca528c513b00f5cab0a508c984ab
+updated: 2016-06-30T10:51:49.633776379-04:00
imports:
- name: github.com/armon/go-radix
version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2
@@ -8,7 +8,7 @@
- name: github.com/Masterminds/semver
version: 0a2c9fc0eee2c4cbb9526877c4a54da047fdcadd
- name: github.com/Masterminds/vcs
- version: 7af28b64c5ec41b1558f5514fd938379822c237c
+ version: fbe9fb6ad5b5f35b3e82a7c21123cfc526cbf895
- name: github.com/sdboyer/gps
version: a868c10855893c21ed05d0f50d6f9acb12b6366d
- name: github.com/termie/go-shutil
diff --git a/glide.yaml b/glide.yaml
index 7a966ad..cb185ed 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -12,7 +12,7 @@
- package: gopkg.in/yaml.v2
branch: v2
- package: github.com/Masterminds/vcs
- version: ^1.7.0
+ version: ^1.8.0
- package: github.com/codegangsta/cli
version: ~1.14.0
- package: github.com/Masterminds/semver
diff --git a/gom/parser.go b/gom/parser.go
index bf54f61..3bcd9e0 100644
--- a/gom/parser.go
+++ b/gom/parser.go
@@ -16,10 +16,10 @@
var qx = `'[^']*'|"[^"]*"`
var kx = `:[a-z][a-z0-9_]*`
var ax = `(?:\s*` + kx + `\s*|,\s*` + kx + `\s*)`
-var re_group = regexp.MustCompile(`\s*group\s+((?:` + kx + `\s*|,\s*` + kx + `\s*)*)\s*do\s*$`)
-var re_end = regexp.MustCompile(`\s*end\s*$`)
-var re_gom = regexp.MustCompile(`^\s*gom\s+(` + qx + `)\s*((?:,\s*` + kx + `\s*=>\s*(?:` + qx + `|\s*\[\s*` + ax + `*\s*\]\s*))*)$`)
-var re_options = regexp.MustCompile(`(,\s*` + kx + `\s*=>\s*(?:` + qx + `|\s*\[\s*` + ax + `*\s*\]\s*)\s*)`)
+var reGroup = regexp.MustCompile(`\s*group\s+((?:` + kx + `\s*|,\s*` + kx + `\s*)*)\s*do\s*$`)
+var reEnd = regexp.MustCompile(`\s*end\s*$`)
+var reGom = regexp.MustCompile(`^\s*gom\s+(` + qx + `)\s*((?:,\s*` + kx + `\s*=>\s*(?:` + qx + `|\s*\[\s*` + ax + `*\s*\]\s*))*)$`)
+var reOptions = regexp.MustCompile(`(,\s*` + kx + `\s*=>\s*(?:` + qx + `|\s*\[\s*` + ax + `*\s*\]\s*)\s*)`)
func unquote(name string) string {
name = strings.TrimSpace(name)
@@ -32,13 +32,13 @@
}
func parseOptions(line string, options map[string]interface{}) {
- ss := re_options.FindAllStringSubmatch(line, -1)
- re_a := regexp.MustCompile(ax)
+ ss := reOptions.FindAllStringSubmatch(line, -1)
+ reA := regexp.MustCompile(ax)
for _, s := range ss {
kvs := strings.SplitN(strings.TrimSpace(s[0])[1:], "=>", 2)
kvs[0], kvs[1] = strings.TrimSpace(kvs[0]), strings.TrimSpace(kvs[1])
if kvs[1][0] == '[' {
- as := re_a.FindAllStringSubmatch(kvs[1][1:len(kvs[1])-1], -1)
+ as := reA.FindAllStringSubmatch(kvs[1][1:len(kvs[1])-1], -1)
a := []string{}
for i := range as {
it := strings.TrimSpace(as[i][0])
@@ -57,6 +57,7 @@
}
}
+// Gom represents configuration from Gom.
type Gom struct {
name string
options map[string]interface{}
@@ -95,14 +96,14 @@
name := ""
options := make(map[string]interface{})
var items []string
- if re_group.MatchString(line) {
- envs = strings.Split(re_group.FindStringSubmatch(line)[1], ",")
+ if reGroup.MatchString(line) {
+ envs = strings.Split(reGroup.FindStringSubmatch(line)[1], ",")
for i := range envs {
envs[i] = strings.TrimSpace(envs[i])[1:]
}
valid = true
continue
- } else if re_end.MatchString(line) {
+ } else if reEnd.MatchString(line) {
if !valid {
skip--
if skip < 0 {
@@ -114,8 +115,8 @@
continue
} else if skip > 0 {
continue
- } else if re_gom.MatchString(line) {
- items = re_gom.FindStringSubmatch(line)[1:]
+ } else if reGom.MatchString(line) {
+ items = reGom.FindStringSubmatch(line)[1:]
name = unquote(items[0])
parseOptions(items[1], options)
} else {
@@ -126,5 +127,4 @@
}
goms = append(goms, Gom{name, options})
}
- return goms, nil
-}
\ No newline at end of file
+}
diff --git a/mkdocs.yml b/mkdocs.yml
index 29109e0..6d6764b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,5 +8,6 @@
- Commands: commands.md
- Resolving Imports: resolving-imports.md
- Vendor Directories: vendor.md
+- Plugins: plugins.md
- F.A.Q.: faq.md
theme: readthedocs
diff --git a/repo/installer.go b/repo/installer.go
index 8004da5..cce24ef 100644
--- a/repo/installer.go
+++ b/repo/installer.go
@@ -58,6 +58,7 @@
Updated *UpdateTracker
}
+// NewInstaller returns an Installer instance ready to use. This is the constructor.
func NewInstaller() *Installer {
i := &Installer{}
i.Updated = NewUpdateTracker()
@@ -93,28 +94,12 @@
newConf.Imports = make(cfg.Dependencies, len(lock.Imports))
for k, v := range lock.Imports {
- newConf.Imports[k] = &cfg.Dependency{
- Name: v.Name,
- Reference: v.Version,
- Repository: v.Repository,
- VcsType: v.VcsType,
- Subpackages: v.Subpackages,
- Arch: v.Arch,
- Os: v.Os,
- }
+ newConf.Imports[k] = cfg.DependencyFromLock(v)
}
newConf.DevImports = make(cfg.Dependencies, len(lock.DevImports))
for k, v := range lock.DevImports {
- newConf.DevImports[k] = &cfg.Dependency{
- Name: v.Name,
- Reference: v.Version,
- Repository: v.Repository,
- VcsType: v.VcsType,
- Subpackages: v.Subpackages,
- Arch: v.Arch,
- Os: v.Os,
- }
+ newConf.DevImports[k] = cfg.DependencyFromLock(v)
}
newConf.DeDupe()
@@ -126,8 +111,8 @@
msg.Info("Downloading dependencies. Please wait...")
- ConcurrentUpdate(newConf.Imports, cwd, i, newConf)
- ConcurrentUpdate(newConf.DevImports, cwd, i, newConf)
+ LazyConcurrentUpdate(newConf.Imports, cwd, i, newConf)
+ LazyConcurrentUpdate(newConf.DevImports, cwd, i, newConf)
return newConf, nil
}
@@ -317,6 +302,43 @@
return conf.Imports
}
+// LazyConcurrentUpdate updates only deps that are not already checkout out at the right version.
+//
+// This is only safe when updating from a lock file.
+func LazyConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error {
+
+ newDeps := []*cfg.Dependency{}
+ for _, dep := range deps {
+ destPath := filepath.Join(i.VendorPath(), dep.Name)
+
+ // Get a VCS object for this directory
+ repo, err := dep.GetRepo(destPath)
+ if err != nil {
+ newDeps = append(newDeps, dep)
+ continue
+ }
+
+ ver, err := repo.Version()
+ if err != nil {
+ newDeps = append(newDeps, dep)
+ continue
+ }
+
+ if ver == dep.Reference {
+ msg.Info("--> Found desired version %s %s!", dep.Name, dep.Reference)
+ continue
+ }
+
+ msg.Debug("--> Queue %s for update (%s != %s).", dep.Name, ver, dep.Reference)
+ newDeps = append(newDeps, dep)
+ }
+ if len(newDeps) > 0 {
+ return ConcurrentUpdate(newDeps, cwd, i, c)
+ }
+
+ return nil
+}
+
// ConcurrentUpdate takes a list of dependencies and updates in parallel.
func ConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error {
done := make(chan struct{}, concurrentWorkers)
diff --git a/repo/vcs.go b/repo/vcs.go
index fc6c9df..ba84ca2 100644
--- a/repo/vcs.go
+++ b/repo/vcs.go
@@ -203,14 +203,14 @@
}
ver := dep.Reference
- // Referenes in Git can begin with a ^ which is similar to semver.
+ // References in Git can begin with a ^ which is similar to semver.
// If there is a ^ prefix we assume it's a semver constraint rather than
// part of the git/VCS commit id.
if repo.IsReference(ver) && !strings.HasPrefix(ver, "^") {
msg.Info("--> Setting version for %s to %s.\n", dep.Name, ver)
} else {
- // Create the constraing first to make sure it's valid before
+ // Create the constraint first to make sure it's valid before
// working on the repo.
constraint, err := semver.NewConstraint(ver)
diff --git a/vendor/github.com/Masterminds/semver/README.md b/vendor/github.com/Masterminds/semver/README.md
index aa133ea..1edec7a 100644
--- a/vendor/github.com/Masterminds/semver/README.md
+++ b/vendor/github.com/Masterminds/semver/README.md
@@ -7,13 +7,15 @@
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix
-[](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](http://goreportcard.com/report/Masterminds/semver)
+[](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](https://goreportcard.com/report/github.com/Masterminds/semver)
## Parsing Semantic Versions
To parse a semantic version use the `NewVersion` function. For example,
+```go
v, err := semver.NewVersion("1.2.3-beta.1+build345")
+```
If there is an error the version wasn't parseable. The version object has methods
to get the parts of the version, compare it to other versions, convert the
@@ -25,6 +27,7 @@
A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
package from the standard library. For example,
+```go
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
@@ -37,12 +40,14 @@
}
sort.Sort(semver.Collection(vs))
+```
## Checking Version Constraints
Checking a version against version constraints is one of the most featureful
parts of the package.
+```go
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
// Handle constraint not being parseable.
@@ -54,6 +59,7 @@
}
// Check if the version meets the constraints. The a variable will be true.
a := c.Check(v)
+```
## Basic Comparisons
@@ -119,6 +125,7 @@
against a constraint. When validation fails a slice of errors containing why a
version didn't meet the constraint is returned. For example,
+```go
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
if err != nil {
// Handle constraint not being parseable.
@@ -139,6 +146,7 @@
// "1.3 is greater than 1.2.3"
// "1.3 is less than 1.4"
}
+```
# Contribute
diff --git a/vendor/github.com/Masterminds/vcs/.travis.yml b/vendor/github.com/Masterminds/vcs/.travis.yml
index a8c32da..5c50c4a 100644
--- a/vendor/github.com/Masterminds/vcs/.travis.yml
+++ b/vendor/github.com/Masterminds/vcs/.travis.yml
@@ -18,4 +18,9 @@
sudo: false
notifications:
- irc: "irc.freenode.net#masterminds"
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/06e3328629952dabe3e0
+ on_success: change # options: [always|never|change] default: always
+ on_failure: always # options: [always|never|change] default: always
+ on_start: never # options: [always|never|change] default: always
diff --git a/vendor/github.com/Masterminds/vcs/CHANGELOG.md b/vendor/github.com/Masterminds/vcs/CHANGELOG.md
index d178685..6362674 100644
--- a/vendor/github.com/Masterminds/vcs/CHANGELOG.md
+++ b/vendor/github.com/Masterminds/vcs/CHANGELOG.md
@@ -1,4 +1,18 @@
-1.7.0 (2016-05-05)
+# 1.8.0 (2016-06-29)
+
+## Added
+- #43: Detect when tool (e.g., git, svn, etc) not installed
+- #49: Detect access denied and not found situations
+
+## Changed
+- #48: Updated Go Report Gard url to new format
+- Refactored SVN handling to detect when not in a top level directory
+- Updating tagging to v[SemVer] structure for compatibility with other tools.
+
+## Fixed
+- #45: Fixed hg's update method so that it pulls from remote before updates
+
+# 1.7.0 (2016-05-05)
- Adds a glide.yaml file with some limited information.
- Implements #37: Ability to export source as a directory.
diff --git a/vendor/github.com/Masterminds/vcs/README.md b/vendor/github.com/Masterminds/vcs/README.md
index 6025f2d..cdb981f 100644
--- a/vendor/github.com/Masterminds/vcs/README.md
+++ b/vendor/github.com/Masterminds/vcs/README.md
@@ -3,7 +3,7 @@
Manage repos in varying version control systems with ease through a common
interface.
-[](https://travis-ci.org/Masterminds/vcs) [](https://godoc.org/github.com/Masterminds/vcs) [](http://goreportcard.com/report/Masterminds/vcs)
+[](https://travis-ci.org/Masterminds/vcs) [](https://godoc.org/github.com/Masterminds/vcs) [](https://goreportcard.com/report/github.com/Masterminds/vcs)
## Quick Usage
diff --git a/vendor/github.com/Masterminds/vcs/bzr.go b/vendor/github.com/Masterminds/vcs/bzr.go
index a62451f..e8f55b6 100644
--- a/vendor/github.com/Masterminds/vcs/bzr.go
+++ b/vendor/github.com/Masterminds/vcs/bzr.go
@@ -16,6 +16,10 @@
// NewBzrRepo creates a new instance of BzrRepo. The remote and local directories
// need to be passed in.
func NewBzrRepo(remote, local string) (*BzrRepo, error) {
+ ins := depInstalled("bzr")
+ if !ins {
+ return nil, NewLocalError("bzr is not installed", nil, "")
+ }
ltype, err := DetectVcsFromFS(local)
// Found a VCS other than Bzr. Need to report an error.
diff --git a/vendor/github.com/Masterminds/vcs/git.go b/vendor/github.com/Masterminds/vcs/git.go
index 778b6af..eb4b86e 100644
--- a/vendor/github.com/Masterminds/vcs/git.go
+++ b/vendor/github.com/Masterminds/vcs/git.go
@@ -14,6 +14,10 @@
// NewGitRepo creates a new instance of GitRepo. The remote and local directories
// need to be passed in.
func NewGitRepo(remote, local string) (*GitRepo, error) {
+ ins := depInstalled("git")
+ if !ins {
+ return nil, NewLocalError("git is not installed", nil, "")
+ }
ltype, err := DetectVcsFromFS(local)
// Found a VCS other than Git. Need to report an error.
diff --git a/vendor/github.com/Masterminds/vcs/hg.go b/vendor/github.com/Masterminds/vcs/hg.go
index 0d7a994..df41cd6 100644
--- a/vendor/github.com/Masterminds/vcs/hg.go
+++ b/vendor/github.com/Masterminds/vcs/hg.go
@@ -14,6 +14,10 @@
// NewHgRepo creates a new instance of HgRepo. The remote and local directories
// need to be passed in.
func NewHgRepo(remote, local string) (*HgRepo, error) {
+ ins := depInstalled("hg")
+ if !ins {
+ return nil, NewLocalError("hg is not installed", nil, "")
+ }
ltype, err := DetectVcsFromFS(local)
// Found a VCS other than Hg. Need to report an error.
@@ -84,11 +88,7 @@
// Update performs a Mercurial pull to an existing checkout.
func (s *HgRepo) Update() error {
- out, err := s.RunFromDir("hg", "update")
- if err != nil {
- return NewRemoteError("Unable to update repository", err, string(out))
- }
- return nil
+ return s.UpdateVersion(``)
}
// UpdateVersion sets the version of a package currently checked out via Hg.
@@ -97,7 +97,11 @@
if err != nil {
return NewLocalError("Unable to update checked out version", err, string(out))
}
- out, err = s.RunFromDir("hg", "update", version)
+ if len(strings.TrimSpace(version)) > 0 {
+ out, err = s.RunFromDir("hg", "update", version)
+ } else {
+ out, err = s.RunFromDir("hg", "update")
+ }
if err != nil {
return NewLocalError("Unable to update checked out version", err, string(out))
}
diff --git a/vendor/github.com/Masterminds/vcs/repo.go b/vendor/github.com/Masterminds/vcs/repo.go
index 99bc2d2..1298a5f 100644
--- a/vendor/github.com/Masterminds/vcs/repo.go
+++ b/vendor/github.com/Masterminds/vcs/repo.go
@@ -257,3 +257,11 @@
}
return out
}
+
+func depInstalled(name string) bool {
+ if _, err := exec.LookPath(name); err != nil {
+ return false
+ }
+
+ return true
+}
diff --git a/vendor/github.com/Masterminds/vcs/repo_test.go b/vendor/github.com/Masterminds/vcs/repo_test.go
index 12f63f5..d61f6cb 100644
--- a/vendor/github.com/Masterminds/vcs/repo_test.go
+++ b/vendor/github.com/Masterminds/vcs/repo_test.go
@@ -60,3 +60,15 @@
t.Errorf("Not detecting repo switch from SVN to Git")
}
}
+
+func TestDepInstalled(t *testing.T) {
+ i := depInstalled("git")
+ if i != true {
+ t.Error("depInstalled not finding installed dep.")
+ }
+
+ i = depInstalled("thisreallyisntinstalled")
+ if i != false {
+ t.Error("depInstalled finding not installed dep.")
+ }
+}
diff --git a/vendor/github.com/Masterminds/vcs/svn.go b/vendor/github.com/Masterminds/vcs/svn.go
index 48d089b..888ae09 100644
--- a/vendor/github.com/Masterminds/vcs/svn.go
+++ b/vendor/github.com/Masterminds/vcs/svn.go
@@ -2,21 +2,23 @@
import (
"encoding/xml"
+ "fmt"
"os"
"os/exec"
"path/filepath"
- "regexp"
"strings"
"time"
)
-var svnDetectURL = regexp.MustCompile("URL: (?P<foo>.+)\n")
-
// NewSvnRepo creates a new instance of SvnRepo. The remote and local directories
// need to be passed in. The remote location should include the branch for SVN.
// For example, if the package is https://github.com/Masterminds/cookoo/ the remote
// should be https://github.com/Masterminds/cookoo/trunk for the trunk branch.
func NewSvnRepo(remote, local string) (*SvnRepo, error) {
+ ins := depInstalled("svn")
+ if !ins {
+ return nil, NewLocalError("svn is not installed", nil, "")
+ }
ltype, err := DetectVcsFromFS(local)
// Found a VCS other than Svn. Need to report an error.
@@ -39,15 +41,18 @@
return nil, NewLocalError("Unable to retrieve local repo information", err, string(out))
}
- m := svnDetectURL.FindStringSubmatch(string(out))
- if m[1] != "" && m[1] != remote {
+ detectedRemote, err := detectRemoteFromInfoCommand(string(out))
+ if err != nil {
+ return nil, NewLocalError("Unable to retrieve local repo information", err, string(out))
+ }
+ if detectedRemote != "" && remote != "" && detectedRemote != remote {
return nil, ErrWrongRemote
}
// If no remote was passed in but one is configured for the locally
// checked out Svn repo use that one.
- if remote == "" && m[1] != "" {
- r.setRemote(m[1])
+ if remote == "" && detectedRemote != "" {
+ r.setRemote(detectedRemote)
}
}
@@ -185,12 +190,15 @@
// CheckLocal verifies the local location is an SVN repo.
func (s *SvnRepo) CheckLocal() bool {
- if _, err := os.Stat(s.LocalPath() + "/.svn"); err == nil {
- return true
+ sep := fmt.Sprintf("%c", os.PathSeparator)
+ psplit := strings.Split(s.LocalPath(), sep)
+ for i := 0; i < len(psplit); i++ {
+ path := fmt.Sprintf("%s%s", sep, filepath.Join(psplit[0:(len(psplit)-(i))]...))
+ if _, err := os.Stat(filepath.Join(path, ".svn")); err == nil {
+ return true
+ }
}
-
return false
-
}
// Tags returns []string{} as there are no formal tags in SVN. Tags are a
@@ -344,3 +352,24 @@
return false
}
+
+// detectRemoteFromInfoCommand finds the remote url from the `svn info`
+// command's output without using a regex. We avoid regex because URLs
+// are notoriously complex to accurately match with a regex and
+// splitting strings is less complex and often faster
+func detectRemoteFromInfoCommand(infoOut string) (string, error) {
+ sBytes := []byte(infoOut)
+ urlIndex := strings.Index(infoOut, "URL: ")
+ if urlIndex == -1 {
+ return "", fmt.Errorf("Remote not specified in svn info")
+ }
+ urlEndIndex := strings.Index(string(sBytes[urlIndex:]), "\n")
+ if urlEndIndex == -1 {
+ urlEndIndex = strings.Index(string(sBytes[urlIndex:]), "\r")
+ if urlEndIndex == -1 {
+ return "", fmt.Errorf("Unable to parse remote URL for svn info")
+ }
+ }
+
+ return string(sBytes[(urlIndex + 5):(urlIndex + urlEndIndex)]), nil
+}
diff --git a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
index 85fac7f..0567af8 100644
--- a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
+++ b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
@@ -88,6 +88,8 @@
t, e := detectVcsFromURL(vcsURL)
if e == nil {
return t, vcsURL, nil
+ } else if e != ErrCannotDetectVCS {
+ return NoVCS, "", e
}
// Pages like https://golang.org/x/net provide an html document with
@@ -114,6 +116,11 @@
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+ if resp.StatusCode == 404 {
+ return NoVCS, "", NewRemoteError(fmt.Sprintf("%s Not Found", vcsURL), nil, "")
+ } else if resp.StatusCode == 401 || resp.StatusCode == 403 {
+ return NoVCS, "", NewRemoteError(fmt.Sprintf("%s Access Denied", vcsURL), nil, "")
+ }
return NoVCS, "", ErrCannotDetectVCS
}
@@ -202,6 +209,10 @@
}
t, err := v.addCheck(info, u)
if err != nil {
+ switch err.(type) {
+ case *RemoteError:
+ return "", err
+ }
return "", ErrCannotDetectVCS
}
@@ -299,7 +310,11 @@
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
- // TODO(mattfarina): log the failed status
+ if resp.StatusCode == 404 {
+ return nil, NewRemoteError("Not Found", err, resp.Status)
+ } else if resp.StatusCode == 401 || resp.StatusCode == 403 {
+ return nil, NewRemoteError("Access Denied", err, resp.Status)
+ }
return nil, fmt.Errorf("%s: %s", url, resp.Status)
}
b, err := ioutil.ReadAll(resp.Body)
diff --git a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
index fd7663e..e97bba8 100644
--- a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
+++ b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
@@ -1,6 +1,7 @@
package vcs
import (
+ "strings"
"testing"
)
@@ -58,7 +59,11 @@
t.Errorf("Error detecting VCS from URL(%s): %s", u, err)
}
- if err != nil && err != ErrCannotDetectVCS && c.work == false {
+ if err != nil &&
+ err != ErrCannotDetectVCS &&
+ !strings.HasSuffix(err.Error(), "Not Found") &&
+ !strings.HasSuffix(err.Error(), "Access Denied") &&
+ c.work == false {
t.Errorf("Unexpected error returned (%s): %s", u, err)
}
@@ -67,3 +72,27 @@
}
}
}
+
+func TestNotFound(t *testing.T) {
+ _, _, err := detectVcsFromRemote("https://mattfarina.com/notfound")
+ if err == nil || !strings.HasSuffix(err.Error(), " Not Found") {
+ t.Errorf("Failed to find not found repo")
+ }
+
+ _, err = NewRepo("https://mattfarina.com/notfound", "")
+ if err == nil || !strings.HasSuffix(err.Error(), " Not Found") {
+ t.Errorf("Failed to find not found repo")
+ }
+}
+
+func TestAccessDenied(t *testing.T) {
+ _, _, err := detectVcsFromRemote("https://bitbucket.org/mattfarina/private-repo-for-vcs-testing")
+ if err == nil || err.Error() != "Access Denied" {
+ t.Errorf("Failed to detect access denied")
+ }
+
+ _, err = NewRepo("https://bitbucket.org/mattfarina/private-repo-for-vcs-testing", "")
+ if err == nil || err.Error() != "Access Denied" {
+ t.Errorf("Failed to detect access denied")
+ }
+}