Merge pull request #264 from divnix/api-next

Implement new api and rebase on flake-utils-plus
This commit is contained in:
Pacman99 2021-04-27 16:55:13 -07:00 committed by GitHub
commit 62c9b126d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 948 additions and 593 deletions

View File

@ -1,45 +1,42 @@
# External Art
When you need to use a module, overlay, or pass a value from one of your inputs
to the rest of your NixOS configuration, [extern][extern] is where you do it.
to the rest of your NixOS configuration, you can make use of a couple arguments.
It is encouraged to add external art directly in your `flake.nix` so the file
represents a complete dependency overview of your flake.
Modules and overlays are self explanatory, and the `specialArgs` attribute is
used to extend the arguments passed to all NixOS modules, allowing for
arbitrary values to be passed from flake inputs to the rest of your
configuration.
## Overlays
External overlays can directly be added to a channel's `overlays` list.
## Home Manager
There is also an `hmModules` attribute set for pulling home-manager modules in
from the outside world:
### Declare:
flake.nix:
```nix
{
inputs.doom-emacs.url = "github:vlaci/nix-doom-emacs";
channels.nixos.overlays = [ inputs.agenix.overlay ];
}
```
These overlays will be automatically filtered by inspecting the `inputs` argument.
extern/default.nix:
## Modules
There is a dedicated `nixos.hostDefaults.externalModules` argument for external
modules.
flake.nix:
```nix
with inputs;
{
hmModules = {
doom-emacs = doom-emacs.hmModule;
};
nixos.hostDefaults.externalModules = [ inputs.agenix.nixosModules.age ];
}
```
### Use:
users/nixos/default.nix:
## Home Manager
Since there isn't a `hosts` concept for home-manager, externalModules is just a
top-level argument in the `home` namespace.
flake.nix:
```nix
{ hmModules, ... }:
{
home-manager.users.nixos = {
imports = [ hmModules.doom-emacs ] ;
programs.doom-emacs.enable = true;
};
home.externalModules = [ doom-emacs = doom-emacs.hmModule ];
}
```
[extern]: https://github.com/divnix/devos/tree/core/extern/default.nix
> ##### Note:
> The optimal solution would be to automatically export modules that were created in
> your flake. But this is not possible due to NixOS/nix#4740.

View File

