4 ms·
> The issue Sam called out about handling the case where someone isn't following the spec. This can be on purpose or by accident. It's not uncommon to find it.
by 49bc 8y ago
> The issue Sam called out about handling the case where someone isn't following the spec. This can be on purpose or by accident. It's not uncommon to find it.
This is a common occurance. So common - in fact - that I think it’s almost always better to either pin everything or nothing and hope the unit test will find any breaking behavior.
- mfer 8y agoThis is a slightly tangential issue to pinning. With MVS and vgo you cannot set a maximum version. When the resolver walks the tree it doesn't know when a version is too new and could break things. Even if it pins it could pin an incompatible version. Maximum version information is not communicated. Note, I'm the posts author.
- kardianos 8y agoMatt: > This is a slightly tangential issue to pinning. With MVS and vgo you cannot set a maximum version. When the resolver walks the tree it doesn't know when a version is too new and could break things. Even if it pins it could pin an incompatible version. This just isn't true. The number you put in the go.mod file can't encode the max version: true. But it won't change underneath you so when you run "vgo list -m" and determine the solved version, it won't change from that.
- mfer 8y agogo.mod isn't a lock file. It doesn't contain the entire dependency tree the way other lock files do unless you choose to track, at the top level, the entire dependency tree yourself. There aren't tools to prune or update that for changes in the underlying transitive dependencies, either. It's not a lock and from what I gather from Russ not intended to be. The solved version doesn't mean it's the right or even a compatible version. This issue here is no maximum version meaning it could solve for an incompatible version due to not having all the information about the complete tree.
- kardianos 8y agogo.mod paired with MVS effectively locks versions into place. It must be computed, but it effectively locks all versions into place for reproducible builds. > It's not a lock and from what I gather from Russ not intended to be. go.mod files lock versions into place. If you disagree read the code / design documents. I find it dishonest to say something technically true "It's not a lock [file]" and yet not be true, as it together locks versions in place.
- mappu 8y ago> it effectively locks all versions into place for reproducible builds Assuming git tags don't move.
- andrewchambers 8y agoModverify is optional and detects that.
- jitl 8y agoYou're right, MVS is deterministic without a lockfile, which is what you're asserting it solves. The issue it does have is one where a transitive dependency is known bad by one of your immediate dependencies, but there's no way to declare that to the resolver. Here's a concrete case: 1. I depend on cool-framework, min 1.5.0 2. I depend on boring-library, min 1.0.0 3. cool-framework depends on boring-library, min 1.0.0 4. cool-framework receives bug reports that boring-library 1.5.0 breaks cool-framework. 5. I upgrade boring-library to min 1.5.0. Everything builds and tests okay, but I get breakage in my staging env. There wasn't non-deterministic package install behavior, but I still ended up with breakage that could have been prevented after (4) in a system that allows library dependencies to articulate more complex version constraints than "min version". In Rubygems or Python, with or without a lockfile, cool-framework could update its dependency on boring-library to specify "min 1.0.0, less-than 1.5.0" until the breakage is fixed.
- infogulch 8y agoOk so what happens when boring-library v1.5.1 is released that fixes the breakage, right after the maintainer of cool-framework goes on vacation? Now you have the opposite problem: you can't update to a perfectly compatible version because one of your dependencies can enforce arbitrarily complex constraints on which libraries you can include. Now the problem isn't a simple "oops gotta revert the upgrade until later" which either library can fix, now the issue is that one of your dependencies is blocking all upgrades for (now) no reason. There are problems either way. I think the other benefits that MVS enables is worth choosing one of these problems over the other. Edit: As mentioned upthread, vgo supports exclusions for the top-level module. This doesn't directly help here currently, but what if exclusions in dependencies produced a warning of a possible incompatibility instead? I think that would solve the issue of you not knowing that an upgrade could break things.
- zenhack 8y agoI think a pretty good spot in the design space would be to respect specified incompatibilities with specific versions, but not ranges. Maybe even require a comment attached to the incompatibility constraint, which would explain the problem. Bugs happen, and users should have some tools for that situation, but if a library is repeatedly releasing one broken version after another, you probably just shouldn't use it.
- bennofs 8y agoPinning does not solve this. You still need a solver to generate new pin versions or update the pinned versions. Or do you manually pin/update each of the dependencies (including transitive ones)?
- reidrac 8y agoYes: the transitive dependencies is the big problem here, and a hard one to solve. I can handle direct dependencies manually, more or less, because that's the code I'm using directly and I know what are my requirements. But then I'm mostly clueless regarding dependencies of my dependencies, and if those aren't pinned by the project that is using them directly, all sort of bad things can happen. And this is why I love Linux distributions so much: they've been solving this problem for a long time. Whenever I can, between using upstream or a slightly older version maintained by my distro, I choose the latter.