Thanks for working on this, Michael! I'm sure you've seen that multiple
threads on GitHub are advancing towards multi-module development in
different directions. I hope your proposal, when filed soon, can help
unify the conversations and get us to a solution.
After a second read of the draft, here are some questions:
What kind of semantic changes do we imagine will happen with go.work's
"go X.Y" directive? Since workspaces are just for local development,
could one not simply get the new semantics by upgrading the Go version
being used?
I'm a bit worried about replace directives in workspace modules applying
to the entire build list. I get why that's likely the only reasonable
option here, but it could easily get confusing when one has more than a
handful of workspace modules. Maybe we want to encourage go.work users
to use go.work replace directives instead, where possible. Or,
alternatively, some way of seeing all the replace directives in effect.
I seem to understand that if workspace mode is on and I'm also inside a
module, that module *must* be listed in go.work's directory. Does that
mean that, if it's not, the go tool will just error? If the module does
not belong in the workspace, is our solution here "move the module
outside the workspace directory"?
If my understanding above is correct, then perhaps I'm missing why the
directory is necessary, if all modules found under the workspace
directory must be part of it. We could reasonably cheaply walk the
directory tree to find all go.mod files. If that's too expensive to do
each time, commands like "go mod initwork" could record them as a form
of cache.
I'm still unconvinced that we need to be able to use the build list in
workspace mode but outside any of its modules. This seems like a feature
that we could keep out of the initial proposal, so if you want to keep
it there, I'd add a section to the draft explaining the use case.
I think the proposal should be opinionated as to whether go.work files
should be published in VCS. Some people initially thought that go.sum
files shouldn't be published, for example. My assumption is that, since
go.work files are for local development, they should generally not be
published. But perhaps it's reasonable to do for monorepos containing
many modules?
If I have two worspace modules A and B, and A depends on B, would
running "go list all" in B list all of A's packages? This is how I
understand the proposal. It does make the proposal more consistent, as
there is just one build list for the entire workspace, no matter what
module one is in. But, from the user's point of view, I'd find it a bit
surprising if the "go list all" command in B listed packages which are
not transitive dependencies of the current module.
This is enough of a wall of text, so I'll stop here :)
Just a couple quick comments.
One thing is the shared build list semantics might be problematic in some cases, including in a future with lazy module load. If the modules in the workspace have shared dependencies, it seems it might be possible in some cases for module A to end up with a different version selected for a shared dependency if module B is in the same workspace, compared to if module A was just consuming the exact same version of module B normally. For example, if module A was just importing a single package from module B, in the normal case without a workspace under lazy load, module A wouldn’t see the full set of direct and indirect dependencies for all of B’s packages, but it sounds like the shared build list in the workspace would see the full set of requirements for all of B’s packages, which could then mean different versions being selected for the same code & go.mod files depending on whether or not a workspace is being used. If so, that seems problematic?
That said, it might be that I'm not understanding the proposal, or I might not understand lazy load. ;-)
Separately, rather than an init command, it might be better to have a sync command that adds new modules to the workspace file or removes them as needed, ideally reporting what it did. That might be more helpful over time than a one shot init command?
For multi-modules workspace, a flag to disable the workspace as outlined in the proposal likely covers the common cases of wanting to test against published versions prior to release, but it also seems commenting out the directories in the workspace file could cover additional cases (e.g., if you have a 4 module workspace, and want to test how the changes in 2 of the modules work against the published versions of the other 2 modules). Is that true, and if so, is it worth mentioning?
It might also be useful to have something like ‘go work status’ (however it might be spelled) that gives an easily digestible summary.
In any event, very nice, and sorry if I’ve misunderstood anything…
Regards,
thepudds
On Apr 17, 2021, at 7:50 AM, Sean Liao <seank...@gmail.com> wrote:
--
You received this message because you are subscribed to a topic in the Google Groups "golang-tools" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-tools/0HfA1HWaTJY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-tools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-tools/7f99fe8f-21a8-4731-a52f-d69333fe2c36n%40googlegroups.com.
This looks great! A few comments:I'm still a bit confused about the scope of a directory directive,does it point to a single module , where the// module/path comment would make sense,or to all the modules under the directory,as your reply here seems to hint at
Also I agree the replace semantics are somewhat confusing,and goes counter to what we have been telling users aboutreplace only mattering in the main module.I was expecting each package in the workspace to be builtwith the main module being the one it is in,and only replaces there and in workspace taking effect.
Single dot or ./ ?directory (.)
--
You received this message because you are subscribed to a topic in the Google Groups "golang-tools" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-tools/0HfA1HWaTJY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-tools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-tools/7f99fe8f-21a8-4731-a52f-d69333fe2c36n%40googlegroups.com.
Hi Michael / all,This is very exciting to see!
Just a couple quick comments.
One thing is the shared build list semantics might be problematic in some cases, including in a future with lazy module load. If the modules in the workspace have shared dependencies, it seems it might be possible in some cases for module A to end up with a different version selected for a shared dependency if module B is in the same workspace, compared to if module A was just consuming the exact same version of module B normally. For example, if module A was just importing a single package from module B, in the normal case without a workspace under lazy load, module A wouldn’t see the full set of direct and indirect dependencies for all of B’s packages, but it sounds like the shared build list in the workspace would see the full set of requirements for all of B’s packages, which could then mean different versions being selected for the same code & go.mod files depending on whether or not a workspace is being used. If so, that seems problematic?
That said, it might be that I'm not understanding the proposal, or I might not understand lazy load. ;-)
Separately, rather than an init command, it might be better to have a sync command that adds new modules to the workspace file or removes them as needed, ideally reporting what it did. That might be more helpful over time than a one shot init command?
For multi-modules workspace, a flag to disable the workspace as outlined in the proposal likely covers the common cases of wanting to test against published versions prior to release, but it also seems commenting out the directories in the workspace file could cover additional cases (e.g., if you have a 4 module workspace, and want to test how the changes in 2 of the modules work against the published versions of the other 2 modules). Is that true, and if so, is it worth mentioning?
It might also be useful to have something like ‘go work status’ (however it might be spelled) that gives an easily digestible summary.
You received this message because you are subscribed to the Google Groups "golang-tools" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-tools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-tools/6AD3EEE7-E509-4FBC-8664-5E24833AD6DD%40gmail.com.
I used to have GOPATH=/globally-cached/go-deps:/personal-tinkering/go-devs:/team-tinkering/go-pkgs, works perfectly well with organization-wide shared filesystems. And I hesitate to pickup further development of my rusted Go projects at this time, just because go.mod is the right way to go, but it still lacks sufficient support rival to my historical workflows with GOPATH like that.
I had been and still am missing Go ever since switched to Haskell a couple of years ago, Go tooling is always the most pragmatic one to my experience, (but I need more powerful abstraction tools there plus the M:N scheduler of GHC RTS as well as Go offers). But w.r.t. the "project" thing, I realize that both Haskell build tools, namely Cabal and Stack, got it right beyond modules and packages.
Situation wrt building tools are even messier and more confusing to outsiders in the Haskell ecosystem, but this stackoverflow answer may explain why "project" is important (as well as to Gophers): https://stackoverflow.com/a/49776281/6394508
Note: I would suggest you replace "package" as heard from a Haskeller, with "import-root" in your Gopher's mind for clearer understanding. I realize that Java might have started use "package" this way even before Go, that's apparently not wrong. But when you talk about "package" and "module" to Haskellers, or Python guys, the terminology can be a source of confusion.
> The *.cabal file is the package-level configuration. ... This configuration provides essential information about the package: dependencies, exported components (libraries, executables, test suites), and settings for the build process (preprocessors, custom Setup.hs). ...
> The stack.yaml file is the project-level configuration, which specifies a particular environment to make a build reproducible, pinning versions of compiler and dependencies. This is usually specified by a resolver (such as lts-11.4).
> stack.yaml is not redundant with package.yaml. package.yaml specifies what dependencies are needed. stack.yaml indicates one way to consistently resolve dependencies (specific package version, and/or where to get it from, for example: on Hackage, a remote repository, or a local directory).
> stack.yaml is most useful to developers: we don't want our build to suddenly break because a dependency upgraded while working on another project, hence we pin everything with stack.yaml. This file is less useful to users, who may have external constraints (typically, versions are already fixed by some distribution).
Release engineering/management concerns had driven a gang of Haskellers to have created [Stackage](https://www.stackage.org), it recruit curators to work on nightly snapshots of the central registry/repository of Haskell packages (https://hackage.haskell.org), making sure all packages are vetted (compiles, passing test suites, etc.) then regularly release such snapshots as [LTS Haskell](https://github.com/commercialhaskell/lts-haskell#readme). [Stackage Curators](https://github.com/commercialhaskell/stackage/blob/master/CURATORS.md) are great people and smart CI tools making all that happen.
I do think it's okay if all modules in a local `go.work` are engineered in a lock-step fashion, but for wider collaboration among upstream/downstream projects (inevitable for open source development), I don't think that solvable by a simple tool. More intensive processes/workflows with dedication of human forces might be inevitable, and https://www.snoyman.com/blog/2018/11/why-i-believe-stackage-succeeded may provide an illustration for what it will look like after done right.
Best regards,
Compl
Thanks Michael! For working on this.Your proposal looks exactly like what I would wish for, I like https://github.com/golang/go/issues/44347 the most before seeing your proposal, but now yours is my most favorite.
I'm repeating something I've commented on a few GH issues (especially https://github.com/golang/go/issues/27542#issuecomment-820425053) here, but intend to show my support and in hope to be any help if possible.
I used to have GOPATH=/globally-cached/go-deps:/personal-tinkering/go-devs:/team-tinkering/go-pkgs, works perfectly well with organization-wide shared filesystems. And I hesitate to pickup further development of my rusted Go projects at this time, just because go.mod is the right way to go, but it still lacks sufficient support rival to my historical workflows with GOPATH like that.
I had been and still am missing Go ever since switched to Haskell a couple of years ago, Go tooling is always the most pragmatic one to my experience, (but I need more powerful abstraction tools there plus the M:N scheduler of GHC RTS as well as Go offers). But w.r.t. the "project" thing, I realize that both Haskell build tools, namely Cabal and Stack, got it right beyond modules and packages.
Situation wrt building tools are even messier and more confusing to outsiders in the Haskell ecosystem, but this stackoverflow answer may explain why "project" is important (as well as to Gophers): https://stackoverflow.com/a/49776281/6394508
Note: I would suggest you replace "package" as heard from a Haskeller, with "import-root" in your Gopher's mind for clearer understanding. I realize that Java might have started use "package" this way even before Go, that's apparently not wrong. But when you talk about "package" and "module" to Haskellers, or Python guys, the terminology can be a source of confusion.
> The *.cabal file is the package-level configuration. ... This configuration provides essential information about the package: dependencies, exported components (libraries, executables, test suites), and settings for the build process (preprocessors, custom Setup.hs). ...
> The stack.yaml file is the project-level configuration, which specifies a particular environment to make a build reproducible, pinning versions of compiler and dependencies. This is usually specified by a resolver (such as lts-11.4).
> stack.yaml is not redundant with package.yaml. package.yaml specifies what dependencies are needed. stack.yaml indicates one way to consistently resolve dependencies (specific package version, and/or where to get it from, for example: on Hackage, a remote repository, or a local directory).
> stack.yaml is most useful to developers: we don't want our build to suddenly break because a dependency upgraded while working on another project, hence we pin everything with stack.yaml. This file is less useful to users, who may have external constraints (typically, versions are already fixed by some distribution).
Release engineering/management concerns had driven a gang of Haskellers to have created [Stackage](https://www.stackage.org), it recruit curators to work on nightly snapshots of the central registry/repository of Haskell packages (https://hackage.haskell.org), making sure all packages are vetted (compiles, passing test suites, etc.) then regularly release such snapshots as [LTS Haskell](https://github.com/commercialhaskell/lts-haskell#readme). [Stackage Curators](https://github.com/commercialhaskell/stackage/blob/master/CURATORS.md) are great people and smart CI tools making all that happen.
I do think it's okay if all modules in a local `go.work` are engineered in a lock-step fashion, but for wider collaboration among upstream/downstream projects (inevitable for open source development), I don't think that solvable by a simple tool. More intensive processes/workflows with dedication of human forces might be inevitable, and https://www.snoyman.com/blog/2018/11/why-i-believe-stackage-succeeded may provide an illustration for what it will look like after done right.
Best regards,
Compl
On Thursday, April 15, 2021 at 10:30:18 AM UTC+8 mat...@golang.org wrote:Hello!I've put up a draft design for a new workspace mode in the go command to be used when working on multiple modules at the same time. It's here: https://go.googlesource.com/proposal/+/refs/heads/master/design/draft-workspace.mdI introduced it at the tools call earlier today, but didn't say anything that's not in the doc. (and the doc's gotten better editing than my remarks on the call!)It's not quite ready for a proposal yet, but I wanted to see what y'all think about it, so please feel free to discuss and leave any comments here!Thanks!Michael
--
You received this message because you are subscribed to a topic in the Google Groups "golang-tools" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-tools/0HfA1HWaTJY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-tools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-tools/24b8869f-35e1-4df3-8cc6-4f2e2eb3d535n%40googlegroups.com.