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
63 changes: 47 additions & 16 deletions README.asc
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,19 @@ include pgxntool/base.mk
== make targets
These are the make targets that are provided by base.mk

NOTE: all the targets normally provided by Postgres http://www.postgresql.org/docs/current/static/extend-pgxs.html[PGXS] still work.
NOTE: all the targets normally provided by Postgres http://www.postgresql.org/docs/current/static/extend-pgxs.html[PGXS] still work. If you need to skip PGXS being included entirely (for advanced/non-standard setups), set `PGXNTOOL_NO_PGXS_INCLUDE` in your Makefile before `include pgxntool/base.mk`.

=== html
This will build any .html files that can be created. See <<_Document_Handling>>.

=== test
Runs unit tests via the PGXS `installcheck` target. Unlike a simple `make installcheck` though, the `test` rule has the following prerequisites: clean testdeps install installcheck. All of those are PGXS rules, except for `testdeps`.
Runs your extension's test suite: installs the extension and runs it through PGXS's `installcheck`, first pulling in anything you've hooked into <<_testdeps>> and, if enabled, sanity-checking your test SQL via <<_test_build>>.

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.
Whether `test-build` runs is controlled by the `PGXNTOOL_ENABLE_TEST_BUILD` variable — see <<_test_build>> for what it does and how to turn it on/off.

NOTE: `test` intentionally does *not* depend on `clean` — that caused problems with incremental/watch-based builds. If your tests need a clean build to pass, that's a sign of a missing dependency elsewhere rather than something to fix by adding `clean` back.

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 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.
Expand Down Expand Up @@ -227,15 +231,20 @@ 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.
By default, `make results` will refuse to run if your tests are failing, so you can't accidentally promote incorrect output into the new expected results. Which failures it looks for is controlled by `PGXNTOOL_VERIFY_RESULTS_MODE`:

`pgtap` (the default):: Scans `test/results/*.out` for pgTAP `not ok` lines (ignoring `# TODO` items) and plan-count mismatches, then also checks `test/results/regression.diffs` for any output mismatch pgTAP itself wouldn't catch.
`diffs`:: Only checks whether `test/results/regression.diffs` exists.

If tests are failing, `make results` prints an explanation of what failed and exits without touching `test/expected/`; fix the failures, then re-run `make results`.

If tests are failing, you'll see:
To select a mode explicitly:
----
ERROR: Tests are failing. Cannot run 'make results'.
Fix test failures first, then run 'make results'.
# In your Makefile
PGXNTOOL_VERIFY_RESULTS_MODE = diffs # or pgtap (the default)
----

To disable this safeguard (not recommended):
To disable this safeguard entirely (not recommended):
----
# In your Makefile
PGXNTOOL_ENABLE_VERIFY_RESULTS = no
Expand All @@ -245,9 +254,9 @@ make PGXNTOOL_ENABLE_VERIFY_RESULTS=no results
----

=== tag
`make tag` will create an annotated git tag for the current version of your extension, as determined by the META.json file (generated from `META.in.json` — see <<_pgxn_distributions_vs_extensions>>), and push it to `origin`. The reason to do this is so you can always refer to the exact code that went into a released version.
`make tag` will create a git tag for the current version of your extension, as determined by the META.json file (generated from `META.in.json` — see <<_pgxn_distributions_vs_extensions>>), and push it to `origin`. The reason to do this is so you can always refer to the exact code that went into a released version.

If there's already a tag for the current version that probably means you forgot to update META.json, so you'll get an error. If you're certain you want to over-write the tag, you can do `make forcetag`, which removes the existing tag (via `make rmtag`) and creates a new one.
If a tag for the current version already exists and points at your current commit, `make tag` does nothing — this makes it safe for other targets (like `dist`) to depend on `tag` without worrying about re-running it. If the existing tag points at a *different* commit — meaning you likely forgot to bump the version — you'll get an error. If you're certain you want to over-write the tag, you can do `make forcetag`, which removes the existing tag (via `make rmtag`) and creates a new one.

WARNING: You will be very unhappy if you forget to update the .control file for your extension! There is an https://github.com/decibel/pgxntool/issues/1[open issue] to improve this.

Expand All @@ -256,15 +265,27 @@ WARNING: You will be very unhappy if you forget to update the .control file for

NOTE: Part of the `clean` recipe is cleaning up these .zip files. If you accidentally clean before uploading, just run `make dist-only`.

WARNING: If your project has a `.gitattributes` file, `make dist`/`make dist-only` will refuse to run unless it's committed to git, and will tell you so. This is because `git archive` (which builds the .zip) only honors `export-ignore` attributes on *committed* files — an uncommitted `.gitattributes` would silently have no effect on the archive contents, which could leak files into your PGXN distribution that you meant to exclude.

`make forcedist` is a shortcut for `forcetag dist`: it force-recreates the tag (see `forcetag` above) before rebuilding the distribution .zip.

=== pgxntool-sync
This rule will pull down the latest released version of PGXNtool via `git subtree pull` and then reconcile the files `setup.sh` copied into your project (`.gitignore`, `test/deps.sql`) with a 3-way merge.

NOTE: Your repository must be clean (no modified files) in order to run this. Running this command will produce a git commit of the merge.

NOTE: `git subtree pull` copies pgxntool's entire tree into your project, including dev-only directories (`pgxntool/.github`, `pgxntool/.claude`) that don't belong in a project that merely embeds pgxntool. Every sync automatically removes these two directories from `pgxntool/` afterward — this is expected, not a bug, and doesn't affect anything else in your project.

TIP: The actual work is done by `pgxntool/pgxntool-sync.sh`, so you can run it directly (`pgxntool/pgxntool-sync.sh`) if you'd rather not go through `make`. It optionally takes `<repo>` and `<ref>` arguments to pull from somewhere other than the default.

TIP: There is also a `pgxntool-sync-%` rule if you need to do more advanced things. `make pgxntool-sync-<name>` pulls from the `<repo> <ref>` defined by the `pgxntool-sync-<name>` make variable.

=== list
`make list` prints every make target defined in your project — including ones provided by PGXS and pgxntool, not just ones you wrote — one per line. Useful for discovering what's available without reading through the Makefile.

=== print-%
`make print-VARNAME` prints the current value (and origin) of any make variable, e.g. `make print-PGXNVERSION`. Useful for debugging why a variable isn't set to what you expect.

=== distclean
`make distclean` removes generated configuration files (`META.json` — generated from `META.in.json` — plus `meta.mk` and `control.mk`) that survive a normal `make clean`.

Expand Down Expand Up @@ -293,7 +314,7 @@ make check-pgtle

=== run-pgtle
Registers all extensions with pg_tle by executing the generated pg_tle registration SQL files in a PostgreSQL database. This target:
- Requires pg_tle extension to be installed (checked via `check-pgtle`)
- Requires pg_tle to be installed in the target database. This isn't a make-level dependency on `check-pgtle` — `pgtle.sh` checks it itself when it runs, and will tell you to run `make check-pgtle` if pg_tle isn't there
- Uses `pgtle.sh` to determine which version range directory to use based on the installed pg_tle version
- Runs all generated SQL files via `psql` to register your extensions with pg_tle

Expand Down Expand Up @@ -459,9 +480,8 @@ PGXNtool replaces each `$(ASCIIDOC_EXTS)` in `$(ASCIIDOC_FILES)` with `html`.
The result is appended to `ASCIIDOC_HTML` using `+=`.

=== Document Rules
If Asciidoc is found (or `$(ASCIIDOC)` is set), the `html` rule will be added as a prerequisite to the `install` and `installchec` rules.
That will ensure that docs are generated for install and test, but only if Asciidoc is available.
The `dist` rule will always depend on `html` though, to ensure html files are up-to-date before creating a distribution.
If Asciidoc is found (or `$(ASCIIDOC)` is set), `html` is added as a dependency of the `all` target, which both `install` and `installcheck` depend on — so docs get built for install and test, but only if Asciidoc is available.
The `dist` rule always depends on `html` directly, regardless of whether Asciidoc was found, to ensure html files are up-to-date before creating a distribution.

The `html` rule simply depends on `$(ASCIIDOC_HTML).
This rule is always present.
Expand All @@ -474,11 +494,11 @@ These rules are generated from `ASCIIDOC_template`:
----
define ASCIIDOC_template
%.html: %.$(1) # <1>
ifndef ASCIIDOC
ifeq (,$(strip $(ASCIIDOC)))
$$(warning Could not find "asciidoc" or "asciidoctor". Add one of them to your PATH,)
$$(warning or set ASCIIDOC to the correct location.)
$$(error Could not build %$$@)
endif # ifndef ASCIIDOC
endif # ifeq ASCIIDOC
$$(ASCIIDOC) $$(ASCIIDOC_FLAGS) $$<
endef # define ASCIIDOC_template
----
Expand All @@ -488,6 +508,8 @@ These rules will *always* exist, even if `$(ASCIIDOC)` isn't set (ie: if Asciido
These rules will throw an error if they are run if `$(ASCIIDOC)` isn't defined.
On a normal user system that should never happen, because the `html` rule won't be included in `install` or `installcheck`.

`make docclean` removes all generated HTML files (`$(DOCS_HTML)`). It's separate from `make clean`/`make distclean`, so you can clear out generated docs without touching your build artifacts.

=== The DOCS variable
This variable has special meaning to PGXS.
See the Postgres documentation for full details.
Expand Down Expand Up @@ -565,6 +587,15 @@ myproject/
└── ext2.sql
----

==== Direct pgtle.sh Invocation

`pgtle`, `check-pgtle`, and `run-pgtle` are thin make wrappers around `pgxntool/pgtle.sh`. For more targeted operations you can run it directly:

- `pgtle.sh --extension NAME [--pgtle-version VERSION]` — generate registration SQL for one extension (what `make pgtle` wraps).
- `pgtle.sh --get-version` — print the pg_tle version installed in the target database (empty if not installed).
- `pgtle.sh --get-dir VERSION` — print which version-range directory (see <<_version_groupings>>) a given pg_tle version maps to, without generating anything.
- `pgtle.sh --run` — execute the generated registration SQL against the target database (what `make run-pgtle` wraps).

=== How It Works
`make pgtle` does the following:

Expand Down
Loading
Loading