9 files changed,
+482,
-0
+8,
-0
1@@ -0,0 +1,8 @@
2+# Devenv
3+.devenv*
4+devenv.local.nix
5+devenv.local.yaml
6+result
7+
8+# direnv
9+.direnv
+67,
-0
1@@ -0,0 +1,67 @@
2+# devkit
3+
4+Shared [devenv](https://devenv.sh) module: my personal dev tools (`bug`,
5+`secrets`, `local-code-review`), a jujutsu/bash toolchain, and the customized
6+interactive bash environment (fish-like completion, history search, etc.).
7+
8+Importing devkit keeps every project's shell identical and lets a single edit
9+here propagate to all of them.
10+
11+## Use it in a project
12+
13+devenv.yaml:
14+
15+```yaml
16+inputs:
17+ nixpkgs:
18+ url: github:cachix/devenv-nixpkgs/rolling
19+ # devenv#2205: an imported input's devenv.yaml is NOT evaluated, so the tool
20+ # inputs must be declared here even though devkit wires the packages.
21+ bug:
22+ url: git+https://git.kilimanjaro.io/bug
23+ local-code-review:
24+ url: git+https://git.kilimanjaro.io/local-code-review
25+ secrets:
26+ url: git+https://git.kilimanjaro.io/secrets
27+ devkit:
28+ url: path:../devkit # sibling-repo layout, or a git+https URL
29+ flake: false
30+imports:
31+ - devkit
32+```
33+
34+That's the whole wiring. A project's own `devenv.nix` only needs its
35+project-specific packages/env; devkit's `enterShell` is concatenated with the
36+project's.
37+
38+## Live updates (why `path:`)
39+
40+With a `path:` input, edits to `devenv.nix` take effect on the **next**
41+`devenv shell` — no `devenv update`. (Verified on devenv 2.4.0.)
42+
43+## Promoting to a shared git input
44+
45+When the module stabilizes, push it to `git+https://git.kilimanjaro.io/devenv-base`
46+and switch each project's `devkit.url` to that. Then changes are pulled with
47+`devenv update devkit` per project (pinned in `devenv.lock`, reproducible).
48+
49+## New project scaffold
50+
51+`devenv init` has no template flag (devenv #1718); its `--from` flag only
52+affects `devenv shell`/`test`/`build`. Use the Nix flake template instead:
53+
54+```sh
55+mkdir ~/projects/newthing && cd ~/projects/newthing
56+nix flake init -t path:/home/btburke/projects/devkit # copies devenv.nix + devenv.yaml (+ .envrc)
57+```
58+
59+(Once pushed: `nix flake init -t git+https://git.kilimanjaro.io/devenv-base`.)
60+
61+The scaffold's `devenv.yaml` uses `path:../devkit`, so the new project must be
62+a sibling of devkit under `~/projects` — adjust otherwise.
63+
64+## Gotchas
65+
66+- Not for the tool repos themselves (`bug`, `secrets`, `local-code-review`):
67+ importing devkit there would be circular.
68+- devkit's own `devenv.yaml` is only for standalone use in this directory.
+238,
-0
1@@ -0,0 +1,238 @@
2+{
3+ "nodes": {
4+ "bug": {
5+ "inputs": {
6+ "flake-utils": "flake-utils",
7+ "nixpkgs": "nixpkgs"
8+ },
9+ "locked": {
10+ "lastModified": 1789299135,
11+ "narHash": "sha256-eU2EKLWUG7+LOdd6xlLELcXaK9yGyS4Hi1NWWuJPyj0=",
12+ "ref": "refs/heads/main",
13+ "rev": "c150b552f4b084877dd7386a5543934d7ad0c7e9",
14+ "revCount": 12,
15+ "type": "git",
16+ "url": "https://git.kilimanjaro.io/bug"
17+ },
18+ "original": {
19+ "type": "git",
20+ "url": "https://git.kilimanjaro.io/bug"
21+ }
22+ },
23+ "devenv": {
24+ "locked": {
25+ "dir": "src/modules",
26+ "lastModified": 1792071910,
27+ "narHash": "sha256-DUCfod12b6e/r9FCjE3+x7mJlVEmIpC10BZKGz+Nrsw=",
28+ "owner": "cachix",
29+ "repo": "devenv",
30+ "rev": "1566050ec14ce238983376e118af9fb220454d39",
31+ "type": "github"
32+ },
33+ "original": {
34+ "dir": "src/modules",
35+ "owner": "cachix",
36+ "repo": "devenv",
37+ "type": "github"
38+ }
39+ },
40+ "flake-utils": {
41+ "inputs": {
42+ "systems": "systems"
43+ },
44+ "locked": {
45+ "lastModified": 1731533236,
46+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
47+ "owner": "numtide",
48+ "repo": "flake-utils",
49+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
50+ "type": "github"
51+ },
52+ "original": {
53+ "owner": "numtide",
54+ "repo": "flake-utils",
55+ "type": "github"
56+ }
57+ },
58+ "flake-utils_2": {
59+ "inputs": {
60+ "systems": "systems_2"
61+ },
62+ "locked": {
63+ "lastModified": 1731533236,
64+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
65+ "owner": "numtide",
66+ "repo": "flake-utils",
67+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
68+ "type": "github"
69+ },
70+ "original": {
71+ "owner": "numtide",
72+ "repo": "flake-utils",
73+ "type": "github"
74+ }
75+ },
76+ "local-code-review": {
77+ "inputs": {
78+ "nixpkgs": "nixpkgs_2"
79+ },
80+ "locked": {
81+ "lastModified": 1790664642,
82+ "narHash": "sha256-Pl7zVsnoxxrbrg/up/5Ue2a9ajtROQptM4AOuo7AYts=",
83+ "ref": "refs/heads/main",
84+ "rev": "95ae244a839007c6aa89fa5230be193d878ee56e",
85+ "revCount": 17,
86+ "type": "git",
87+ "url": "https://git.kilimanjaro.io/local-code-review"
88+ },
89+ "original": {
90+ "type": "git",
91+ "url": "https://git.kilimanjaro.io/local-code-review"
92+ }
93+ },
94+ "nixpkgs": {
95+ "locked": {
96+ "lastModified": 1789149629,
97+ "narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=",
98+ "owner": "NixOS",
99+ "repo": "nixpkgs",
100+ "rev": "eaad089433ca2bb662274377d33df3d0e51ef28b",
101+ "type": "github"
102+ },
103+ "original": {
104+ "owner": "NixOS",
105+ "ref": "nixos-unstable",
106+ "repo": "nixpkgs",
107+ "type": "github"
108+ }
109+ },
110+ "nixpkgs-src": {
111+ "flake": false,
112+ "locked": {
113+ "lastModified": 1791487292,
114+ "narHash": "sha256-tqM7xDEsaeK1p6VvRygeZ9LkQRpUUkbRT02BHv6hnTM=",
115+ "owner": "NixOS",
116+ "repo": "nixpkgs",
117+ "rev": "8edc0c72e3a38faf5434e40d1f19431125fe4b30",
118+ "type": "github"
119+ },
120+ "original": {
121+ "owner": "NixOS",
122+ "ref": "nixpkgs-unstable",
123+ "repo": "nixpkgs",
124+ "type": "github"
125+ }
126+ },
127+ "nixpkgs_2": {
128+ "locked": {
129+ "lastModified": 1790323409,
130+ "narHash": "sha256-VVTPf+Hyd5ebpjBMHmrLMSBIeW6ls48Bqtosj7CNKLA=",
131+ "owner": "NixOS",
132+ "repo": "nixpkgs",
133+ "rev": "e94cb152ed51bd6e24eb4a41f1460252beb52cd2",
134+ "type": "github"
135+ },
136+ "original": {
137+ "owner": "NixOS",
138+ "ref": "nixos-unstable",
139+ "repo": "nixpkgs",
140+ "type": "github"
141+ }
142+ },
143+ "nixpkgs_3": {
144+ "inputs": {
145+ "nixpkgs-src": "nixpkgs-src"
146+ },
147+ "locked": {
148+ "lastModified": 1791812882,
149+ "narHash": "sha256-4AdYH2HoD21mys5lk9NoDcM2Z7iPeEUjxJeGE3Pw278=",
150+ "owner": "cachix",
151+ "repo": "devenv-nixpkgs",
152+ "rev": "760b85220489f69855e6df78a6d1dad5873f8bf6",
153+ "type": "github"
154+ },
155+ "original": {
156+ "owner": "cachix",
157+ "ref": "rolling",
158+ "repo": "devenv-nixpkgs",
159+ "type": "github"
160+ }
161+ },
162+ "nixpkgs_4": {
163+ "locked": {
164+ "lastModified": 1790578696,
165+ "narHash": "sha256-ZoxIApko70jCdbH3l20HWXOBaT2HZd87orzd2yJ9dVE=",
166+ "owner": "NixOS",
167+ "repo": "nixpkgs",
168+ "rev": "7a0f122f5090cf4c2ade2a13a0e229d4e19ba71f",
169+ "type": "github"
170+ },
171+ "original": {
172+ "owner": "NixOS",
173+ "ref": "nixos-unstable",
174+ "repo": "nixpkgs",
175+ "type": "github"
176+ }
177+ },
178+ "root": {
179+ "inputs": {
180+ "bug": "bug",
181+ "devenv": "devenv",
182+ "local-code-review": "local-code-review",
183+ "nixpkgs": "nixpkgs_3",
184+ "secrets": "secrets"
185+ }
186+ },
187+ "secrets": {
188+ "inputs": {
189+ "flake-utils": "flake-utils_2",
190+ "nixpkgs": "nixpkgs_4"
191+ },
192+ "locked": {
193+ "lastModified": 1790680131,
194+ "narHash": "sha256-p3xPff0d3O4T8AW0Zbv7sZDZcJk61f5LEHRKcSTRF58=",
195+ "ref": "refs/heads/main",
196+ "rev": "96a2b2da934d769c76c19073e89e19e231964868",
197+ "revCount": 1,
198+ "type": "git",
199+ "url": "https://git.kilimanjaro.io/secrets"
200+ },
201+ "original": {
202+ "type": "git",
203+ "url": "https://git.kilimanjaro.io/secrets"
204+ }
205+ },
206+ "systems": {
207+ "locked": {
208+ "lastModified": 1681028828,
209+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
210+ "owner": "nix-systems",
211+ "repo": "default",
212+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
213+ "type": "github"
214+ },
215+ "original": {
216+ "owner": "nix-systems",
217+ "repo": "default",
218+ "type": "github"
219+ }
220+ },
221+ "systems_2": {
222+ "locked": {
223+ "lastModified": 1681028828,
224+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
225+ "owner": "nix-systems",
226+ "repo": "default",
227+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
228+ "type": "github"
229+ },
230+ "original": {
231+ "owner": "nix-systems",
232+ "repo": "default",
233+ "type": "github"
234+ }
235+ }
236+ },
237+ "root": "root",
238+ "version": 7
239+}
+100,
-0
1@@ -0,0 +1,100 @@
2+# devkit — shared devenv module: personal tools + the customized interactive
3+# bash environment.
4+#
5+# Consumers import this from their devenv.yaml:
6+#
7+# inputs:
8+# devkit:
9+# url: path:../devkit # or git+https://git.kilimanjaro.io/devenv-base
10+# flake: false
11+# # devenv#2205: an imported input's devenv.yaml is NOT evaluated, so each
12+# # consumer must declare the tool inputs its own config here.
13+# bug: { url: git+https://git.kilimanjaro.io/bug }
14+# local-code-review: { url: git+https://git.kilimanjaro.io/local-code-review }
15+# secrets: { url: git+https://git.kilimanjaro.io/secrets }
16+# imports:
17+# - devkit
18+#
19+# Each tool is added automatically when its input is declared. Disable one with
20+# e.g. `devkit.bug.enable = false` (a project that ships its own wrapper).
21+#
22+# Changes to this file are picked up on the next `devenv shell` (path inputs,
23+# devenv 2.2+). Once promoted to a git input, consumers pull them with
24+# `devenv update devkit`.
25+{ pkgs, lib, config, inputs, ... }:
26+
27+let
28+ cfg = config.devkit;
29+ hasInput = name: lib.hasAttr name inputs;
30+in
31+
32+{
33+ options.devkit = {
34+ enable = lib.mkOption {
35+ type = lib.types.bool;
36+ default = true;
37+ description = "Add the devkit toolchain and customized bash environment.";
38+ };
39+ bug.enable = lib.mkOption {
40+ type = lib.types.bool;
41+ default = hasInput "bug";
42+ description = "Add the `bug` CLI (set false if the project ships its own wrapper).";
43+ };
44+ local-code-review.enable = lib.mkOption {
45+ type = lib.types.bool;
46+ default = hasInput "local-code-review";
47+ description = "Add the `lcr` CLI.";
48+ };
49+ secrets.enable = lib.mkOption {
50+ type = lib.types.bool;
51+ default = hasInput "secrets";
52+ description = "Add the `secrets` CLI.";
53+ };
54+ };
55+
56+ config = lib.mkIf cfg.enable {
57+ packages = [
58+ # toolchain the interactive bash environment needs
59+ pkgs.bash
60+ pkgs.bash-completion
61+ pkgs.bashInteractive
62+ pkgs.jujutsu
63+ ]
64+ # tools; the inputs are declared by the consumer (see header), so only add
65+ # each one when it is present and not explicitly disabled.
66+ ++ lib.optional cfg.bug.enable (inputs.bug.packages.${pkgs.system}.bug)
67+ ++ lib.optional cfg.local-code-review.enable (inputs.local-code-review.packages.${pkgs.system}.default)
68+ ++ lib.optional cfg.secrets.enable (inputs.secrets.packages.${pkgs.system}.default);
69+
70+ # The customized bash environment. It is `types.lines`, so each project's
71+ # own enterShell is concatenated onto this.
72+ enterShell = ''
73+ # Interactive shells only: `devenv shell -- <cmd>` has no line editing,
74+ # and bind warns there.
75+ if [[ $- == *i* ]]; then
76+ # Configure bash with fish-like features
77+ bind 'set completion-ignore-case on' # Case-insensitive completion
78+ bind 'set show-all-if-ambiguous on' # Show all completions on first tab
79+ bind 'set menu-complete-display-prefix on'
80+ bind 'TAB:menu-complete' # Tab cycles through completions
81+ bind '"\e[A":history-search-backward' # Up arrow searches history
82+ bind '"\e[B":history-search-forward' # Down arrow searches history
83+ bind 'set colored-completion-prefix on' # Color the completion prefix
84+ bind 'set colored-stats on' # Color the completion stats
85+
86+ # Enable bash-completion if available
87+ if [ -f ${pkgs.bash-completion}/etc/profile.d/bash_completion.sh ]; then
88+ source ${pkgs.bash-completion}/etc/profile.d/bash_completion.sh
89+ fi
90+
91+ # Better directory navigation
92+ shopt -s autocd 2>/dev/null # Type directory name to cd
93+ shopt -s dirspell 2>/dev/null # Correct spelling of dir names
94+ shopt -s cdspell 2>/dev/null # Correct spelling of cd args
95+
96+ # Enable ** globbing for recursive directory matching
97+ shopt -s globstar 2>/dev/null
98+ fi
99+ '';
100+ };
101+}
+14,
-0
1@@ -0,0 +1,14 @@
2+# Standalone config for working on devkit itself (`cd devkit && devenv shell`).
3+#
4+# NOTE: when a project imports devkit, THIS FILE IS IGNORED (devenv#2205).
5+# The consuming project declares these same inputs in its own devenv.yaml.
6+inputs:
7+ nixpkgs:
8+ url: github:cachix/devenv-nixpkgs/rolling
9+ bug:
10+ url: git+https://git.kilimanjaro.io/bug
11+ local-code-review:
12+ url: git+https://git.kilimanjaro.io/local-code-review
13+ secrets:
14+ url: git+https://git.kilimanjaro.io/secrets
15+reload: false
+19,
-0
1@@ -0,0 +1,19 @@
2+{
3+ # devkit is also usable as a `nix flake init` template:
4+ #
5+ # mkdir newthing && cd newthing
6+ # nix flake init -t path:/home/btburke/projects/devkit
7+ #
8+ # (or `-t git+https://git.kilimanjaro.io/devenv-base` once published).
9+ # NOTE: `devenv init` has no template flag (#1718); `--from` only affects
10+ # `devenv shell`/`test`/`build`, not `init`. Use the flake template above.
11+ description = "devkit - personal devenv module and new-project template";
12+
13+ outputs = { self }: {
14+ templates.default = {
15+ description = "New project wired to devkit (tools + customized bash env)";
16+ path = ./template;
17+ };
18+ templates.devkit = self.templates.default;
19+ };
20+}
+2,
-0
1@@ -0,0 +1,2 @@
2+eval "$(devenv direnvrc)"
3+use devenv
+14,
-0
1@@ -0,0 +1,14 @@
2+{ ... }:
3+
4+# Scaffold for a new project. devkit (imported in devenv.yaml) already provides
5+# bug, secrets, local-code-review, jujutsu, and the customized interactive bash
6+# environment, so don't repeat those here.
7+{
8+ packages = [
9+ # project-specific packages
10+ ];
11+
12+ # enterShell = ''
13+ # project-specific setup; concatenated onto devkit's
14+ # '';
15+}
+20,
-0
1@@ -0,0 +1,20 @@
2+# New-project scaffold. Copy alongside devenv.nix.
3+#
4+# `path:../devkit` assumes the project is a sibling of devkit under ~/projects.
5+# devenv#2205: the three tool inputs must be declared here (devkit's own
6+# devenv.yaml is not evaluated when imported).
7+inputs:
8+ nixpkgs:
9+ url: github:cachix/devenv-nixpkgs/rolling
10+ bug:
11+ url: git+https://git.kilimanjaro.io/bug
12+ local-code-review:
13+ url: git+https://git.kilimanjaro.io/local-code-review
14+ secrets:
15+ url: git+https://git.kilimanjaro.io/secrets
16+ devkit:
17+ url: path:../devkit
18+ flake: false
19+imports:
20+ - devkit
21+reload: false