-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
cmd/go: add global ignore mechanism for Go tooling ecosystem #42965
Comments
I'm not sure that I understand this argument. Presumably, it's a program that creates and fills those directories, since they have to contain a significant amount of files for you to really want to ignore them in Go. If they were just a handful of files created manually by a human, it would be a negligible cost for Go to walk those and realise there are no Go packages there. So, given that it is a program or script creating those large directories, why not add a
This is unlikely to happen, see #42343 (comment).
I have to admit that I dislike this option. It's bad enough that all these other tools use separate ignore files. |
@mvdan It is indeed a program that creates these directories. But it's a program that you don't control normally. Wrapping well-known tools like On the other hand by placing arbitrary files in these directories you're invading the territory of other tools. What if that program checks the integrity of the directory and would break seeing a random unknown file? It's not the case with I understand the objection about
Could you elaborate on why do you think it's bad? It may not be the most elegant solution, but it's common practice, well-understood and somewhat expected. If we already have |
Wouldn't you need to wrap the tool to add a |
@bcmills My proposal is to add a file in the root of the project, not in the directory being ignored. So it would be checked in. Like |
...ok? But why would you not also check in the injected |
The common practice is to litter repositories with dot files. That does not mean we should do the same, making the problem worse :) Go already has multiple mechanisms to ignore entire directories ( |
@bcmills because often directories to ignore aren't checked in. |
@mvdan IMHO, having a dot file in one place, that is trackable, is less of an evil, than sprinkling empty Thinking about pros and cons of implementing such a feature, I'm struggling to see any cons (probably due to my ignorance), besides having to spend the time to implement it. I'd appreciate if anyone could bring some light into this to understand the implications. |
I have a use case where I have a multi-language repo where not all of the developers are touching the go components. I don't think it is reasonable to ask my docker, bazel, and nodejs developers to all wrap their normal tooling in scripts that touch extra files in their build directories, nor ask them to try to rename their standard build directories to match existing go conventions, some of which conflict with the other tool conventions. It seems like there should be a way to specify how to ignore certain files or directories that does not require modifying the content of those files or directories, because the ignored content is not being managed by go and may have its own conflicting conventions and lifecycle. |
@psigen Go wants a directory tree that belongs to it. In a multi-language repo, why not create a top-level go/ directory? |
@rsc: because my projects are not organized that way. I have services like:
I know what you are asking, which is why not reorganize to:
And the answer, (besides "that's a lot of work right now") is that it is not how our ownership is structured. It is not convenient to have duplication in the I could go on, but I'm really just reiterating the core premise of this proposal:
|
I use the serverless framework to deploy lambdas on AWS. Some plugins that I have to use contains go files. So when I run
|
Reading this statement does not make me happy. It goes against the entire premise of the code organization at my company. We use a monorepo with projects in several languages. Some Go programs live inside projects written in other languages. Sometimes we rewrite a project from one language to another. Some projects use a combination of Go and other languages (imagine a website written using both Go and JavaScript extensively). We already have an organizational hierarchy within the monorepo that is based around purpose and ownership, not language. This all worked fine with Moving to modules has raised some challenges, but mostly it has worked. The whole repo is one module so we use a fixed, shared set of dependencies. One issue we faced is that the But when I read "Go wants a directory tree that belongs to it", it sounds like you don't think this use case matters as far as the standard Go tools are concerned. I don't know how we could possibly adapt our repo to a "Go code all belongs in its own tree" model. Probably we wouldn't -- I imagine that if push came to shove, we'd look into alternative build tools. |
In #50225 I'm bring in concerns about the resources (network, disk space) wasted on every developers machine because the module zips contain many irrelevant files. Check this list of files that are in your Go modules cache:
I have more than 200,000 useless files on my machine. This also impacts CI builds (download time/space of new dependencies, requires to enable strong module caching to reduce the problem). |
While similar, I think this proposal is a bit different from yours @dolmen in a sense that here I mostly care about ignoring directories, not specific files, and definitely not for specific packages like |
BTW, I updated the initial comment. |
I consider Instead, ignore patterns must be available for tools that download the code from a VCS (for publishing on a proxy, or for filling the module cache, see #50225), so the ignore patterns must be always available in the repository. So |
@dolmen While I suspect that |
@burdiyan,
|
It is kind of frustrating that the responses from Go contributors are uniformly "Everyone else on earth is wrong, they should change to accommodate our design choices." No matter how inelegant another dotfile is, it solves the problem in a universal way that will work for all repository structures and build tools. None of the proposed alternatives even attempt to do the same. I currently just don't run gopls and try to minimize how often I have to write Go, which is not a "solution" that is available to everyone. |
Some of us discussed the problem this proposal aims to address - i.e., allow to exclude certain directories when running We agree this is a problem for some tools (e.g. @bcmills had a great idea during the discussion - The overlay config isn't as flexible as glob patterns many dotfiles accept, but I think it still provides the sufficient knob #50225 (for mechanism to fine tune the scope of a module) was mentioned during the discussion, but I don't think that is the goal of this proposal. For example, I think it's possible one wants to speed up @jaronsummers I think the Go team is trying to understand the problem better, not dismiss or ignore problems users are facing in the real world. |
Today we don't filter directories beginning with That said, I am concerned that that seems not to address the use-case of pruning non-Go files (such as checked-in source subtrees for other languages) out of the module zip archives. I worry that this only addresses something like half of the use-cases that have been brought up on this issue. 😅 |
Which is perfectly fine IMO. I have seen /My two coppers. |
If you don't want files in a module, one option is to use a tagging procedure that makes a commit on a temporary branch (or a detached head) and then remove the files and tag that commit. I don't think this will come up often, and we have a way to address it, so I think it's OK to have just one kind of ignore (ignore for Go files, like _ directories, but still include in the module). |
To summarize the discussion and try to move things along, there are two different ways files can be ignored: let's call them build-ignore (like _ files and directories today), mod-ignore (do not pack into the module), and git-ignore (the .gitignore file, do not commit into git). Note that a few combinations are suspicious:
With that note, here are the eight possible combinations:
It seems clear to me that "build-ignore", enabling (4), is an important use case, and calling it "ignore" matches the meaning of "IgnoredGoFiles" in go list output: the files exist but are ignored. It seems like we should move forward with that meaning in this proposal. It's less clear to me whether "mod-ignore", enabling (2) or (6), is also an important use case. If so, we could potentially add a second kind of statement, perhaps 'omit', to control what is and is not included in the module form. Given that ignore can ignore the files, 'omit' ends up being purely a module size optimization. Are there use cases where this space savings would be important? Thanks. |
On the topic of having ignore in go.work, I spoke to @bcmills and @matloob and we decided it seemed odd to add it to go.work: whether files are ignored seems like it should be part of the definition of the module itself. We couldn't come up with a reason that a go.work would want to override parts of one of the modules it contains, and in general go.work is meant to be a "union of modules" not manipulation of the internals of any of the modules. |
I would be tempted to mod-ignore $ find $(go env GOMODCACHE) -name '[._]*' | sed 's!.*/!!' | sort -u However package |
Rightfully so. I had the issue that |
Maybe but maybe not. It depends. And since we have included them to date, we can't really start eliding them now, or else checksums will no longer match. We could change based on Go version, but it doesn't seem worth the churn. |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
Attempting to summarize the state of the world to figure out the state of this proposal. My understanding from #42965 (comment) is as follows (please chime in if incorrect):
So, if you want to ignore directories with goimports or similar tooling, continue using other workarounds for now. It's probably worth updating the first comment since it's quite hard to figure out the state of this proposal. |
I updated the initial post to include the link to #42965 (comment). |
@rsc any idea when this will be available? |
How should "ignore" affect a tree embedded with //go:embed ? |
@dolmen |
UPDATE: The summary of the accepted proposal at: #42965 (comment).
Problem
For non-trivial (often multi-language) projects it's often desirable to make all the Go tools (including
gopls
) ignore certain directories.Some of the examples could be the huge amount of files within
node_modules
, orbazel-*
directories generated by Bazel. This causes many operations with./...
wildcards taking longer than desired. Alsogopls
often eats up a lot of CPU in VS Code depending on what you are doing.Prior Art
This is something that has been discussed in several issues before, but seems like people couldn't get agree on a solution.
.goignore
in file scans #30058Some tools started to have their own solutions which causes fragmentation and is cumbersome.
For example
goimports
have its own machinery for this -.goimportsignore
file in this case. But it's not working with Go Modules.Other tools have a hard-coded list of directories to ignore, like
.git
and so on.It seems like having a global solution that all the Go ecosystem could understand would make sense to solve this kind of problem.
Recently a workaround for this was to place a dummy
go.mod
file in the directories you wanted to ignore. But this is not easily portable between users of the project, because often these directories can be re-created on the user's machine and aren't even checked-in. Asking people to sprinkle somego.mod
files all around every time is cumbersome.@robpike was against of creating more dot files (#30058 (comment)).
Proposed Solution
Here're some of the options that this could be implemented with.
Use(Rejected becausego.mod
file for specifying directories to ignore.go.mod
is not a catch-all config file likepackage.json
in NodeJS).Use a separate(This would go against Rob's desire to avoid new dot files, and although being in the spirit with other tools:.goignore
file..dockerignore
,.gitignore
,.bazelignore
, etc. is concerning. The concerns are discussed in this thread).go.work
file that's coming in the next Go 1.18 release.go.ignore
file that would specify directories to ignore./cc @tj @stamblerre
The text was updated successfully, but these errors were encountered: