info.go raw

   1  // Copyright 2023 Google LLC
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //      http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  package externalaccount
  16  
  17  import (
  18  	"runtime"
  19  	"strings"
  20  	"unicode"
  21  )
  22  
  23  var (
  24  	// version is a package internal global variable for testing purposes.
  25  	version = runtime.Version
  26  )
  27  
  28  // versionUnknown is only used when the runtime version cannot be determined.
  29  const versionUnknown = "UNKNOWN"
  30  
  31  // goVersion returns a Go runtime version derived from the runtime environment
  32  // that is modified to be suitable for reporting in a header, meaning it has no
  33  // whitespace. If it is unable to determine the Go runtime version, it returns
  34  // versionUnknown.
  35  func goVersion() string {
  36  	const develPrefix = "devel +"
  37  
  38  	s := version()
  39  	if strings.HasPrefix(s, develPrefix) {
  40  		s = s[len(develPrefix):]
  41  		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
  42  			s = s[:p]
  43  		}
  44  		return s
  45  	} else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
  46  		s = s[:p]
  47  	}
  48  
  49  	notSemverRune := func(r rune) bool {
  50  		return !strings.ContainsRune("0123456789.", r)
  51  	}
  52  
  53  	if strings.HasPrefix(s, "go1") {
  54  		s = s[2:]
  55  		var prerelease string
  56  		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
  57  			s, prerelease = s[:p], s[p:]
  58  		}
  59  		if strings.HasSuffix(s, ".") {
  60  			s += "0"
  61  		} else if strings.Count(s, ".") < 2 {
  62  			s += ".0"
  63  		}
  64  		if prerelease != "" {
  65  			// Some release candidates already have a dash in them.
  66  			if !strings.HasPrefix(prerelease, "-") {
  67  				prerelease = "-" + prerelease
  68  			}
  69  			s += prerelease
  70  		}
  71  		return s
  72  	}
  73  	return versionUnknown
  74  }
  75