Package Recipes' Overrides and Overriding Recipes' Arguments

As of my understanding, when a package that depends on another which cannot be changed globally to meet their needs a local override may be done. What I’m calling a local override may be seen here in the imaginary pkgs/by-name/fo/foo/packages.nix with the bar' variable:

{ stdenv
, fetchurl
, bar
}: let
  bar' = bar.overrideAttrs {
    src = fetchurl rec {
      version = "0.2.0";
      url = "https://bar.org/bar-${version}";
      hash = "sha256-<hash>";
    };
  };
in
  stdenv.mkDerivation {
    # This does not matter for the point being made
  }

In such case, foo will now work, since an overwritten version of barbar' — is being used. However, when the user utilizes foo’s override function in regards to bar, any changes to its src attribute would be ignored, since they are overwritten on the recipe.

So, my questions are:

  1. Are local overrides to be avoided?
  2. If so, what should one do if a change must be made to a package’s dependency, but cannot be made to the dependency globally?
  3. If not, how would one still provide users the ability to override the locally overwritten packages? An use case for this would, for instance, taking the example above, if one uses an overlay for foo that provides a different version of bar.
1 Like

Maybe this pattern solves the problem?

{
  pkgs,
  stdenv,
  fetchurl,
  bar ? pkgs.bar.overrideAttrs {
    src = fetchurl { ... };
  },
}:
stdenv.mkDerivation {
  ...
}

I believe this would only work if bar was not a package. Since it is,
when the foo recipe is used — e. g., with callPackage — the
bar argument is given, ignoring the default value.

Ah, interesting. I didn’t think callPackage worked that way but it appears that you’re right.

Yeah, this is a good question, particularly given the by-name style being preferred over specifying dependencies in all-packages.