Turn THIS:
pkgs.mkShell {
packages = [pkgs.curl pkgs.git pkgs.jq pkgs.wget];
};
into THIS!
pkgs.make-shell {
packages = [pkgs.curl pkgs.git pkgs.jq pkgs.wget];
};
Alright, I admit that this project wonât help many simple use cases, but changing
mkShell
to accept a module as its argument is helping me manage a herd of devShells, using imports
to manage common features, and to define new options.
I wrote a full rationale for the project in a WHY.md document, which might tell you if you could get any use from it, but if you prefer to see that by example, hereâs a âShell Moduleâ which adds and authenticates a configurable Google Cloud CLI package:
{
lib,
pkgs,
config,
...
}: {
options.gcloud.enable = lib.mkEnableOption "install google cloud sdk";
options.gcloud.extraComponents =
lib.mkOption
{
description = "IDs of Google Cloud SDK components to install (list them with `gcloud components list`)";
default = [];
example = ["gke-gcloud-auth-plugin"];
type = lib.types.listOf lib.types.nonEmptyStr;
};
config = lib.mkIf config.gcloud.enable {
packages = [
(
if config.gcloud.extraComponents == []
then pkgs.google-cloud-sdk
else
pkgs.google-cloud-sdk.withExtraComponents
(builtins.map (c: pkgs.google-cloud-sdk.components.${c})
config.gcloud.extraComponents)
)
];
shellHook = ''
gcloudAccount=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
if [ -z ''${gcloudAccount:+set} ]; then
echo "Google Cloud SDK is not authorized"
read -rp "In the browser tab about to open, authenticate to your Google Cloud account. (press enter to continue)"
gcloud auth login
fi
if ! gcloud auth application-default print-access-token&>/dev/null; then
read -rp "You don't have any default application credentials for Google Cloud. In the browser tab about to open, authorize the use of your Google Cloud account. (press enter to continue)"
gcloud auth application-default login
fi
'';
};
}
âŚand hereâs a simple option which uses that âgcloudâ module to set a developer up to authenticate with clusters running in google cloudâs kubernetes engine:
{
lib,
pkgs,
config,
...
}: {
options.k8s.enable = lib.mkEnableOption "kubernetes tools";
config = lib.mkIf config.k8s.enable {
packages = [pkgs.kubectl pkgs.minikube];
gcloud.enable = true;
gcloud.extraComponents = ["gke-gcloud-auth-plugin"];
};
};
Commit those files to a flake and then you could write a consuming flake like this:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
make-shell.url = "github:nicknovitski/make-shell";
my-org-nix.url = "github:myOrg/nix-config"
};
outputs = {
self,
nixpkgs,
flake-utils,
make-shell,
my-org-nix,
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
config = {};
overlays = [make-shell.overlays.default];
};
in {
devShells.gcloud-function = pkgs.make-shell {
imports = [my-org-nix.shellModules.default];
gcloud.enable = true;
};
devShells.kubernetes = pkgs.make-shell {
imports = [my-org-nix.shellModules.default];
k8s.enable = true;
};
});
}
It also has a flake.parts flake module, if you like those. I hope at least a few people find it useful!