feat: db-tool: update hook realization
This commit is contained in:
+26
-3
@@ -115,19 +115,42 @@ in {
|
||||
hectic = let
|
||||
versionString = lib.fileContents ./hook/sql/HECTIC_VERSION;
|
||||
static = path: { inherit path; sql = builtins.readFile path; };
|
||||
templated = path: {
|
||||
templated = path: let
|
||||
sql = builtins.replaceStrings
|
||||
[ "@HECTIC_VERSION@" ]
|
||||
[ versionString ]
|
||||
(builtins.readFile path);
|
||||
};
|
||||
in {
|
||||
inherit sql;
|
||||
path = builtins.toFile (builtins.baseNameOf (toString path)) sql;
|
||||
};
|
||||
in rec {
|
||||
inherit versionString;
|
||||
version = templated ./hook/sql/hectic-version.sql;
|
||||
secret = static ./hook/sql/hectic-secret.sql;
|
||||
migration = static ./hook/sql/hectic-migration.sql;
|
||||
inheritance = static ./hook/sql/hectic-inheritance.sql;
|
||||
applyBundleScript = ./hook/apply-hectic-bundle.sh;
|
||||
bundleFiles = [
|
||||
version.path
|
||||
secret.path
|
||||
migration.path
|
||||
inheritance.path
|
||||
];
|
||||
applyBundleScript =
|
||||
builtins.replaceStrings
|
||||
[
|
||||
"@HECTIC_VERSION_SQL@"
|
||||
"@HECTIC_SECRET_SQL@"
|
||||
"@HECTIC_MIGRATION_SQL@"
|
||||
"@HECTIC_INHERITANCE_SQL@"
|
||||
]
|
||||
[
|
||||
"${version.path}"
|
||||
"${secret.path}"
|
||||
"${migration.path}"
|
||||
"${inheritance.path}"
|
||||
]
|
||||
(builtins.readFile ./hook/apply-hectic-bundle.sh);
|
||||
};
|
||||
|
||||
# Back-compat alias. Prefer `self.lib.hectic.inheritance`.
|
||||
|
||||
@@ -7,17 +7,12 @@
|
||||
#
|
||||
# Idempotent: each SQL file uses IF NOT EXISTS / CREATE OR REPLACE.
|
||||
#
|
||||
# Required env (caller injects from Nix):
|
||||
# HECTIC_VERSION_SQL - path to hectic-version.sql (substituted)
|
||||
# HECTIC_SECRET_SQL - path to hectic-secret.sql
|
||||
# HECTIC_MIGRATION_SQL - path to hectic-migration.sql
|
||||
# HECTIC_INHERITANCE_SQL - path to hectic-inheritance.sql
|
||||
#
|
||||
# Usage:
|
||||
# apply_hectic_bundle <PGURL> [<DOTENV_CONTENT>]
|
||||
#
|
||||
# If DOTENV_CONTENT is non-empty, it is loaded into hectic.secret via
|
||||
# hectic.load_secrets_from_env() after the bundle is applied.
|
||||
# SQL file paths are substituted by Nix evaluation time.
|
||||
|
||||
apply_hectic_bundle() {
|
||||
pgurl="${1:-}"
|
||||
@@ -28,22 +23,22 @@ apply_hectic_bundle() {
|
||||
return 3
|
||||
fi
|
||||
|
||||
for var in HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL; do
|
||||
eval "val=\${$var:-}"
|
||||
if [ -z "$val" ]; then
|
||||
printf '%s\n' "apply-hectic-bundle: $var not set" >&2
|
||||
return 3
|
||||
fi
|
||||
if [ ! -r "$val" ]; then
|
||||
printf '%s\n' "apply-hectic-bundle: $var not readable: $val" >&2
|
||||
set -- \
|
||||
"@HECTIC_VERSION_SQL@" \
|
||||
"@HECTIC_SECRET_SQL@" \
|
||||
"@HECTIC_MIGRATION_SQL@" \
|
||||
"@HECTIC_INHERITANCE_SQL@"
|
||||
|
||||
for sql_path do
|
||||
if [ ! -r "$sql_path" ]; then
|
||||
printf '%s\n' "apply-hectic-bundle: SQL file not readable: $sql_path" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_VERSION_SQL" || return 1
|
||||
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_SECRET_SQL" || return 1
|
||||
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_MIGRATION_SQL" || return 1
|
||||
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_INHERITANCE_SQL" || return 1
|
||||
for sql_path do
|
||||
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$sql_path" || return 1
|
||||
done
|
||||
|
||||
if [ -n "$env_content" ]; then
|
||||
# Dollar-quote with $ps_env$ tag to preserve all content verbatim.
|
||||
|
||||
+18
-21
@@ -42,23 +42,26 @@ that already matches.
|
||||
```nix
|
||||
self.lib.hectic = {
|
||||
versionString; # e.g. "0.1.0"
|
||||
version = { sql; }; # templated
|
||||
version = { sql; path; }; # templated
|
||||
secret = { sql; path; };
|
||||
migration = { sql; path; };
|
||||
inheritance = { sql; path; };
|
||||
applyBundleScript; # ./hook/apply-hectic-bundle.sh
|
||||
bundleFiles; # ordered bundle file paths
|
||||
applyBundleScript; # generated helper shell source with paths embedded
|
||||
};
|
||||
```
|
||||
|
||||
`.sql` is the file contents as a string. `.path` is the Nix store path of the
|
||||
verbatim source (only available on non-templated entries; consumers needing a
|
||||
materialized version of `version.sql` must do
|
||||
`pkgs.runCommand "hectic-version.sql" { text = self.lib.hectic.version.sql; passAsFile = ["text"]; } ''cp "$textPath" "$out"''`).
|
||||
materialized file to pass to `psql -f`. `version.path` is generated at Nix
|
||||
evaluation time from the templated SQL; the other `*.path` entries point at the
|
||||
verbatim source files in the store.
|
||||
|
||||
## Shell helper (`apply-hectic-bundle.sh`)
|
||||
|
||||
`lib/hook/apply-hectic-bundle.sh` is a dash-compatible helper sourced by both
|
||||
`migrator` and `db-tool`. Public entry point:
|
||||
`lib/hook/apply-hectic-bundle.sh` is a dash-compatible helper template.
|
||||
`self.lib.hectic.applyBundleScript` is the generated shell source with concrete
|
||||
SQL paths embedded at Nix evaluation time. `migrator` and `db-tool` splice that
|
||||
shell source directly into their generated scripts. Public entry point:
|
||||
|
||||
```sh
|
||||
apply_hectic_bundle <PGURL> [<DOTENV_CONTENT>]
|
||||
@@ -70,25 +73,19 @@ apply_hectic_bundle <PGURL> [<DOTENV_CONTENT>]
|
||||
dollar-quoted (`$ps_env$`) string so secret values cannot terminate the
|
||||
literal.
|
||||
|
||||
Required environment (paths to the SQL files):
|
||||
|
||||
- `HECTIC_VERSION_SQL`
|
||||
- `HECTIC_SECRET_SQL`
|
||||
- `HECTIC_MIGRATION_SQL`
|
||||
- `HECTIC_INHERITANCE_SQL`
|
||||
|
||||
`migrator` and `db-tool` set these via Nix at build time. External consumers
|
||||
typically invoke `psql -f` against the paths directly instead of sourcing the
|
||||
helper.
|
||||
The SQL file paths are embedded into the helper at Nix evaluation time, so
|
||||
callers only need to source the generated script and call the function.
|
||||
External consumers that do not want to source the helper can still invoke
|
||||
`psql -f` against `self.lib.hectic.bundleFiles` or the individual
|
||||
`self.lib.hectic.*.path` entries directly.
|
||||
|
||||
## Adding a new SQL file
|
||||
|
||||
1. Add `lib/hook/sql/hectic-<name>.sql`.
|
||||
2. Wire it into `lib/default.nix` under `lib.hectic.<name>`.
|
||||
3. Inject `HECTIC_<NAME>_SQL` in both `package/migrator/default.nix` and
|
||||
`package/db-tool/default.nix`.
|
||||
4. Append a `psql -f "$HECTIC_<NAME>_SQL"` step to
|
||||
`lib/hook/apply-hectic-bundle.sh` in the correct order.
|
||||
3. Add its `.path` to `lib.hectic.bundleFiles` in the correct order.
|
||||
4. Add a matching placeholder/replacement in `lib.hectic.applyBundleScript` and
|
||||
update `lib/hook/apply-hectic-bundle.sh` to apply the file.
|
||||
5. Bump `HECTIC_VERSION` if the new content changes existing semantics.
|
||||
6. Update tests in `test/package/migrator/test/postgresql/init-hectic-bundle/`
|
||||
and `test/package/db-tool/test/postgresql/hydrate-hook/`.
|
||||
|
||||
@@ -210,15 +210,13 @@ directly against the paths exposed by `self.lib.hectic.*.path`:
|
||||
|
||||
```nix
|
||||
services.postgresql.initialScript = pkgs.writeText "hectic-init.sql" ''
|
||||
\i ${self.lib.hectic.version.path}
|
||||
\i ${self.lib.hectic.secret.path}
|
||||
\i ${self.lib.hectic.migration.path}
|
||||
\i ${self.lib.hectic.inheritance.path}
|
||||
'';
|
||||
```
|
||||
|
||||
The version file (`self.lib.hectic.version`) is templated and only exposes
|
||||
`.sql` (a string). Materialize it with `pkgs.writeText` if a path is needed.
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|
||||
@@ -1,30 +1,12 @@
|
||||
{ dash, hectic, postgresql_17, neovim, openssh, coreutils, gawk, lib, runCommand, self }:
|
||||
let
|
||||
shell = "${dash}/bin/dash";
|
||||
|
||||
hecticInheritanceSqlPath = ../../lib/hook/sql/hectic-inheritance.sql;
|
||||
|
||||
hecticInheritance = runCommand "hectic-inheritance" { } ''
|
||||
mkdir -p "$out/share/hectic"
|
||||
cp ${hecticInheritanceSqlPath} "$out/share/hectic/hectic-inheritance.sql"
|
||||
cp ${self.lib.hectic.inheritance.path} "$out/share/hectic/hectic-inheritance.sql"
|
||||
'';
|
||||
|
||||
# Materialize the templated version SQL into the Nix store as a real file
|
||||
# so it can be passed by path to psql -f (alongside the static siblings).
|
||||
hecticVersionSqlFile = pkgs-writeText "hectic-version.sql" self.lib.hectic.version.sql;
|
||||
pkgs-writeText = name: text: runCommand name { inherit text; passAsFile = [ "text" ]; } ''
|
||||
cp "$textPath" "$out"
|
||||
'';
|
||||
|
||||
hecticEnv = ''
|
||||
HECTIC_VERSION_SQL=${hecticVersionSqlFile}
|
||||
HECTIC_SECRET_SQL=${self.lib.hectic.secret.path}
|
||||
HECTIC_MIGRATION_SQL=${self.lib.hectic.migration.path}
|
||||
HECTIC_INHERITANCE_SQL=${self.lib.hectic.inheritance.path}
|
||||
export HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL
|
||||
'';
|
||||
|
||||
applyBundle = builtins.readFile self.lib.hectic.applyBundleScript;
|
||||
applyBundle = self.lib.hectic.applyBundleScript;
|
||||
|
||||
mkDatabase =
|
||||
{ postgresql ? postgresql_17 }:
|
||||
@@ -44,7 +26,6 @@ let
|
||||
${builtins.readFile hectic.helpers.posix-shell.quote}
|
||||
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
|
||||
${builtins.readFile hectic.helpers.posix-shell.with_closed_fds}
|
||||
${hecticEnv}
|
||||
${applyBundle}
|
||||
${builtins.readFile ./database.sh}
|
||||
'';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ dash, hectic, sqlite, postgresql_17, gawk, runCommand, self }:
|
||||
{ dash, hectic, sqlite, postgresql_17, gawk, self }:
|
||||
let
|
||||
shell = "${dash}/bin/dash";
|
||||
bashOptions = [
|
||||
@@ -6,20 +6,7 @@ let
|
||||
"nounset"
|
||||
];
|
||||
|
||||
hecticVersionSqlFile = runCommand "hectic-version.sql" {
|
||||
text = self.lib.hectic.version.sql;
|
||||
passAsFile = [ "text" ];
|
||||
} ''cp "$textPath" "$out"'';
|
||||
|
||||
hecticEnv = ''
|
||||
HECTIC_VERSION_SQL=${hecticVersionSqlFile}
|
||||
HECTIC_SECRET_SQL=${self.lib.hectic.secret.path}
|
||||
HECTIC_MIGRATION_SQL=${self.lib.hectic.migration.path}
|
||||
HECTIC_INHERITANCE_SQL=${self.lib.hectic.inheritance.path}
|
||||
export HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL
|
||||
'';
|
||||
|
||||
applyBundle = builtins.readFile self.lib.hectic.applyBundleScript;
|
||||
applyBundle = self.lib.hectic.applyBundleScript;
|
||||
|
||||
migrator = hectic.writeShellApplication {
|
||||
inherit shell bashOptions;
|
||||
@@ -28,7 +15,6 @@ let
|
||||
|
||||
text = ''
|
||||
${builtins.readFile hectic.helpers.posix-shell.log}
|
||||
${hecticEnv}
|
||||
${applyBundle}
|
||||
${builtins.readFile ./migrator.sh}
|
||||
'';
|
||||
|
||||
Reference in New Issue
Block a user