chore: update template
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
Look for one of these patterns in the consuming repo:
|
||||
|
||||
- `repo-lib.lib.mkRepo`
|
||||
- `repo-lib.lib.mkDevShell`
|
||||
- `repo-lib.lib.mkRelease`
|
||||
- `inputs.repo-lib`
|
||||
|
||||
@@ -27,6 +26,7 @@ repo-lib.lib.mkRepo {
|
||||
extraShellText = "";
|
||||
allowImpureBootstrap = false;
|
||||
bootstrap = "";
|
||||
banner = { };
|
||||
};
|
||||
|
||||
formatting = {
|
||||
@@ -54,12 +54,35 @@ repo-lib.lib.mkRepo {
|
||||
Generated outputs:
|
||||
|
||||
- `devShells.${system}.default`
|
||||
- `checks.${system}.formatting-check`
|
||||
- `checks.${system}.hook-check`
|
||||
- `checks.${system}.lefthook-check`
|
||||
- `formatter.${system}`
|
||||
- `packages.${system}.release` when `config.release != null`
|
||||
- merged `packages` and `apps` from `perSystem`
|
||||
|
||||
Merge points:
|
||||
|
||||
- `config.checks` merges with `perSystem.checks`
|
||||
- `config.lefthook` recursively merges with `perSystem.lefthook`
|
||||
- `config.shell` recursively merges with `perSystem.shell`
|
||||
- generated release packages merge with `perSystem.packages`
|
||||
|
||||
Conflicts on `checks`, `packages`, and `apps` names throw.
|
||||
|
||||
## `config.includeStandardPackages`
|
||||
|
||||
Default: `true`
|
||||
|
||||
When enabled, the shell includes:
|
||||
|
||||
- `nixfmt`
|
||||
- `gitlint`
|
||||
- `gitleaks`
|
||||
- `shfmt`
|
||||
|
||||
Use `false` only when the consumer explicitly wants to own the full shell package list.
|
||||
|
||||
## `config.shell`
|
||||
|
||||
Fields:
|
||||
@@ -71,13 +94,38 @@ Fields:
|
||||
- `bootstrap`
|
||||
Shell snippet that runs before the banner.
|
||||
- `allowImpureBootstrap`
|
||||
Must be `true` if `bootstrap` is non-empty.
|
||||
Must be `true` when `bootstrap` is non-empty.
|
||||
- `banner`
|
||||
Shell banner configuration.
|
||||
|
||||
Rules:
|
||||
|
||||
- Default is pure-first.
|
||||
- Do not add bootstrap work unless the user actually wants imperative setup.
|
||||
- Use `bootstrap` for unavoidable local setup only.
|
||||
- Do not add bootstrap work unless the user actually wants imperative local setup.
|
||||
- The template uses bootstrap intentionally for Bun global install paths and Moon bootstrapping; do not generalize that into normal package setup unless the repo already wants that behavior.
|
||||
|
||||
### `config.shell.banner`
|
||||
|
||||
Defaults:
|
||||
|
||||
```nix
|
||||
{
|
||||
style = "simple";
|
||||
icon = "🚀";
|
||||
title = "Dev shell ready";
|
||||
titleColor = "GREEN";
|
||||
subtitle = "";
|
||||
subtitleColor = "GRAY";
|
||||
borderColor = "BLUE";
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `style` must be `simple` or `pretty`.
|
||||
- `borderColor` matters only for `pretty`.
|
||||
- Tool rows can also set `banner.color`, `banner.icon`, and `banner.iconColor`.
|
||||
- Required tool probe failures abort shell startup.
|
||||
|
||||
## `config.formatting`
|
||||
|
||||
@@ -91,7 +139,7 @@ Fields:
|
||||
Rules:
|
||||
|
||||
- `nixfmt` is always enabled.
|
||||
- Use formatter settings instead of ad hoc shell formatting logic.
|
||||
- Use formatter settings instead of shell hooks for formatting behavior.
|
||||
|
||||
## Checks
|
||||
|
||||
@@ -99,10 +147,10 @@ Rules:
|
||||
|
||||
```nix
|
||||
{
|
||||
command = "go test ./...";
|
||||
command = "bun test";
|
||||
stage = "pre-push"; # or "pre-commit"
|
||||
passFilenames = false;
|
||||
runtimeInputs = [ pkgs.go ];
|
||||
runtimeInputs = [ pkgs.bun ];
|
||||
}
|
||||
```
|
||||
|
||||
@@ -114,37 +162,53 @@ Defaults:
|
||||
|
||||
Rules:
|
||||
|
||||
- Only `pre-commit` and `pre-push` are supported.
|
||||
- The command is wrapped as a script and connected into `lefthook.nix`.
|
||||
- `pre-commit` and `pre-push` commands are configured to run in parallel.
|
||||
- Only `pre-commit` and `pre-push` are supported here.
|
||||
- The command is wrapped with `writeShellApplication`.
|
||||
- `pre-commit` and `pre-push` stages are configured to run in parallel.
|
||||
- `passFilenames = true` maps to `{staged_files}` for `pre-commit` and `{push_files}` for `pre-push`.
|
||||
|
||||
## Raw Lefthook config
|
||||
|
||||
Use `config.lefthook` or `perSystem.lefthook` for advanced Lefthook features that the built-in `checks` abstraction does not carry.
|
||||
Use `config.lefthook` or `perSystem.lefthook` when the task needs advanced Lefthook features or unsupported stages.
|
||||
|
||||
Example:
|
||||
Pass-through attrset example:
|
||||
|
||||
```nix
|
||||
{
|
||||
checks.tests = {
|
||||
command = "go test ./...";
|
||||
command = "bun test";
|
||||
stage = "pre-push";
|
||||
runtimeInputs = [ pkgs.bun ];
|
||||
};
|
||||
|
||||
lefthook.pre-push.commands.tests.stage_fixed = true;
|
||||
|
||||
lefthook.commit-msg.commands.commitlint = {
|
||||
run = "pnpm commitlint --edit {1}";
|
||||
run = "bun commitlint --edit {1}";
|
||||
stage_fixed = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Structured hook-entry example in a raw hook list:
|
||||
|
||||
```nix
|
||||
perSystem = { pkgs, ... }: {
|
||||
lefthook.biome = {
|
||||
entry = "${pkgs.biome}/bin/biome check";
|
||||
pass_filenames = true;
|
||||
stages = [ "pre-commit" "pre-push" ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- These attrsets are passed through to `lefthook.nix`.
|
||||
- They are merged after generated checks, so they can extend generated commands.
|
||||
- Prefer `checks` for the simple common case and `lefthook` for advanced fields such as `stage_fixed`, `files`, `glob`, `exclude`, `jobs`, or `scripts`.
|
||||
- `config.lefthook` and `perSystem.lefthook` are recursive attrset passthroughs merged after generated checks.
|
||||
- Structured hook entries support only:
|
||||
`description`, `enable`, `entry`, `name`, `package`, `pass_filenames`, `stages`
|
||||
- `stages` may include `pre-commit`, `pre-push`, or `commit-msg`.
|
||||
- `pass_filenames = true` maps to `{1}` for `commit-msg`.
|
||||
|
||||
## Tools
|
||||
|
||||
@@ -152,17 +216,19 @@ Preferred shape in `perSystem.tools`:
|
||||
|
||||
```nix
|
||||
(repo-lib.lib.tools.fromPackage {
|
||||
name = "Go";
|
||||
package = pkgs.go;
|
||||
exe = "go"; # optional
|
||||
name = "Bun";
|
||||
package = pkgs.bun;
|
||||
version = {
|
||||
args = [ "version" ];
|
||||
args = [ "--version" ];
|
||||
match = null;
|
||||
regex = null;
|
||||
group = 0;
|
||||
line = 1;
|
||||
};
|
||||
banner = {
|
||||
color = "CYAN";
|
||||
color = "YELLOW";
|
||||
icon = "";
|
||||
iconColor = null;
|
||||
};
|
||||
required = true;
|
||||
})
|
||||
@@ -174,7 +240,10 @@ For a tool that should come from the host `PATH` instead of `nixpkgs`:
|
||||
(repo-lib.lib.tools.fromCommand {
|
||||
name = "Nix";
|
||||
command = "nix";
|
||||
version.args = [ "--version" ];
|
||||
version = {
|
||||
args = [ "--version" ];
|
||||
group = 1;
|
||||
};
|
||||
})
|
||||
```
|
||||
|
||||
@@ -186,10 +255,11 @@ repo-lib.lib.tools.simple "Go" pkgs.go [ "version" ]
|
||||
|
||||
Tool behavior:
|
||||
|
||||
- Tool packages are added to the shell automatically.
|
||||
- Package-backed tools are added to the shell automatically.
|
||||
- Command-backed tools are probed from the existing `PATH` and are not added to the shell automatically.
|
||||
- Banner probing uses absolute executable paths.
|
||||
- Banner probing uses the resolved executable path.
|
||||
- `required = true` by default.
|
||||
- When `version.match` is set, the first matching output line is selected before `regex` extraction.
|
||||
- Required tool probe failure aborts shell startup.
|
||||
|
||||
Use `shell.packages` instead of `tools` when:
|
||||
@@ -246,73 +316,66 @@ Set `release = null` to disable the generated release package.
|
||||
}
|
||||
```
|
||||
|
||||
### `run`
|
||||
### `versionMetaSet`
|
||||
|
||||
```nix
|
||||
{
|
||||
run = {
|
||||
script = ''
|
||||
curl -fsS https://example.invalid/hook \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"tag":"'"$FULL_TAG"'"}'
|
||||
'';
|
||||
runtimeInputs = [ pkgs.curl ];
|
||||
versionMetaSet = {
|
||||
key = "desktop_binary_version_max";
|
||||
value = "$FULL_VERSION";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Also accepted for compatibility:
|
||||
### `versionMetaUnset`
|
||||
|
||||
- `{ run = ''...''; }`
|
||||
- legacy `mkRelease { release = [ { file = ...; content = ...; } ... ]; }`
|
||||
```nix
|
||||
{
|
||||
versionMetaUnset = {
|
||||
key = "desktop_unused";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Current supported step kinds are only `writeFile`, `replace`, `versionMetaSet`, and `versionMetaUnset`.
|
||||
- Do not document or implement a `run` step in consumer repos unless the library itself gains that feature.
|
||||
|
||||
## Release ordering
|
||||
|
||||
The generated `release` command does this:
|
||||
The generated `release` command currently does this:
|
||||
|
||||
1. Update `VERSION`
|
||||
2. Run `release.steps`
|
||||
3. Run `postVersion`
|
||||
4. Run `nix fmt`
|
||||
5. `git add -A`
|
||||
6. Commit
|
||||
7. Tag
|
||||
8. Push branch
|
||||
9. Push tags
|
||||
1. Require a clean git worktree
|
||||
2. Update `VERSION`
|
||||
3. Run `release.steps`
|
||||
4. Run `postVersion`
|
||||
5. Run `nix fmt`
|
||||
6. `git add -A`
|
||||
7. Commit with `chore(release): <tag>`
|
||||
8. Tag
|
||||
9. Push branch
|
||||
10. Push tags
|
||||
|
||||
Important consequence:
|
||||
Important consequences:
|
||||
|
||||
- `postVersion` is still before commit, tag, and push.
|
||||
- `postVersion` is before formatting, commit, tag, and push.
|
||||
- There is no true post-tag or post-push hook in current `repo-lib`.
|
||||
- The current release runner is opinionated and performs commit, tag, and push as part of the flow.
|
||||
|
||||
## Post-tag webhook limitation
|
||||
## `mkRelease`
|
||||
|
||||
If the user asks for a webhook after the tag exists remotely:
|
||||
`repo-lib.lib.mkRelease` remains available when a repo wants only the release package:
|
||||
|
||||
- Prefer CI triggered by pushed tags in the consuming repo.
|
||||
- Do not claim `postVersion` is post-tag; it is not.
|
||||
- Only extend `repo-lib` itself if the user explicitly wants a new library capability.
|
||||
```nix
|
||||
repo-lib.lib.mkRelease {
|
||||
system = system;
|
||||
nixpkgsInput = nixpkgs; # optional
|
||||
channels = [ "alpha" "beta" "rc" "internal" ];
|
||||
steps = [ ];
|
||||
postVersion = "";
|
||||
runtimeInputs = [ ];
|
||||
}
|
||||
```
|
||||
|
||||
## Legacy API summary
|
||||
|
||||
`mkDevShell` still supports:
|
||||
|
||||
- `extraPackages`
|
||||
- `preToolHook`
|
||||
- `extraShellHook`
|
||||
- `lefthook`
|
||||
- `additionalHooks`
|
||||
- old `tools = [ { name; bin; versionCmd; color; } ]`
|
||||
- `features.oxfmt`
|
||||
- `formatters`
|
||||
- `formatterSettings`
|
||||
|
||||
`mkRelease` still supports:
|
||||
|
||||
- `release = [ ... ]` as legacy alias for `steps`
|
||||
- `extraRuntimeInputs` as legacy alias merged into `runtimeInputs`
|
||||
|
||||
When a repo already uses these APIs:
|
||||
|
||||
- preserve them unless the user asked to migrate
|
||||
- do not mix old and new styles accidentally in the same call
|
||||
Use the same release-step rules as `config.release`.
|
||||
|
||||
@@ -7,18 +7,22 @@ Edit `perSystem.tools` in the consuming repo:
|
||||
```nix
|
||||
tools = [
|
||||
(repo-lib.lib.tools.fromPackage {
|
||||
name = "Go";
|
||||
package = pkgs.go;
|
||||
version.args = [ "version" ];
|
||||
banner.color = "CYAN";
|
||||
name = "Bun";
|
||||
package = pkgs.bun;
|
||||
version.args = [ "--version" ];
|
||||
banner = {
|
||||
color = "YELLOW";
|
||||
icon = "";
|
||||
};
|
||||
})
|
||||
];
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Do not also add `pkgs.go` to `shell.packages`; `tools` already adds it.
|
||||
- Use `exe = "name"` only when the package exposes multiple binaries or the main program is not the desired one.
|
||||
- Do not also add the same package to `shell.packages`; `tools` already adds package-backed tools to the shell.
|
||||
- Use `exe = "name"` only when the package exposes multiple binaries or the default binary is not the right one.
|
||||
- Use `fromCommand` when the executable should come from the host environment instead of `nixpkgs`.
|
||||
|
||||
## Add a non-banner package to the shell
|
||||
|
||||
@@ -37,16 +41,38 @@ Use this for:
|
||||
- internal scripts
|
||||
- the generated `release` package itself
|
||||
|
||||
## Add a test phase or lint hook
|
||||
## Customize the shell banner
|
||||
|
||||
For a simple global check:
|
||||
Use `config.shell.banner`:
|
||||
|
||||
```nix
|
||||
config.checks.tests = {
|
||||
command = "go test ./...";
|
||||
config.shell.banner = {
|
||||
style = "pretty";
|
||||
icon = "☾";
|
||||
title = "Moonrepo shell ready";
|
||||
titleColor = "GREEN";
|
||||
subtitle = "Bun + TypeScript + Varlock";
|
||||
subtitleColor = "GRAY";
|
||||
borderColor = "BLUE";
|
||||
};
|
||||
```
|
||||
|
||||
Guidance:
|
||||
|
||||
- Use `style = "pretty"` when the repo already has a styled shell banner.
|
||||
- Keep icons and colors consistent with the repo's current shell UX.
|
||||
- Remember that required tool probe failures will still abort shell startup.
|
||||
|
||||
## Add a test phase or lint hook
|
||||
|
||||
For a simple shared check:
|
||||
|
||||
```nix
|
||||
config.checks.typecheck = {
|
||||
command = "bun run typecheck";
|
||||
stage = "pre-push";
|
||||
passFilenames = false;
|
||||
runtimeInputs = [ pkgs.go ];
|
||||
runtimeInputs = [ pkgs.bun ];
|
||||
};
|
||||
```
|
||||
|
||||
@@ -54,20 +80,44 @@ For a system-specific check:
|
||||
|
||||
```nix
|
||||
perSystem = { pkgs, ... }: {
|
||||
checks.lint = {
|
||||
command = "bun test";
|
||||
stage = "pre-push";
|
||||
runtimeInputs = [ pkgs.bun ];
|
||||
checks.format = {
|
||||
command = "oxfmt --check .";
|
||||
stage = "pre-commit";
|
||||
passFilenames = false;
|
||||
runtimeInputs = [ pkgs.oxfmt ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Guidance:
|
||||
|
||||
- Use `pre-commit` for fast format/lint work.
|
||||
- Use `pre-commit` for fast format or lint work.
|
||||
- Use `pre-push` for slower test suites.
|
||||
- Prefer `runtimeInputs` over inline absolute paths when the command needs extra CLIs.
|
||||
|
||||
## Add a `commit-msg` hook
|
||||
|
||||
`config.checks` cannot target `commit-msg`. Use raw Lefthook config:
|
||||
|
||||
```nix
|
||||
config.lefthook.commit-msg.commands.gitlint = {
|
||||
run = "${pkgs.gitlint}/bin/gitlint --staged --msg-filename {1}";
|
||||
stage_fixed = true;
|
||||
};
|
||||
```
|
||||
|
||||
Or use a structured hook entry:
|
||||
|
||||
```nix
|
||||
perSystem = { pkgs, ... }: {
|
||||
lefthook.commitlint = {
|
||||
entry = "${pkgs.nodejs}/bin/node scripts/commitlint.mjs";
|
||||
pass_filenames = true;
|
||||
stages = [ "commit-msg" ];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Add or change formatters
|
||||
|
||||
Use `config.formatting`:
|
||||
@@ -76,11 +126,12 @@ Use `config.formatting`:
|
||||
config.formatting = {
|
||||
programs = {
|
||||
shfmt.enable = true;
|
||||
gofmt.enable = true;
|
||||
oxfmt.enable = true;
|
||||
};
|
||||
|
||||
settings = {
|
||||
shfmt.options = [ "-i" "2" "-s" "-w" ];
|
||||
oxfmt.excludes = [ "*.md" "*.yml" ];
|
||||
};
|
||||
};
|
||||
```
|
||||
@@ -116,31 +167,27 @@ config.release.steps = [
|
||||
];
|
||||
```
|
||||
|
||||
## Add a webhook during release
|
||||
|
||||
If the webhook may run before commit and tag creation, use a `run` step or `postVersion`.
|
||||
|
||||
Use a `run` step when it belongs with other release mutations:
|
||||
Update metadata inside `VERSION`:
|
||||
|
||||
```nix
|
||||
config.release = {
|
||||
runtimeInputs = [ pkgs.curl ];
|
||||
steps = [
|
||||
{
|
||||
run = {
|
||||
script = ''
|
||||
curl -fsS https://example.invalid/release-hook \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"version":"'"$FULL_VERSION"'"}'
|
||||
'';
|
||||
runtimeInputs = [ pkgs.curl ];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
config.release.steps = [
|
||||
{
|
||||
versionMetaSet = {
|
||||
key = "desktop_binary_version_max";
|
||||
value = "$FULL_VERSION";
|
||||
};
|
||||
}
|
||||
{
|
||||
versionMetaUnset = {
|
||||
key = "desktop_unused";
|
||||
};
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
Use `postVersion` when the action should happen after all `steps`:
|
||||
## Add a webhook during release
|
||||
|
||||
Current `repo-lib` does not expose a `run` release step. If the action must happen during local release execution, put it in `postVersion`:
|
||||
|
||||
```nix
|
||||
config.release.postVersion = ''
|
||||
@@ -153,8 +200,8 @@ config.release.runtimeInputs = [ pkgs.curl ];
|
||||
|
||||
Important:
|
||||
|
||||
- Both of these still run before commit, tag, and push.
|
||||
- They are not true post-tag hooks.
|
||||
- `postVersion` still runs before `nix fmt`, commit, tag, and push.
|
||||
- This is not a true post-tag hook.
|
||||
|
||||
## Add a true post-tag webhook
|
||||
|
||||
@@ -162,11 +209,11 @@ Do not fake this with `postVersion`.
|
||||
|
||||
Preferred approach in the consuming repo:
|
||||
|
||||
1. Keep local release generation in `repo-lib`.
|
||||
2. Add CI triggered by tag push.
|
||||
3. Put the webhook call in CI, where the tag is already created and pushed.
|
||||
1. Keep local version generation in `repo-lib`.
|
||||
2. Trigger CI from tag push.
|
||||
3. Put the webhook call in CI, where the tag already exists remotely.
|
||||
|
||||
Only change `repo-lib` itself if the user explicitly asks for a new local post-tag capability.
|
||||
Only change `repo-lib` itself if the user explicitly asks for a new library capability.
|
||||
|
||||
## Add impure bootstrap work
|
||||
|
||||
@@ -175,8 +222,9 @@ Only do this when the user actually wants imperative shell setup:
|
||||
```nix
|
||||
config.shell = {
|
||||
bootstrap = ''
|
||||
export GOBIN="$PWD/.tools/bin"
|
||||
export PATH="$GOBIN:$PATH"
|
||||
export BUN_INSTALL_GLOBAL_DIR="$PWD/.tools/bun/install/global"
|
||||
export BUN_INSTALL_BIN="$PWD/.tools/bun/bin"
|
||||
export PATH="$BUN_INSTALL_BIN:$PATH"
|
||||
'';
|
||||
allowImpureBootstrap = true;
|
||||
};
|
||||
@@ -184,14 +232,14 @@ config.shell = {
|
||||
|
||||
Do not add bootstrap work for normal Nix-packaged tools.
|
||||
|
||||
## Migrate a legacy consumer to `mkRepo`
|
||||
## Move from direct `mkRelease` to `mkRepo`
|
||||
|
||||
Only do this if requested.
|
||||
|
||||
Migration outline:
|
||||
|
||||
1. Move repeated shell/check/formatter config into `config`.
|
||||
2. Move old banner tools into `perSystem.tools`.
|
||||
3. Move extra shell packages into `perSystem.shell.packages`.
|
||||
4. Replace old `mkRelease { release = [ ... ]; }` with `config.release.steps`.
|
||||
1. Move release package config into `config.release`.
|
||||
2. Move shell setup into `config.shell` and `perSystem.shell.packages`.
|
||||
3. Move bannered CLIs into `perSystem.tools`.
|
||||
4. Move hook commands into `config.checks` or raw `lefthook`.
|
||||
5. Keep behavior the same first; do not redesign the repo in the same change unless asked.
|
||||
|
||||
Reference in New Issue
Block a user