From e732ecb878fe9648ed69635ce76a8334aea62d8b Mon Sep 17 00:00:00 2001 From: yukkop Date: Thu, 30 Apr 2026 12:00:08 +0000 Subject: [PATCH] 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). --- package/db-tool/README.md | 21 +++++++ package/db-tool/default.nix | 94 +++++++++++++++++--------------- package/db-tool/postgres-init.sh | 7 ++- 3 files changed, 77 insertions(+), 45 deletions(-) diff --git a/package/db-tool/README.md b/package/db-tool/README.md index e265599..9003257 100644 --- a/package/db-tool/README.md +++ b/package/db-tool/README.md @@ -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. | | `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_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. | | `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 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: diff --git a/package/db-tool/default.nix b/package/db-tool/default.nix index 8d71a2b..83073a1 100644 --- a/package/db-tool/default.nix +++ b/package/db-tool/default.nix @@ -2,61 +2,67 @@ let shell = "${dash}/bin/dash"; - database = hectic.writeShellApplication { - inherit shell; - bashOptions = [ - "errexit" - "nounset" - ]; - # SC2209: false positive — PAGER_OR_CAT=cat stores the string "cat" intentionally - excludeShellChecks = [ "SC2209" ]; - name = "database"; - runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql_17 neovim openssh coreutils gawk ]; + mkDatabase = + { postgresql ? postgresql_17 }: + hectic.writeShellApplication { + inherit shell; + bashOptions = [ + "errexit" + "nounset" + ]; + # SC2209: false positive — PAGER_OR_CAT=cat stores the string "cat" intentionally + excludeShellChecks = [ "SC2209" ]; + name = "database"; + runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql neovim openssh coreutils gawk ]; - text = '' - ${builtins.readFile hectic.helpers.posix-shell.log} - ${builtins.readFile hectic.helpers.posix-shell.change_namespace} - ${builtins.readFile hectic.helpers.posix-shell.quote} - ${builtins.readFile hectic.helpers.posix-shell.pager_or_cat} - ${builtins.readFile ./database.sh} - ''; + text = '' + ${builtins.readFile hectic.helpers.posix-shell.log} + ${builtins.readFile hectic.helpers.posix-shell.change_namespace} + ${builtins.readFile hectic.helpers.posix-shell.quote} + ${builtins.readFile hectic.helpers.posix-shell.pager_or_cat} + ${builtins.readFile ./database.sh} + ''; - meta = { - description = "PostgreSQL development database management"; - mainProgram = "database"; + meta = { + description = "PostgreSQL development database management"; + mainProgram = "database"; + }; }; - }; - postgresInit = hectic.writeShellApplication { - inherit shell; - bashOptions = [ ]; - name = "postgres-init"; - runtimeInputs = [ postgresql_17 coreutils ]; + mkPostgresInit = + { postgresql ? postgresql_17 }: + hectic.writeShellApplication { + inherit shell; + bashOptions = [ ]; + name = "postgres-init"; + runtimeInputs = [ postgresql coreutils ]; - text = builtins.readFile ./postgres-init.sh; + text = builtins.readFile ./postgres-init.sh; - meta = { - description = "Initialize local PostgreSQL instance"; - mainProgram = "postgres-init"; + meta = { + description = "Initialize local PostgreSQL instance"; + mainProgram = "postgres-init"; + }; }; - }; - postgresCleanup = hectic.writeShellApplication { - inherit shell; - bashOptions = [ ]; - name = "postgres-cleanup"; - runtimeInputs = [ postgresql_17 coreutils ]; + mkPostgresCleanup = + { postgresql ? postgresql_17 }: + hectic.writeShellApplication { + inherit shell; + bashOptions = [ ]; + name = "postgres-cleanup"; + runtimeInputs = [ postgresql coreutils ]; - text = builtins.readFile ./postgres-cleanup.sh; + text = builtins.readFile ./postgres-cleanup.sh; - meta = { - description = "Clean up local PostgreSQL instance"; - mainProgram = "postgres-cleanup"; + meta = { + description = "Clean up local PostgreSQL instance"; + mainProgram = "postgres-cleanup"; + }; }; - }; in { - "db-tool" = database; - "postgres-init" = postgresInit; - "postgres-cleanup" = postgresCleanup; + "db-tool" = lib.makeOverridable mkDatabase { }; + "postgres-init" = lib.makeOverridable mkPostgresInit { }; + "postgres-cleanup" = lib.makeOverridable mkPostgresCleanup { }; } diff --git a/package/db-tool/postgres-init.sh b/package/db-tool/postgres-init.sh index 2a9a89f..f47a84a 100644 --- a/package/db-tool/postgres-init.sh +++ b/package/db-tool/postgres-init.sh @@ -24,7 +24,12 @@ postgres_init_main() { rm -rf "$data" "$sockdir" || return 1 mkdir -p "$sockdir" || 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 fi