Use package from flake in another flake module

Hi, so I have a package in a repo and it’s packaged with a flake. Now in another flake, I want to use this package to write a NixOS module and use it.

Package flake:

{
  description = "Some rust package";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs =
    { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db, ... }:

    {
      # Defining an overlay so I can use it in my NixOS config and use `pkgs.refmt`.
      overlays = rec {
        default = refmt;
        refmt = (final: prev: { refmt = refmt.packages.${prev.system}.default; });
      };

    } // flake-utils.lib.eachDefaultSystem (system:
      let
        refmt = # Some derivation, skipped for simplicity
      in {
        packages = {
          inherit refmt;
          default = refmt;
        };
      });
}

Using the package flake in the NixOS config flake. We want to manage multiple hosts here, so we have an attribute set with the name of the host and it’s configuration.

Nixos flake:

{
  description = "NixOS hosts for HopTech";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    refmt = {
      url = "URL_OF_THE_PACKAGE_FLAKE";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        flake-utils.follows = "flake-utils";
      };
    };
  };

  outputs = { self, nixpkgs, flake-utils, refmt }:
    let
      pkgs = nixpkgs;
      utils = import ./lib {
        inherit pkgs;
        inherit (nixpkgs) lib;
      };
     # Some custom libraries where the overlay works properly
      lib = nixpkgs.lib.extend (self: super: { my = utils; });
      hosts = import ./hosts; # set of hosts with their config
    in {
      # Generate a nixos configuration for each hosts
      nixosConfigurations = nixpkgs.lib.mapAttrs (hostName: hostConfig:
        nixpkgs.lib.nixosSystem {
          system = hostConfig.system;
          specialArgs = {
            inherit lib; # Provides lib with the `my` overlay
          };

          modules = [
            ./modules
            hostConfig.cfg
            # Cause an error: value is a function while a set was expected
            { nixpkgs.overlays = [ refmt.overlays.default ]; }
            # Using this instead works, which I find weird
            #  nixpkgs.overlays = [
            #    (final: prev: {
            #      refmt = refmt.packages.${prev.system}.default;
            #    })
            #  ];
          ];
        }) hosts;
    }
}

Then in modules, I have a module that would use pkgs.refmt and create a systemd service with it.

First, is this the right way to do this via an overlay? If so, I’m clearly having some issues on the overlay code itself in the package flake, what would be the right code so the overlay adds refmt to the pkgs?
Also why does using the overlay does not work, but doing it manually (see commented code just above) does?

Just realized the issue on why one was working and not the other.

      overlays = rec {
        default = refmt;
        refmt = (final: prev: { refmt = refmt.packages.${prev.system}.default; });
      };

The refmt.package reference the refmt overlay, not the package.

How would I fix this if I want to reference the package in the overlay?

Ok nevermind, found the a way to fix the overlay. I’m not convinced it’s the right way to do it, but it works. Still curious if it’s the right way to do it though

rec {
  description = "Rust dev shell";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs =
    { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db, ... }:

    let
      all = flake-utils.lib.eachDefaultSystem (system:
        let
          # Package
          refmt = # Some derivaltion

        in {
          packages = {
            inherit refmt;
            default = refmt;
          };

          # Dev shell, check and other flake output
        });
    in {
      overlays = {
        default =
          (final: prev: { refmt = all.packages.${prev.system}.default; });
      };
    } // all;
}

2 Likes

Here is a slightly simpler approach that I’ve found to work:

{
  description = "Rust dev shell";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs =
    { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db, ... }:
    {
      overlays.default =
        (final: prev: { inherit (self.packages.${final.system}) refmt; });
    } // flake-utils.lib.eachDefaultSystem (system:
      let refmt = your-derivation;
      in rec {
        packages = {
          inherit refmt;
          default = refmt;
        };

        # Dev shell, check and other flake output
      });
}
1 Like