Live data from Hacker News

Using Go Modules

blog.golang.org

41–50 of 124 posts

Re: Using Go Modules

#41
post #35

Every mainstream programming language that came out in the last 20 years has already solved this. Java, Javascript, Ruby, Python, Rust, you name it. I am baffled to why Go has not figured this out and are presenting recent developments as some kind of breakthroughs - they are not. To me, and I'm not trying to be disrespectful here, because of the shortcomings it has, Go is in the experimental/keep an eye on bucket. I…

I never had any issues with the GOPATH and vendor approach, but I have experience with using a huge monorepo, so I never had expectations that it would be any different.

But go mod is great, and it is very different than cargo, pip, npm, etc. I don't think they are claiming it's a spiritual revolution, but it solves the problems people who needed traditional package versioning where having in an elegant and Goish way.

Go is also far from experimental. It has areas where it could be better, but it's a panacea compared to writing Java in an IDE with Maven for a living.

Re: Using Go Modules

#42
All I wanted was a way to safely and easily cleanup my $GOPATH. I don't have a lot disk space and $GOPATH takes up most of it.

This thing apparently doesn't solve my problem. `go mod tidy` simply removes a dependency from a module, but that dependency is still cached in a big arcane directory at $GOPATH/src/mod. Why?

I think we all should be using something like Nix for dependency management that solves all problems, but that is so hard to setup!

Re: Using Go Modules

#43

Earlier quoted context omitted.

For a single module, there is a "replace" directive that you can use to point to a local fork: https://github.com/golang/go/wiki/Modules#when-should-i-use-... But if you have an internal version that's used in lots of modules, it's probably better to use an import path under your own organization, to avoid confusion.

Does this account for the scenario where you have a dependency of a dependency? For example, if I'm patching a bug in something that several of my upstream dependencies import, do I have to fork/replace everything in that chain to get it to do the right thing? Debian packages can Replace each other too, and that's certainly an option for managing this scenario, but I feel it's often more disruptive— it's a much more…

Not an expert (I just read the docs), but if you only have one binary that you ship, or all your binaries are in the same module, then it looks like a single "replace" directive will do the right thing.

If your binaries are spread across multiple modules, each one would need its own replace directives, so you'd have a bit of duplication. (But maybe this independence is good, since you can upgrade them one at a time?)

If you're publishing a library and don't control the binaries (this is something your customers build) then it looks like "replace" isn't going to work (it's under their control, so they have to do it). If you need to control the exact versions used by your library, you'll want to look into vendoring.

Re: Using Go Modules

#44
post #40

"the go command automatically looks up the module containing that package" Looks up where? GOPATH? The tree below the current file? The current directory? What's the "current module", anyway? Where is that stored? "go: downloading rsc.io/sampler v1.3.0" Downloading from where? Github? From what repository? The page for "go get" now talks about "module-aware" mode, but doesn't make it clear how that works. This is the…

> There's some specific directory layout required, and you have to know what it is

No you don't. If it supposedly works, why would you care where these modules end up in when they are downloaded? There's currently no indication that you need to be aware at all of whatever directory layout the module system needs, as it takes care of it automatically.

Finally, the article does actually mention where the modules are downloaded:

> ... the downloaded modules are cached locally (in $GOPATH/pkg/mod)

Re: Using Go Modules

#45
post #40

"the go command automatically looks up the module containing that package" Looks up where? GOPATH? The tree below the current file? The current directory? What's the "current module", anyway? Where is that stored? "go: downloading rsc.io/sampler v1.3.0" Downloading from where? Github? From what repository? The page for "go get" now talks about "module-aware" mode, but doesn't make it clear how that works. This is the…

> from where?

Given that the import paths are URL-ish, I personally find it fairly obvious where things are coming from - far more so than any other language/dependency manager I've worked with. That's something unchanged with go modules vs GOPATH.

Re: Using Go Modules

#46

I'm not an active golang user, but something which gives me pause here is the insistence on a strict 3-number semver. For a commercial entity shipping software which may include upstream components, it's important to have options for maintaining (and versioning) in-house forks of upstream components. This becomes a problem when you fork v1.2.3 from upstream and want to internally release your fixes, but now your inte…

This has never been a problem in Go, the repo name encodes the owner of a fork, and two separate repo paths with the same version are still completely different modules. The nice thing about not doing what debian does is that there is consistency. Freeform usually means diverging opinions, which is not the Go way.

