Using custom/older versions of libraries and packages using nix.

Ever had the need to work on a legacy project having an old version of a language or framework or library and went through the pain of installing those dependencies? - yea we all have.

I recently had to setup an old project and was facing the same exact situation.

ruby version: 2.2.2

I was trying to setup the project using nix, but unfortunately nix does not support ruby 2.2.2 now. The least supported version is 2.5.

$ nix-env -qaP ruby

nixpkgs.ruby_2_5     ruby-2.5.8
nixpkgs.ruby         ruby-2.6.6
nixpkgs.rubyMinimal  ruby-2.6.6
nixpkgs.ruby_2_7     ruby-2.7.1

So I need to find a way to install ruby-2.2.2 using nix.

One recommended way of doing that is using pinned versions. Finding out the old sha/rev from hydra and pinning it.

But unfortunately this did not work out for me. The old version that was built in hydra was using an old version of nix, but is no longer compatible with the mac os version that I am using now. So that was out of the equation.

Next option is to override the package derivation using overrideAttrs

  ruby_2_2_2 = pkgs.ruby.overrideAttrs (oldAttrs: rec {
    version = "2.2.2";
    src = fetchurl {
      url = "https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.gz";
      sha256 = "0i4v7l8pnam0by2cza12zldlhrffqchwb2m9shlnp7j2gqqhzz2z";
    };

    # nixpkgs does not have 2.2.2 related patches anymore.
    patches = [];
    postPatch = "";
  });

Notice the override of patches = []This was necessary as nix would try to patch the ruby version from a list of available patchsets. But then again, ruby 2.2.2 is outdated, and nixpkgs does not maintain those patches any more.

After a bit of tweaking and skipping the patches it worked, and I did not have to try installing ruby 2.2.2 on host or setting up a docker image for that.

Hope that helps someone.