github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/dist/cmdversion.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/zxy12/go_duplicate_112_new/src/zdebug" 10 ) 11 12 func branchtag(branch string) (tag string, precise bool) { 13 log := run(goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", "master.."+branch) 14 tag = branch 15 for row, line := range strings.Split(log, "\n") { 16 // Each line is either blank, or looks like 17 // (tag: refs/tags/go1.4rc2, refs/remotes/origin/release-branch.go1.4, refs/heads/release-branch.go1.4) 18 // We need to find an element starting with refs/tags/. 19 const s = " refs/tags/" 20 i := strings.Index(line, s) 21 if i < 0 { 22 continue 23 } 24 // Trim off known prefix. 25 line = line[i+len(s):] 26 // The tag name ends at a comma or paren. 27 j := strings.IndexAny(line, ",)") 28 if j < 0 { 29 continue // malformed line; ignore it 30 } 31 tag = line[:j] 32 if row == 0 { 33 precise = true // tag denotes HEAD 34 } 35 break 36 } 37 return 38 } 39 40 // isGitRepo reports whether the working directory is inside a Git repository. 41 func isGitRepo() bool { 42 // NB: simply checking the exit code of `git rev-parse --git-dir` would 43 // suffice here, but that requires deviating from the infrastructure 44 // provided by `run`. 45 gitDir := chomp(run(goroot, 0, "git", "rev-parse", "--git-dir")) 46 if !filepath.IsAbs(gitDir) { 47 gitDir = filepath.Join(goroot, gitDir) 48 } 49 return isdir(gitDir) 50 } 51 52 // findgoversion determines the Go version to use in the version string. 53 func findgoversion() string { 54 // The $GOROOT/VERSION file takes priority, for distributions 55 // without the source repo. 56 path := pathf("%s/VERSION", goroot) 57 58 zdebug.T("goversion file:%v", path) 59 if isfile(path) { 60 b := chomp(readfile(path)) 61 // Commands such as "dist version > VERSION" will cause 62 // the shell to create an empty VERSION file and set dist's 63 // stdout to its fd. dist in turn looks at VERSION and uses 64 // its content if available, which is empty at this point. 65 // Only use the VERSION file if it is non-empty. 66 if b != "" { 67 // Some builders cross-compile the toolchain on linux-amd64 68 // and then copy the toolchain to the target builder (say, linux-arm) 69 // for use there. But on non-release (devel) branches, the compiler 70 // used on linux-amd64 will be an amd64 binary, and the compiler 71 // shipped to linux-arm will be an arm binary, so they will have different 72 // content IDs (they are binaries for different architectures) and so the 73 // packages compiled by the running-on-amd64 compiler will appear 74 // stale relative to the running-on-arm compiler. Avoid this by setting 75 // the version string to something that doesn't begin with devel. 76 // Then the version string will be used in place of the content ID, 77 // and the packages will look up-to-date. 78 // TODO(rsc): Really the builders could be writing out a better VERSION file instead, 79 // but it is easier to change cmd/dist than to try to make changes to 80 // the builder while Brad is away. 81 if strings.HasPrefix(b, "devel") { 82 if hostType := os.Getenv("META_BUILDLET_HOST_TYPE"); strings.Contains(hostType, "-cross") { 83 fmt.Fprintf(os.Stderr, "warning: changing VERSION from %q to %q\n", b, "builder "+hostType) 84 b = "builder " + hostType 85 } 86 } 87 return b 88 } 89 } 90 91 // The $GOROOT/VERSION.cache file is a cache to avoid invoking 92 // git every time we run this command. Unlike VERSION, it gets 93 // deleted by the clean command. 94 path = pathf("%s/VERSION.cache", goroot) 95 if isfile(path) { 96 return chomp(readfile(path)) 97 } 98 99 // Show a nicer error message if this isn't a Git repo. 100 if !isGitRepo() { 101 fatalf("FAILED: not a Git repo; must put a VERSION file in $GOROOT") 102 } 103 104 // Otherwise, use Git. 105 // What is the current branch? 106 branch := chomp(run(goroot, CheckExit, "git", "rev-parse", "--abbrev-ref", "HEAD")) 107 108 // What are the tags along the current branch? 109 tag := "devel" 110 precise := false 111 112 // If we're on a release branch, use the closest matching tag 113 // that is on the release branch (and not on the master branch). 114 if strings.HasPrefix(branch, "release-branch.") { 115 tag, precise = branchtag(branch) 116 } 117 118 if !precise { 119 // Tag does not point at HEAD; add hash and date to version. 120 tag += chomp(run(goroot, CheckExit, "git", "log", "-n", "1", "--format=format: +%h %cd", "HEAD")) 121 } 122 123 // Cache version. 124 writefile(tag, path, 0) 125 126 return tag 127 }