I have a project where I've specified a default.nix. I want to install a specific version of sqlite (and other packages) but cannot get it to work in the following manner. What is the correct way of specifying package version?
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
stdenv.mkDerivation {
name = "mylib";
buildInputs = [
sqlite_3_21_0
];
}
For most packages any given checkout of Nixpkgs contains only one version. When there are multiple versions, naming is somewhat package-specific…
@7c6f434c I am a newbie here but I believe that is untrue. The whole point of nix channels is to allow multiple versions of a package. Now if you meant at one in point in time I understand.
The issue as a developer is when coming back to a project with updated dependencies the project itself may break. There has to be a solution here or devs would never use nix, for long...
How can I specify the version, or search for hash of the version I want?
I know that one possibility is by pinning nix-channel, but then we still have no guarantees that the version of sqlite I install now will be the same as when the channel is finalized?
Well, it may seem paradoxical. https://nixos.org/nixpkgs/manual/#sec-versioning
_Technically_ nix does make it easier to have multiple versions/configurations of packages in a single /nix/store, but the reality is that the multiplicity makes maintenance harder, so in NixPkgs we do _not_ maintain more versions/configurations unless there's some reason for the particular package. (For example, we now have two openssl branches simultaneously.)
Still, you can probably make a _local_ copy of a package's expression and make it work as a different version. It might be just changing two lines, it might be more work. You may also find old expression versions in historical commits of NixPkgs...
Well, if you want to import Nixpkgs once, you get a single version. SQLite, by the way, is one of the projects I would trust not to mess things up during updates. You can import multiple checkouts of Nixpkgs with different versions (git log lists updates as «from -> to», so it is not that hard to find for needed points in time). _If_ an upgrade actually breaks the existing code, you can port the old version to the new Nixpkgs and add it with the name that includes version — what you suggest in the code block is a good name, yes. We add multiple versions when there is something that can be declared a good reason; compatibility breakage with a live human to complain is a good reason most of the time.
Guys, can you show me some code? I would usually do it myself but nix is a truly exoteric language.
I think the most practical way forward here is:
The point is that taking a version not in the current Nixpkgs is an esoteric operation. What is the library that provoked your question by causing breakage on update? Because SQLite is probably not it, and stuff like boost does have multiple versions (see pkgs/top-level/all-packages.nix
). If you want to pin everything, just read git log
output to find a point in time with good versions, checkout this revision and do not update it.
@7c6f434c So I pin nixpkgs and now I must use the particular version of all packages that it specifies, and I cannot override those versions? That just creates new problems. I need a way to set the version I want of any package.
It isn't about which package broke, no package broke I am just thinking ahead. This is about me coming back to dev in the future, or another dev cloning my project, running nix-shell, and discovering I have hours of work ahead of me debugging potentially esoteric issues because some package got upgraded. I could never recommend nix to my company with such possibilities, and I don't think the smart people that created nix could have missed such an obvious problem.
Noone forces you to follow master of nixpkgs. You may e.g. want to fork it, perhaps apply some local patches (to get desired versions) and only merge updates from master by hand (if you even care for them).
@vcunat Are you saying if I want a particular package version to find the nixpkgs channel hash that has the version I want, and pin my project's nixpkgs to that channel and go about it that way?
Why can't I just copy the nix definition for sqlite and import it in my default.nix? If I can how is it done?
@7c6f434c So I pin nixpkgs and now I must use the particular version of all packages that it specifies, and I cannot override those versions?
Well, you can have multiple Nixpkgs checkouts and import from them. You can have stdenv.lib.overrideDerivation sqlite (x: {src = …; })
to set a different source.
That just creates new problems. I need a way to set the version I want of any package.
It isn't about which package broke, no package broke. This is about me coming back to dev in the future, running nix-shell, and discovering I have hours of work ahead of me debugging potentially esoteric issues because some package got upgraded.
This is called breaking backwards compatibility, and some packages — say, SQLite — have good reputation about just not doing that.
Also, if you don't want anything to change, why not just pick a single revision of Nixpgks and not update it? Most of the fixes that happen are applied by just updating the package version anyway.
I don't think the smart people that created nix could have missed such an obvious problem.
Having more versions of the same package without mentioning any backward-compatibility violation has been explicitly discouraged multiple times, mainly by the original author of Nix.
There various ways. I don't feel like I know what exactly you want. For my usual dev-env it's perfectly OK to base on the "moving" stable channel, as that tries hard not to do any breaking updates – I just have a couple overrides atop (trying some newer versions, etc.)
How about this: Why can't I just copy the nix definition for sqlite and import it in my default.nix? If I can how is it done?
let sqlite_pinned = (pkgs.callPackage ./sqlite.nix { }); in …
— unless you also want to specify some of its dependencies, too, in which case you need to pass them as parameters (inside the braces)
@7c6f434c I think I clearly explained I just need a way to pin my package versions, individually. Clearly pinning nixpkgs will not work, at least the way that has been described thus far, because that pins all packages to the version set in nix-pkgs which may not be the version I want for all. Is there some disadvantage to this approach that explains why this wasn't your first answer?
"This is called breaking backwards compatibility, and some packages — say, SQLite — have good reputation about just not doing that."
I haven't specified a major version for sqlite in default.nix meaning nix is free to upgrade it whenever it can. Many projects follow semver - when the major changes the versions break. That's what everyone expects. Please explain why I'm wrong.
@7c6f434c As per docs use of overrideDerivation is discouraged.
Say I use the recommended approach:
sqlite = pkgs.sqlite.overrideAttrs (oldAttrs: rec {
name = "sqlite-3.21.0";
src = fetchurl {
url = "http://sqlite.org/2017/sqlite-autoconf-3210000.tar.gz";
sha256 = "1qxvzdjwzw6k0kqjfabj86rnq87xdbwbca7laxxdhnh0fmkm3pfp";
};
});
But hold on, there are build steps, compile options, and more that will come from the base sqlite derivation file that may not be the same across versions of the package. How do I reconcile that?
So the only option I see is copying the sqlite derivation in its entirety. Is this correct?
@7c6f434c I think I clearly explained I just need a way to pin my package versions, individually. Clearly pinning nixpkgs will not work, at least the way that has been described thus far, because that pins all packages to the version set in nix-pkgs which may not be the version I want for all. Is there some huge disadvantage to this approach that explains why this wasn't your first answer, or was I unclear in my request?
Well, Nixpkgs is developed without caring whether someone tries to import packages from multiple Nixpkgs revisions into a single build. This does work most of the time, so it is most likely that you can get a small set of checkouts and collect the necessary versions. Maybe a few overrides of src
will simplify the job. But nobody cares about that working, so it might be that your specific version combination is just unlucky, for example, if these versions fall on the different sides of a glibc
upgrade.
Just making a checkout close to your desired versions and manually copying definitions of the exact versions required is very likely to work, though. This checkout would be your private fork of Nixpkgs, but as you don't need updates, if it works once, there is nothing to break.
"This is called breaking backwards compatibility, and some packages — say, SQLite — have good reputation about just not doing that."
I haven't specified a major version for sqlite in default.nix. They follow semver - when the major changes the versions break. That's what everyone expects. Please explain why I'm wrong.
Major version of SQLite is the constant «3», likely forever, as SQLite4 has been attempted and cancelled.
More specifically, «In addition to "supporting" SQLite through the year 2050, the developers also promise to keep the SQLite C-language API and on-disk format fully backwards compatible. This means that application written to use SQLite today should be able to link against and use future versions of SQLite released decades in the future.»
@7c6f434c As per docs overrideDerivation is dicsouraged.
There are no non-discouraged way to do what you want with Nixpkgs. If this use case was supported, my attempt to keep previous version around on upgrades wouldn't have been purged (eight years ago or so).
But hold on, there are build steps that will come from the base file that may not be the same across versions of the package. How do I reconcile that?
Well, you can override these, too.
- Major version of SQLite is the constant «3», likely forever, as SQLite4 has been attempted and cancelled.
What about other projects that aren't sqlite and will do major version updates?
- More specifically, «In addition to "supporting" SQLite through the year 2050, the developers also promise to keep the SQLite C-language API and on-disk format fully backwards compatible. This means that application written to use SQLite today should be able to link against and use future versions of SQLite released decades in the future.»
What about other projects that aren't sqlite and don't provide such guarantees?
There are no non-discouraged way to do what you want with Nixpkgs.
Huh?
Well, you can override these, too.
Why wouldn't I just copy the file in the first place? If I do what you suggest then there is a chance it may not work on a system with a different version of sqlite that is used as the base nix derivation . nix is supposed to be reproducible, there is nothing reproducible about this approach other than the chance for failure.
What about other projects that aren't sqlite and don't provide such guarantees?
Well, for some of them we do have multiple versions because they are clearly needed.
There are no non-discouraged way to do what you want with Nixpkgs.
Huh?
Nixpkgs tries to have the minimal set of versions that generally covers the needs of building dependent software. The expected way is not to pick the exact version in advance, but to see which of the provided ones is good enough. If none is good enough, then one more version could be added to Nixpkgs, probably with a reference to an example of software that needs it in the commit message or pull request description.
Am I correct in saying that for nix channel 17.09, from its first release date on, is totally immutable? That the versions are fixed at the time of publication?
Nixpkgs tries to have the minimal set of versions that generally covers the needs of building dependent software.
It seems to me the sole reason for this philosophy is to save on compute costs - so that the main build farm doesn't have to build every version of every package known to man. However, why should we care? People can build old versions themselves. Aren't we significantly hurting ourselves with the restriction?
Am I correct in saying that for nix channel 17.09, from its first release date on, is totally immutable? That the versions are fixed at the time of publication?
No; say, Firefox updates will get backported for sure. In general, if an upgrade fixes a major data consistency bug or a vulnerability, and upstream says that it is most likely backwards compatible, the new version will replace the old one in stable.
It seems to me the sole reason for this philosophy is to save on compute costs
Well, as far as I understand it (I don't fully share the position I have described, but I have decided that continuing to oppose this policy is not worth the effort for me) there is also the question of triaging bug reports: if there are too many versions, there will be even more problems than there are now, and there will be a need to check for every bug report whether it applies only to a rare version combination of two packages, or only to a specific version of some package, or to the most popular versions too.
It seems to me the sole reason for this philosophy is to save on compute costs - so that the main build farm doesn't have to build every version of every package known to man. However, why should we care? People can build old versions themselves. Aren't we significantly hurting ourselves with the restriction?
No, it is about maintenance costs, as mentioned in https://github.com/NixOS/nixpkgs/issues/36266#issuecomment-370184402, which is not just compute costs but mainly labor costs (fixing expressions). A source of a package can be described by its version, but the build artifact depends not only on its source but also its build inputs. As also multiple versions of a build input could technically be used, supporting multiple versions of multiple packages will scale combinatorally.
Am I correct in saying that for nix channel 17.09, from its first release date on, is totally immutable? That the versions are fixed at the time of publication?
As @7c6f434c said, channels are not fixed. But the Git revisions are, you can just pin a specific commit of Nixpkgs to use, with the script here:
let
pkgs = let
hostPkgs = import <nixpkgs> {};
pinnedPkgs = hostPkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs-channels";
# nixos-unstable as of 2017-11-13T08:53:10-00:00
rev = "ac355040656de04f59406ba2380a96f4124ebdad";
sha256 = "0frhc7mnx88sird6ipp6578k5badibsl0jfa22ab9w6qrb88j825";
};
in import pinnedPkgs {};
in
stdenv.mkDerivation {
name = "mylib";
buildInputs = [
pkgs.sqlite
];
}
It's less work than copying the sqlite derivation over but has mostly the same effect. And this method allows combining different Nixpkgs checkouts, e.g. you could use sqlite of one revision and bzip2 from a different revision for example (just import pkgs2, pkgs3, etc.).
This is common request from newcomers. "You say, you can handle multiple versions of same packages, then provide me version XXX for package YYY"
Which later translates to: "Hell, why it's so complicated to get a package version I want, given multiple simultaneous versions for a package is a core feature of Nix?"
What can we do for such requests?
Improve docs for this kind of requests. I see the following topics should be added/improved:
git log --oneline YYY | grep XXX
, because some versions may be skipped, and user may want some closest available version apt-get
users. If user wants old package with newer deps, they should be pointed to another part of doccallPackage
there. The problems areoverrideAttrs
: replace src
with an old one, hoping that newer build expression will work for old src
. Problems:src
should be described (refer to one of previous methods and show how sha256
should be computed).src
isn't sufficient. Why? The package will contain package version for original src
, because derivation attrs do not form a fixpoint. So all attrs that refer to name
internally should be overriden too. This requires package expression inspectionWhat if there existed a function .overrideVersion
? Here is proposed API:
/* Try to get specified version of a package
If package version not found, it will print an error and closest available version.
*/
overrideVersion = {
# desired package version
version
# whether to fetch original dependecies for an old version. Actually, corresponds
# to "pin nixpkgs" way of fetching a package expression. When false, next parameter
# differentiates method further
, originalDependencies ? true
# whether to fetch original package expression. If originalDependencies == false,
# corresponds to fetch single expression method. If set to false, uses .overrideAttrs
# and optimistically assumes that only src, name and version should be changed
, originalExpression ? true
}: ...
Internally it should use a "package" -> "version" -> "checkout" mapping. Sort of index.
Because .overrideVersion
most likely requires IFD, it is possible to build index
locally, but maybe it's possible to build it centralized each month and distribute as
package. Because the index should be written in Nix (or JSON), we still have to IFD, but we may use IFD from Nix2, which allows to specify output hash and thus will be a good reproducible citizen.
@Mathnerd314 That is pretty much what I came up with, but yours looks better. Thanks!
I propose that snippet be moved to docs asap to prevent this issue which will surely show itself once more.
There was #27994 "Document pinning nixpkgs in manual" but I guess they closed it once it was added to the wiki. I added it to the FAQ: https://nixos.wiki/wiki/FAQ#How_do_I_install_a_specific_version_of_a_package_for_build_reproducibility_etc..3F
With Nix 2.0 there is fetchTarball
and fetchGit
which are preferred.
Well, I was hoping that nix could replace hacky language specific stuff like nodenv, rbenv, kerl etc and work better than apt in terms of deployments. Long term I would like to make my project to be OS independent rhel/ubuntu.
My use-case:
I want to define default.nix for given project. When I come back to project 1 year later I could install project dependencies. When I deploy I also want to make sure that my project will build correctly and not to fail because apache-maven was upgraded and my CI box cannot install version.
I would like to avoid using docker, but it seems that's the only way for more reproducible builds.
I am still new to nix, but why nix cannot introduce some kind of .lock format? When there is a new version of the package then lock file will be generated with a specific version of dependencies. This way I can use any version of the package and use the lock file to pull current dependencies.
I want to define default.nix for given project. When I come back to project 1 year later I could install project dependencies. When I deploy I also want to make sure that my project will build correctly and not to fail because apache-maven was upgraded and my CI box cannot install version.
That you can use Nix/NixOS just fine for.
I would like to avoid using docker, but it seems that's the only way for more reproducible builds.
What do you consider not to be reproducible with Nix/NixOS?
I am still new to nix, but why nix cannot introduce some kind of .lock format? When there is a new version of the package then lock file will be generated with a specific version of dependencies. This way I can use any version of the package and use the lock file to pull current dependencies.
Your Nix expression for building a project (along with its dependencies) can be considered a lock file.
Please read my previous comment (https://github.com/NixOS/nixpkgs/issues/36266#issuecomment-370215841). When you have programs and dependencies, it is not just about the versions of whatever you're interested in, or the versions of the dependencies. It's also how they are built, as that can be version-dependent. There is a lot more to it than just specifying versions.
Certain language-specific package managers "can" work with the concept of lock files, but that's because of assumptions made, e.g. a common build method. Typically this breaks as soon as source in other languages needs to be considered.
That you can use Nix/NixOS just fine for.
Lets say that I have default.nix for my project like this:
with import <nixpkgs> {};
stdenv.mkDerivation rec {
name = "env";
env = buildEnv { name = name; paths = buildInputs; };
buildInputs = [
python
python27Packages.virtualenv
python27Packages.pip
go_1_4
lua5_3
];
}
I clone my project to another computer and this woul fail with to start nix-shell.
error: undefined variable 'go_1_4' at /home/raziel/Test/default.nix:10:5
By thay way above example come from first page of google about shell-nix. https://ariya.io/2016/06/isolated-development-environment-using-nix
What do you consider not to be reproducible with Nix/NixOS?
I cannot build my code with predictable versions of dependencies. I either need to manually copy closure from my local PC or fiddle with manually pinning and vendoring dependencies.
Please read my previous comment (#36266 (comment)). When you have programs and dependencies, it is not just about the versions of whatever you're interested in, or the versions of the dependencies. It's also how they are built, as that can be version-dependent. There is a lot more to it than just specifying versions.
Certain language-specific package managers "can" work with the concept of lock files, but that's because of assumptions made, e.g. a common build method. Typically this breaks as soon as the source in other languages needs to be considered.
That why I am saying that you should keep build recipes locked as well. Or even better keep build results forever. I understand that there are important considerations for a project like nix. As an outsider, I might not understand this but you need to create ROI for people to switch. People don't need another Arch with rolling updates with the fancy package manager.
For me personly I am looking for:
As it seems now. Ubuntu snap is going right direction even if less mature than nix at the moment.
Right, because you import <nixpkgs>
. Instead, you can pin it, with fetchTarball
or fetchGit
.
A nice improvement would be a script/option that pins <nixpkgs>
with its current value, although a generic solution for that is not possible.
Edit:
As an example of something that is fully reproducible, using fetchTarball
, see my thesis.
Right, because you import
. Instead, you can pin it, with fetchTarball or fetchGit
But then I will end up with pinning everything.
# import <nixpkgs> {}; but from a specific commit.
pkgs = import (fetchTarballFromGitHub {
owner = "NixOS";
repo = "nixpkgs";
rev= "afd2bdbad25db4b0007b52d07161345e6426ae72";
sha256 = "1n47x3y2q6pxncnp9xq7kxvc9p239g1xkp1wzdw2a9sp9hfva65q";
}){};
I will just pin to specificic version of nixpkgs? What if I only need go_1_4? but I want to use latest version of python.
You can select a certain revision of Nixpkgs and pick certain packages from that, and pin another version of Nixpkgs and pick packages from there.
@danbst I really like your overrideVersion idea - perhaps that could be pulled out into a separate proposal or PR? I wonder if there's a way to extend nix
so it doesn't have to pass the PR hurdle? (see plugins https://github.com/NixOS/nix/commit/88cd2d41acb994684a3e4ead1b1676019f43b4b6#diff-b61a6d542f9036550ba9c401c80f00ef) I hope it doesn't get lost in the shuffle. The suggestions that people have offered - fetchTarball (or from git or whatever) and/or pinning to a channel - are workable, but they could use some syntactic sugar to make them even easier. Ultimately I want to be able to bisect my changes to my system if I feel so inclined, which requires the version control to be exact.
@matthewbauer motivation for closing?
Sorry thought it wasn’t actionable.
I agree, but it's good to write the motivation so that it's clear.
@matthewbauer I've written (https://github.com/NixOS/nixpkgs/issues/36266#issuecomment-370753857) above some ideas on how to improve manual. Unfortunately, I don't have much time to actually sit down and write a PR.
@jcrben That .overrideVersion
is something that sits in my head for a long time. I don't think it should go to nixpkgs
- it's quite contra nixpkgs
purposes. Also, it's implementation looks like to be complicated...
I've made some progress on getting multiple versions of Ruby ready for use. The repository with all Ruby versions and their hashes is available here: https://github.com/bobvanderlinden/nixpkgs-ruby. It reuses the derivation from nixpkgs/pkgs and overrides it for each version.
It is being kept up-to-date using a scraper that runs in a Travis cron job. It pushes the results to nixpkgs-ruby
. You can find the updater here: https://github.com/bobvanderlinden/nixpkgs-ruby-updater.
To use nixpkgs-ruby
, you can do the following:
{ pkgs, stdenv, fetchFromGitHub }:
let
nixpkgsRubySource = fetchFromGitHub {
owner = "bobvanderlinden";
repo = "nixpkgs-ruby";
rev = "aaf2d46c7e166fd4cd52cc71720b72eef2486f18";
sha256 = "10rbw0kmbgq3jc2gngxqkdb6x4dkrh4fyrfqn6bx864vd4cszh5z";
};
in
rec {
nixpkgsRuby = import nixpkgsRubySource { inherit pkgs; };
rubyVersion = nixpkgsRuby.getVersion;
# Make your own easy-to-access attributes for the versions you use:
ruby_2_5_1 = rubyVersion ["2" "5" "1"];
ruby_2_4_4 = rubyVersion ["2" "4" "4"];
# ... or use it directly as buildInput in your derivation:
example = stdenv.mkDerivation {
name = "example";
buildInputs = [ (rubyVersion ["2" "5" "1"]) ];
installPhase = ''
ruby --version > $out
'';
};
}
It might be even nicer to use something like https://github.com/target/nix-fetchers, so that SHAs do not need to be retrieved by a scraper anymore and git tags can be used directly. If that will be usable in the future, nixpkgs-ruby doesn't have much value anymore. In that case, why use overrideVersion
and not just allow something like:
ruby-version = version: ruby.override { inherit version; };
@bobvanderlinden .overrideVersion
has intent to select appropriate Nix build expression. In your case, every ruby version is built with same receipt, but in reality there can be situation that old version can't be built with new derivation receipt (or new deps versions).
@danbst You still need a way to define which version of Nixpkgs is the one that is considered stable for the version of the package you're after. It could be placed in Nixpkgs itself and have it refer to earlier Nixpkgs revisions. Which revision to pick though?
I was looking for a solution and came with something similar to what you said @bobvanderlinden.
When upgrading the package, I keep the current version as a different variable pointing to a previous commit which allow the end-user to select the desired version. This is kinda recursive and could be generalized to any package.
{ pkgs ? import <nixpkgs> {} }: with pkgs;
let
mkOlderVersion = {rev, sha256}:
let olderVersion = fetchFromGitHub {
owner = "hussein-aitlahcen";
repo = "clever-tools-nix";
rev = rev;
sha256 = sha256;
};
in (import olderVersion {}).latest;
in
{
v0_9_3 = mkOlderVersion {
rev = "719156204e8a9569a687ec14ef88660da1eb08f3";
sha256 = "0a7ylqymx7wi97cd5f4gx7vpn8kk5sfgj35q5ha2y552mirzjlzf";
};
latest = callPackage ./clever-tools {
nodegit = callPackage ./nodegit {};
};
}
I would also echo @danbst post here https://github.com/NixOS/nixpkgs/issues/36266#issuecomment-370753857, would really like this functionality after being hit by not being able to pin specific package versions without huge complication.
Furthermore just quoting this statement
This is common request from newcomers. "You say, you can handle multiple versions of same packages, then provide me version XXX for package YYY"
Which later translates to: "Hell, why it's so complicated to get a package version I want, given multiple simultaneous versions for a package is a core feature of Nix?"
There is a bit of "misleading advertising" here in the sense that NixOS main selling points (as a linux distribution) is about having multiple package versions installed at the same time however in reality this is incredibly complex to do.
Ironically, pinning a specific version is easier to do in distros like Arch. Even though its not sandboxed/is global at least its very painless/easy to do.
Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:
still important to me
@cosarara check out flakes https://www.tweag.io/blog/2020-05-25-flakes/
I am going to close this because, within the scope of Nixpkgs, this is never going to happen because it's too intensive on the maintenance side.
Most helpful comment
This is common request from newcomers. "You say, you can handle multiple versions of same packages, then provide me version XXX for package YYY"
Which later translates to: "Hell, why it's so complicated to get a package version I want, given multiple simultaneous versions for a package is a core feature of Nix?"
What can we do for such requests?
Better docs
Improve docs for this kind of requests. I see the following topics should be added/improved:
git log --oneline YYY | grep XXX
, because some versions may be skipped, and user may want some closest available versiona) slower evaluation
b) extra checkout of nixpkgs in store, disk space/inode usage
c) use of IFD (import from derivation)
d) the rev doesn't contain semantic notes, so it's impossible to eye-check Nix code to understand which version of package is requested.
e) deps are NOT updated. This is often wanted, but counter-intuitive for
apt-get
users. If user wants old package with newer deps, they should be pointed to another part of doccallPackage
there. The problems area) deps are updated, which may break the package
b) some packages are defined in multiple files, so copy-pasting from GitHub website becomes problem
c) probably need use of overlays
overrideAttrs
: replacesrc
with an old one, hoping that newer build expression will work for oldsrc
. Problems:a) sometimes works, sometimes doesn't
b) the algorithm to find correct
src
should be described (refer to one of previous methods and show howsha256
should be computed).c) overriding
src
isn't sufficient. Why? The package will contain package version for originalsrc
, because derivation attrs do not form a fixpoint. So all attrs that refer toname
internally should be overriden too. This requires package expression inspectiona) nix-update-source
b) ? I think there are more
Better support
What if there existed a function
.overrideVersion
? Here is proposed API:Internally it should use a "package" -> "version" -> "checkout" mapping. Sort of index.
Because
.overrideVersion
most likely requires IFD, it is possible to build indexlocally, but maybe it's possible to build it centralized each month and distribute as
package. Because the index should be written in Nix (or JSON), we still have to IFD, but we may use IFD from Nix2, which allows to specify output hash and thus will be a good reproducible citizen.