summaryrefslogtreecommitdiff
path: root/flake.nix
blob: a18f2c78b165e096a5bcfbef5ae4546542f51de2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
{
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = {
    self,
    nixpkgs,
    flake-utils,
  }: let
    mapOverlayOverride = namespace: overlay: final: prev: let
      overlayPkgs = overlay final prev;
    in
      {
        "${namespace}" = builtins.removeAttrs overlayPkgs ["override"];
      }
      // (overlayPkgs.override or {});
  in
    flake-utils.lib.eachDefaultSystem (system: {
      formatter = (import nixpkgs {inherit system;}).alejandra;

      packages =
        (import nixpkgs {
          inherit system;
          overlays = [(mapOverlayOverride "local" (import ./pkgs))];
        }).local;
    })
    // {
      templates = let
        system-flake = {
          path = ./templates/system-flake;
          description = "Opinionated flake for a NixOS system with Home Manager";
        };
      in {
        inherit system-flake;

        default = system-flake;
      };

      overlays = let
        overlay = mapOverlayOverride "trivium" (import ./pkgs);
      in {
        default = overlay;
        trivium = overlay;
      };

      homeManagerModules.default = ./hm;
      nixosModules.default = ./nixos;

      lib = {
        mkSystemFlake = {
          flakes,
          system,
          formatter ? "alejandra",
          localOverlayPath ? /. + "${flakes.self}" + /pkgs,
          nixpkgsConfigPath ? localOverlayPath + /config,
          nixosSourcePath ? /. + "${flakes.self}" + /sys,
          nixosPlatformsPath ?
            if nixosSourcePath != null
            then nixosSourcePath + /platform
            else null,
          hmSourcePath ? /. + "${flakes.self}" + /home,
          hmPlatformsPath ?
            if hmSourcePath != null
            then hmSourcePath + /platform
            else null,
        }: let
          optionalFlake = name:
            if flakes ? "${name}"
            then flakes.${name}
            else null;

          requireFlake = name:
            if flakes ? "${name}"
            then flakes.${name}
            else throw "Required flake input '${name}' is required but was not provided";

          nur = optionalFlake "nur";
          nixpkgs = requireFlake "nixpkgs";
          unstable = optionalFlake "unstable";

          home-manager =
            if hmSourcePath != null
            then requireFlake "home-manager"
            else null;

          pkgs = importPkgs nixpkgs;

          importPkgs = flake:
            import flake ({
                inherit system;

                config = import ./pkgs/config nixpkgs.lib;
                overlays = let
                  conditions = [
                    {
                      overlay = nur.overlays.default;
                      condition = nur != null;
                    }
                    # NB: Preserve the relative order
                    {
                      overlay = self.overlays.trivium;
                      condition = true;
                    }
                    {
                      overlay = flakes.self.overlays.default;
                      condition = true;
                    }
                  ];
                in
                  builtins.map (cond: cond.overlay) (builtins.filter (cond: cond.condition) conditions);
              }
              // (
                if nixpkgsConfigPath != null
                then {
                  config = import nixpkgsConfigPath {inherit (nixpkgs) lib;};
                }
                else {}
              ));

          inherit (pkgs.trivium.lib) importAll;
        in
          with pkgs.lib;
            {
              formatter.${system} =
                if formatter == "alejandra"
                then pkgs.alejandra
                else if formatter == "nixpkgs-fmt"
                then pkgs.nixpkgs-fmt
                else throw "Unknown formatter: '${formatter}'";

              packages.${system} = pkgs.local;

              overlays.default = final: prev: let
                overlay =
                  if localOverlayPath != null
                  then import localOverlayPath
                  else (final: prev: {});
              in
                mapOverlayOverride "local" overlay final prev
                // optionalAttrs (unstable != null) {
                  unstable = importPkgs unstable;
                };
            }
            // optionalAttrs (nixosSourcePath != null) {
              nixosConfigurations = let
                nixosSystem = {modules}:
                  makeOverridable nixpkgs.lib.nixosSystem {
                    inherit modules pkgs system;

                    specialArgs = {
                      inherit flakes;
                    };
                  };

                hostConfig = platform:
                  nixosSystem {
                    modules = [
                      self.nixosModules.default
                      nixosSourcePath
                      platform
                    ];
                  };
              in
                mapAttrs (_: hostConfig) (importAll {root = nixosPlatformsPath;});
            }
            // optionalAttrs (hmSourcePath != null) {
              homeConfigurations = let
                registry = {...}: {
                  config.nix.registry =
                    mapAttrs
                    (_: value: {flake = value;})
                    flakes;
                };

                home = name: platform:
                  home-manager.lib.homeManagerConfiguration {
                    inherit pkgs;

                    extraSpecialArgs = {
                      inherit flakes;
                    };

                    modules = [
                      self.homeManagerModules.default
                      hmSourcePath
                      platform
                      registry
                    ];
                  };
              in
                mapAttrs home (importAll {root = hmPlatformsPath;});
            };
      };
    };
}