github.com/wuciyou/godep@v0.0.0-20170205210856-a9cd0561f946/dep.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"sort"
     8  	"strings"
     9  )
    10  
    11  // A Dependency is a specific revision of a package.
    12  type Dependency struct {
    13  	ImportPath string
    14  	Comment    string `json:",omitempty"` // Description of commit, if present.
    15  	Rev        string // VCS-specific commit ID.
    16  
    17  	// used by command save & update
    18  	ws   string // workspace
    19  	root string // import path to repo root
    20  	dir  string // full path to package
    21  
    22  	// used by command update
    23  	matched bool // selected for update by command line
    24  	pkg     *Package
    25  	missing bool // packages is missing
    26  
    27  	// used by command go
    28  	vcs *VCS
    29  }
    30  
    31  func eqDeps(a, b []Dependency) bool {
    32  	ok := true
    33  	for _, da := range a {
    34  		for _, db := range b {
    35  			if da.ImportPath == db.ImportPath && da.Rev != db.Rev {
    36  				ok = false
    37  			}
    38  		}
    39  	}
    40  	return ok
    41  }
    42  
    43  // containsPathPrefix returns whether any string in a
    44  // is s or a directory containing s.
    45  // For example, pattern ["a"] matches "a" and "a/b"
    46  // (but not "ab").
    47  func containsPathPrefix(pats []string, s string) bool {
    48  	for _, pat := range pats {
    49  		if pat == s || strings.HasPrefix(s, pat+"/") {
    50  			return true
    51  		}
    52  	}
    53  	return false
    54  }
    55  
    56  func uniq(a []string) []string {
    57  	var s string
    58  	var i int
    59  	if !sort.StringsAreSorted(a) {
    60  		sort.Strings(a)
    61  	}
    62  	for _, t := range a {
    63  		if t != s {
    64  			a[i] = t
    65  			i++
    66  			s = t
    67  		}
    68  	}
    69  	return a[:i]
    70  }
    71  
    72  // trimGoVersion and return the major version
    73  func trimGoVersion(version string) (string, error) {
    74  	if version == "devel" {
    75  		return "devel", nil
    76  	}
    77  	if strings.HasPrefix(version, "devel+") || strings.HasPrefix(version, "devel-") {
    78  		return strings.Replace(version, "devel+", "devel-", 1), nil
    79  	}
    80  	p := strings.Split(version, ".")
    81  	if len(p) < 2 {
    82  		return "", fmt.Errorf("Error determining major go version from: %q", version)
    83  	}
    84  	var split string
    85  	switch {
    86  	case strings.Contains(p[1], "beta"):
    87  		split = "beta"
    88  	case strings.Contains(p[1], "rc"):
    89  		split = "rc"
    90  	}
    91  	if split != "" {
    92  		p[1] = strings.Split(p[1], split)[0]
    93  	}
    94  	return p[0] + "." + p[1], nil
    95  }
    96  
    97  var goVersionTestOutput = ""
    98  
    99  func getGoVersion() (string, error) {
   100  	// For testing purposes only
   101  	if goVersionTestOutput != "" {
   102  		return goVersionTestOutput, nil
   103  	}
   104  
   105  	// Godep might have been compiled with a different
   106  	// version, so we can't just use runtime.Version here.
   107  	cmd := exec.Command("go", "version")
   108  	cmd.Stderr = os.Stderr
   109  	out, err := cmd.Output()
   110  	return string(out), err
   111  }
   112  
   113  // goVersion returns the major version string of the Go compiler
   114  // currently installed, e.g. "go1.5".
   115  func goVersion() (string, error) {
   116  	out, err := getGoVersion()
   117  	if err != nil {
   118  		return "", err
   119  	}
   120  	gv := strings.Split(out, " ")
   121  	if len(gv) < 4 {
   122  		return "", fmt.Errorf("Error splitting output of `go version`: Expected 4 or more elements, but there are < 4: %q", out)
   123  	}
   124  	if gv[2] == "devel" {
   125  		return trimGoVersion(gv[2] + gv[3])
   126  	}
   127  	return trimGoVersion(gv[2])
   128  }