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  }