4 ms·
If you use the flake system (which is technically still experimental, but everyone is already using it anyway), all your flake 'inputs' are automatically pinned
by malmeloo 7mo ago
If you use the flake system (which is technically still experimental, but everyone is already using it anyway), all your flake 'inputs' are automatically pinned in a flake.lock file that can be committed to git for reproducibility. So if you add nixpkgs as a flake input, your nix expressions will always be referring to the same exact package versions until you update the lock file.
The downside is that flake inputs refer to other flakes, not individual packages, so if you update the nixpkgs input it will upgrade all of your packages at once. For some packages such as Python, nixpkgs tracks multiple major versions so you can loosely pin to that version. You can also include nixpkgs as an input multiple times under different git tags/commits and only use that input for some of your packages to effectively pin them. You could keep using one nixpkgs but override the package's source to build it for a specific version/commit, but this setup could break in the future, because the derivation (and therefore build instructions) will keep evolving while your package's version will not. Or, if you really wanted to, you could straight up just copy the derivation from nixpkgs into your local repository and use that instead.
Nix is quite flexible so there's more options than just these, it just takes a little getting used to to find out what's possible. I don't use devenv myself, but some quick googling reveals it works just fine with flakes, so I would try that to see if it suits your needs.
- foldr 7mo agoOk, but I guess a more concrete version of my question is the following: > How do I set up my development environment using devenv.sh to pin nodejs to 24.14.0? If I understand your response correctly, I can't do this in any very practical way.
- JamesSwift 7mo agoGenerally something like languages.javascript.enable = true languages.javascript.package = pkgs.nodejs_24
- foldr 7mo agoBut that doesn’t pin to a specific version?
- JamesSwift 7mo agoIt does, but its implicit (and so may not be the exact patch version you have in mind). See my other comment for how to handle if you _do actually care_ about pinning to a specific version explicitly.
- foldr 7mo agoDoesn't that pin me to a particular versions of nixpkgs? That's fine if I only care about nodejs, but if I want to maintain particular versions of different tools, it won't work.
- JamesSwift 7mo agoAgain, generally in other systems the full semver pinning is more of a crutch to get some 'reproducibility' that nix gives you out of the box at a much higher level. So, in general, people just pin to the major version in nix. But if you _really_ want the full semver pinning there are multiple options that I lay out in the other post. You can even patch the _actual nodejs source itself_ in reproducible/version-pinned ways.
- foldr 6mo agoI do want exact version pinning of individual packages. (As I said in my initial post, I’m aware that Nix advocates think that I shouldn’t want this.) I’m not sure what other post you’re referring to. There’s one where you describe some approaches in broad terms, but as far as what the relevant devenv.sh config would look like, I’m none the wiser.
- JamesSwift 6mo agoYou still are pinning to exact versions of packages (and in fact are pinning to specific shas / content hashes of the packages) but you are doing so implicitly by going this "path of least resistance". The only thing that will change what _exact sha_ you are pointed at is an explicit update by someone. There is no risk of someone running install on one box and someone running it on another and them getting different _exact versions_ (or likewise, in CI it also will be the exact same). And in general thats what people are trying to achieve on teams by pinning to full semver. So thats what I mean by its generally not needed on nix. However, to actually address your question it would be something like this (with ruby also added for comparison of whats possible depending on the language ecosystem you are using) ```devenv.yaml``` inputs: nixpkgs: url: github:cachix/devenv-nixpkgs/rolling nixpkgs-node: url: github:nixos/nixpkgs?rev=9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7 nixpkgs-ruby: url: github:bobvanderlinden/nixpkgs-ruby inputs: nixpkgs: follows: nixpkgs ```devenv.nix``` { inputs, pkgs, ... } { languages.javascript = { enable = true; package = inputs.nixpkgs-node.nodejs_24; }; languages.ruby = { enable = true; versionfile = ./.ruby-version; // alternatively // version = "3.2.4"; }; }
- Novosell 7mo ago24 != 24.14.0
- JamesSwift 7mo agoIf you care about the _exact version you are pinning_ (even though you will guarantee the pin between team members without needing to do this step), you can either pin nixpkgs repo to the state that had that version, source the target version directly, or for some ecosystems (eg ruby) you can just specify a version with a number and it has tooling to resolve that using "traditional" approaches. In general though when working on a team, you dont really care about the _exact semver version_, you care about the major and handle version bumps by bumping the pin of nix packages.