feat(db-tool): expose overridable postgresql arg and PG_CONF_FILE env

Wrap db-tool, postgres-init, postgres-cleanup with lib.makeOverridable so
consumers can inject extension-enabled PostgreSQL via .override { postgresql = ...; }.
Add PG_CONF_FILE: when set, replaces script-generated postgresql.conf entirely
(runtime port and unix_socket_directories still appended/overridden).
This commit is contained in:
2026-04-30 12:00:08 +00:00
parent 705f5bbd01
commit e732ecb878
3 changed files with 77 additions and 45 deletions

View File

@@ -29,9 +29,30 @@ These variables must be set for `db-tool` to function.
| `DATABASE_SOURCE` | `${DATABASE_DIR}/src` | Directory containing source SQL files for hydration. | | `DATABASE_SOURCE` | `${DATABASE_DIR}/src` | Directory containing source SQL files for hydration. |
| `PG_URL_VAR` | `PGURL` | The name of the environment variable where the computed PG URL will be exported. | | `PG_URL_VAR` | `PGURL` | The name of the environment variable where the computed PG URL will be exported. |
| `PG_LOG_PATH` | (unset) | Path to redirect PostgreSQL server logs. | | `PG_LOG_PATH` | (unset) | Path to redirect PostgreSQL server logs. |
| `PG_CONF_FILE` | (unset) | Path to a `postgresql.conf` file. When set, replaces the script-generated config entirely on fresh init. `port` and `unix_socket_directories` are still appended at runtime (always overridden). When set, `PG_DISABLE_LOGGING` and `PG_SHARED_PRELOAD_LIBRARIES` are ignored. |
| `PG_SHARED_PRELOAD_LIBRARIES` | `pg_cron` | Comma-separated `shared_preload_libraries` value. Set to empty string to disable. Ignored when `PG_CONF_FILE` is set. |
| `PG_DISABLE_LOGGING` | `0` | Set to `1` to disable PostgreSQL logging collector. Ignored when `PG_CONF_FILE` is set. |
| `PATCH_LOG` | (stdout) | Path to log the output of database patches. | | `PATCH_LOG` | (stdout) | Path to log the output of database patches. |
| `HYDRATE_LOG` | (stdout) | Path to log the output of database hydration. | | `HYDRATE_LOG` | (stdout) | Path to log the output of database hydration. |
## Postgres Package Override
By default, `db-tool`/`postgres-init`/`postgres-cleanup` use plain `postgresql_17` from nixpkgs. If you need extensions (e.g. `pg_cron`), override the postgres package per-output:
```nix
let
myPg = pkgs.postgresql_17.withJIT.withPackages (_: [
pkgs.postgresql_17.pkgs.pg_cron
]);
in {
packages = [
(pkgs.hectic."db-tool".override { postgresql = myPg; })
(pkgs.hectic."postgres-init".override { postgresql = myPg; })
(pkgs.hectic."postgres-cleanup".override { postgresql = myPg; })
];
}
```
## pull_staging Contract ## pull_staging Contract
The `pull_staging` subcommand allows importing data from a remote staging environment into the local `test-data.sql` file. This functionality requires four specific environment variables to be defined: The `pull_staging` subcommand allows importing data from a remote staging environment into the local `test-data.sql` file. This functionality requires four specific environment variables to be defined:

View File

