Hacker News new | ask | show | jobs
by orf 2420 days ago
I’ll leave it to someone else to explain to you how a .gitmodules file or a source tarball URL with a hash is a lockfile equivalent, or how “c, c++” isn’t a package manager, or how Debian do intact use several methods or specifying locked dependencies in a file format (a lockfile, if you will).

Most build environments do have lockfiles. And, just to clarify, that doesn’t have to be a specific dedicated file. It has to be something that can be versioned alongside the code, so each build gets the exact same set of dependencies and updates are explicit commits.

This basic principle is a requirement for anything serious (I.e something with customers). I’m sorry that this statement hit a nerve for you, but it’s true. In fact in some industries it’s a legal requirement.

And no, a dodgy third party plugin that hasn’t been updated in a year isn’t a good solution.

1 comments

You missed the /s sarcasm tag in my post. You can, in fact specify specific versions for conda without any external plugins and people who are serious about their build being reproducible do.

In fact, they also specify a specific gcc for extensions that need it, because relying on the system gcc is not reproducible. How do you do it in pip/vent/pipenv/poetry?

Specifying first-level versions is not the same as a lockfile and does not ensure you have the same tree of dependencies each time, and is no way to ensure that your builds are reproducible. I'm not sure you're clear on exactly what a lockfile is, but the problem it solves is this:

You depend on `cool-package==1.0`. That depends on `another-package` with a loose specifier, i.e `another-package=LATEST`.

Now when `another-package` is updated you suddenly have a different tree of dependencies, because the package resolution is run again and `another-package=LATEST` is installed. Imagine you're in the middle of rolling back (or rolling out) a deploy to your product. Suddently what you've been testing and working with has changed, and `another-package=LATEST` breaks the deploy due to some changes or bugs.

What's worse is that it's now harder to roll back, as a re-build and a re-deploy will still bring in the broken `another-package=LATEST`!

The solution is to lock the tree of dependencies, including all sub-dependencies. This has the advantage of speeding up installation as resolution doesn't need to happen. So, your package tree is locked to:

    cool-package==1.0
    another-package==0.1 # Non-broken!
That makes any updates to your packages safe, versioned and able to be reverted.

The lack of this feature makes Conda a no-go for anything serious.

> specific gcc for extensions that need it, because relying on the system gcc is not reproducible

apt install gcc:4:4.9.2-2

I'm not sure why you think conda doesn't support that. You might want to look at [0] specifically the section titled "Building identical conda environments", and at the documentation for "conda list --export --md5" and "conda list --explicit" (and if you don't use pip also "conda list --canonical") which all do exactly that, and which can all be fed back to start a new environment.

Also "conda env export", which adds some more documentation; In fact, all defaults list explicit versions of packages. The only way you can list installed packages without it is "conda env export --from-history", which will reproduce the non-version-annotated list.

So, yes, you don't have a "requirements.txt" and a specific lockfile maintained on disk; instead, conda manages it, and if you want it in source control (and you likely do), you need to make sure your local pre-commit hook runs the export. But everything is indeed reproducible, without any additional package needed.

> apt install gcc:4:4.9.2-2

Ok, so your ci (and everyone) must be root / fakeroot; and you somehow have to manage that outside your requirements.txt and lockfile (e.g. in a pre-commit or post-checkout hook). And you can't have more than one at the same time on the same system (so your ci must have different containers/vms to build two executables with conflicting requirements, even if they are part of the same project). And you can't do it on Windows or Mac at all (whether root or brew user or whatever).

From every possible aspect, Conda is much, much more suited for reproducible and well defined builds. It does it differently than managers using lockfiles; But it definitely does it, and more completely.

p.s. conda also has "conda list --revision" which shows you the entire history of version updates. Very useful for troubleshooting, even if not strictly required.

[0] https://docs.conda.io/projects/conda/en/latest/user-guide/ta...