-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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
embed: go:embed produces error when "go.mod" has go version < 1.16 #43980
Comments
This is intentional, because a |
Even with "// +build go1.16" protecting it? -- just making sure, because while I understand go:embed not working with go < 1.16, I would think that if the source code was not eligible for compilation via build tags, it should be ignored. And if so, I would appreciate a doc explaining that go will not consider build tags in that case. My skimming through the release notes or the embed docs didn't produce such explanation. I can certainly provide a patch if need be. |
By my understanding,
|
golang/go#43980 go1.16 probably won't allow us to use go:embed, so just implement an in memory FS
I have learned that |
@ianlancetaylor while I get the current check against |
@mvdan Fair point. I'll reopen. |
I made a typo, by the way. I meant that the |
Thanks, understood. |
For reference, that's #40067, and it even affects users of modules that try and use new standard library packages. No module can successfully guard its use of a new standard library package with a build tag and have it not still break downstream users with older Go versions. (I expect this to start happening pretty often now that everyone is excited for |
Having spent little time playing around with If you want to use a language feature introduced in Go 1.16, you will need tools >= 1.16 |
The confusion is in the fact that we (well, at least I) have used build tags to switch between certain features that were newly introduced. For example, I have the following successfully compiling in go1.16rc1 // +build go1.15
package ecutil
import (
"math/big"
)
func bigIntFillBytes(v *big.Int, buf []byte) []byte {
v.FillBytes(buf)
return buf
} // +build !go1.15
package ecutil
import (
"math/big"
)
func bigIntFillBytes(v *big.Int, buf []byte) []byte {
data := v.Bytes()
if len(data) > len(buf) {
panic("ecutil: invalid call to bigIntFillBytes (len(data) > len(buf))")
}
copy(buf[len(buf)-len(data):], data)
return buf
}
In this scenario, I was able to provide support for go 1.14 that doesn't have At first glance I fail to see the difference between the above and below // +build go1.16
import "embed" // +build !go1.16
// (code without embed)
Hope that clears up my reasoning on this issue, at least. |
I guess the difference between the two is: generally new added APIs are not features. I do admit sometimes this is a little confusing. I guess there are several feature switches in the compiler code to control on/off of some admitted features. |
@go101 I can appreciate the distinction, but I would argue that to the layman the question is just "does this code run on go 1.xx?". In that sense, differentiating between API changes or language features or toolchain changes don't really mean anything to me. As a library writer, I tried to give maximum flexibility to my users by adding a feature to pass in a To the maintainers: while I maintain that the current state is inconsistent and confusing, I can appreciate the history, the decisions that went behind, etc, so I'm not demanding immediate change or anything. Again, I think it's confusing, so I would hope that relevant parties see that there is some room to either clarify the documentation or think this "feature" through a bit more now or in the future. |
As a developer I often rely on the compiler to tell me when I have broken the code. The fact that it will fail on errors on files guarded by build tags Of course people will tell me I should make sure that my CI system builds and test on every possible If this issue was "fixed" by allowing the code above to compile without error, it would make To @lestrrat, my suggestion would be: if you really have to support Go versions < 1.16, then don't |
It would be great if there is an official document to list the features each version supports (and to explain features and functionalities are different). |
https://tip.golang.org/doc/go1.16 explains which new features were added to go1.16 which are not in go1.15. If we try to "help" our users by maintaining a table mapping features to versions, |
@amnonbc @lestrrat
It looks this is not true. gc1.16rc1 doesn't view |
On the other hand, it is really worth considering how to handle the case if a new Go version both introduces and removes features. |
The point I was trying to make earlier is that we are doing our users no favours if we try to "help" them continue to use The Go 1.0 promise guarantees the features don't get removed. But they will get added. And the best answer is |
There might be features to be removed later, such as the |
I would like to point out that I ended up facing the same issue and created a gist reproducing it. Then I realized this issue existed, but just in case the gist might be useful here it goes: https://gist.github.com/campoy/f85824233233b8e25e53605087d4e871 |
@campoy That's #40067 and it's existed for a while (first seen when I'll also point out that the |
The expectation is that you don't use embed until you are ready to bump your users forward. |
Introducing Am I missing a way to introduce I tried to use an app with |
I would not consider requiring the latest tools to build the code to be a breaking API change. If the API stays the same, then the calling code does not need to change, so the major version should not be incremented. New code using new features will generally fail to build using old tools. So I would not try to protect new features with build tags. That way lies madness. |
Funny enough, I can "workaround" the issue by removing |
Yes having no |
For the record, you can work around this issue by declaring
|
Why do you need the build tag? |
Because the |
@rogpeppe Was that changed in a recent 1.15.x version? Because in the other comments in this thread it's mentioned that build tags don't help in this particular case, which is one issue that the OP also mentions.
Using the code from Francesc's Gist I can reproduce the issue with Go 1.15.7, but not with Go 1.15.11. I'm interested to know whether the build tag solution now properly works for embed or if there's another reason why the error doesn't occur in 1.15.11. |
I believe that the build tag solution now works correctly with 1.15.11 - |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
with the rc release? yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Using github.com/lestrrat-go/jwx@09b6dea (note that it's at a tracking branch)
What did you expect to see?
What did you see instead?
Discussion
My go.mod contains the following
If I change the line
go 1.13
togo 1.16
, then it works on go1.16rc1go1.16beta1 worked just fine.
Shouldn't features like this just depend on the runtime version, and not contents of go.mod?
The text was updated successfully, but these errors were encountered: