Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 0 additions & 78 deletions .claude/commands/commit.md

This file was deleted.

19 changes: 0 additions & 19 deletions .claude/settings.json

This file was deleted.

9 changes: 9 additions & 0 deletions HISTORY.asc
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
1.0.0
-----
== Add test-build for pre-test validation
New optional feature validates extension SQL syntax before running the full test suite. Place SQL files in `test/build/` to catch syntax errors early with better error messages than `CREATE EXTENSION` failures. Auto-detects based on file presence.

== Add test/install for one-time test setup
New optional feature runs `test/install/` SQL files before the main test suite via a schedule file, all within a single `pg_regress` invocation. State created by install files (tables, extensions, etc.) persists into regular tests. Auto-detects based on file presence.

== Add verify-results safeguard for make results
`make results` now refuses to run when tests are failing (detected via `regression.diffs`). Prevents accidentally updating expected files with incorrect output. Enabled by default; disable with `PGXNTOOL_ENABLE_VERIFY_RESULTS=no`.

== Fix broken multi-extension support
Prior to this fix, distributions with multiple extensions or extensions with versions different from the PGXN distribution version were completely broken. Extension versions are now correctly read from each `.control` file's `default_version` instead of using META.json's distribution version.

Expand Down
133 changes: 132 additions & 1 deletion README.asc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,119 @@ Runs unit tests via the PGXS `installcheck` target. Unlike a simple `make instal

NOTE: While you can still run `make installcheck` or any other valid PGXS make target directly, it's recommended to use `make test` when using pgxntool. The `test` target ensures clean builds, proper test isolation, and correct dependency installation.

=== test-build
Validates that extension SQL files are syntactically correct before running the full test suite. This feature runs SQL files from `test/build/` through `pg_regress`, providing better error messages than `CREATE EXTENSION` failures when there are syntax errors in your extension code.

**How it works:**

1. Place SQL files in `test/build/*.sql` (or `test/build/input/*.source` for source-processed files)
2. Place expected output in `test/build/expected/*.out`
3. These files run through `pg_regress` before `make test` runs the main test suite
4. If any build test fails, the test run stops immediately with clear error messages

**Directory structure:**

----
test/build/
β”œβ”€β”€ *.sql # SQL test files (checked in)
β”œβ”€β”€ input/ # Optional: .source files for pg_regress processing
β”‚ └── *.source
β”œβ”€β”€ expected/ # Expected output files (checked in)
β”‚ └── *.out
└── sql/ # GENERATED - do not edit or check in
└── *.sql # Copied from *.sql above; generated from input/*.source
----

The `sql/` subdirectory is generated automatically by `make test-build`. It is listed in `.gitignore` and removed by `make clean`. Do not place files directly in `test/build/sql/`.

**Configuration:**

The feature auto-detects based on whether `test/build/*.sql` or `test/build/input/*.source` files exist:

- Files present β†’ feature enabled automatically
- No files β†’ feature disabled (no impact on existing projects)

You can override auto-detection by setting `PGXNTOOL_ENABLE_TEST_BUILD`:
----
# In your Makefile
PGXNTOOL_ENABLE_TEST_BUILD = yes # or no
----

**Example: Validate extension SQL compiles**

Create `test/build/build.sql` to run your extension's SQL directly:

----
\set ECHO none
\i test/pgxntool/psql.sql
\t

BEGIN;
SET client_min_messages = WARNING;

-- Install dependencies your extension requires
CREATE EXTENSION IF NOT EXISTS pgtap CASCADE;
CREATE EXTENSION IF NOT EXISTS some_dependency CASCADE;

-- Clean slate
DROP EXTENSION IF EXISTS myext;
DROP SCHEMA IF EXISTS myext;
CREATE SCHEMA myext;

-- Run the actual extension SQL (not CREATE EXTENSION)
\i sql/myext.sql

\echo # BUILD TEST SUCCEEDED
ROLLBACK;
----

This approach catches SQL syntax errors *before* running `CREATE EXTENSION`, giving clearer error messages with line numbers. The `ROLLBACK` ensures nothing persistsβ€”this is purely validation.

**Why use `\i` instead of `CREATE EXTENSION`?**

When `CREATE EXTENSION` fails, PostgreSQL shows only "syntax error" with limited context. Running the SQL directly via `\i` shows the exact line and position of errors, making debugging much faster.

=== test/install
Runs setup files before the main test suite within the same `pg_regress` invocation. This allows expensive one-time operations (like extension installation) to set up state that persists into the regular test files.

**How it works:**

1. Place SQL files in `test/install/*.sql`
2. Place expected output alongside as `test/install/*.out`
3. A schedule file is auto-generated that lists install files with `../install/` relative paths
4. `pg_regress` processes the install schedule first, then runs regular test files β€” all in one invocation, so database state persists

**Directory structure:**

----
test/install/
β”œβ”€β”€ *.sql # SQL setup files (checked in)
β”œβ”€β”€ *.out # Expected output (checked in, alongside .sql)
β”œβ”€β”€ .gitignore # Ignores pg_regress artifacts (*.out.diff)
└── schedule # GENERATED - auto-created by make
----

The `schedule` file is generated automatically and listed in `.gitignore`. Do not edit it.

**Configuration:**

The feature auto-detects based on whether `test/install/*.sql` files exist:

- Files present β†’ feature enabled automatically
- No files β†’ feature disabled (no impact on existing projects)

You can override auto-detection by setting `PGXNTOOL_ENABLE_TEST_INSTALL`:
----
# In your Makefile
PGXNTOOL_ENABLE_TEST_INSTALL = yes # or no
----

**Why this is useful:**

Without `test/install`, each test file typically needs to run `CREATE EXTENSION` in its setup, which adds overhead and doesn't allow validating the installation step separately. With `test/install`, setup runs once before all tests, and any state it creates (tables, extensions, etc.) is available to every subsequent test file.

**Key detail:** Install files and regular tests run in a single `pg_regress` invocation. This means the database is NOT dropped between install and test phases β€” state created by install files persists into the main test suite.

=== testdeps
This rule allows you to ensure certain actions have taken place before running tests. By default it has a single prerequisite, `pgtap`, which will attempt to install http://pgtap.org[pgtap] from PGXN. This depneds on having the pgxn client installed.

Expand Down Expand Up @@ -78,6 +191,24 @@ IMPORTANT: *`make results` requires manual verification first*. The correct work

Never run `make results` without first verifying the test changes are correct. The `results` target copies files from `test/results/` to `test/expected/`, so running it blindly will make incorrect output become the new expected behavior.

==== verify-results safeguard
By default, `make results` will refuse to run if `test/results/regression.diffs` exists (indicating failing tests). This prevents accidentally updating expected files with incorrect output.

If tests are failing, you'll see:
----
ERROR: Tests are failing. Cannot run 'make results'.
Fix test failures first, then run 'make results'.
----

To disable this safeguard (not recommended):
----
# In your Makefile
PGXNTOOL_ENABLE_VERIFY_RESULTS = no

# Or on the command line
make PGXNTOOL_ENABLE_VERIFY_RESULTS=no results
----

=== tag
`make tag` will create a git branch for the current version of your extension, as determined by the META.json file. The reason to do this is so you can always refer to the exact code that went into a released version.

Expand Down Expand Up @@ -223,7 +354,7 @@ Location of `asciidoc` or equivalent executable.
If not set PGXNtool will search for first `asciidoctor`, then `asciidoc`.
ASCIIDOC_EXTS::
File extensions to consider as Asciidoc.
Defined as `+= adoc asciidoc`.
Defined as `+= adoc asciidoc asc`.
ASCIIDOC_FILES::
Asciidoc input files.
PGXNtool searches each `$(DOC_DIRS)` directory, looking for files with any `$(ASCIIDOC_EXTS)` extension.
Expand Down
Loading