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
proposal: new option to configure internal packages from go.mod #59205
Comments
Unless I'm misunderstanding what you mean, you don't need to do that.
|
What concrete problem would this solve? Can you give some specific examples of repos that already exist that could be substantially improved using this? |
@bcmills I guess the problem is the opinionated nature of forcing certain directories of certain names at certain places in the repo. This optional feature would free users from that constraint. Plus, it would be more easily discoverable where internal packages are since they are specified in one central place at the root of the module. |
"opinionated nature" and enforcing a structure sound like desirable properties of a programming language to me. |
@DeedleFake The proposal is a feature that frees people from a particular constraint in favor of a solution that is centralized. Specifying the internal (or not) nature of a package/directory need not require |
It's easy to discover where internal packages are today: |
@bcmills Yes but it is not easy to change or specify them as that requires directory structure manipulation. I think the |
Yes, I agree and love Go's idiomatic style. I think this change is overdue since the |
I don't see these as related. |
@gophun Modules and packages are definitely related. Modules are made up exclusively of packages with a certain directory structure which is where |
what does it mean for a module to be "internal"? who can use it? what are the rules for who can use internal directories specified centrally like this? |
I suppose an internal module is just a module where
It would be the same rules, a prefix. The UX issue is a fair point but the UX for most is that the packages inside internal just don't show up and are not documented, etc. That would still be the same here. Even better, one would not have to traverse the file structure of a module to find all of the internal "nodes". EDIT: @bcmills Made a great point that there is a command to run to get all internal packages but imagine the nightmare of tracking how internal packages have changed over the history of the repo. You would be faced with tracking potentially hundreds of file renames or more. If you could configure this sort of thing inside |
I'm trying to form a concrete model of the behavior you are intending in my mind. What I think you are proposing is that, given the example
...the toolchain should essentially treat both I think this would mean that any package under This would (I think) match today's treatment if these packages were instead named Does what I've described above match your intention? Thanks! |
@apparentlymart Hi, I appreciate you looking into this humble proposal.
Yes, that seems accurate...
Yes, same as current behavior...
Yes, I believe you captured it. Current behavior says that importing code can only access the internal code if it's within the same tree as the parent of the internal package (from the docs):
As I mentioned before, another really cool part of this would be that the module prefix itself would be valid. This would make it possible to mark whole modules as internal without disturbing file structure. For example, you could provide prefix EDIT: I updated the description to clarify, I think if the |
I would like to propose a new feature for Go modules where
internal
package behavior can be managed centrally from thego.mod
file.I am proposing a new option enabling us to use directory names other than
internal
to indicate internal behavior and instead use a more centralized configuration at the module level. When this statement block is used in thego.mod
file, it would otherwise disable normal internal behavior in that the toolchain would not treat directories namedinternal
as special.This would be completely optional, like Go module replace directives, but if present would allow users to manage where internal "nodes" are located in their module with a declarative syntax for managing internal functionality:
Or for the entire module
If the
go.mod
block is present, all directories are treated equally and there is no more special treatment of directories namedinternal
. This would be useful in development if an outside test module wanted to import/test internal code in a CI scenario. For example, if I wanted to use the Go CLI to modifygo.mod
and add thisinternal
block so that I can build my test module which imports/tests internal code without being denied by the toolchain. That is a simpler and more practical solution than copying a package directory from its source module to the test module. Of course, many would say to just keep the test code together in theinternal
directory but you may have outside tools that use have developed which makes things difficult.Example scenarios where this might be useful:
Change management of internal functionality. For example, I can put a package exactly where I want in a repo when I start working on it. Then, I update
go.mod
to make that package internal so it's not exposed to anyone. Finally, when it's ready I remove the entry fromgo.mod
and the package is there. At no point does that process involve new or changing directories, file move/renames, etc. Plus, the entire history of these changes are captured centrally within the commit history of thego.mod
file.Eliminate useless nesting. If I have a package called
services
and want everything in there to be internal. Currently, I would have to rename this directory tointernal
to accomplish this. Or worse, I could nest theservices
directory inside aninternal
directory, creating a.../internal/services
structure where there are no Go files inside theinternal
directory.Internal Modules. Currently, this is not possible unless the root directory of the module is named
internal
. This is not practical when many modules are at the repo root as it means a repo must be namedinternal
.The solution with the directory naming came before Go modules. I think this is a more "Go modules" approach to internal functionality.
The text was updated successfully, but these errors were encountered: