chore: scaffold dev-env module (options + config + lib stubs)
default.nix composes the three sub-modules. options.nix declares the public surface (projects, regtest, fakewallet, tmux) so consumers can wire values today even though config.nix is empty. lib.nix reserves dev-env-scoped helpers separate from the global lnbits-sensei.lib. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6adc82e8f3
commit
a21428e482
4 changed files with 238 additions and 0 deletions
29
modules/dev-env/config.nix
Normal file
29
modules/dev-env/config.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# lnbits-sensei dev-env — wire-up.
|
||||||
|
#
|
||||||
|
# Skeleton-only. The substantive pass will:
|
||||||
|
# - install the regtest.sh / fakewallet.sh wrappers on PATH
|
||||||
|
# - render a /etc/dev-env/config.sh consumed by the loose bash
|
||||||
|
# helpers (worktree nav, upstream-PR helper)
|
||||||
|
# - emit systemd.user units for any long-running pieces
|
||||||
|
# - hook into config.lnbits-sensei.git.remotes to drive the
|
||||||
|
# bootstrap script's remote reconciliation
|
||||||
|
#
|
||||||
|
# Empty body for now so the module composes cleanly.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf;
|
||||||
|
cfg = config.lnbits-sensei.devEnv;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# TODO(skeleton): wire scripts, systemd units, and the
|
||||||
|
# /etc/dev-env/config.sh render here. See omnixy
|
||||||
|
# modules/dev-env/config.nix for the reference shape.
|
||||||
|
};
|
||||||
|
}
|
||||||
16
modules/dev-env/default.nix
Normal file
16
modules/dev-env/default.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# lnbits-sensei dev-env — entry point.
|
||||||
|
#
|
||||||
|
# Composes the dev-env sub-modules (option schema, helpers, wire-up).
|
||||||
|
# The dev-env module owns the workflow surface area: worktree
|
||||||
|
# management, navigation helpers, the regtest stack wrapper, the
|
||||||
|
# FakeWallet symmetric-no-op wrapper, and tmux session presets.
|
||||||
|
#
|
||||||
|
# It only configures tools — it never materializes repos on disk.
|
||||||
|
# That is the job of the user-invoked bootstrap script (later pass).
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./options.nix
|
||||||
|
./lib.nix
|
||||||
|
./config.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
32
modules/dev-env/lib.nix
Normal file
32
modules/dev-env/lib.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# lnbits-sensei dev-env — helpers.
|
||||||
|
#
|
||||||
|
# Skeleton-only. Place dev-env-internal helpers here (project path
|
||||||
|
# resolution, worktree-path expansion, remote-URL canonicalisation)
|
||||||
|
# rather than in the global `lnbits-sensei.lib` so they're scoped to
|
||||||
|
# the dev-env module and don't pollute the public helper namespace.
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
|
||||||
|
helpers = {
|
||||||
|
# Resolve a project's on-disk root given a project name.
|
||||||
|
# projectRoot = name: "${config.lnbits-sensei.devEnv.root}/${name}";
|
||||||
|
projectRoot = _name: throw "dev-env.lib.projectRoot: not yet implemented";
|
||||||
|
|
||||||
|
# Resolve a worktree path: <root>/<project>/<worktree>.
|
||||||
|
worktreePath =
|
||||||
|
_project: _worktree: throw "dev-env.lib.worktreePath: not yet implemented";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.lnbits-sensei.devEnv.lib = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
internal = true;
|
||||||
|
description = "dev-env-internal helpers (see modules/dev-env/lib.nix).";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
lnbits-sensei.devEnv.lib = helpers;
|
||||||
|
};
|
||||||
|
}
|
||||||
161
modules/dev-env/options.nix
Normal file
161
modules/dev-env/options.nix
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
# lnbits-sensei dev-env — option schema.
|
||||||
|
#
|
||||||
|
# Skeleton-only. Declares the option surface so consumers can wire
|
||||||
|
# values today and the substantive implementation can land later
|
||||||
|
# without churning the public API.
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkEnableOption mkOption types;
|
||||||
|
|
||||||
|
# One entry in dev-env.projects. A project is a git repo with one or
|
||||||
|
# more worktrees (or a single clone if `isClone = true`). Worktrees
|
||||||
|
# are derived from a bare repo at `${dev-env.root}/repos/<name>.git`
|
||||||
|
# by default.
|
||||||
|
projectType = types.submodule (
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
url = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Origin URL for this project. May be an upstream URL, a
|
||||||
|
personal fork, or a private mirror — the dev-env bootstrap
|
||||||
|
script reconciles the rest of the remote topology from
|
||||||
|
`lnbits-sensei.git.remotes`.
|
||||||
|
'';
|
||||||
|
example = "https://github.com/lnbits/lnbits";
|
||||||
|
};
|
||||||
|
|
||||||
|
worktrees = mkOption {
|
||||||
|
type = types.attrsOf (
|
||||||
|
types.submodule {
|
||||||
|
options = {
|
||||||
|
branch = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Branch to check out in this worktree.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Worktrees to materialize for this project, keyed by
|
||||||
|
worktree name. Each becomes a directory under the project
|
||||||
|
root.
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
main = { branch = "main"; };
|
||||||
|
dev = { branch = "dev"; };
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
isClone = mkEnableOption ''
|
||||||
|
Treat as a plain clone rather than a bare-repo + worktrees
|
||||||
|
set. Use for projects you won't have multiple simultaneous
|
||||||
|
branches checked out for
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# One entry in dev-env.tmux.sessions. Mirrors the omnixy shape so
|
||||||
|
# the `dev-tm <name>` launcher can ship later with a familiar API.
|
||||||
|
tmuxSessionType = types.submodule {
|
||||||
|
options = {
|
||||||
|
cwd = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Session-default cwd, relative to dev-env.root.";
|
||||||
|
};
|
||||||
|
windows = mkOption {
|
||||||
|
type = types.listOf (
|
||||||
|
types.submodule {
|
||||||
|
options = {
|
||||||
|
name = mkOption { type = types.str; };
|
||||||
|
cwd = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
cmd = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Command to run in the window on creation.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.lnbits-sensei.devEnv = {
|
||||||
|
enable = mkEnableOption "lnbits-sensei dev-env tooling";
|
||||||
|
|
||||||
|
root = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/home/${config.lnbits-sensei.user or "user"}/dev";
|
||||||
|
defaultText = "/home/\${config.lnbits-sensei.user}/dev";
|
||||||
|
description = ''
|
||||||
|
Root directory for the dev environment. Worktrees and project
|
||||||
|
clones live under this prefix; bare repos under
|
||||||
|
`''${root}/repos/`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
projects = mkOption {
|
||||||
|
type = types.attrsOf projectType;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Hand-authored project list. Consumed by the bootstrap script
|
||||||
|
(later pass) to materialize repos and worktrees on disk.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
regtest = {
|
||||||
|
enable = mkEnableOption ''
|
||||||
|
Bitcoin/Lightning regtest docker stack. Wraps an upstream
|
||||||
|
fork of `lnbits/legend-regtest-enviroment` (LND + CLN +
|
||||||
|
Eclair + bitcoind + electrs). Implies a container engine —
|
||||||
|
the substantive pass will gate this on a containers feature
|
||||||
|
'';
|
||||||
|
|
||||||
|
repoUrl = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "https://github.com/lnbits/legend-regtest-enviroment";
|
||||||
|
description = ''
|
||||||
|
Git URL of the regtest docker-compose repo. Cloned by the
|
||||||
|
dev-env bootstrap script. Point at your own fork if you've
|
||||||
|
customised the stack.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fakewallet = {
|
||||||
|
enable = mkEnableOption ''
|
||||||
|
FakeWallet dev mode helpers. Installs the symmetric `fakewallet`
|
||||||
|
wrapper script (a no-op for parity with `regtest up`) so the
|
||||||
|
dev experience is identical whether you're on the default
|
||||||
|
FakeWallet path or the full regtest stack
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tmux = {
|
||||||
|
enable = mkEnableOption "declarative tmux session launcher";
|
||||||
|
|
||||||
|
sessions = mkOption {
|
||||||
|
type = types.attrsOf tmuxSessionType;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Named tmux session layouts. The launcher script (later pass)
|
||||||
|
reads these at runtime and recreates the session.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in a new issue