I believe parent's question was: Yes, you will have different repo names. But there is sub version pinning. i.e. The first patch of v1.2.3 is called v1.2.3.1 (or v1.2.3-1 or something). Then the repo itself will evolve, and keep publishing v1.2.3-2, v1.2.3-4 and so on.

Patched versions are "sub" versions of the main version, and those sub versions also keep evolving for the same upstream version.

Re: Using Go Modules

#47
post #40

"the go command automatically looks up the module containing that package" Looks up where? GOPATH? The tree below the current file? The current directory? What's the "current module", anyway? Where is that stored? "go: downloading rsc.io/sampler v1.3.0" Downloading from where? Github? From what repository? The page for "go get" now talks about "module-aware" mode, but doesn't make it clear how that works. This is the…

> What's the "current module", anyway? Where is that stored?

The article uses "current module" like you might use "current git repository"; it's the module containing the directory that you are currently `cd`ed to. Just as git identifies the repo by looking for `.git` in successive parent directories, go identifies the module by looking for `go.mod` in successive parent directories.

> > "go: downloading rsc.io/sampler v1.3.0"

> Downloading from where? Github? From what repository?

From the same place that non-module-aware `go get` downloads it. The only difference on the "remote side" of that from old `go get` is that it grabs the `v1.3.0` git tag, instead of git HEAD; if you don't specify a version it grabs the most recent `vSEMVER` git tag instead of git HEAD.

> > "the go command automatically looks up the module containing that package"

> Looks up where? GOPATH? The tree below the current file? The current directory?

Looks it up on the network, à la `go get`. Exceptions:

- The `replace` directive in your `go.mod` can manually override where it looks up a specific package.

- Telling Go `-mod=vendor` will have it look up all depended-upon modules in `vendor/`, rather than via the normal mechanisms; you can create the `vendor/` directory with `go mod vendor`.

It doesn't use the network every time; a module cache lives in `${GOPATH:-${HOME}/go}/pkg/mod/`; but you don't need to know that any more than you need to know that a build cache lives in `${GOCACHE:-${HOME}/.cache/go-build}`.

> There's some specific directory layout required, and you have to know what it is.

Not really, the only requirement is that you have a `go.mod` file that identifies a package name for the directory that it's in. So that if I have github.com/lukeshu/foo, it just needs a `go.mod` saying

    module github.com/lukeshu/foo
instead of having the requirement that it be checked out to `$GOPATH/src/github.com/lukeshu/foo`. Beyond having the `go.mod` file, there aren't really any structure requirements.

> This article needs to be more explicit about that.

Does it, though? It's a blog-post, not the "normal" documentation. The full docs are much more explicit and nitty-gritty than a high-level blog post.

Re: Using Go Modules

#49
post #9

I've been using Go modules, and I really like them. It's obvious they really paid a lot of attention to backwards compatibility. Being able to vendor using mod is really awesome, as well as see all your transitive dependancies automatically. It's very goish to focus on minimizing your dependancies and actually think about what you're pulling in. I'm not yet sure how I feel about the v2+ stuff. Having a separate modul…

It does not put modules in GOPATH, at least not where you'd normally find them. Pre-modules github.com/foo/bar would be in $GOPATH/src/github.com/foo/bar. Now they are in $GOPATH/pkg/mod/... (... being based on the URL with some handling for versions and characters that don't work well in filesystems, I don't know the exact details). The main problems I've had with go modules are fast-and-loose upstreams that happily…

> The main problems I've had with go modules are fast-and-loose upstreams that happily rewrite history. go mod detects this and stops the world, and you have to manually edit go.sum.

This is really irritating. I have the same problem with TLS: every time a malicious actor tries to manipulate my connection and steal my cookies I get an error page and can't do online banking anymore!

Sarcasm aside: this is not a problem with Go modules. This is a problem with the libraries you're using and you should avoid those projects until they get their act together.

Re: Using Go Modules

#50
post #9

Earlier quoted context omitted.

It does not put modules in GOPATH, at least not where you'd normally find them. Pre-modules github.com/foo/bar would be in $GOPATH/src/github.com/foo/bar. Now they are in $GOPATH/pkg/mod/... (... being based on the URL with some handling for versions and characters that don't work well in filesystems, I don't know the exact details). The main problems I've had with go modules are fast-and-loose upstreams that happily…

That's what I meant, pkg is definitely in GOPATH. It's annoying because I can't put my code in src anymore, which is where I've been organizing it for years, but I still have to keep GOPATH around for bin and pkg.

Fair enough. I clarified because the days of editing code in some dependency of yours are over; it's not easily exposed for that purpose (but you can do it ;).
Post reply on HN