Proper way to patch programs.thunderbird in Home Manager

Home Manager’s Thunderbird package (home-manager/modules/programs/thunderbird.nix at af59809e9413ec8adb9597a8636491af356fe525 · nix-community/home-manager · GitHub) contains the following function:

profilesIni =
    lib.foldl lib.recursiveUpdate
      {
        General = {
          StartWithLastProfile = 1;
        }
        // lib.optionalAttrs (cfg.profileVersion != null) {
          Version = cfg.profileVersion;
        };
      }
      (
        lib.flip map profilesWithId (profile: {
          "Profile${profile.id}" = {
            Name = profile.name;
            Path = if isDarwin then "Profiles/${profile.name}" else profile.name;
            IsRelative = 1;
            Default = if profile.isDefault then 1 else 0;
          };
        })
      );

I’m interested in storing my profile in a different location (default ~/thunderbird). This means I need to change Path and IsRelative. I copied thunderbird.nix into my configuration directory and changed the values as needed, but I can’t figure out how to apply the patch. My flake.nix contains:

inputs = {
        nixpkgs.url = "nixpkgs/nixos-unstable";
        home-manager = {
            url = "github:nix-community/home-manager/master";
            inputs.nixpkgs.follows = "nixpkgs";
        };
};
outputs = { nixpkgs, home-manager, ... }:
        let
            lib = nixpkgs.lib;
            system = "x86_64-linux";
            pkgs = import nixpkgs { inherit system; };
        in {
            homeConfigurations = {
                user = home-manager.lib.homeManagerConfiguration {
                    inherit pkgs;
                    modules = [ ./home.nix ];
                };
            };
        };

The only relevant line of home.nix is:

programs.thunderbird = {
        enable = true;
};

I’ve read through the wiki page on overlays, but I’m at a loss for what exactly to override since I’m installing Thunderbird through Home Manager’s programs.thunderbird instead of the nixpkg.

Any guidance would be appreciated. I just started using Home Manager, and I’ve never tried to patch anything this way.

1 Like

Somewhere in your home-manager config, set:

{
  disabledModules = [ "programs/thunderbird.nix" ];
  imports = [ ./path/to/your/modified/module.nix ];
}

You’re changing a module, not a package. Modules don’t have the override shenanigans, because mostly you’re intended to use module composition, not patch the original files. If you want to replace a module, you have to tell nix to disable the original, and replace its import with your own.

In this case, because lib.recursiveUpdate is used on a value in a let binding, you don’t really have a good alternative. This is an anti-pattern, sadly the home-manager modules are generally of pretty low quality.

I would recommend changing the upstream module to compose the profile settings with an option instead, then you can upstream your changes and simply override these values with lib.mkForce & co.

3 Likes

This is an anti-pattern, sadly the home-manager modules are generally of pretty low quality.

Is there a list of common anti-patterns available somewhere? I’d like to learn, but not sure where to get this information.

Not really. nix.dev has a short list that they refuse to be authorative on: Best practices — nix.dev documentation

I’ve been slowly writing a linter/set of ast-grep rules where I want to record the things I am aware of, but as usual with personal projects that has kinda stalled.

The let binding thing is an anti-pattern in specifically modules because it makes it impossible to modify or use the values within the module system, forcing you to modify the original file instead of being able to use the module system. Kinda precisely what I’m pointing out.

1 Like

Thank you, that’s helpful.