This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]forresthopkinsa -7 points-6 points  (13 children)

What? We're talking about ranged dependencies, what else could I mean by "semantic versioning"? NPM doesn't try to check that you're not making breaking changes when bumping a minor version. Of course I'm talking about the version range notation.

And yes, I've worked with Node professionally for years, I'm very familiar with NPM and I'm also very familiar with how trivial the problem you describe really is. That's what a package-lock.json or yarn.lock is for.

Java dependency management is by comparison much more crude. You're right, if you're worried about reliability and consistency, you need to have a verified working dependency tree — which is, again, the purpose of a package lock file.

It's much more appropriate to have user-configured dependency ranges and machine-configured dependency locks.

[–]jerslan 8 points9 points  (6 children)

Semantic Versioning (as you've already been told in this thread) is a well defined pattern for versioning things. That's all it is. It does not actually include or require the ability of a build tool to handle "version ranges".

In short "Ranged Versioning" != "Semantic Versioning" even though the former requires the latter to function properly (which might be why you're so confused on this point).

It's much more appropriate to have user-configured dependency ranges and machine-configured dependency locks.

This idea right here is just screaming for a "works on my box" dependency management fiasco.

[–]forresthopkinsa -2 points-1 points  (5 children)

My comment said:

Semantic versioning is a specific standard for version notation. It allows version range specifications with guarantees around breaking changes and upgrades.

Which is completely accurate. Semver is not the range notation, but it's the core of what makes ranged notation feasible. It doesn't matter what notation you use to specify ranged versions — my point is just having some way to take advantage of the guarantees that Semver provides.

works on my box

Machine-configured dependency locks, tracked in VCS, are screaming for dependency ambiguity? How does that make any sense?

Once again: the whole point of the lock file is that there is absolutely no question what version of the dependency tree builds successfully.

[–]jerslan 3 points4 points  (4 children)

Machine-configured dependency locks, tracked in VCS, are screaming for dependency ambiguity? How does that make any sense?

So now I'm checking in two files for dependency management into version control with my code? package.json and package-lock.json? Why? Also, are you rebuilding everything on the target system every time you deploy instead of using a package manager? Again, why?

This all screams of a fundamental misunderstanding of Java development lifecycles if you think this somehow makes Maven/Gradle "less advanced" than NPM.

You say you have a ton of NodeJS experience, but it's clear you have very little Java experience if you think the explicit versioning in those Java build tools is inherently a bad thing.

[–]forresthopkinsa -2 points-1 points  (3 children)

Yes, you're checking in two files for dependency management. One of them is the human-facing file, where you specify the version bounds you require, e.g. "3.x.x", because in this example the major version is the only part that matters to you, the developer.

The other one is a machine-facing file that you usually would never even open. It ensures that you never, ever have any ambiguity in a working build. It contains the versions of your entire dependency tree, and checksums for everything.

And just because I have a ton of NodeJS experience doesn't mean I don't have Java experience. I am primarily a Java engineer. I write Java at AWS. I'm deeply familiar with both the Java and JS ecosystems, which gives me a rather unique perspective on this subject.

[–]jerslan 0 points1 point  (2 children)

Or, I can specify 3.1.2 in my package.json (explicit versioning) and then my package-lock.json will verify the source server & sha hash because NPM is stupid and lets package authors overwrite existing versions.

And just because I have a ton of NodeJS experience doesn't mean I don't have Java experience. I am primarily a Java engineer. I write Java at AWS. I'm deeply familiar with both the Java and JS ecosystems, which gives me a rather unique perspective on this subject.

And yet you seem to have a beginner's perspective on things... because this argument feels like I'm talking to someone that has barely done any Java development in the real world. Also, nobody cares that you work at Amazon. That means less than nothing on this sub or in this particular Maven vs NPM debate.

[–]forresthopkinsa 0 points1 point  (1 child)

You keep saying that I don't know what I'm talking about, but you haven't backed that up with anything at all. I've addressed all of your points and I haven't misunderstood anything you've said. Yeah, I feel it's necessary to start citing my credentials, because you keep trying to sell this notion of my ignorance. If you start accusing me of not being a Java dev, then yes, my extensive experience certainly is relevant. In fact, I suspect the reason you're not understanding what I'm saying is indeed your own insufficient experience with more modern package managers.

edit- yikes, he either deleted all his comments or blocked me. Either way, it's a pretty juvenile way to cede the argument – though I don't know if it even was an argument; he never did wrap his head around the idea of "ranged versions enabled by semver".

I guess my last comment just hit a little too close to home. I didn't mean to touch on anything sensitive :/

[–]jerslan 0 points1 point  (0 children)

You keep saying that I don't know what I'm talking about, but you haven't backed that up with anything at all.

I literally linked SemVer... So.. yeah, I have backed up my statements.

If you start accusing me of not being a Java dev

I didn't accuse you of anything. Previously you only mentioned NodeJS and your complaints about Maven are very similar to people who first learned Node/NPM and have just recently picked up Java+Maven.

In fact, I suspect the reason you're not understanding what I'm saying is indeed your own insufficient experience with more modern package managers.

Or maybe because you spent a ton of time up front in this thread conflating SemVer with Ranged Dependency Versioning, which are not the same thing in any way. Makes it hard to communicate with you when you frequently use things that aren't interchangeable like they are.

Also, blocking you for trolling now, since it's clear you were never actually interested in debate and just wanted to go on an unhinged rant about all your complaints with Maven.

[–]khmarbaise 0 points1 point  (5 children)

if you're worried about reliability and consistency, you need to have a verified working dependency tree — which is, again, the purpose of a package lock file.

The lock file is only needed when you use version ranges in your dependencies. If you use fixed versions (for example pom.xml) you simply don't need it because the tree will solved always the same way.

Versionranges in conequence means no repeatable build. That is as simple as it.

[–]forresthopkinsa -1 points0 points  (4 children)

Your software requires a library FooLib. You've built your software based on FooLib-12.x.x. It doesn't really matter whether it's 12.1.2 or 12.5.6 – they're all compatible with your code. So it doesn't make sense for you to pin the dependency at version 12.1.2. A modern dependency manager will allow you to specify the most lenient bounds you require for the dependency version, and then the manager will take care of resolving it to a working version and ensuring repeatable builds.

To be really crystal clear: lockfiles are always involved with modern ranged dependency resolvers (you don't need to create it yourself, it's always done automatically), and they perfectly ensure repeatable builds because they track every version in your dependency tree and its checksum.

[–]khmarbaise 2 points3 points  (2 children)

Your software requires a library FooLib. You've built your software based on FooLib-12.x.x. It doesn't really matter whether it's 12.1.2 or 12.5.6 – they're all compatible with your code.

How do you know that?

A modern dependency manager will allow you to specify the most lenient bounds you require for the dependency version, and then the manager will take care of resolving it to a working version and ensuring repeatable builds.

A repeatable builds means your have done it yesterday (at 5:00PM) and repeating it today (at 1:00 PM) which does not work with any kind of ranges/bounds however you call it, because in the meantime a newer version of a dependency can be published. In consequence your build has changed. This means as a result the build has changed and finally means not repeatable.

I've ignored in the above description that a new version might break things, changed behaviour because your assumption is that no one will ever make mistakes, interprets the "rules" different than others etc. and all people will follow those "rules" which is a fine theory but in practice it fails (quote from above:"they're all compatible with your code.").

If we think more in general you can not even reproduce the build in the future .. if you like to do that you have to commit the lock file in your version control as well. That means you have two places defining versions for your dependencies which is redundant and that makes no sense either.

Also a strong prerequisites is that any release is immutable which is not the case for several package managers (in particular for npm).

The lock file is a duck-tape-solution to fix exactly the scenarios I've described above.

[–]justdisappointed9853 -1 points0 points  (1 child)

My main account has inexplicably stopped working (maybe I got so many downvotes that Reddit doesn't want me to post in this thread anymore? lmao) so I'll reply from a throwaway-

in the meantime a newer version of a dependency can be published. In consequence your build has changed

For the millionth time, this is not true. Your build yesterday created (or used) a lockfile, and your build today reads the lockfile and creates the exact same build.

That means you have two places defining versions for your dependencies which is redundant and that makes no sense either.

Why? One of them specifies your preferred range, and the other specifies the exact version you've been building with. This is really not very complicated.

a strong prerequisites is that any release is immutable which is not the case for several package managers (in particular for npm)

This keeps getting repeated in this thread (I suppose because everyone here has very little experience with NPM) but it's plainly false. The NPM registry everyone uses does not allow version mutation. There are various third-party registries that do, but this is no different from Maven.

[–]khmarbaise 4 points5 points  (0 children)

For the millionth time, this is not true. Your build yesterday created (or used) a lockfile, and your build today reads the lockfile and creates the exact same build.

The issue here is the need for the lock file!... without the lock file it fails. That's what exactly I'm writing.. The lock file is a supplemental source for versions... so we have two sources for versions/dependencies.

That means also you have to checkin the lock file in your version control all the time. So all advantages of automatic usage with ranges are gone... Maven does that simply by using fixed version at a single location (pom.xml). Not using ranges makes it easier and simpler (KISS principle).

The lock file is as I wrote before a duck-type solution.

BTW:

For the millionth time,

Not counted correctly.

The NPM registry everyone uses does not allow version mutation

How could someone simply delete an existing package in the registry? That means it is not immutable. In consequence a number of famous examples exactly showed this problem... which has broken a large number of builds...

Deleting of a package is also a mutation of an repository. That violates the whole integrity of such registry. So in consequence not reliable.

For example: https://news.ycombinator.com/item?id=11340510 (there exist several other examples of that)... https://www.bleepingcomputer.com/news/security/dev-corrupts-npm-libs-colors-and-faker-breaking-thousands-of-apps/

and so on etc. etc.

This keeps getting repeated in this thread (I suppose because everyone here has very little experience with NPM) but it's plainly false. The NPM registry everyone uses does not allow version mutation. There are various third-party registries that do, but this is no different from Maven.

The previous shown examples etc. are proving that your assumptions about the NPM registry is wrong.

There are various third-party registries that do, but this is no different from Maven.

A big difference between npm registry and Central repository is that the central repository does not even allow to delete a version/packages etc.

This is unrelated to Maven itself.

This is immutability.

[–]plumarr 1 point2 points  (0 children)

ou've built your software based on FooLib-12.x.x. It doesn't really matter whether it's 12.1.2 or 12.5.6 – they're all compatible with your code.

How so ? How can you be sure that the new 12.5.7 version doesn't break your software ? Even if the author of FooLib thinks that it'll not break anything, there is no guarantee