@ -15,6 +15,11 @@ attribute to the name of the file minus the _.nix_ extension. This is for
convenience, since `nixos-rebuild` automatically searches for a configuration
matching the current systems hostname if one is not specified explicitly.
You can set channels, systems, and add extra modules to each host by editing the
`nixos.hosts` argument in flake.nix. This is the perfect place to import
host specific modules from external sources, such as the
[nixos-hardware][nixos-hardware] repository.
It is recommended that the host modules only contain configuration information
specific to a particular piece of hardware. Anything reusable across machines
is best saved for [profile modules](./profiles.md).
@ -22,20 +27,29 @@ is best saved for [profile modules](./profiles.md).
This is a good place to import sets of profiles, called [suites](./suites.md),
that you intend to use on your machine.
Additionally, this is the perfect place to import anything you might need from
the [nixos-hardware][nixos-hardware] repository.
> ##### _Note:_
> Set `nixpkgs.system` to the architecture of this host, default is "x86_64-linux".
> Keep in mind that not all packages are available for all architectures.
## Example
flake.nix:
```nix
{
nixos.hosts = mkMerge [
(devos.lib.importHosts ./hosts)
{
librem = {
channelName = "latest";
modules = [ hardware.purism-librem-13v3 ];
};
}
];
}
```
hosts/librem.nix:
```nix
{ suites, hardware, ... }:
{ suites, ... }:
{
imports = suites.laptop ++ [ hardware.purism-librem-13v3 ];
imports = suites.laptop;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;

View File

@ -1,47 +1,36 @@
# Overrides
By default, the NixOS systems are based on unstable. While it is trivial to
change this to a stable release, or any other branch of nixpkgs by
changing the flake url, sometimes all we want is a single package from another
branch.
Each NixOS host follows one channel. But many times it is useful to get packages
or modules from different channels.
This is what the overrides are for. By default, they are pulled directly from
nixpkgs/master, but you can change the `override` flake input url to
nixos-unstable, or even a specific sha revision.
## Packages
You can make use of `overlays/overrides.nix` to override specific packages in the
default channel to be pulled from other channels. That file is simply an example
of how any overlay can get `channels` as their first argument.
They are defined in the `extern/overrides.nix` file.
You can add overlays to any channel to override packages from other channels.
## Example
### Packages
The override packages are defined as a regular overlay with an extra arguement
`pkgs`. This refers to the packages built from the `override` flake.
Pulling the manix package from the override flake:
Pulling the manix package from the `latest` channel:
```nix
{
packages = pkgs: final: prev: {
inherit (pkgs) manix;
};
channels: final: prev: {
inherit (pkgs.latest) manix;
}
```
### Modules
## Modules
You can also pull modules from override. Simply specify their path relative to
the nixpkgs [modules][nixpkgs-modules] directory. The old version will be added
to `disabledModules` and the new version imported into the configuration.
You can also pull modules from other channels. All modules have access to the
`modulesPath` for each channel as `<channelName>ModulesPath`. And you can use
`disabledModules` to remove modules from the current channel.
Pulling the zsh module from the override flake:
Pulling the zsh module from the `latest` channel:
```nix
{
modules = [ "programs/zsh/zsh.nix" ];
{ latestModulesPath }: {
modules = [ "${latestModulesPath}/programs/zsh/zsh.nix" ];
disabledModules = [ "programs/zsh/zsh.nix" ];
}
```
> ##### _Note:_
> Sometimes a modules name will change from one branch to another. This is what
> the `disabledModules` list is for. If the module name changes, the old
> version will not automatically be disabled, so simply put it's old name in
> this list to disable it.
> Sometimes a modules name will change from one branch to another.
[nixpkgs-modules]: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules

View File

@ -6,7 +6,13 @@ profiles. For good examples, check out the suites defined in the community
In the future, we will use suites as a mechanism for deploying various machine
types which don't depend on hardware, such as vm's and containers.
They are defined in `profiles/suites.nix`.
They are defined with the `suites` argument in either `home` or `nixos` namespace.
Suites should be passed as a function that take profiles as an argument.
The profiles are passed based on the folder names and list passed to the relevant
`profiles` argument. In the template's flake.nix `profiles` is set as
`[ ./profiles ./users ]` and that corresponds to the `{ profiles, users }` argument
pattern.
## Definition
```nix

407
doc/mkFlakeOptions.md Normal file
View File

@ -0,0 +1,407 @@
## channels
nixpkgs channels to create
*_Type_*:
attribute set of submodules
*_Default_*
```
{}
```
## channels.\<name\>.config
nixpkgs config for this channel
*_Type_*:
attribute set or path convertible to it
*_Default_*
```
{}
```
## channels.\<name\>.input
nixpkgs flake input to use for this channel
*_Type_*:
nix flake
*_Default_*
```
"inputs.<name>"
```
## channels.\<name\>.overlays
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as \<channel\>/\<name\> and any overlay pulled from ${inputs}
will be filtered out
*_Type_*:
list of valid Nixpkgs overlay or path convertible to its or anything convertible to it
*_Default_*
```
[]
```
## channelsConfig
nixpkgs config for all channels
*_Type_*:
attribute set or path convertible to it
*_Default_*
```
{}
```
## home
hosts, modules, suites, and profiles for home-manager
*_Type_*:
submodule
*_Default_*
```
{}
```
## home.externalModules
modules to include that won't be exported
meant importing modules from external flakes
*_Type_*:
list of valid module or path convertible to its
*_Default_*
```
[]
```
## home.modules
modules to include in all hosts and export to homeModules output
*_Type_*:
list of path to a modules or anything convertible to it or path convertible to it
*_Default_*
```
[]
```
## home.profiles
profile folders that can be collected into suites
the name of the argument passed to suites is based
on the folder name.
[ ./profiles ] => { profiles }:
*_Type_*:
list of paths
*_Default_*
```
[]
```
## home.suites
Function that takes profiles and returns suites for this config system
These can be accessed through the 'suites' special argument.
*_Type_*:
function that evaluates to a(n) attrs or path convertible to it
*_Default_*
```
"<function>"
```
## inputs
inputs for this flake
used to set channel defaults and create registry
*_Type_*:
attribute set of nix flakes
## nixos
hosts, modules, suites, and profiles for nixos
*_Type_*:
submodule
*_Default_*
```
{}
```
## nixos.hostDefaults
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the 'nixosModules' flake output.
They will also be added to all hosts.
*_Type_*:
submodule
*_Default_*
```
{}
```
## nixos.hostDefaults.channelName
Channel this host should follow
*_Type_*:
a channel defined in `channels`
*_Default_*
```
null
```
## nixos.hostDefaults.externalModules
modules to include that won't be exported
meant importing modules from external flakes
*_Type_*:
list of valid module or path convertible to its
*_Default_*
```
[]
```
## nixos.hostDefaults.modules
modules to include in all hosts and export to nixosModules output
*_Type_*:
list of path to a modules or anything convertible to it or path convertible to it
*_Default_*
```
[]
```
## nixos.hostDefaults.system
system for this host
*_Type_*:
system defined in `supportedSystems`
*_Default_*
```
null
```
## nixos.hosts
configurations to include in the nixosConfigurations output
*_Type_*:
attribute set of submodules
*_Default_*
```
{}
```
## nixos.hosts.\<name\>.channelName
Channel this host should follow
*_Type_*:
a channel defined in `channels`
*_Default_*
```
null
```
## nixos.hosts.\<name\>.modules
modules to include
*_Type_*:
list of valid module or path convertible to its or anything convertible to it
*_Default_*
```
[]
```
## nixos.hosts.\<name\>.system
system for this host
*_Type_*:
system defined in `supportedSystems`
*_Default_*
```
null
```
## nixos.profiles
profile folders that can be collected into suites
the name of the argument passed to suites is based
on the folder name.
[ ./profiles ] => { profiles }:
*_Type_*:
list of paths
*_Default_*
```
[]
```
## nixos.suites
Function that takes profiles and returns suites for this config system
These can be accessed through the 'suites' special argument.
*_Type_*:
function that evaluates to a(n) attrs or path convertible to it
*_Default_*
```
"<function>"
```
## self
The flake to create the devos outputs for
*_Type_*:
nix flake
## supportedSystems
The systems supported by this flake
*_Type_*:
list of strings
*_Default_*
```
["aarch64-linux","i686-linux","x86_64-darwin","x86_64-linux"]
```

View File

@ -4,7 +4,7 @@ we want to keep the process as simple and straightforward as possible.
Any _.nix_ files declared in this directory will be assumed to be a valid
overlay, and will be automatically imported into all [hosts](../concepts/hosts.md), and
exported via `overlays.<file-basename>` _as well as_
exported via `overlays.<channel>/<pkgName>` _as well as_
`packages.<system>.<pkgName>` (for valid systems), so all you have to do is
write it.

View File

@ -10,10 +10,18 @@ flk up
This will make a new file `hosts/up-$(hostname).nix`, which you can edit to
your liking.
You must then add a host to `nixos.hosts` in flake.nix:
```nix
{
nixos.hosts = {
modules = hosts/NixOS.nix;
};
}
```
Make sure your `i18n.defaultLocale` and `time.timeZone` are set properly for
your region. Keep in mind that `networking.hostName` with be automatically
set to the filename of your hosts file, so `hosts/my-host.nix` will have the
hostname `my-host`.
set to the name of your host;
Now might be a good time to read the docs on [suites](../concepts/suites.md) and
[profiles](../concepts/profiles.md) and add or create any that you need.

View File

@ -7,7 +7,7 @@ configuration, and, optionally, run them in
## Lib Tests
You can easily write tests for your own library functions in the
___tests/lib.nix___ file and they will be run on every `nix flake check` or
lib/___tests/lib.nix___ file and they will be run on every `nix flake check` or
during a CI run.
## Unit Tests

25
extern/default.nix vendored
View File

@ -1,25 +0,0 @@
{ inputs }: with inputs;
{
modules = [
home.nixosModules.home-manager
ci-agent.nixosModules.agent-profile
];
overlays = [
nur.overlay
pkgs.overlay
];
# passed to all nixos modules
specialArgs = {
overrideModulesPath = "${override}/nixos/modules";
hardware = nixos-hardware.nixosModules;
};
# added to home-manager
userModules = [
];
# passed to all home-manager modules
userSpecialArgs = { };
}

33
extern/overrides.nix vendored
View File

@ -1,33 +0,0 @@
# override defaults to nixpkgs/master
{
# modules to pull from override, stable version is automatically disabled
modules = [ ];
# if a modules name changed in override, add the old name here
disabledModules = [ ];
# packages pulled from override
packages = pkgs: final: prev: {
inherit (pkgs)
cachix
dhall
discord
element-desktop
manix
nixpkgs-fmt
qutebrowser
signal-desktop
starship;
haskellPackages = prev.haskellPackages.override {
overrides = hfinal: hprev:
let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version;
in
{
# same for haskell packages, matching ghc versions
inherit (pkgs.haskell.packages."ghc${version}")
haskell-language-server;
};
};
};
}

View File

@ -12,7 +12,7 @@
"nixos"
],
"nixos-unstable": [
"override"
"latest"
],
"pre-commit-hooks-nix": "pre-commit-hooks-nix"
},
@ -33,7 +33,7 @@
"darwin": {
"inputs": {
"nixpkgs": [
"override"
"latest"
]
},
"locked": {
@ -81,7 +81,7 @@
"utils": "utils_2"
},
"locked": {
"narHash": "sha256-t14TKUtw83dZ2mbqjRpeUvdAx4zpe/ySr5KhPhB1JMU=",
"narHash": "sha256-hpvEXcpq85cDKi0F5UUsuMVISKlk8hgVJiz5FF29RwA=",
"path": "./lib",
"type": "path"
},
@ -138,6 +138,21 @@
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1619345332,
"narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home": {
"inputs": {
"nixpkgs": [
@ -158,10 +173,24 @@
"type": "github"
}
},
"latest": {
"locked": {
"lastModified": 1619400530,
"narHash": "sha256-7ZO7B+b9i1wFbHw62EFT+iwuBBpXeA/fcHlR63Z4J0w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e8dc8adab655eb27957859c62bef11484b53f639",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"naersk": {
"inputs": {
"nixpkgs": [
"override"
"latest"
]
},
"locked": {
@ -182,7 +211,7 @@
"naersk_2": {
"inputs": {
"nixpkgs": [
"override"
"latest"
]
},
"locked": {
@ -259,20 +288,6 @@
"type": "indirect"
}
},
"override": {
"locked": {
"lastModified": 1615926763,
"narHash": "sha256-yeq8A3EPNuQVlsxlEQrIRsklfJwJK0Us6jtcG/u8wNs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b702a56d417647de4090ac56c0f18bdc7e646610",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"pkgs": {
"inputs": {
"nixpkgs": [
@ -312,11 +327,11 @@
"devos": "devos",
"flake-compat": "flake-compat_2",
"home": "home",
"latest": "latest",
"naersk": "naersk_2",
"nixos": "nixos",
"nixos-hardware": "nixos-hardware",
"nur": "nur",
"override": "override",
"pkgs": "pkgs"
}
},
@ -336,17 +351,21 @@
}
},
"utils_2": {
"inputs": {
"flake-utils": "flake-utils"
},
"locked": {
"lastModified": 1618868421,
"narHash": "sha256-vyoJhLV6cJ8/tWz+l9HZLIkb9Rd9esE7p+0RL6zDR6Y=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "eed214942bcfb3a8cc09eb3b28ca7d7221e44a94",
"lastModified": 1619532520,
"narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"owner": "gytis-ivaskevicius",
"ref": "staging",
"repo": "flake-utils-plus",
"type": "github"
}
}

View File

@ -4,7 +4,7 @@
inputs =
{
nixos.url = "nixpkgs/nixos-unstable";
override.url = "nixpkgs";
latest.url = "nixpkgs";
devos.url = "path:./lib"; # TODO: outfactor into separate repo
devos.inputs = {
nixpkgs.follows = "nixos";
@ -17,38 +17,71 @@
ci-agent = {
url = "github:hercules-ci/hercules-ci-agent";
inputs = { nix-darwin.follows = "darwin"; flake-compat.follows = "flake-compat"; nixos-20_09.follows = "nixos"; nixos-unstable.follows = "override"; };
inputs = { nix-darwin.follows = "darwin"; flake-compat.follows = "flake-compat"; nixos-20_09.follows = "nixos"; nixos-unstable.follows = "latest"; };
};
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "override";
flake-compat.url = "github:BBBSnowball/flake-compat/pr-1";
flake-compat.flake = false;
darwin.inputs.nixpkgs.follows = "latest";
home.url = "github:nix-community/home-manager";
home.inputs.nixpkgs.follows = "nixos";
naersk.url = "github:nmattia/naersk";
naersk.inputs.nixpkgs.follows = "override";
naersk.inputs.nixpkgs.follows = "latest";
nixos-hardware.url = "github:nixos/nixos-hardware";
pkgs.url = "path:./pkgs";
pkgs.inputs.nixpkgs.follows = "nixos";
};
outputs = inputs@{ self, devos, nixos, nur, ... }:
outputs = inputs@{ self, pkgs, devos, nixos, ci-agent, home, nixos-hardware, nur, ... }:
devos.lib.mkFlake {
inherit self inputs nixos;
hosts = ./hosts;
packages = import ./pkgs;
suites = import ./profiles/suites.nix;
extern = import ./extern;
overrides = import ./extern/overrides.nix;
overlays = ./overlays;
profiles = ./profiles;
userProfiles = ./users/profiles;
modules = import ./modules/module-list.nix;
userModules = import ./users/modules/module-list.nix;
} // {
defaultTemplate = self.templates.flk;
inherit self inputs;
channelsConfig = { allowUnfree = true; };
channels = {
nixos = {
overlays = [
(devos.lib.pathsIn ./overlays)
./pkgs/default.nix
pkgs.overlay # for `srcs`
nur.overlay
];
};
latest = { };
};
nixos = {
hostDefaults = {
system = "x86_64-linux";
channelName = "nixos";
modules = ./modules/module-list.nix;
externalModules = [
ci-agent.nixosModules.agent-profile
home.nixosModules.home-manager
];
};
hosts = nixos.lib.mkMerge [
(devos.lib.importHosts ./hosts)
{ /* set host specific properties here */ }
];
profiles = [ ./profiles ./users ];
suites = { profiles, users, ... }: with profiles; {
base = [ cachix core users.nixos users.root ];
};
};
home = {
modules = ./users/modules/module-list.nix;
externalModules = [ ];
profiles = [ ./users/profiles ];
suites = { profiles, ... }: with profiles; {
base = [ direnv git ];
};
};
#defaultTemplate = self.templates.flk;
templates.flk.path = ./.;
templates.flk.description = "flk template";
};
}
;
}

View File

@ -30,6 +30,14 @@ rec {
value = import path;
});
importHosts = dir:
lib.os.recImport {
inherit dir;
_import = base: {
modules = import "${toString dir}/${base}.nix";
};
};
concatAttrs = lib.fold (attr: sum: lib.recursiveUpdate sum attr) { };
# Filter out packages that support given system and follow flake check requirements
@ -41,5 +49,6 @@ rec {
in
lib.filterAttrs filter packages;
safeReadDir = path: lib.optionalAttrs (builtins.pathExists path) (builtins.readDir path);
safeReadDir = path:
lib.optionalAttrs (builtins.pathExists (toString path)) (builtins.readDir (toString path));
}

View File

@ -1,12 +1,10 @@
let
inherit (lock.nodes.flake-compat.locked) rev narHash;
lock = builtins.fromJSON (builtins.readFile "${../..}/flake.lock");
rev = "e7e5d481a0e15dcd459396e55327749989e04ce0";
flake = (import
(
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz";
sha256 = narHash;
sha256 = "0zd3x46fswh5n6faq4x2kkpy6p3c6j593xbdlbsl40ppkclwc80x";
}
)
{

View File

@ -1,31 +1,40 @@
{ lib }:
{ self, nixos, inputs, modules, ... } @ allArgs:
let args = builtins.removeAttrs allArgs [ "self" "nixos" "inputs" ]; in
lib.nixosSystem (args // {
# dependencies to return a builder
{ self, inputs }:
{ modules, specialArgs, ... } @ args:
let inherit (specialArgs.channel.input.lib) nixosSystem; in
nixosSystem
(args // {
modules =
let
moduleList = builtins.attrValues modules;
fullHostConfig = (nixosSystem (args // { inherit modules; })).config;
fullHostConfig = (lib.nixosSystem (args // { modules = moduleList; })).config;
isoConfig = (lib.nixosSystem
isoConfig = (nixosSystem
(args // {
modules = moduleList ++ [
(lib.modules.iso { inherit self nixos inputs fullHostConfig; })
modules = modules ++ [
(lib.modules.iso { inherit self inputs fullHostConfig; })
];
})).config;
hmConfig = (lib.nixosSystem
hmConfig = (nixosSystem
(args // {
modules = moduleList ++ [
modules = modules ++ [
(lib.modules.hmConfig)
];
})).config;
in
moduleList ++ [{
modules ++ [{
system.build = {
iso = isoConfig.system.build.isoImage;
homes = hmConfig.home-manager.users;
};
lib = {
inherit specialArgs;
testModule = {
imports = modules;
};
};
}];
})
})

View File

@ -1,20 +1,20 @@
{ lib }:
{ users, profiles, userProfiles, suites } @ args:
{ suites, profiles } @ args:
let
inherit (lib) os;
definedSuites = suites {
inherit (args) users profiles userProfiles;
};
profileSet = lib.genAttrs' profiles (path: {
name = baseNameOf path;
value = os.mkProfileAttrs (toString path);
});
allProfiles = lib.collectProfiles profiles;
allUsers = lib.collectProfiles users;
createSuites = _: suites: lib.mapAttrs (_: v: os.profileMap v) suites // {
inherit allProfiles allUsers;
};
definedSuites = suites profileSet;
allProfiles = lib.collectProfiles profileSet;
in
lib.mapAttrs createSuites definedSuites
lib.mapAttrs (_: v: os.profileMap v) definedSuites // {
inherit allProfiles;
}

View File

@ -52,6 +52,21 @@
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1619345332,
"narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"naersk": {
"inputs": {
"nixpkgs": [
@ -127,17 +142,21 @@
}
},
"utils_2": {
"inputs": {
"flake-utils": "flake-utils"
},
"locked": {
"lastModified": 1618868421,
"narHash": "sha256-vyoJhLV6cJ8/tWz+l9HZLIkb9Rd9esE7p+0RL6zDR6Y=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "eed214942bcfb3a8cc09eb3b28ca7d7221e44a94",
"lastModified": 1619532520,
"narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"owner": "gytis-ivaskevicius",
"ref": "staging",
"repo": "flake-utils-plus",
"type": "github"
}
}

View File

@ -5,7 +5,7 @@
{
deploy.url = "github:serokell/deploy-rs";
devshell.url = "github:numtide/devshell";
utils.url = "github:numtide/flake-utils";
utils.url = "github:gytis-ivaskevicius/flake-utils-plus/staging";
};
outputs = inputs@{ self, nixpkgs, deploy, devshell, utils, ... }:
@ -35,12 +35,11 @@
inherit deploy;
};
evalArgs = import ./mkFlake/evalArgs.nix { lib = nixpkgs.lib // self; };
evalOldArgs = import ./mkFlake/evalOldArgs.nix { lib = nixpkgs.lib // self; };
};
pkgs-lib = import ./pkgs-lib {
lib = nixpkgs.lib // self;
inherit nixpkgs deploy devshell;
inherit deploy devshell;
};
inherit (attrs)
@ -49,8 +48,9 @@
safeReadDir
pathsToImportedAttrs
concatAttrs
filterPackages;
inherit (lists) pathsIn collectProfiles;
filterPackages
importHosts;
inherit (lists) pathsIn collectProfiles unifyOverlays;
inherit (strings) rgxToString;
inherit modules;
}
@ -61,7 +61,7 @@
{
lib = utils.lib // {
inherit (lib)
mkFlake;
mkFlake pathsIn importHosts;
};
}
@ -83,7 +83,7 @@
mkFlakeDoc = pkgs.writeText "mkFlakeOptions.md"
(
pkgs.nixosOptionsDoc {
inherit (lib.mkFlake.evalArgs { nixos = "nixos"; args = { }; }) options;
inherit (lib.mkFlake.evalArgs { args = { }; }) options;
}
).optionsMDDoc;
};

View File

@ -16,4 +16,6 @@
fullPath = name: "${toString dir}/${name}";
in
map fullPath (lib.attrNames (lib.safeReadDir dir));
unifyOverlays = channels: map (o: if builtins.isFunction (o null null) then o channels else o);
}

View File

@ -1,64 +1,94 @@
{ lib, deploy }:
let
inherit (lib) os;
inherit (builtins) mapAttrs attrNames attrValues head isFunction;
in
_: { self, inputs, nixos, ... } @ args:
_: { self, inputs, ... } @ args:
let
cfg = (
lib.mkFlake.evalOldArgs
{ inherit self inputs args; }
).config;
multiPkgs = os.mkPkgs
{
inherit self inputs nixos;
inherit (cfg) extern overrides;
config = lib.mkFlake.evalArgs {
inherit args;
};
outputs = {
nixosConfigurations = os.mkHosts
cfg = config.config;
otherArguments = removeAttrs args (attrNames config.options);
defaultModules = with lib.modules; [
(hmDefaults {
inherit (cfg.home) suites;
modules = cfg.home.modules ++ cfg.home.externalModules;
})
(globalDefaults {
inherit self inputs;
})
];
stripChannel = channel: removeAttrs channel [
# arguments in our channels api that shouldn't be passed to fup
"overlays"
];
getDefaultChannel = channels: channels.${cfg.nixos.hostDefaults.channelName};
# evalArgs sets channelName and system to null by default
# but for proper default handling in fup, null args have to be removed
stripHost = args: removeAttrs (lib.filterAttrs (_: arg: arg != null) args) [
# arguments in our hosts/hostDefaults api that shouldn't be passed to fup
"externalModules"
];
hosts = lib.mapAttrs (_: stripHost) cfg.nixos.hosts;
hostDefaults = stripHost cfg.nixos.hostDefaults;
in
lib.systemFlake (lib.recursiveUpdate
otherArguments
{
inherit self inputs nixos multiPkgs;
inherit (cfg) extern suites overrides;
dir = cfg.hosts;
inherit self inputs hosts;
inherit (cfg) channelsConfig supportedSystems;
channels = mapAttrs
(name: channel:
stripChannel (channel // {
# pass channels if "overlay" has three arguments
overlaysBuilder = channels: lib.unifyOverlays channels channel.overlays;
})
)
cfg.channels;
hostDefaults = lib.mergeAny hostDefaults {
specialArgs.suites = cfg.nixos.suites;
modules = cfg.nixos.hostDefaults.externalModules ++ defaultModules;
builder = os.devosSystem { inherit self inputs; };
};
nixosModules = lib.exporter.modulesFromList cfg.nixos.hostDefaults.modules;
homeModules = lib.exporter.modulesFromList cfg.home.modules;
homeConfigurations = os.mkHomeConfigurations self.nixosConfigurations;
nixosModules = cfg.modules;
homeModules = cfg.userModules;
overlay = cfg.packages;
inherit (cfg) overlays;
deploy.nodes = os.mkNodes deploy self.nixosConfigurations;
overlays = lib.exporter.overlaysFromChannelsExporter {
# since we can't detect overlays owned by self
# we have to filter out ones exported by the inputs
# optimally we would want a solution for NixOS/nix#4740
inherit inputs;
inherit (self) pkgs;
};
systemOutputs = lib.eachDefaultSystem (system:
let
pkgs = multiPkgs.${system};
pkgs-lib = lib.pkgs-lib.${system};
# all packages that are defined in ./pkgs
legacyPackages = os.mkPackages {
inherit pkgs;
inherit (self) overlay overlays;
};
in
{
checks = pkgs-lib.tests.mkChecks {
packagesBuilder = lib.builder.packagesFromOverlaysBuilderConstructor self.overlays;
checksBuilder = channels:
lib.pkgs-lib.tests.mkChecks {
pkgs = getDefaultChannel channels;
inherit (self.deploy) nodes;
hosts = self.nixosConfigurations;
homes = self.homeConfigurations;
};
inherit legacyPackages;
packages = lib.filterPackages system legacyPackages;
devShell = pkgs-lib.shell;
});
in
outputs // systemOutputs
devShellBuilder = channels:
lib.pkgs-lib.shell {
pkgs = getDefaultChannel channels;
};
}
)

View File

@ -1,11 +1,12 @@
{ lib }:
{ nixos, args }:
{ args }:
let
argOpts = with lib; { config, ... }:
let
inherit (lib) os;
cfg = config;
inherit (config) self;
maybeImport = obj:
@ -20,6 +21,12 @@ let
inherit (submodule { }) check;
description = "valid module";
});
# to export modules we need paths to get the name
exportModuleType = with types;
(addCheck path (x: moduleType.check (import x))) // {
description = "path to a module";
};
overlayType = pathTo (types.anything // {
check = builtins.isFunction;
description = "valid Nixpkgs overlay";
@ -33,46 +40,37 @@ let
# To simplify apply keys and improve type checking
pathTo = elemType: with types; coercedTo path maybeImport elemType;
# Accepts single item or a list
# apply keys end up with a list
# This should not be used if expecting a nested list
# all lists will get flattened by this
coercedListOf = elemType:
let coerceToList = x: flatten (singleton x); in
with types; coercedTo elemType coerceToList (listOf elemType);
pathToListOf = elemType: with types; pathTo (listOf elemType);
pathToListOf = x: pathTo (coercedListOf x);
coercedListOf = elemType: with types;
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
/* Submodules needed for API containers */
channelsModule = {
channelsModule = { name, ... }: {
options = with types; {
input = mkOption {
type = flakeType;
default = nixos;
default = cfg.inputs.${name};
defaultText = "inputs.<name>";
description = ''
nixpkgs flake input to use for this channel
'';
};
overlays = mkOption {
type = pathToListOf overlayType;
type = coercedListOf overlayType;
default = [ ];
description = ''
description = escape [ "<" ">" ] ''
overlays to apply to this channel
these will get exported under the 'overlays' flake output as <channel>/<name>
'';
};
externalOverlays = mkOption {
type = pathToListOf overlayType;
default = [ ];
description = ''
overlays to apply to the channel that don't get exported to the flake output
useful to include overlays from inputs
these will get exported under the 'overlays' flake output
as <channel>/<name> and any overlay pulled from ''\${inputs}
will be filtered out
'';
};
config = mkOption {
type = pathTo attrs;
default = { };
apply = lib.recursiveUpdate cfg.channelsConfig;
description = ''
nixpkgs config for this channel
'';
@ -82,21 +80,25 @@ let
hostModule = {
options = with types; {
# anything null in hosts gets filtered out by mkFlake
system = mkOption {
type = systemType;
default = "x86_64-linux";
type = (nullOr systemType) // {
description = "system defined in `supportedSystems`";
};
default = null;
description = ''
system for this host
'';
};
channelName = mkOption {
type = types.enum (builtins.attrValues config.channels);
default = "nixpkgs";
type = (nullOr (types.enum (builtins.attrNames config.channels))) // {
description = "a channel defined in `channels`";
};
default = null;
description = ''
Channel this host should follow
'';
};
};
};
@ -105,10 +107,11 @@ let
externalModulesModule = {
options = {
externalModules = mkOption {
type = pathToListOf moduleType;
type = with types; listOf moduleType;
default = [ ];
description = ''
The configuration for this host
modules to include that won't be exported
meant importing modules from external flakes
'';
};
};
@ -117,7 +120,7 @@ let
modulesModule = {
options = {
modules = mkOption {
type = pathToListOf moduleType;
type = with types; coercedListOf moduleType;
default = [ ];
description = ''
modules to include
@ -126,13 +129,31 @@ let
};
};
exportModulesModule = name: {
options = {
modules = mkOption {
type = with types; pathTo (coercedListOf exportModuleType);
default = [ ];
description = ''
modules to include in all hosts and export to ${name}Modules output
'';
};
};
};
# Home-manager's configs get exported automatically from nixos.hosts
# So there is no need for a host options in the home namespace
# This is only needed for nixos
includeHostsModule = { name, ... }: {
includeHostsModule = name: {
options = with types; {
hostDefaults = mkOption {
type = submodule [ hostModule externalModulesModule modulesModule ];
type = submodule [
hostModule
externalModulesModule
(exportModulesModule name)
];
default = { };
description = ''
Defaults for all hosts.
@ -152,16 +173,17 @@ let
};
# profiles and suites - which are profile collections
profilesModule = { name, ... }: {
profilesModule = { config, ... }: {
options = with types; {
profiles = mkOption {
type = coercedListOf path;
type = listOf path;
default = [ ];
apply = list:
# Merge a list of profiles to one set
let profileList = map (x: os.mkProfileAttrs (toString x)) list; in
foldl (a: b: a // b) { } profileList;
description = "path to profiles folder that can be collected into suites";
description = ''
profile folders that can be collected into suites
the name of the argument passed to suites is based
on the folder name.
[ ./profiles ] => { profiles }:
'';
};
suites = mkOption {
type = pathTo (functionTo attrs);
@ -171,8 +193,7 @@ let
inherit (config) profiles;
};
description = ''
Function with the input of 'profiles' that returns an attribute set
with the suites for this config system.
Function that takes profiles and returns suites for this config system
These can be accessed through the 'suites' special argument.
'';
};
@ -180,11 +201,22 @@ let
};
in
{
# this does not get propagated to submodules
# to allow passing flake outputs directly to mkFlake
config._module.check = false;
options = with types; {
self = mkOption {
type = flakeType;
description = "The flake to create the devos outputs for";
};
inputs = mkOption {
type = attrsOf flakeType;
description = ''
inputs for this flake
used to set channel defaults and create registry
'';
};
supportedSystems = mkOption {
type = listOf str;
default = lib.defaultSystems;
@ -192,31 +224,33 @@ let
The systems supported by this flake
'';
};
channels =
let
default = {
nixpkgs = {
input = nixos;
channelsConfig = mkOption {
type = pathTo attrs;
default = { };
description = ''
nixpkgs config for all channels
'';
};
};
in
mkOption {
channels = mkOption {
type = attrsOf (submodule channelsModule);
inherit default;
apply = x: default // x;
default = { };
description = ''
nixpkgs channels to create
'';
};
os = mkOption {
type = submodule [ includeHostsModule profilesModule ];
nixos = mkOption {
type = submodule [ (includeHostsModule "nixos") profilesModule ];
default = { };
description = ''
hosts, modules, suites, and profiles for nixos
'';
};
home = mkOption {
type = submodule [ profilesModule modulesModule ];
type = submodule [
profilesModule
(exportModulesModule "home")
externalModulesModule
];
default = { };
description = ''
hosts, modules, suites, and profiles for home-manager

View File

@ -1,162 +0,0 @@
{ lib }:
{ self, inputs, args }:
let
argOpts = with lib; { config, options, ... }:
let
inherit (lib) os;
inherit (config) self;
inputAttrs = with types; functionTo attrs;
moduleType = with types; anything // {
inherit (submodule { }) check;
description = "valid module";
};
in
{
options = with types; {
self = mkOption {
type = addCheck attrs lib.isStorePath;
description = "The flake to create the devos outputs for";
};
nixos = mkOption {
type = addCheck attrs lib.isStorePath;
description = "The default nixpkgs channel of the devos";
};
inputs = mkOption {
type = addCheck attrs lib.isStorePath;
description = "All inptus of the devos";
};
hosts = mkOption {
type = path;
default = "${self}/hosts";
defaultText = "\${self}/hosts";
apply = toString;
description = ''
Path to directory containing host configurations that will be exported
to the 'nixosConfigurations' output.
'';
};
packages = mkOption {
# functionTo changes arg names which breaks flake check
type = types.anything // {
check = builtins.isFunction;
description = "Nixpkgs overlay";
};
default = (final: prev: { });
defaultText = "(final: prev: {})";
description = ''
Overlay for custom packages that will be included in treewide 'pkgs'.
This should follow the standard nixpkgs overlay format - two argument function
that returns an attrset.
These packages will be exported to the 'packages' and 'legacyPackages' outputs.
'';
};
modules = mkOption {
type = listOf moduleType;
default = [ ];
apply = lib.pathsToImportedAttrs;
description = ''
list of modules to include in confgurations and export in 'nixosModules' output
'';
};
userModules = mkOption {
type = listOf moduleType;
default = [ ];
apply = lib.pathsToImportedAttrs;
description = ''
list of modules to include in home-manager configurations and export in
'homeModules' output
'';
};
profiles = mkOption {
type = path;
default = "${self}/profiles";
defaultText = "\${self}/profiles";
apply = x: os.mkProfileAttrs (toString x);
description = "path to profiles folder that can be collected into suites";
};
userProfiles = mkOption {
type = path;
default = "${self}/users/profiles";
defaultText = "\${self}/users/profiles";
apply = x: os.mkProfileAttrs (toString x);
description = "path to user profiles folder that can be collected into userSuites";
};
suites =
let
defaults = { user = { }; system = { }; };
in
mkOption {
type = inputAttrs;
default = { ... }: defaults;
defaultText = "{ user = {}; system = {}; }";
apply = suites: defaults // os.mkSuites {
inherit suites;
inherit (config) profiles users userProfiles;
};
description = ''
Function with inputs 'users' and 'profiles' that returns attribute set
with user and system suites. The former for Home Manager and the latter
for nixos configurations.
These can be accessed through the 'suites' specialArg in each config system.
'';
};
users = mkOption {
type = path;
default = "${self}/users";
defaultText = "\${self}/users";
apply = x: os.mkProfileAttrs (toString x);
description = ''
path to folder containing profiles that define system users
'';
};
extern =
let
defaults = {
modules = [ ];
overlays = [ ];
specialArgs = { };
userModules = [ ];
userSpecialArgs = { };
};
in
mkOption {
type = inputAttrs;
default = { ... }: defaults;
defaultText = ''
{ modules = []; overlays = []; specialArgs = []; userModules = []; userSpecialArgs = []; }
'';
# So unneeded extern attributes can safely be deleted
apply = x: defaults // (x { inputs = inputs // self.inputs; });
description = ''
Function with argument 'inputs' that contains all devos and ''${self}'s inputs.
The function should return an attribute set with modules, overlays, and
specialArgs to be included across nixos and home manager configurations.
Only attributes that are used should be returned.
'';
};
overlays = mkOption {
type = path;
default = "${self}/overlays";
defaultText = "\${self}/overlays";
apply = x: lib.pathsToImportedAttrs (lib.pathsIn (toString x));
description = ''
path to folder containing overlays which will be applied to pkgs and exported in
the 'overlays' output
'';
};
overrides = mkOption rec {
type = attrs;
default = { modules = [ ]; disabledModules = [ ]; packages = _: _: _: { }; };
defaultText = "{ modules = []; disabledModules = []; packages = {}; }";
apply = x: default // x;
description = "attrset of packages and modules that will be pulled from nixpkgs master";
};
};
};
in
lib.evalModules {
modules = [ argOpts args ];
}

View File

@ -1,28 +1,16 @@
{ lib }:
{
modOverrides = { overrides }:
{ config, overrideModulesPath, ... }:
let
inherit (overrides) modules disabledModules;
in
{
disabledModules = modules ++ disabledModules;
imports = map
(path: "${overrideModulesPath}/${path}")
modules;
};
hmDefaults = { userSuites, extern, homeModules }: {
hmDefaults = { suites, modules }: {
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = extern.userSpecialArgs // { suites = userSuites; };
sharedModules = extern.userModules ++ (builtins.attrValues homeModules);
extraSpecialArgs = { inherit suites; };
sharedModules = modules;
};
};
globalDefaults = { self, nixos, inputs, multiPkgs }:
globalDefaults = { self, inputs }:
let
experimentalFeatures = [
"flakes"
@ -31,49 +19,41 @@
"ca-derivations"
];
in
{ config, pkgs, ... }: {
{ channel, config, pkgs, ... }: {
users.mutableUsers = lib.mkDefault false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
nix.nixPath = [
"nixpkgs=${nixos}"
"nixpkgs=${channel.input}"
"nixos-config=${self}/lib/compat/nixos"
"home-manager=${inputs.home}"
];
nixpkgs.pkgs = lib.mkDefault multiPkgs.${config.nixpkgs.system};
nix.registry = {
devos.flake = self;
nixos.flake = nixos;
override.flake = inputs.override;
nixos.flake = channel.input;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = ${lib.concatStringsSep " "
experimentalFeatures
}
'';
_module.args = {
inherit self;
hosts = builtins.mapAttrs (_: host: host.config)
(removeAttrs self.nixosConfigurations [ config.networking.hostName ]);
};
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
};
cachix = { self }:
let rootCachix = "${self}/cachix.nix"; in
if builtins.pathExists rootCachix
then rootCachix
else { };
isoConfig = { self, inputs, fullHostConfig }:
{ config, modulesPath, suites, ... }: {
flakeModules = { self, extern }: { imports = builtins.attrValues self.nixosModules ++ extern.modules; };
isoConfig = { self, nixos, inputs, fullHostConfig }:
{ config, suites, ... }: {
imports = let modpath = "nixos/modules"; in
[ "${nixos}/${modpath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ];
imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ];
# avoid unwanted systemd service startups
# all strings in disabledModules get appended to modulesPath
# so convert each to list which can be coerced to string

View File

@ -1,13 +1,6 @@
{ lib, nixpkgs, deploy, devshell }:
{ lib, deploy, devshell }:
{
tests = import ./tests { inherit lib deploy; };
shell = import ./shell { inherit lib devshell deploy; };
}
lib.genAttrs
lib.defaultSystems
(system:
let
pkgs = import nixpkgs { inherit system; };
in
{
tests = import ./tests { inherit lib deploy nixpkgs pkgs system; };
shell = import ./shell { inherit lib devshell deploy nixpkgs system; };
}
)

View File

@ -1,27 +1,30 @@
{ lib, nixpkgs, devshell, deploy, system }:
{ lib, devshell, deploy }:
{ pkgs }:
let
overlays = [
devshell.overlay
(final: prev: {
deploy-rs =
deploy.packages.${prev.system}.deploy-rs;
})
];
pkgs = import nixpkgs { inherit system overlays; config = { }; };
pkgs' = import pkgs.path {
inherit (pkgs) system;
inherit overlays;
};
flk = pkgs.callPackage ./flk.nix { };
flk = pkgs'.callPackage ./flk.nix { };
installPkgs = (lib.nixosSystem {
inherit system;
inherit (pkgs') system;
modules = [ ];
}).config.system.build;
in
pkgs.devshell.mkShell {
imports = [ (pkgs.devshell.importTOML ./devshell.toml) ];
pkgs'.devshell.mkShell {
imports = [ (pkgs'.devshell.importTOML ./devshell.toml) ];
packages = with installPkgs; [
nixos-install
@ -33,13 +36,13 @@ pkgs.devshell.mkShell {
pre-commit.text = lib.fileContents ./pre-commit.sh;
};
commands = with pkgs; [
commands = with pkgs'; [
{ package = flk; }
{
name = "nix";
help = pkgs.nixFlakes.meta.description;
help = pkgs'.nixFlakes.meta.description;
command = ''
${pkgs.nixFlakes}/bin/nix --experimental-features "nix-command flakes ca-references" "${"\${@}"}"
${pkgs'.nixFlakes}/bin/nix --experimental-features "nix-command flakes ca-references" "${"\${@}"}"
'';
}
]

View File

@ -1,25 +1,28 @@
{ lib, nixpkgs, pkgs, deploy, system }:
{ lib, deploy }:
let
mkChecks = { hosts, nodes, homes ? { } }:
mkChecks = { pkgs, hosts, nodes, homes ? { } }:
let
deployHosts = lib.filterAttrs
(n: _: hosts.${n}.config.nixpkgs.system == system)
(n: _: hosts.${n}.config.nixpkgs.system == pkgs.system)
nodes;
deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; };
deployChecks = deploy.lib.${pkgs.system}.deployChecks { nodes = deployHosts; };
tests =
lib.optionalAttrs (deployHosts != { })
{
profilesTest = profilesTest (hosts.${(builtins.head (builtins.attrNames deployHosts))});
profilesTest = profilesTest {
inherit pkgs;
host = hosts.${(builtins.head (builtins.attrNames deployHosts))};
};
} // lib.mapAttrs (n: v: v.activationPackage) homes;
in
lib.recursiveUpdate tests deployChecks;
mkTest = host:
mkTest = { pkgs, host }:
let
nixosTesting =
(import "${nixpkgs}/nixos/lib/testing-python.nix" {
inherit system;
(import "${toString pkgs.path}/nixos/lib/testing-python.nix" {
inherit (pkgs) system;
inherit (host.config.lib) specialArgs;
inherit pkgs;
extraConfigurations = [
@ -40,15 +43,15 @@ let
in
nixosTesting.makeTest calledTest;
profilesTest = host: mkTest host {
profilesTest = args@{ host, ... }: mkTest args {
name = "profiles";
machine = { suites, ... }: {
imports = suites.allProfiles ++ suites.allUsers;
imports = suites.allProfiles;
};
testScript = ''
machine.systemctl("is-system-running --wait")
${host.config.networking.hostName}.systemctl("is-system-running --wait")
'';
};
in

View File

@ -71,23 +71,19 @@ lib.runTests {
};
};
testSuites =
let
profiles = os.mkProfileAttrs (toString ./profiles);
users = "";
userProfiles = "";
suites = { profiles, ... }: {
system.bar = [ profiles.foo ];
testSuites = {
expr = os.mkSuites {
suites = { profiles, ... }: with profiles; {
bar = [ foo ];
};
profiles = [ (./profiles) ];
};
in
{
expr = os.mkSuites { inherit profiles users userProfiles suites; };
expected = {
system = {
bar = [ profiles.foo.default ];
allProfiles = [ profiles.foo.default profiles.t.default ];
allUsers = [ ];
};
bar = [ (toString ./profiles/foo) ];
allProfiles = [
(toString ./profiles/foo)
(toString ./profiles/t)
];
};
};
}

26
overlays/overrides.nix Normal file
View File

@ -0,0 +1,26 @@
channels: final: prev: {
inherit (channels.latest)
cachix
dhall
discord
element-desktop
manix
nixpkgs-fmt
qutebrowser
signal-desktop
starship;
haskellPackages = prev.haskellPackages.override {
overrides = hfinal: hprev:
let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version;
in
{
# same for haskell packages, matching ghc versions
inherit (channels.latest.haskell.packages."ghc${version}")
haskell-language-server;
};
};
}