build(deps): bump github.com/onsi/ginkgo/v2 from 2.17.3 to 2.19.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.17.3 to 2.19.0. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.17.3...v2.19.0) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
7b47d55837
commit
7999751890
@@ -68,7 +68,7 @@ require (
|
||||
github.com/oklog/run v1.1.0
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.17.3
|
||||
github.com/onsi/ginkgo/v2 v2.19.0
|
||||
github.com/onsi/gomega v1.33.1
|
||||
github.com/open-policy-agent/opa v0.64.1
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
@@ -342,7 +342,7 @@ require (
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.20.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
|
||||
|
||||
@@ -1785,8 +1785,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU=
|
||||
github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@@ -2640,8 +2640,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
+20
@@ -1,3 +1,23 @@
|
||||
## 2.19.0
|
||||
|
||||
### Features
|
||||
|
||||
[Label Sets](https://onsi.github.io/ginkgo/#label-sets) allow for more expressive and flexible label filtering.
|
||||
|
||||
## 2.18.0
|
||||
|
||||
### Features
|
||||
- Add --slience-skips and --force-newlines [f010b65]
|
||||
- fail when no tests were run and --fail-on-empty was set [d80eebe]
|
||||
|
||||
### Fixes
|
||||
- Fix table entry context edge case [42013d6]
|
||||
|
||||
### Maintenance
|
||||
- Bump golang.org/x/tools from 0.20.0 to 0.21.0 (#1406) [fcf1fd7]
|
||||
- Bump github.com/onsi/gomega from 1.33.0 to 1.33.1 (#1399) [8bb14fd]
|
||||
- Bump golang.org/x/net from 0.24.0 to 0.25.0 (#1407) [04bfad7]
|
||||
|
||||
## 2.17.3
|
||||
|
||||
### Fixes
|
||||
|
||||
+6
-4
@@ -6,8 +6,10 @@ Your contributions to Ginkgo are essential for its long-term maintenance and imp
|
||||
- Ensure adequate test coverage:
|
||||
- When adding to the Ginkgo library, add unit and/or integration tests (under the `integration` folder).
|
||||
- When adding to the Ginkgo CLI, note that there are very few unit tests. Please add an integration test.
|
||||
- Make sure all the tests succeed via `ginkgo -r -p`
|
||||
- Vet your changes via `go vet ./...`
|
||||
- Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle exec jekyll serve` in the `docs` directory to preview your changes.
|
||||
- Run `make` or:
|
||||
- Install ginkgo locally via `go install ./...`
|
||||
- Make sure all the tests succeed via `ginkgo -r -p`
|
||||
- Vet your changes via `go vet ./...`
|
||||
- Update the documentation. Ginkgo uses `godoc` comments and documentation in `docs/index.md`. You can run `bundle && bundle exec jekyll serve` in the `docs` directory to preview your changes.
|
||||
|
||||
Thanks for supporting Ginkgo!
|
||||
Thanks for supporting Ginkgo!
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# default task since it's first
|
||||
.PHONY: all
|
||||
all: vet test
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go run github.com/onsi/ginkgo/v2/ginkgo -r -p
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet ./...
|
||||
+6
-1
@@ -489,10 +489,15 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
|
||||
newGroup(suite).run(specs.AtIndices(groupedSpecIndices[groupedSpecIdx]))
|
||||
}
|
||||
|
||||
if specs.HasAnySpecsMarkedPending() && suite.config.FailOnPending {
|
||||
if suite.config.FailOnPending && specs.HasAnySpecsMarkedPending() {
|
||||
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Detected pending specs and --fail-on-pending is set")
|
||||
suite.report.SuiteSucceeded = false
|
||||
}
|
||||
|
||||
if suite.config.FailOnEmpty && specs.CountWithoutSkip() == 0 {
|
||||
suite.report.SpecialSuiteFailureReasons = append(suite.report.SpecialSuiteFailureReasons, "Detected no specs ran and --fail-on-empty is set")
|
||||
suite.report.SuiteSucceeded = false
|
||||
}
|
||||
}
|
||||
|
||||
if ranBeforeSuite {
|
||||
|
||||
+9
-1
@@ -202,6 +202,11 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
||||
v := r.conf.Verbosity()
|
||||
inParallel := report.RunningInParallel
|
||||
|
||||
//should we completely omit this spec?
|
||||
if report.State.Is(types.SpecStateSkipped) && r.conf.SilenceSkips {
|
||||
return
|
||||
}
|
||||
|
||||
header := r.specDenoter
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
header = fmt.Sprintf("[%s]", report.LeafNodeType)
|
||||
@@ -278,9 +283,12 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no content to show, jsut emit the header and return
|
||||
// If we have no content to show, just emit the header and return
|
||||
if !reportHasContent {
|
||||
r.emit(r.f(highlightColor + header + "{{/}}"))
|
||||
if r.conf.ForceNewlines {
|
||||
r.emit("\n")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -177,6 +177,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
|
||||
{"FocusFiles", strings.Join(report.SuiteConfig.FocusFiles, ";")},
|
||||
{"SkipFiles", strings.Join(report.SuiteConfig.SkipFiles, ";")},
|
||||
{"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)},
|
||||
{"FailOnEmpty", fmt.Sprintf("%t", report.SuiteConfig.FailOnEmpty)},
|
||||
{"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)},
|
||||
{"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)},
|
||||
{"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)},
|
||||
|
||||
+6
-2
@@ -269,11 +269,15 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
|
||||
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
|
||||
|
||||
hasContext := false
|
||||
if internalBodyType.NumIn() > 0. {
|
||||
if internalBodyType.NumIn() > 0 {
|
||||
if internalBodyType.In(0).Implements(specContextType) {
|
||||
hasContext = true
|
||||
} else if internalBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) {
|
||||
} else if internalBodyType.In(0).Implements(contextType) {
|
||||
hasContext = true
|
||||
if len(entry.parameters) > 0 && reflect.TypeOf(entry.parameters[0]) != nil && reflect.TypeOf(entry.parameters[0]).Implements(contextType) {
|
||||
// we allow you to pass in a non-nil context
|
||||
hasContext = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -25,6 +25,7 @@ type SuiteConfig struct {
|
||||
SkipFiles []string
|
||||
LabelFilter string
|
||||
FailOnPending bool
|
||||
FailOnEmpty bool
|
||||
FailFast bool
|
||||
FlakeAttempts int
|
||||
MustPassRepeatedly int
|
||||
@@ -90,6 +91,8 @@ type ReporterConfig struct {
|
||||
FullTrace bool
|
||||
ShowNodeEvents bool
|
||||
GithubOutput bool
|
||||
SilenceSkips bool
|
||||
ForceNewlines bool
|
||||
|
||||
JSONReport string
|
||||
JUnitReport string
|
||||
@@ -275,6 +278,8 @@ var SuiteConfigFlags = GinkgoFlags{
|
||||
Usage: "If set, ginkgo will stop running a test suite after a failure occurs."},
|
||||
{KeyPath: "S.FlakeAttempts", Name: "flake-attempts", SectionKey: "failure", UsageDefaultValue: "0 - failed tests are not retried", DeprecatedName: "flakeAttempts", DeprecatedDocLink: "changed-command-line-flags",
|
||||
Usage: "Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed."},
|
||||
{KeyPath: "S.FailOnEmpty", Name: "fail-on-empty", SectionKey: "failure",
|
||||
Usage: "If set, ginkgo will mark the test suite as failed if no specs are run."},
|
||||
|
||||
{KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags",
|
||||
Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."},
|
||||
@@ -334,6 +339,10 @@ var ReporterConfigFlags = GinkgoFlags{
|
||||
Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"},
|
||||
{KeyPath: "R.GithubOutput", Name: "github-output", SectionKey: "output",
|
||||
Usage: "If set, default reporter prints easier to manage output in Github Actions."},
|
||||
{KeyPath: "R.SilenceSkips", Name: "silence-skips", SectionKey: "output",
|
||||
Usage: "If set, default reporter will not print out skipped tests."},
|
||||
{KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output",
|
||||
Usage: "If set, default reporter will ensure a newline appears after each test."},
|
||||
|
||||
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
|
||||
|
||||
+227
-2
@@ -45,6 +45,83 @@ func orAction(a, b LabelFilter) LabelFilter {
|
||||
return func(labels []string) bool { return a(labels) || b(labels) }
|
||||
}
|
||||
|
||||
func labelSetFor(key string, labels []string) map[string]bool {
|
||||
key = strings.ToLower(strings.TrimSpace(key))
|
||||
out := map[string]bool{}
|
||||
for _, label := range labels {
|
||||
components := strings.SplitN(label, ":", 2)
|
||||
if len(components) < 2 {
|
||||
continue
|
||||
}
|
||||
if key == strings.ToLower(strings.TrimSpace(components[0])) {
|
||||
out[strings.ToLower(strings.TrimSpace(components[1]))] = true
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func isEmptyLabelSetAction(key string) LabelFilter {
|
||||
return func(labels []string) bool {
|
||||
return len(labelSetFor(key, labels)) == 0
|
||||
}
|
||||
}
|
||||
|
||||
func containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter {
|
||||
return func(labels []string) bool {
|
||||
set := labelSetFor(key, labels)
|
||||
for _, value := range expectedValues {
|
||||
if set[value] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func containsAllLabelSetAction(key string, expectedValues []string) LabelFilter {
|
||||
return func(labels []string) bool {
|
||||
set := labelSetFor(key, labels)
|
||||
for _, value := range expectedValues {
|
||||
if !set[value] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter {
|
||||
return func(labels []string) bool {
|
||||
set := labelSetFor(key, labels)
|
||||
if len(set) != len(expectedValues) {
|
||||
return false
|
||||
}
|
||||
for _, value := range expectedValues {
|
||||
if !set[value] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter {
|
||||
expectedSet := map[string]bool{}
|
||||
for _, value := range expectedValues {
|
||||
expectedSet[value] = true
|
||||
}
|
||||
return func(labels []string) bool {
|
||||
set := labelSetFor(key, labels)
|
||||
for value := range set {
|
||||
if !expectedSet[value] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
type lfToken uint
|
||||
|
||||
const (
|
||||
@@ -58,6 +135,9 @@ const (
|
||||
lfTokenOr
|
||||
lfTokenRegexp
|
||||
lfTokenLabel
|
||||
lfTokenSetKey
|
||||
lfTokenSetOperation
|
||||
lfTokenSetArgument
|
||||
lfTokenEOF
|
||||
)
|
||||
|
||||
@@ -71,6 +151,8 @@ func (l lfToken) Precedence() int {
|
||||
return 2
|
||||
case lfTokenNot:
|
||||
return 3
|
||||
case lfTokenSetOperation:
|
||||
return 4
|
||||
}
|
||||
return -1
|
||||
}
|
||||
@@ -93,6 +175,12 @@ func (l lfToken) String() string {
|
||||
return "/regexp/"
|
||||
case lfTokenLabel:
|
||||
return "label"
|
||||
case lfTokenSetKey:
|
||||
return "set_key"
|
||||
case lfTokenSetOperation:
|
||||
return "set_operation"
|
||||
case lfTokenSetArgument:
|
||||
return "set_argument"
|
||||
case lfTokenEOF:
|
||||
return "EOF"
|
||||
}
|
||||
@@ -148,6 +236,35 @@ func (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("RegExp compilation error: %s", err))
|
||||
}
|
||||
return matchLabelRegexAction(re), nil
|
||||
case lfTokenSetOperation:
|
||||
tokenSetOperation := strings.ToLower(tn.value)
|
||||
if tokenSetOperation == "isempty" {
|
||||
return isEmptyLabelSetAction(tn.leftNode.value), nil
|
||||
}
|
||||
if tn.rightNode == nil {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Set operation '%s' is missing an argument.", tn.value))
|
||||
}
|
||||
|
||||
rawValues := strings.Split(tn.rightNode.value, ",")
|
||||
values := make([]string, len(rawValues))
|
||||
for i := range rawValues {
|
||||
values[i] = strings.ToLower(strings.TrimSpace(rawValues[i]))
|
||||
if strings.ContainsAny(values[i], "&|!,()/") {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf("Invalid label value '%s' in set operation argument.", values[i]))
|
||||
} else if values[i] == "" {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, "Empty label value in set operation argument.")
|
||||
}
|
||||
}
|
||||
switch tokenSetOperation {
|
||||
case "containsany":
|
||||
return containsAnyLabelSetAction(tn.leftNode.value, values), nil
|
||||
case "containsall":
|
||||
return containsAllLabelSetAction(tn.leftNode.value, values), nil
|
||||
case "consistsof":
|
||||
return consistsOfLabelSetAction(tn.leftNode.value, values), nil
|
||||
case "issubsetof":
|
||||
return isSubsetOfLabelSetAction(tn.leftNode.value, values), nil
|
||||
}
|
||||
}
|
||||
|
||||
if tn.rightNode == nil {
|
||||
@@ -203,7 +320,17 @@ func (tn *treeNode) toString(indent int) string {
|
||||
return out
|
||||
}
|
||||
|
||||
var validSetOperations = map[string]string{
|
||||
"containsany": "containsAny",
|
||||
"containsall": "containsAll",
|
||||
"consistsof": "consistsOf",
|
||||
"issubsetof": "isSubsetOf",
|
||||
"isempty": "isEmpty",
|
||||
}
|
||||
|
||||
func tokenize(input string) func() (*treeNode, error) {
|
||||
lastToken := lfTokenInvalid
|
||||
lastValue := ""
|
||||
runes, i := []rune(input), 0
|
||||
|
||||
peekIs := func(r rune) bool {
|
||||
@@ -233,6 +360,53 @@ func tokenize(input string) func() (*treeNode, error) {
|
||||
}
|
||||
|
||||
node := &treeNode{location: i}
|
||||
defer func() {
|
||||
lastToken = node.token
|
||||
lastValue = node.value
|
||||
}()
|
||||
|
||||
if lastToken == lfTokenSetKey {
|
||||
//we should get a valid set operation next
|
||||
value, n := consumeUntil(" )")
|
||||
if validSetOperations[strings.ToLower(value)] == "" {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf("Invalid set operation '%s'.", value))
|
||||
}
|
||||
i += n
|
||||
node.token, node.value = lfTokenSetOperation, value
|
||||
return node, nil
|
||||
}
|
||||
if lastToken == lfTokenSetOperation {
|
||||
//we should get an argument next, if we aren't isempty
|
||||
var arg = ""
|
||||
origI := i
|
||||
if runes[i] == '{' {
|
||||
i += 1
|
||||
value, n := consumeUntil("}")
|
||||
if i+n >= len(runes) {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, "Missing closing '}' in set operation argument?")
|
||||
}
|
||||
i += n + 1
|
||||
arg = value
|
||||
} else {
|
||||
value, n := consumeUntil("&|!,()/")
|
||||
i += n
|
||||
arg = strings.TrimSpace(value)
|
||||
}
|
||||
if strings.ToLower(lastValue) == "isempty" && arg != "" {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("isEmpty does not take arguments, was passed '%s'.", arg))
|
||||
}
|
||||
if arg == "" && strings.ToLower(lastValue) != "isempty" {
|
||||
if i < len(runes) && runes[i] == '/' {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, "Set operations do not support regular expressions.")
|
||||
} else {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("Set operation '%s' requires an argument.", lastValue))
|
||||
}
|
||||
}
|
||||
// note that we sent an empty SetArgument token if we are isempty
|
||||
node.token, node.value = lfTokenSetArgument, arg
|
||||
return node, nil
|
||||
}
|
||||
|
||||
switch runes[i] {
|
||||
case '&':
|
||||
if !peekIs('&') {
|
||||
@@ -264,8 +438,38 @@ func tokenize(input string) func() (*treeNode, error) {
|
||||
i += n + 1
|
||||
node.token, node.value = lfTokenRegexp, value
|
||||
default:
|
||||
value, n := consumeUntil("&|!,()/")
|
||||
value, n := consumeUntil("&|!,()/:")
|
||||
i += n
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
//are we the beginning of a set operation?
|
||||
if i < len(runes) && runes[i] == ':' {
|
||||
if peekIs(' ') {
|
||||
if value == "" {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set key.")
|
||||
}
|
||||
i += 1
|
||||
//we are the beginning of a set operation
|
||||
node.token, node.value = lfTokenSetKey, value
|
||||
return node, nil
|
||||
}
|
||||
additionalValue, n := consumeUntil("&|!,()/")
|
||||
additionalValue = strings.TrimSpace(additionalValue)
|
||||
if additionalValue == ":" {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set operation.")
|
||||
}
|
||||
i += n
|
||||
value += additionalValue
|
||||
}
|
||||
|
||||
valueToCheckForSetOperation := strings.ToLower(value)
|
||||
for setOperation := range validSetOperations {
|
||||
idx := strings.Index(valueToCheckForSetOperation, " "+setOperation)
|
||||
if idx > 0 {
|
||||
return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf("Looks like you are using the set operator '%s' but did not provide a set key. Did you forget the ':'?", validSetOperations[setOperation]))
|
||||
}
|
||||
}
|
||||
|
||||
node.token, node.value = lfTokenLabel, strings.TrimSpace(value)
|
||||
}
|
||||
return node, nil
|
||||
@@ -307,7 +511,7 @@ LOOP:
|
||||
switch node.token {
|
||||
case lfTokenEOF:
|
||||
break LOOP
|
||||
case lfTokenLabel, lfTokenRegexp:
|
||||
case lfTokenLabel, lfTokenRegexp, lfTokenSetKey:
|
||||
if current.rightNode != nil {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found two adjacent labels. You need an operator between them.")
|
||||
}
|
||||
@@ -326,6 +530,18 @@ LOOP:
|
||||
node.setLeftNode(nodeToStealFrom.rightNode)
|
||||
nodeToStealFrom.setRightNode(node)
|
||||
current = node
|
||||
case lfTokenSetOperation:
|
||||
if current.rightNode == nil {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Set operation '%s' missing left hand operand.", node.value))
|
||||
}
|
||||
node.setLeftNode(current.rightNode)
|
||||
current.setRightNode(node)
|
||||
current = node
|
||||
case lfTokenSetArgument:
|
||||
if current.rightNode != nil {
|
||||
return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unexpected set argument '%s'.", node.token))
|
||||
}
|
||||
current.setRightNode(node)
|
||||
case lfTokenCloseGroup:
|
||||
firstUnmatchedOpenNode := current.firstUnmatchedOpenNode()
|
||||
if firstUnmatchedOpenNode == nil {
|
||||
@@ -354,5 +570,14 @@ func ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) {
|
||||
if strings.ContainsAny(out, "&|!,()/") {
|
||||
return "", GinkgoErrors.InvalidLabel(label, cl)
|
||||
}
|
||||
if out[0] == ':' {
|
||||
return "", GinkgoErrors.InvalidLabel(label, cl)
|
||||
}
|
||||
if strings.Contains(out, ":") {
|
||||
components := strings.SplitN(out, ":", 2)
|
||||
if len(components) < 2 || components[1] == "" {
|
||||
return "", GinkgoErrors.InvalidLabel(label, cl)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.17.3"
|
||||
const VERSION = "2.19.0"
|
||||
|
||||
+29
-10
@@ -129,9 +129,8 @@ type Config struct {
|
||||
Mode LoadMode
|
||||
|
||||
// Context specifies the context for the load operation.
|
||||
// If the context is cancelled, the loader may stop early
|
||||
// and return an ErrCancelled error.
|
||||
// If Context is nil, the load cannot be cancelled.
|
||||
// Cancelling the context may cause [Load] to abort and
|
||||
// return an error.
|
||||
Context context.Context
|
||||
|
||||
// Logf is the logger for the config.
|
||||
@@ -214,8 +213,8 @@ type Config struct {
|
||||
// Config specifies loading options;
|
||||
// nil behaves the same as an empty Config.
|
||||
//
|
||||
// Load returns an error if any of the patterns was invalid
|
||||
// as defined by the underlying build system.
|
||||
// If any of the patterns was invalid as defined by the
|
||||
// underlying build system, Load returns an error.
|
||||
// It may return an empty list of packages without an error,
|
||||
// for instance for an empty expansion of a valid wildcard.
|
||||
// Errors associated with a particular package are recorded in the
|
||||
@@ -428,6 +427,10 @@ type Package struct {
|
||||
// The NeedTypes LoadMode bit sets this field for packages matching the
|
||||
// patterns; type information for dependencies may be missing or incomplete,
|
||||
// unless NeedDeps and NeedImports are also set.
|
||||
//
|
||||
// Each call to [Load] returns a consistent set of type
|
||||
// symbols, as defined by the comment at [types.Identical].
|
||||
// Avoid mixing type information from two or more calls to [Load].
|
||||
Types *types.Package
|
||||
|
||||
// Fset provides position information for Types, TypesInfo, and Syntax.
|
||||
@@ -854,6 +857,12 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// If the context is done, return its error and
|
||||
// throw out [likely] incomplete packages.
|
||||
if err := ld.Context.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*Package, len(initial))
|
||||
for i, lpkg := range initial {
|
||||
result[i] = lpkg.Package
|
||||
@@ -949,6 +958,14 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
|
||||
lpkg.Fset = ld.Fset
|
||||
|
||||
// Start shutting down if the context is done and do not load
|
||||
// source or export data files.
|
||||
// Packages that import this one will have ld.Context.Err() != nil.
|
||||
// ld.Context.Err() will be returned later by refine.
|
||||
if ld.Context.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Subtle: we populate all Types fields with an empty Package
|
||||
// before loading export data so that export data processing
|
||||
// never has to create a types.Package for an indirect dependency,
|
||||
@@ -1068,6 +1085,13 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
return
|
||||
}
|
||||
|
||||
// Start shutting down if the context is done and do not type check.
|
||||
// Packages that import this one will have ld.Context.Err() != nil.
|
||||
// ld.Context.Err() will be returned later by refine.
|
||||
if ld.Context.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
lpkg.TypesInfo = &types.Info{
|
||||
Types: make(map[ast.Expr]types.TypeAndValue),
|
||||
Defs: make(map[*ast.Ident]types.Object),
|
||||
@@ -1245,11 +1269,6 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
||||
parsed := make([]*ast.File, n)
|
||||
errors := make([]error, n)
|
||||
for i, file := range filenames {
|
||||
if ld.Config.Context.Err() != nil {
|
||||
parsed[i] = nil
|
||||
errors[i] = ld.Config.Context.Err()
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func(i int, filename string) {
|
||||
parsed[i], errors[i] = ld.parseFile(filename)
|
||||
|
||||
+8
-4
@@ -16,10 +16,14 @@ import (
|
||||
// NewAlias creates a new TypeName in Package pkg that
|
||||
// is an alias for the type rhs.
|
||||
//
|
||||
// When GoVersion>=1.22 and GODEBUG=gotypesalias=1,
|
||||
// the Type() of the return value is a *types.Alias.
|
||||
func NewAlias(pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
|
||||
if enabled() {
|
||||
// The enabled parameter determines whether the resulting [TypeName]'s
|
||||
// type is an [types.Alias]. Its value must be the result of a call to
|
||||
// [Enabled], which computes the effective value of
|
||||
// GODEBUG=gotypesalias=... by invoking the type checker. The Enabled
|
||||
// function is expensive and should be called once per task (e.g.
|
||||
// package import), not once per call to NewAlias.
|
||||
func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
|
||||
if enabled {
|
||||
tname := types.NewTypeName(pos, pkg, name, nil)
|
||||
newAlias(tname, rhs)
|
||||
return tname
|
||||
|
||||
+8
-7
@@ -15,16 +15,17 @@ import (
|
||||
// It will never be created by go/types.
|
||||
type Alias struct{}
|
||||
|
||||
func (*Alias) String() string { panic("unreachable") }
|
||||
|
||||
func (*Alias) String() string { panic("unreachable") }
|
||||
func (*Alias) Underlying() types.Type { panic("unreachable") }
|
||||
|
||||
func (*Alias) Obj() *types.TypeName { panic("unreachable") }
|
||||
func (*Alias) Obj() *types.TypeName { panic("unreachable") }
|
||||
func Rhs(alias *Alias) types.Type { panic("unreachable") }
|
||||
|
||||
// Unalias returns the type t for go <=1.21.
|
||||
func Unalias(t types.Type) types.Type { return t }
|
||||
|
||||
// Always false for go <=1.21. Ignores GODEBUG.
|
||||
func enabled() bool { return false }
|
||||
|
||||
func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") }
|
||||
|
||||
// Enabled reports whether [NewAlias] should create [types.Alias] types.
|
||||
//
|
||||
// Before go1.22, this function always returns false.
|
||||
func Enabled() bool { return false }
|
||||
|
||||
+30
-39
@@ -12,14 +12,22 @@ import (
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Alias is an alias of types.Alias.
|
||||
type Alias = types.Alias
|
||||
|
||||
// Rhs returns the type on the right-hand side of the alias declaration.
|
||||
func Rhs(alias *Alias) types.Type {
|
||||
if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok {
|
||||
return alias.Rhs() // go1.23+
|
||||
}
|
||||
|
||||
// go1.22's Alias didn't have the Rhs method,
|
||||
// so Unalias is the best we can do.
|
||||
return Unalias(alias)
|
||||
}
|
||||
|
||||
// Unalias is a wrapper of types.Unalias.
|
||||
func Unalias(t types.Type) types.Type { return types.Unalias(t) }
|
||||
|
||||
@@ -33,40 +41,23 @@ func newAlias(tname *types.TypeName, rhs types.Type) *Alias {
|
||||
return a
|
||||
}
|
||||
|
||||
// enabled returns true when types.Aliases are enabled.
|
||||
func enabled() bool {
|
||||
// Use the gotypesalias value in GODEBUG if set.
|
||||
godebug := os.Getenv("GODEBUG")
|
||||
value := -1 // last set value.
|
||||
for _, f := range strings.Split(godebug, ",") {
|
||||
switch f {
|
||||
case "gotypesalias=1":
|
||||
value = 1
|
||||
case "gotypesalias=0":
|
||||
value = 0
|
||||
}
|
||||
}
|
||||
switch value {
|
||||
case 0:
|
||||
return false
|
||||
case 1:
|
||||
return true
|
||||
default:
|
||||
return aliasesDefault()
|
||||
}
|
||||
// Enabled reports whether [NewAlias] should create [types.Alias] types.
|
||||
//
|
||||
// This function is expensive! Call it sparingly.
|
||||
func Enabled() bool {
|
||||
// The only reliable way to compute the answer is to invoke go/types.
|
||||
// We don't parse the GODEBUG environment variable, because
|
||||
// (a) it's tricky to do so in a manner that is consistent
|
||||
// with the godebug package; in particular, a simple
|
||||
// substring check is not good enough. The value is a
|
||||
// rightmost-wins list of options. But more importantly:
|
||||
// (b) it is impossible to detect changes to the effective
|
||||
// setting caused by os.Setenv("GODEBUG"), as happens in
|
||||
// many tests. Therefore any attempt to cache the result
|
||||
// is just incorrect.
|
||||
fset := token.NewFileSet()
|
||||
f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0)
|
||||
pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil)
|
||||
_, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias)
|
||||
return enabled
|
||||
}
|
||||
|
||||
// aliasesDefault reports if aliases are enabled by default.
|
||||
func aliasesDefault() bool {
|
||||
// Dynamically check if Aliases will be produced from go/types.
|
||||
aliasesDefaultOnce.Do(func() {
|
||||
fset := token.NewFileSet()
|
||||
f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0)
|
||||
pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil)
|
||||
_, gotypesaliasDefault = pkg.Scope().Lookup("A").Type().(*types.Alias)
|
||||
})
|
||||
return gotypesaliasDefault
|
||||
}
|
||||
|
||||
var gotypesaliasDefault bool
|
||||
var aliasesDefaultOnce sync.Once
|
||||
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package tag provides the labels used for telemetry throughout gopls.
|
||||
package tag
|
||||
|
||||
import (
|
||||
"golang.org/x/tools/internal/event/keys"
|
||||
)
|
||||
|
||||
var (
|
||||
// create the label keys we use
|
||||
Method = keys.NewString("method", "")
|
||||
StatusCode = keys.NewString("status.code", "")
|
||||
StatusMessage = keys.NewString("status.message", "")
|
||||
RPCID = keys.NewString("id", "")
|
||||
RPCDirection = keys.NewString("direction", "")
|
||||
File = keys.NewString("file", "")
|
||||
Directory = keys.New("directory", "")
|
||||
URI = keys.New("URI", "")
|
||||
Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs
|
||||
PackagePath = keys.NewString("package_path", "")
|
||||
Query = keys.New("query", "")
|
||||
Snapshot = keys.NewUInt64("snapshot", "")
|
||||
Operation = keys.NewString("operation", "")
|
||||
|
||||
Position = keys.New("position", "")
|
||||
Category = keys.NewString("category", "")
|
||||
PackageCount = keys.NewInt("packages", "")
|
||||
Files = keys.New("files", "")
|
||||
Port = keys.NewInt("port", "")
|
||||
Type = keys.New("type", "")
|
||||
HoverKind = keys.NewString("hoverkind", "")
|
||||
|
||||
NewServer = keys.NewString("new_server", "A new server was added")
|
||||
EndServer = keys.NewString("end_server", "A server was shut down")
|
||||
|
||||
ServerID = keys.NewString("server", "The server ID an event is related to")
|
||||
Logfile = keys.NewString("logfile", "")
|
||||
DebugAddress = keys.NewString("debug_address", "")
|
||||
GoplsPath = keys.NewString("gopls_path", "")
|
||||
ClientID = keys.NewString("client_id", "")
|
||||
|
||||
Level = keys.NewInt("level", "The logging level")
|
||||
)
|
||||
|
||||
var (
|
||||
// create the stats we measure
|
||||
Started = keys.NewInt64("started", "Count of started RPCs.")
|
||||
ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes)
|
||||
SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes)
|
||||
Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds)
|
||||
)
|
||||
|
||||
const (
|
||||
Inbound = "in"
|
||||
Outbound = "out"
|
||||
)
|
||||
+1
-18
@@ -21,7 +21,6 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
@@ -529,7 +528,7 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
if alias, ok := t.(*aliases.Alias); ok {
|
||||
// Preserve materialized aliases,
|
||||
// even of non-exported types.
|
||||
t = aliasRHS(alias)
|
||||
t = aliases.Rhs(alias)
|
||||
}
|
||||
w.typ(t, obj.Pkg())
|
||||
break
|
||||
@@ -1331,19 +1330,3 @@ func (e internalError) Error() string { return "gcimporter: " + string(e) }
|
||||
func internalErrorf(format string, args ...interface{}) error {
|
||||
return internalError(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// aliasRHS removes exactly one Alias constructor.
|
||||
func aliasRHS(alias *aliases.Alias) types.Type {
|
||||
// TODO(adonovan): if proposal #66559 is accepted, this will
|
||||
// become Alias.RHS(alias). In the meantime, we must punch
|
||||
// through the drywall.
|
||||
type go123Alias struct {
|
||||
_ *types.TypeName
|
||||
_ *types.TypeParamList
|
||||
RHS types.Type
|
||||
_ types.Type
|
||||
}
|
||||
var raw *go123Alias
|
||||
*(**aliases.Alias)(unsafe.Pointer(&raw)) = alias
|
||||
return raw.RHS
|
||||
}
|
||||
|
||||
+3
-1
@@ -210,6 +210,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
|
||||
p := iimporter{
|
||||
version: int(version),
|
||||
ipath: path,
|
||||
aliases: aliases.Enabled(),
|
||||
shallow: shallow,
|
||||
reportf: reportf,
|
||||
|
||||
@@ -369,6 +370,7 @@ type iimporter struct {
|
||||
version int
|
||||
ipath string
|
||||
|
||||
aliases bool
|
||||
shallow bool
|
||||
reportf ReportFunc // if non-nil, used to report bugs
|
||||
|
||||
@@ -567,7 +569,7 @@ func (r *importReader) obj(name string) {
|
||||
// tparams := r.tparamList()
|
||||
// alias.SetTypeParams(tparams)
|
||||
// }
|
||||
r.declare(aliases.NewAlias(pos, r.currPkg, name, typ))
|
||||
r.declare(aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ))
|
||||
|
||||
case constTag:
|
||||
typ, val := r.value()
|
||||
|
||||
+3
-1
@@ -26,6 +26,7 @@ type pkgReader struct {
|
||||
|
||||
ctxt *types.Context
|
||||
imports map[string]*types.Package // previously imported packages, indexed by path
|
||||
aliases bool // create types.Alias nodes
|
||||
|
||||
// lazily initialized arrays corresponding to the unified IR
|
||||
// PosBase, Pkg, and Type sections, respectively.
|
||||
@@ -99,6 +100,7 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
|
||||
|
||||
ctxt: ctxt,
|
||||
imports: imports,
|
||||
aliases: aliases.Enabled(),
|
||||
|
||||
posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
|
||||
pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
|
||||
@@ -524,7 +526,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||
case pkgbits.ObjAlias:
|
||||
pos := r.pos()
|
||||
typ := r.typ()
|
||||
declare(aliases.NewAlias(pos, objPkg, objName, typ))
|
||||
declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ))
|
||||
|
||||
case pkgbits.ObjConst:
|
||||
pos := r.pos()
|
||||
|
||||
+6
-4
@@ -25,7 +25,6 @@ import (
|
||||
"golang.org/x/tools/internal/event"
|
||||
"golang.org/x/tools/internal/event/keys"
|
||||
"golang.org/x/tools/internal/event/label"
|
||||
"golang.org/x/tools/internal/event/tag"
|
||||
)
|
||||
|
||||
// An Runner will run go command invocations and serialize
|
||||
@@ -55,11 +54,14 @@ func (runner *Runner) initialize() {
|
||||
// 1.14: go: updating go.mod: existing contents have changed since last read
|
||||
var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
|
||||
|
||||
// verb is an event label for the go command verb.
|
||||
var verb = keys.NewString("verb", "go command verb")
|
||||
// event keys for go command invocations
|
||||
var (
|
||||
verb = keys.NewString("verb", "go command verb")
|
||||
directory = keys.NewString("directory", "")
|
||||
)
|
||||
|
||||
func invLabels(inv Invocation) []label.Label {
|
||||
return []label.Label{verb.Of(inv.Verb), tag.Directory.Of(inv.WorkingDir)}
|
||||
return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)}
|
||||
}
|
||||
|
||||
// Run is a convenience wrapper around RunRaw.
|
||||
|
||||
+54
@@ -107,3 +107,57 @@ func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*Modul
|
||||
}
|
||||
return mod, lines[4] == "go1.14", nil
|
||||
}
|
||||
|
||||
// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands
|
||||
// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
|
||||
// of which only Verb and Args are modified to run the appropriate Go command.
|
||||
// Inspired by setDefaultBuildMod in modload/init.go
|
||||
func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) {
|
||||
inv.Verb = "env"
|
||||
inv.Args = []string{"GOWORK"}
|
||||
stdout, err := r.Run(ctx, inv)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
goWork := string(bytes.TrimSpace(stdout.Bytes()))
|
||||
if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() {
|
||||
mainMods, err := getWorkspaceMainModules(ctx, inv, r)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, mainMods, nil
|
||||
}
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
// getWorkspaceMainModules gets the main modules' information.
|
||||
// This is the information needed to figure out if vendoring should be enabled.
|
||||
func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) {
|
||||
const format = `{{.Path}}
|
||||
{{.Dir}}
|
||||
{{.GoMod}}
|
||||
{{.GoVersion}}
|
||||
`
|
||||
inv.Verb = "list"
|
||||
inv.Args = []string{"-m", "-f", format}
|
||||
stdout, err := r.Run(ctx, inv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n")
|
||||
if len(lines) < 4 {
|
||||
return nil, fmt.Errorf("unexpected stdout: %q", stdout.String())
|
||||
}
|
||||
mods := make([]*ModuleJSON, 0, len(lines)/4)
|
||||
for i := 0; i < len(lines); i += 4 {
|
||||
mods = append(mods, &ModuleJSON{
|
||||
Path: lines[i],
|
||||
Dir: lines[i+1],
|
||||
GoMod: lines[i+2],
|
||||
GoVersion: lines[i+3],
|
||||
Main: true,
|
||||
})
|
||||
}
|
||||
return mods, nil
|
||||
}
|
||||
|
||||
+34
-4
@@ -301,6 +301,20 @@ func (p *pass) loadPackageNames(imports []*ImportInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if there is a trailing major version, remove it
|
||||
func withoutVersion(nm string) string {
|
||||
if v := path.Base(nm); len(v) > 0 && v[0] == 'v' {
|
||||
if _, err := strconv.Atoi(v[1:]); err == nil {
|
||||
// this is, for instance, called with rand/v2 and returns rand
|
||||
if len(v) < len(nm) {
|
||||
xnm := nm[:len(nm)-len(v)-1]
|
||||
return path.Base(xnm)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nm
|
||||
}
|
||||
|
||||
// importIdentifier returns the identifier that imp will introduce. It will
|
||||
// guess if the package name has not been loaded, e.g. because the source
|
||||
// is not available.
|
||||
@@ -310,7 +324,7 @@ func (p *pass) importIdentifier(imp *ImportInfo) string {
|
||||
}
|
||||
known := p.knownPackages[imp.ImportPath]
|
||||
if known != nil && known.name != "" {
|
||||
return known.name
|
||||
return withoutVersion(known.name)
|
||||
}
|
||||
return ImportPathToAssumedName(imp.ImportPath)
|
||||
}
|
||||
@@ -1059,6 +1073,18 @@ func addStdlibCandidates(pass *pass, refs references) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localbase := func(nm string) string {
|
||||
ans := path.Base(nm)
|
||||
if ans[0] == 'v' {
|
||||
// this is called, for instance, with math/rand/v2 and returns rand/v2
|
||||
if _, err := strconv.Atoi(ans[1:]); err == nil {
|
||||
ix := strings.LastIndex(nm, ans)
|
||||
more := path.Base(nm[:ix])
|
||||
ans = path.Join(more, ans)
|
||||
}
|
||||
}
|
||||
return ans
|
||||
}
|
||||
add := func(pkg string) {
|
||||
// Prevent self-imports.
|
||||
if path.Base(pkg) == pass.f.Name.Name && filepath.Join(goenv["GOROOT"], "src", pkg) == pass.srcDir {
|
||||
@@ -1067,13 +1093,17 @@ func addStdlibCandidates(pass *pass, refs references) error {
|
||||
exports := symbolNameSet(stdlib.PackageSymbols[pkg])
|
||||
pass.addCandidate(
|
||||
&ImportInfo{ImportPath: pkg},
|
||||
&packageInfo{name: path.Base(pkg), exports: exports})
|
||||
&packageInfo{name: localbase(pkg), exports: exports})
|
||||
}
|
||||
for left := range refs {
|
||||
if left == "rand" {
|
||||
// Make sure we try crypto/rand before math/rand.
|
||||
// Make sure we try crypto/rand before any version of math/rand as both have Int()
|
||||
// and our policy is to recommend crypto
|
||||
add("crypto/rand")
|
||||
add("math/rand")
|
||||
// if the user's no later than go1.21, this should be "math/rand"
|
||||
// but we have no way of figuring out what the user is using
|
||||
// TODO: investigate using the toolchain version to disambiguate in the stdlib
|
||||
add("math/rand/v2")
|
||||
continue
|
||||
}
|
||||
for importPath := range stdlib.PackageSymbols {
|
||||
|
||||
+33
-15
@@ -112,11 +112,11 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
|
||||
}
|
||||
|
||||
vendorEnabled := false
|
||||
var mainModVendor *gocommand.ModuleJSON
|
||||
var mainModVendor *gocommand.ModuleJSON // for module vendoring
|
||||
var mainModsVendor []*gocommand.ModuleJSON // for workspace vendoring
|
||||
|
||||
// Module vendor directories are ignored in workspace mode:
|
||||
// https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
|
||||
if len(r.env.Env["GOWORK"]) == 0 {
|
||||
goWork := r.env.Env["GOWORK"]
|
||||
if len(goWork) == 0 {
|
||||
// TODO(rfindley): VendorEnabled runs the go command to get GOFLAGS, but
|
||||
// they should be available from the ProcessEnv. Can we avoid the redundant
|
||||
// invocation?
|
||||
@@ -124,18 +124,35 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
vendorEnabled, mainModsVendor, err = gocommand.WorkspaceVendorEnabled(context.Background(), inv, r.env.GocmdRunner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if mainModVendor != nil && vendorEnabled {
|
||||
// Vendor mode is on, so all the non-Main modules are irrelevant,
|
||||
// and we need to search /vendor for everything.
|
||||
r.mains = []*gocommand.ModuleJSON{mainModVendor}
|
||||
r.dummyVendorMod = &gocommand.ModuleJSON{
|
||||
Path: "",
|
||||
Dir: filepath.Join(mainModVendor.Dir, "vendor"),
|
||||
if vendorEnabled {
|
||||
if mainModVendor != nil {
|
||||
// Module vendor mode is on, so all the non-Main modules are irrelevant,
|
||||
// and we need to search /vendor for everything.
|
||||
r.mains = []*gocommand.ModuleJSON{mainModVendor}
|
||||
r.dummyVendorMod = &gocommand.ModuleJSON{
|
||||
Path: "",
|
||||
Dir: filepath.Join(mainModVendor.Dir, "vendor"),
|
||||
}
|
||||
r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
|
||||
r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
|
||||
} else {
|
||||
// Workspace vendor mode is on, so all the non-Main modules are irrelevant,
|
||||
// and we need to search /vendor for everything.
|
||||
r.mains = mainModsVendor
|
||||
r.dummyVendorMod = &gocommand.ModuleJSON{
|
||||
Path: "",
|
||||
Dir: filepath.Join(filepath.Dir(goWork), "vendor"),
|
||||
}
|
||||
r.modsByModPath = append(append([]*gocommand.ModuleJSON{}, mainModsVendor...), r.dummyVendorMod)
|
||||
r.modsByDir = append(append([]*gocommand.ModuleJSON{}, mainModsVendor...), r.dummyVendorMod)
|
||||
}
|
||||
r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
|
||||
r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
|
||||
} else {
|
||||
// Vendor mode is off, so run go list -m ... to find everything.
|
||||
err := r.initAllMods()
|
||||
@@ -166,8 +183,9 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
|
||||
return count(j) < count(i) // descending order
|
||||
})
|
||||
|
||||
r.roots = []gopathwalk.Root{
|
||||
{Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT},
|
||||
r.roots = []gopathwalk.Root{}
|
||||
if goenv["GOROOT"] != "" { // "" happens in tests
|
||||
r.roots = append(r.roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT})
|
||||
}
|
||||
r.mainByDir = make(map[string]*gocommand.ModuleJSON)
|
||||
for _, main := range r.mains {
|
||||
|
||||
+4
@@ -23,6 +23,9 @@ type PkgDecoder struct {
|
||||
// version is the file format version.
|
||||
version uint32
|
||||
|
||||
// aliases determines whether types.Aliases should be created
|
||||
aliases bool
|
||||
|
||||
// sync indicates whether the file uses sync markers.
|
||||
sync bool
|
||||
|
||||
@@ -73,6 +76,7 @@ func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
|
||||
func NewPkgDecoder(pkgPath, input string) PkgDecoder {
|
||||
pr := PkgDecoder{
|
||||
pkgPath: pkgPath,
|
||||
//aliases: aliases.Enabled(),
|
||||
}
|
||||
|
||||
// TODO(mdempsky): Implement direct indexing of input string to
|
||||
|
||||
+2
-2
@@ -1449,10 +1449,10 @@ const (
|
||||
NotAGenericType
|
||||
|
||||
// WrongTypeArgCount occurs when a type or function is instantiated with an
|
||||
// incorrent number of type arguments, including when a generic type or
|
||||
// incorrect number of type arguments, including when a generic type or
|
||||
// function is used without instantiation.
|
||||
//
|
||||
// Errors inolving failed type inference are assigned other error codes.
|
||||
// Errors involving failed type inference are assigned other error codes.
|
||||
//
|
||||
// Example:
|
||||
// type T[p any] int
|
||||
|
||||
Vendored
+2
-3
@@ -1477,7 +1477,7 @@ github.com/onsi/ginkgo/reporters/stenographer
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
|
||||
github.com/onsi/ginkgo/types
|
||||
# github.com/onsi/ginkgo/v2 v2.17.3
|
||||
# github.com/onsi/ginkgo/v2 v2.19.0
|
||||
## explicit; go 1.20
|
||||
github.com/onsi/ginkgo/v2
|
||||
github.com/onsi/ginkgo/v2/config
|
||||
@@ -2168,7 +2168,7 @@ golang.org/x/text/width
|
||||
# golang.org/x/time v0.5.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/time/rate
|
||||
# golang.org/x/tools v0.20.0
|
||||
# golang.org/x/tools v0.21.0
|
||||
## explicit; go 1.19
|
||||
golang.org/x/tools/cmd/stringer
|
||||
golang.org/x/tools/cover
|
||||
@@ -2184,7 +2184,6 @@ golang.org/x/tools/internal/event
|
||||
golang.org/x/tools/internal/event/core
|
||||
golang.org/x/tools/internal/event/keys
|
||||
golang.org/x/tools/internal/event/label
|
||||
golang.org/x/tools/internal/event/tag
|
||||
golang.org/x/tools/internal/gcimporter
|
||||
golang.org/x/tools/internal/gocommand
|
||||
golang.org/x/tools/internal/gopathwalk
|
||||
|
||||
Reference in New Issue
Block a user