Hi all, This thread is hitting on a fairly important set of topics.
It certainly seems some additional brainstorming and community discussion about how things could or should work regarding multi-module workspaces would be beneficial. A file tree with a `go.mod` has been described as something like "a little GOPATH", but as has been observed, if you want to edit multiple modules simultaneously, you have to decide how you want to wire together those multiple "little GOPATHs". Manually adding `replace` directives is one approach to using local copies of related modules that you might be simultaneously editing. However, that can translate to many manual steps, especially if they are frequently added and removed. If you haven't already, it is definitely worthwhile to look at https://github.com/rogpeppe/gohack, which is a new community tool to automate and greatly simplify multi-module workflows and related `replace` directive workflows. It allows you to very easily modify one of your dependencies. For example, `gohack github.com/some/dependency` automatically clones the appropriate repository to your local disk and adds the necessary `replace` directives to your go.mod so that your build picks up the local copy that you can start editing. You could do this as part of a one-off investigatory workflow, or you could do `gohack example.com/foo example.com/bar example.com/baz` as part of your normal development setup if that makes sense for your workflow. When done, `gohack -u` removes all gohack replace statements (which can be done prior to committing). A related note is that community-based tooling for modules in general is starting to emerge. You can see an initial list here: https://github.com/golang/go/wiki/Modules#what-community-tooling-exists-for-working-with-modules Overall, it seems clear one of the intents of the modules system is to enable one-off or community-based tooling to be built on top of the core modules functionality, and often it can be done in a relatively straightforward manner. For example, there is whole section of the official documentation titled "Edit go.mod from tools or scripts" (https://tip.golang.org/cmd/go/#hdr-Edit_go_mod_from_tools_or_scripts). Some example capabilities for inspecting module configuration (which might be used to encode a sanity check, or to automate further tooling): * `go mod edit -json` outputs the current module's `go.mod` file in JSON format. * `go mod edit -json <path/to/go.mod>` outputs a particular `go.mod` file in JSON format. * `go list -m -json all` gives a JSON representation for the full set of modules available to a build, including the path to each `go.mod` file. (You can then feed each `go.mod` path to `go mod edit -json <path/to/go.mod>` to get the additional details for that `go.mod`). Some example capabilities for programmatically editing module configuration (which for example could support automating adding/removing `replace` directives to wire together multiple related modules for simultaneous editing of multiple modules): * `go mod edit -replace github.com/my/foo=../foo` adds a `replace` statement to use a copy of `foo` on the local disk. * `go mod edit -dropreplace=github.com/my/foo` removes all replacements for `foo` from the current `go.mod`. One of the concerns raised in this thread is that if you use a `replace` directive to point a module to a development copy of another module, someone might accidentally check that the `go.mod` containing the `replace` directive. To help guard against that (and as a simple example of one-off tooling that could be built on top of 1.11 modules), you could consider some type of pre-commit VCS check or CI check to validate that a go.mod does not have any development replace directives, such as something along the lines of: go mod edit -json | python2.7 -c 'import json, sys; assert json.load(sys.stdin)["Replace"] == None' (Sorry for slipping in a python one-liner; that was just to convey a simplified example. Obviously could instead be in Go, bash, jq, or whatever your preferred method might be). There are admittedly many different opinions on how to use git, but another approach to add and remove development-specific `replace` directives could be via something like the git smudge/clean workflow that lets you tweak things on checkout (e.g., add `replace` directives) but then automatically reverse the tweak when checking back in (to strip out development `replace` directives). Or perhaps something similar could be automated however might work best for your current workflows... A completely different approach could be to make the on-disk organization of your multiple modules always be the same in their development/environment/test/build/CI environment, and wire that together via replace directives that you do check in (in contrast to adding and removing replace directives for specifically for development). That is not something that would work for all projects, but perhaps something to consider. A small number of modules could be manually wired together like that via a one-time hand edit of the various `go.mod` files, or the actual edits to the `go.mod` files could be automated if there are many modules that would need to be touched. Overall, and setting aside any particular solution -- there are probably a few different timescales to think about regarding the topic of this thread and how multi-module workspaces should be set up: 1. What do people do immediately? (For example, based on manual workflows, or via small amounts of automation on top of 1.11 modules). 2. What might be done in community tools like `gohack` on top of 1.11? (For example, hopefully people can contribute ideas or pull requests to `gohack` or other existing efforts, or perhaps some people might start their own experimental module tooling repo, which might help flesh out a few different independent perspectives). 3. How could and should this all work in a 1.12 time frame? Part of the nature of the current on-going modules experiment is such that hopefully that near-term experience and community experimentation will help shape what happens in a 1.12 time frame. Stepping backing even further, though -- when it comes to multi-module projects, one key initial question to ask is how many modules do you want to create for a given project, including asking yourself what do you really need to version separately (given modules are defined as "the unit of source code interchange and versioning"). Especially to start as people ramp up on modules and as the community is working out different workflows, larger modules are likely easier than finer-grained modules, and one module per repo is definitely easier than multiple modules per repo. The official modules proposal is predicting "most projects will adopt a workflow in which a version-control repository corresponds exactly to a single module" (from https://golang.org/design/24301-versioned-go). That said, different people will have different preferences. Sorry for the long-ish comments, but I guess my broadest point would be that the topics raised in this thread do seem worthy of some thinking and discussion by the overall community... --thepudds On Monday, September 3, 2018 at 8:11:13 AM UTC-4, kortschak wrote: > > And here we have the problem. Low probability of error events do not > scale. > > On Fri, 2018-08-31 at 19:30 -0700, Jim wrote: > > Changes from the master/development go.mod will need to be carefully > > merged > > into release go.mod. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.