Overriding packages in rPackages

Is it possible to override r-packages such that other r-packages will see the overridden version? From what i can tell from pkgs/development/r-modules/default.nix, it seems like the answer is no?

Specifically, it seems to use this pattern

{ R, pkgs, overrides }:
let
...
  # Recursive override pattern.
  # `_self` is a collection of packages;
  # `self` is `_self` with overridden packages;
  # packages in `_self` may depends on overridden packages.
  self = (defaultOverrides _self self) // overrides;
  _self = { inherit buildRPackage; } //
...
in self

which afaict only allows completely replacing a package with a new one, not making a modification to an existing version of a package.

For example, if I try this, it does “work”, since I completely remove a dependency:

(rPackages.override (oldOverrides : oldOverrides // {overrides = {slam = null;};})).textclean

but if I were to try to actually modify the package instead of removing it, I would either get an infinite loop or it wouldn’t see the other modifications:

with nixkgs;
myRPackages = (rPackages.override (oldOverrides: oldOverrides // { overrides = { slam = myRPackages.slam.override something; }; }));
# <infinite loop>

myRPackages2 = (rPackages.override (oldOverrides: oldOverrides // {
  overrides = {
    slam = rPackages.slam.override something;
    textclean = rPackages.textclean.override something;
  };
}));
# Now myRPackages.textclean uses the old version of slam instead of my modified version in a transitive dependency

It appears your analysis is correct.

This is one of the major limitations of single-argument overrides. The two-argument final: prev: ... style used by overlays (and by otherOverrides in r-modules/default.nix) is much preferred because it allows changes rather than just additions and replacements.

I suggest submitting a PR that changes

    in old // (otherOverrides old new);

to

    old9 = old // (otherOverrides old new);
  in old9 // (overlay new old9);

where overlay is a new top-level argument with default value (final: prev: prev).

Note: I haven’t tested this, mainly because I don’t use R. But it should get you most of the way to a solution.

1 Like

This page on the NixOS wiki is really helpful in understanding the two-argument style. Especially the diagram!

That’s what I figured, thank you!

That also makes me wonder, is there a function in the nix standard library for automating the chaining of overlays? Having a bunch of numbered variables like it does currently strikes me as somewhat silly.

But the more important question, which I guess I would get feedback on if I submit the pull request, is how do I make it backwards compatible? I noticed now that there are instructions in the wiki page on how to use the current overrides system for R.