github.com/glimps-jbo/go-licenses@v0.0.0-20230908151000-e06d3c113277/internal/third_party/pkgsite/stdlib/stdlib.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package stdlib supports special handling of the Go standard library. 6 // Regardless of the how the standard library has been split into modules for 7 // development and testing, the discovery site treats it as a single module 8 // named "std". 9 package stdlib 10 11 import ( 12 "fmt" 13 "strings" 14 15 "github.com/glimps-jbo/go-licenses/internal/third_party/pkgsite/derrors" 16 "github.com/glimps-jbo/go-licenses/internal/third_party/pkgsite/version" 17 "golang.org/x/mod/semver" 18 ) 19 20 const ( 21 // ModulePath is the name of the module for the standard library. 22 ModulePath = "std" 23 24 // DevFuzz is the branch name for fuzzing in beta. 25 DevFuzz = "dev.fuzz" 26 27 // DevBoringCrypto is the branch name for dev.boringcrypto. 28 DevBoringCrypto = "dev.boringcrypto" 29 ) 30 31 // SupportedBranches are the branches of the stdlib repo supported by pkgsite. 32 var SupportedBranches = map[string]bool{ 33 version.Master: true, 34 DevBoringCrypto: true, 35 DevFuzz: true, 36 } 37 38 // TagForVersion returns the Go standard library repository tag corresponding 39 // to semver. The Go tags differ from standard semantic versions in a few ways, 40 // such as beginning with "go" instead of "v". 41 func TagForVersion(v string) (_ string, err error) { 42 defer derrors.Wrap(&err, "TagForVersion(%q)", v) 43 44 // Special case: master => master or dev.fuzz => dev.fuzz 45 if SupportedBranches[v] { 46 return v, nil 47 } 48 if strings.HasPrefix(v, "v0.0.0") { 49 return version.Master, nil 50 } 51 // Special case: v1.0.0 => go1. 52 if v == "v1.0.0" { 53 return "go1", nil 54 } 55 if !semver.IsValid(v) { 56 return "", fmt.Errorf("%w: requested version is not a valid semantic version: %q ", derrors.InvalidArgument, v) 57 } 58 goVersion := semver.Canonical(v) 59 prerelease := semver.Prerelease(goVersion) 60 versionWithoutPrerelease := strings.TrimSuffix(goVersion, prerelease) 61 patch := strings.TrimPrefix(versionWithoutPrerelease, semver.MajorMinor(goVersion)+".") 62 if patch == "0" { 63 versionWithoutPrerelease = strings.TrimSuffix(versionWithoutPrerelease, ".0") 64 } 65 goVersion = fmt.Sprintf("go%s", strings.TrimPrefix(versionWithoutPrerelease, "v")) 66 if prerelease != "" { 67 // Go prereleases look like "beta1" instead of "beta.1". 68 // "beta1" is bad for sorting (since beta10 comes before beta9), so 69 // require the dot form. 70 i := finalDigitsIndex(prerelease) 71 if i >= 1 { 72 if prerelease[i-1] != '.' { 73 return "", fmt.Errorf("%w: final digits in a prerelease must follow a period", derrors.InvalidArgument) 74 } 75 // Remove the dot. 76 prerelease = prerelease[:i-1] + prerelease[i:] 77 } 78 goVersion += strings.TrimPrefix(prerelease, "-") 79 } 80 return goVersion, nil 81 } 82 83 // finalDigitsIndex returns the index of the first digit in the sequence of digits ending s. 84 // If s doesn't end in digits, it returns -1. 85 func finalDigitsIndex(s string) int { 86 // Assume ASCII (since the semver package does anyway). 87 var i int 88 for i = len(s) - 1; i >= 0; i-- { 89 if s[i] < '0' || s[i] > '9' { 90 break 91 } 92 } 93 if i == len(s)-1 { 94 return -1 95 } 96 return i + 1 97 } 98 99 const ( 100 GoSourceRepoURL = "https://cs.opensource.google/go/go" 101 ) 102 103 // Directory returns the directory of the standard library relative to the repo root. 104 func Directory(v string) string { 105 if semver.Compare(v, "v1.4.0-beta.1") >= 0 || 106 SupportedBranches[v] || strings.HasPrefix(v, "v0.0.0") { 107 return "src" 108 } 109 // For versions older than v1.4.0-beta.1, the stdlib is in src/pkg. 110 return "src/pkg" 111 }