@@ -2,61 +2,67 @@
let let
shell = "${dash}/bin/dash"; shell = "${dash}/bin/dash";
database = hectic.writeShellApplication { mkDatabase =
inherit shell; { postgresql ? postgresql_17 }:
bashOptions = [ hectic.writeShellApplication {
"errexit" inherit shell;
"nounset" bashOptions = [
]; "errexit"
# SC2209: false positive — PAGER_OR_CAT=cat stores the string "cat" intentionally "nounset"
excludeShellChecks = [ "SC2209" ]; ];
name = "database"; # SC2209: false positive — PAGER_OR_CAT=cat stores the string "cat" intentionally
runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql_17 neovim openssh coreutils gawk ]; excludeShellChecks = [ "SC2209" ];
name = "database";
runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql neovim openssh coreutils gawk ];
text = '' text = ''
${builtins.readFile hectic.helpers.posix-shell.log} ${builtins.readFile hectic.helpers.posix-shell.log}
${builtins.readFile hectic.helpers.posix-shell.change_namespace} ${builtins.readFile hectic.helpers.posix-shell.change_namespace}
${builtins.readFile hectic.helpers.posix-shell.quote} ${builtins.readFile hectic.helpers.posix-shell.quote}
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat} ${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
${builtins.readFile ./database.sh} ${builtins.readFile ./database.sh}
''; '';
meta = { meta = {
description = "PostgreSQL development database management"; description = "PostgreSQL development database management";
mainProgram = "database"; mainProgram = "database";
};
}; };
};
postgresInit = hectic.writeShellApplication { mkPostgresInit =
inherit shell; { postgresql ? postgresql_17 }:
bashOptions = [ ]; hectic.writeShellApplication {
name = "postgres-init"; inherit shell;
runtimeInputs = [ postgresql_17 coreutils ]; bashOptions = [ ];
name = "postgres-init";
runtimeInputs = [ postgresql coreutils ];
text = builtins.readFile ./postgres-init.sh; text = builtins.readFile ./postgres-init.sh;
meta = { meta = {
description = "Initialize local PostgreSQL instance"; description = "Initialize local PostgreSQL instance";
mainProgram = "postgres-init"; mainProgram = "postgres-init";
};
}; };
};
postgresCleanup = hectic.writeShellApplication { mkPostgresCleanup =
inherit shell; { postgresql ? postgresql_17 }:
bashOptions = [ ]; hectic.writeShellApplication {
name = "postgres-cleanup"; inherit shell;
runtimeInputs = [ postgresql_17 coreutils ]; bashOptions = [ ];
name = "postgres-cleanup";
runtimeInputs = [ postgresql coreutils ];
text = builtins.readFile ./postgres-cleanup.sh; text = builtins.readFile ./postgres-cleanup.sh;
meta = { meta = {
description = "Clean up local PostgreSQL instance"; description = "Clean up local PostgreSQL instance";
mainProgram = "postgres-cleanup"; mainProgram = "postgres-cleanup";
};
}; };
};
in in
{ {
"db-tool" = database; "db-tool" = lib.makeOverridable mkDatabase { };
"postgres-init" = postgresInit; "postgres-init" = lib.makeOverridable mkPostgresInit { };
"postgres-cleanup" = postgresCleanup; "postgres-cleanup" = lib.makeOverridable mkPostgresCleanup { };
} }

View File

@@ -24,7 +24,12 @@ postgres_init_main() {
rm -rf "$data" "$sockdir" || return 1 rm -rf "$data" "$sockdir" || return 1
mkdir -p "$sockdir" || return 1 mkdir -p "$sockdir" || return 1
initdb -D "$data" --no-locale -E UTF8 || return 1 initdb -D "$data" --no-locale -E UTF8 || return 1
{ printf '%s\n' "listen_addresses = ''"; [ "$PG_DISABLE_LOGGING" -eq 0 ] && { printf '%s\n' 'logging_collector = on'; printf '%s\n' "log_directory = 'log'"; }; [ -n "$PG_SHARED_PRELOAD_LIBRARIES" ] && { printf '%s\n' "shared_preload_libraries = '$PG_SHARED_PRELOAD_LIBRARIES'"; printf '%s\n' "cron.database_name = '$db'"; printf '%s\n' "cron.host = '$sockdir'"; }; :; } >> "$data/postgresql.conf" || return 1 if [ -n "${PG_CONF_FILE:-}" ]; then
[ -r "$PG_CONF_FILE" ] || { printf '%s\n' "postgres-init: PG_CONF_FILE not readable: $PG_CONF_FILE" >&2; return 1; }
cp -f -- "$PG_CONF_FILE" "$data/postgresql.conf" || return 1
else
{ printf '%s\n' "listen_addresses = ''"; [ "$PG_DISABLE_LOGGING" -eq 0 ] && { printf '%s\n' 'logging_collector = on'; printf '%s\n' "log_directory = 'log'"; }; [ -n "$PG_SHARED_PRELOAD_LIBRARIES" ] && { printf '%s\n' "shared_preload_libraries = '$PG_SHARED_PRELOAD_LIBRARIES'"; printf '%s\n' "cron.database_name = '$db'"; printf '%s\n' "cron.host = '$sockdir'"; }; :; } >> "$data/postgresql.conf" || return 1
fi
sed -i "1ilocal all all trust" "$data/pg_hba.conf" || return 1 sed -i "1ilocal all all trust" "$data/pg_hba.conf" || return 1
fi fi