src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

stdlib.go (2153B)


      1 // Copyright 2022 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 scan
      6 
      7 import (
      8 	"fmt"
      9 	"strings"
     10 
     11 	"golang.org/x/mod/semver"
     12 )
     13 
     14 // Support functions for standard library packages.
     15 // These are copied from the internal/stdlib package in the pkgsite repo.
     16 
     17 // semverToGoTag returns the Go standard library repository tag corresponding
     18 // to semver, a version string without the initial "v".
     19 // Go tags differ from standard semantic versions in a few ways,
     20 // such as beginning with "go" instead of "v".
     21 func semverToGoTag(v string) string {
     22 	if strings.HasPrefix(v, "v0.0.0") {
     23 		return "master"
     24 	}
     25 	// Special case: v1.0.0 => go1.
     26 	if v == "v1.0.0" {
     27 		return "go1"
     28 	}
     29 	if !semver.IsValid(v) {
     30 		return fmt.Sprintf("<!%s:invalid semver>", v)
     31 	}
     32 	goVersion := semver.Canonical(v)
     33 	prerelease := semver.Prerelease(goVersion)
     34 	versionWithoutPrerelease := strings.TrimSuffix(goVersion, prerelease)
     35 	patch := strings.TrimPrefix(versionWithoutPrerelease, semver.MajorMinor(goVersion)+".")
     36 	if patch == "0" {
     37 		versionWithoutPrerelease = strings.TrimSuffix(versionWithoutPrerelease, ".0")
     38 	}
     39 	goVersion = fmt.Sprintf("go%s", strings.TrimPrefix(versionWithoutPrerelease, "v"))
     40 	if prerelease != "" {
     41 		// Go prereleases look like  "beta1" instead of "beta.1".
     42 		// "beta1" is bad for sorting (since beta10 comes before beta9), so
     43 		// require the dot form.
     44 		i := finalDigitsIndex(prerelease)
     45 		if i >= 1 {
     46 			if prerelease[i-1] != '.' {
     47 				return fmt.Sprintf("<!%s:final digits in a prerelease must follow a period>", v)
     48 			}
     49 			// Remove the dot.
     50 			prerelease = prerelease[:i-1] + prerelease[i:]
     51 		}
     52 		goVersion += strings.TrimPrefix(prerelease, "-")
     53 	}
     54 	return goVersion
     55 }
     56 
     57 // finalDigitsIndex returns the index of the first digit in the sequence of digits ending s.
     58 // If s doesn't end in digits, it returns -1.
     59 func finalDigitsIndex(s string) int {
     60 	// Assume ASCII (since the semver package does anyway).
     61 	var i int
     62 	for i = len(s) - 1; i >= 0; i-- {
     63 		if s[i] < '0' || s[i] > '9' {
     64 			break
     65 		}
     66 	}
     67 	if i == len(s)-1 {
     68 		return -1
     69 	}
     70 	return i + 1
     71 }