Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syntax support for toolchain directive #3633

Merged
merged 1 commit into from
Jan 21, 2024

Conversation

matthewhughes934
Copy link
Contributor

@matthewhughes934 matthewhughes934 commented Jan 19, 2024

This directive was added to go.mod with Go 1.21[1] So that this
directive can be highlighted in go.mod.

It's not entirely clear exactly what the fully supported syntax is. The
docs[1] suggests any Go release version, e.g.

  • go1.20
  • go1.21.1
  • go1.21.1rc1

golang.org/x/mod gives a much more relaxed definition, requiring just
that things match against the regex ^default$|^go1($|\.)[2]

Finally there's FromToolchain from the stdlib's internals for
processing versions[3] which is broader than that from[1] but more
limited than that from[2], supporting arbitrary suffixes (after any of
" \t-") appended to the version, e.g.

  • go1.21.3-somesuffix
  • go1.21rc2-somesuffix
  • go1.21 some-suffix

The approach taken for the syntax matching here is closest to this final
condition, and will not include some toolchain verison's that would be
supported by the modfile regex, e.g.

  • go1.21.1blah
  • go1.21!some-suffix

Since these would be rejected by the go tool itself with an error like

go: invalid toolchain "go1.21.1blah" in go.mod

Copy link
Collaborator

@bhcleek bhcleek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contributing. In addition to the comments I made inline, can you add tests for this to autoload/go/highlight_test.vim? The first test in that file, Test_gomodVersion_highlight, is a good template to follow.

@matthewhughes934
Copy link
Contributor Author

matthewhughes934 commented Jan 20, 2024

can you add tests for this to autoload/go/highlight_test.vim? The first test in that file, Test_gomodVersion_highlight, is a good template to follow.

Oh, that's really nice to have some tests for the highlighting. I've added some new ones: 92af479

In addition to the comments I made inline

🤔 I don't see any comments from you besides this one

syntax/gomod.vim Outdated
" * go1.XrcN
" * go1.X.Y-somesuffix
" * go1.XrcN-somesuffix more stuff
syntax match gomodToolchainVersion "go1\.\d\+\(\(.\d\+\)\|\(rc\d\+\)\)\?\([ \t-].*\)\?" contained
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any comments from you besides this one

Oof. I must have forgotten to hit Start a review before I submitted. I'll repost the quick summary here:

Two things about this after comparing this expression to the docs.

  1. From the docs, it doesn't appear that any space separated strings are valid. Did you find something otherwise?
  2. The docs indicate that a string is valid, but when I check rules, I think the only string that's allowed is default.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a link to the regular expression used by Go to validate the toolchain directive: https://cs.opensource.google/go/x/mod/+/refs/tags/v0.14.0:modfile/rule.go;l=309-311

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the docs, it doesn't appear that any space separated strings are valid. Did you find something otherwise?

I found some more detail digging around the stdlib https://go.googlesource.com/go/+/165383381199de6632665f43561e8e0dfc96f067/src/cmd/go/internal/gover/toolchain.go#24 (from looking for the source of the error 'go: invalid toolchain "%s" in go.mod'

Here's a link to the regular expression used by Go to validate the toolchain directive: https://cs.opensource.google/go/x/mod/+/refs/tags/v0.14.0:modfile/rule.go;l=309-311

More than happy to just use that since it's 1. simpler, 2. public documentation. It will permit versions that aren't accepted by the Go tool, e.g. toolchain go1.2.2rc4 will satisfy that but error go: invalid toolchain "go1.2.2rc4" in go.mod if actually used. I think it's fine if the highlighting accepts some invalid values (as long as it doesn't reject any valid ones)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying this with f4260d8. It's still more restrictive than just matching on ^go1 (trying to follow the examples) let me know if you'd like it relaxed further

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to relax it further, and I think it may be appropriate to tighten it up so that we don't match invalid versions.

This should also allow default if I'm not mistaken.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewhughes934 please feel free to let me know if you'd like to be done with this. I'm happy to take it as is and submit the incremental improvements on top of it myself.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find in stdlib. It looks like my assertion about spaces was wrong: https://go.googlesource.com/go/+/165383381199de6632665f43561e8e0dfc96f067/src/cmd/go/internal/gover/toolchain.go#39.

With that in mind, I think your original regular expression was mostly right except for we should also allow default.

If I'm reading the stdlib source code correctly, then it looks like anything other than default is validated by "internal/gover".IsValid: https://go.googlesource.com/go/+/165383381199de6632665f43561e8e0dfc96f067/src/internal/gover/gover.go#92

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fun tidbit from https://go.dev/doc/toolchain:

The standard Go toolchains are named goV where V is a Go version denoting a beta release, release candidate, or release. For example, go1.21rc1 and go1.21.0 are toolchain names; go1.21 and go1.22 are not (the initial releases are go1.21.0 and go1.22.0), but go1.20 and go1.19 are.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With that in mind, I think your original regular expression was mostly right except for we should also allow default.

👍 I've done this, and squashed all the changes down into 26f4ff5 there's some reasoning+a summary of this discussion in the commit

please feel free to let me know if you'd like to be done with this. I'm happy to take it as is and submit the incremental improvements on top of it myself.

Go for it

This directive was added to `go.mod` with Go 1.21[1] So that this
directive can be highlighted in `go.mod`.

It's not entirely clear exactly what the fully supported syntax is. The
docs[1] suggests any Go release version, e.g.

* `go1.20`
* `go1.21.1`
* `go1.21.1rc1`

`golang.org/x/mod` gives a much more relaxed definition, requiring just
that things match against the regex `^default$|^go1($|\.)`[2]

Finally there's `FromToolchain` from the stdlib's internals for
processing versions[3] which is broader than that from[1] but more
limited than that from[2], supporting arbitrary suffixes (after any of
`" \t-"`) appended to the version, e.g.

* go1.21.3-somesuffix
* go1.21rc2-somesuffix
* go1.21 some-suffix

The approach taken for the syntax matching here is closest to this final
condition, and will not include some toolchain verison's that would be
supported by the `modfile` regex, e.g.

* go1.21.1blah
* go1.21!some-suffix

Since these would be rejected by the `go` tool itself with an error like

> go: invalid toolchain "go1.21.1blah" in go.mod
@bhcleek bhcleek merged commit 1a5e0e2 into fatih:master Jan 21, 2024
8 checks passed
bhcleek added a commit that referenced this pull request Jan 21, 2024
@matthewhughes934 matthewhughes934 deleted the add-toolchain-syntax-support branch January 21, 2024 19:44
@bhcleek bhcleek added this to the vim-go v1.29 milestone Jan 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants