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  }