Overlay window manager with the flake version

Hi everyone!

I just migrated from configuration.nix to flake.nix.

here the flake.nix:

{
  description = "My first flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.11";
    home-manager.url = "github:nix-community/home-manager/master";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    # leftwm.url = "github:leftwm/leftwm";
  };

  outputs = { self, nixpkgs, home-manager, }:
    let
      me = "marcel";
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
        config = { allowUnfree = true; };
      };
      lib = nixpkgs.lib;
    in
    {
      homeManagerConfigurations = {
        ${me} = home-manager.lib.homeManagerConfiguration {
          inherit system pkgs;
          username = me;
          homeDirectory = "/home/${me}";
          configuration = {
            imports = [
              ./home-manager/home.nix
            ];
          };
        };
      };

      nixosConfigurations = {
        nixos = lib.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
          ];
        };
      };

    };
}

On my configuration.nix I use leftwm as the only WM on the system, like this:

    windowManager.leftwm = {
      enable = true;
    };
    displayManager = {
      defaultSession = "none+leftwm";
      autoLogin = {
        enable = true;
        user = "marcel";
      };
    };

How can I install the flake.nix of leftwm in a declarative way, and so that configuration.nix uses that instead of the leftwm nix package.

Thanks in advance!

You’re close:

{
  description = "My first flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.11";
    home-manager.url = "github:nix-community/home-manager/master";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    leftwm.url = "github:leftwm/leftwm";
  };

  outputs = { self, nixpkgs, home-manager, leftwm }:
    let
      me = "marcel";
      system = "x86_64-linux";
      overlays = [ leftwm.overlay ];
      pkgs = import nixpkgs {
        inherit system overlays;
        config = { allowUnfree = true; };
      };
      lib = nixpkgs.lib;
    in
    {
      homeManagerConfigurations = {
        ${me} = home-manager.lib.homeManagerConfiguration {
          inherit system pkgs;
          username = me;
          homeDirectory = "/home/${me}";
          configuration = {
            imports = [
              ./home-manager/home.nix
            ];
          };
        };
      };

      nixosConfigurations = {
        nixos = lib.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
          ];
        };
      };

    };
}

That will make your config use the leftwm overlay, from the leftwm flake, which overrides the leftwm package from nixpkgs with the leftwm provided by the flake.

Edit: You may need to get rid of the lib = nixpkgs.lib definition, and use pkgs.lib instead, or also inherit pkgs for the nixosSystem.

Thanks @TLATER,

I found a way before reading your solution but I think yours is better.
I created module with just the nixpkgs.overlays and added it to nixosConfiguration, like this:

nixosConfigurations = {
  nixos = nixpkgs.lib.nixosSystem {
    inherit system;
    modules = [
      ({ config, pkgs, ... }: { nixpkgs.overlays = [ leftwm.overlay ]; })
      ./configuration.nix
    ];
  };
};

Just to be sure, with your solution, the overlays declaration will be user from homeConfiguration and nixosConfiguration, I am correct ?
Why overlays needs to be inherit? Can it be declared inside directly?

Just for context this is my flake.nix now:

{
  description = "My first flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.11";
    home-manager.url = "github:nix-community/home-manager/master";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    leftwm.url = "github:leftwm/leftwm";
    neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
  };

  outputs = { self, nixpkgs, home-manager, leftwm, neovim-nightly-overlay }:
    let
      me = "marcel";
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
        config = { allowUnfree = true; };
        overlays = [
          neovim-nightly-overlay.overlay
        ];
      };
    in
    {
      homeConfigurations = {
        ${me} = home-manager.lib.homeManagerConfiguration {
          inherit system pkgs;
          username = me;
          stateVersion = "21.05";
          homeDirectory = "/home/${me}";
          configuration = {
            imports = [
              ./home-manager/home.nix
            ];
          };
        };
      };

      nixosConfigurations = {
        nixos = nixpkgs.lib.nixosSystem {
          inherit system;
          modules = [
            ({ config, pkgs, ... }: { nixpkgs.overlays = [ leftwm.overlay ]; })
            ./configuration.nix
          ];
        };
      };
    };
}

To understand how this works, it’s important to understand that import nixpkgs { }; simply imports the default.nix at the root of the nixpkgs repo, in other words this file, which in turn eventually imports this one.

The args that you pass to import nixpkgs { }; are fed there; in other words, if the overlays are given as an arg as above, you’re directly changing the contents of pkgs as they are used in the evaluation later.

We then pass that modified pkgs variable to the home-manager and nixos config functions, which use it to produce their configurations. So yes, we’re passing it to both - I imagine this doesn’t work with your example because the modified pkgs are only passed to the nixpkgs module, but it would also be possible that way if you used the home-manager module (because that would use the pkgs present in the system config, whose overlays you can indeed set with that option).

inherit x; is just syntactic sugar for x = x;. You could use either, but since the variable is already named pkgs we might as well use inherit to make the definition more succinct.

You could, for example also rename me to username and also inherit that.

Note that there is a cost to this - unlike using nixpkgs.legacyPackages, this requires actually evaluating the nixpkgs repository; that’s not a trivial computation. This way of producing overlays should therefore ideally be avoided in most non-leaf flakes, but it’s probably the best practice for system configuration flakes like this one.

Thanks for the explanation @TLATER
Good to know about the cost of evaluating the nixpkgs repo each time. I will have it in mind if I build a flake for some project. I inherit pkgs in configuration.nix and everything works good too.

I have read that home-manager can be used as a module and the build can run automatically when flake.nix builds, that seems a good alternative to importing it to homeConfigurations.