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
22 changes: 21 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,26 @@ jobs:
# (pgxntool marks installcheck `.IGNORE`), so failures would pass silently.
make verify-results

# Style linter (https://github.com/Postgres-Extensions/linter, vendored at
# .vendor/linter). Deliberately checked out WITHOUT submodules -- `make
# lint` is the same command a developer runs locally, and lint.mk
# self-initializes the submodule on first use (see its comment). Using the
# exact same entry point here is what actually proves that self-init works,
# rather than papering over it with a submodules: true checkout. The
# linter's own test suite (fixtures + scanner edge cases) is that repo's
# own CI's job, not this one's. No PostgreSQL needed -- sql-lint is a
# standalone Perl script -- so this doesn't use the pgxn-tools container.
lint:
needs: [changes]
if: needs.changes.outputs.docs_only != 'true'
name: 🧹 SQL Lint
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v6
- name: Lint SQL
run: make lint

# Proves cat_tools survives a BINARY pg_upgrade (in-place catalog migration to a
# newer PostgreSQL major), not just an in-place extension update. Each leg is a
# SINGLE jump: install an old cat_tools on an old cluster, plant a dependency
Expand Down Expand Up @@ -555,7 +575,7 @@ jobs:
# the heavy jobs gated off by the `changes` job on a docs-only push), and
# fails if any failed or were cancelled.
all-checks-passed:
needs: [changes, test, pg-upgrade-test, pg-upgrade-stepwise, extension-update-test]
needs: [changes, test, lint, pg-upgrade-test, pg-upgrade-stepwise, extension-update-test]
if: always()
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule ".vendor/linter"]
path = .vendor/linter
url = https://github.com/Postgres-Extensions/linter.git
1 change: 1 addition & 0 deletions .vendor/linter
Submodule linter added at b8632c
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,16 @@ $(DESTDIR)$(datadir)/extension/cat_tools--0.2.0.sql:
.PHONY: clean_old_version
clean_old_version:
pgxn uninstall --unstable 'cat_tools=0.2.0'

# Style linter (see https://github.com/Postgres-Extensions/linter, vendored
# at .vendor/linter -- lint.mk is the thin local hand-off, see its comment).
# Scoped to the actively-maintained source rather than the default
# `sql/ test/`: version-specific install/update scripts under sql/ are
# frozen once released (SQL file conventions rule 5 in CLAUDE.md — never
# hand-edited again), so linting them would produce permanent, unfixable
# findings and make `make lint` unusable as a CI gate. Lint the current
# source instead; a version file still under active development can be
# linted directly, e.g.
# `.vendor/linter/sql/bin/sql-lint sql/cat_tools--0.3.0.sql.in`.
LINT_TARGETS = sql/cat_tools.sql.in sql/omit_column.sql test/
include lint.mk
11 changes: 11 additions & 0 deletions lint.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# lint.mk — thin wrapper; the whole local footprint for consuming
# https://github.com/Postgres-Extensions/linter. Everything else lives in
# the .vendor/linter submodule; see its README for available targets/rules.
#
# Self-initializing (via the rule below) so `make lint` works right after a
# plain `git clone`, with no --recurse-submodules needed, and so CI can rely
# on the exact same entry point a developer would use locally.
.vendor/linter/lint.mk:
git submodule update --init -- .vendor/linter

include .vendor/linter/lint.mk
46 changes: 37 additions & 9 deletions sql.mk
Original file line number Diff line number Diff line change
Expand Up @@ -199,23 +199,51 @@ define _apply_version_seds
{print}' $@.tmp > $@.tmp2 && mv $@.tmp2 $@.tmp
endef

# The recipe builds $@.tmp then moves it into place atomically.
# ----------------------------------------------------------------------------
# Two .sql.in sources feed the same .sql.in -> .sql transform below (wrap with
# @generated@ markers, then _apply_version_seds), producing two different
# targets:
#
# sql/cat_tools.sql.in (hand-maintained master, committed)
# --pattern rule--> sql/cat_tools.sql
#
# sql/cat_tools.sql.in
# --copy rule, tags @generated@ as "VERSIONED FILE!"-->
# sql/cat_tools--X.Y.Z.sql.in (committed per-version snapshot; frozen
# once released, see CLAUDE.md's SQL file conventions)
# --override rule, same transform as the pattern rule-->
# sql/cat_tools--X.Y.Z.sql = $(EXTENSION_VERSION_FILES)
# (what CREATE EXTENSION actually installs)
#
# The bottom (override) rule can't just be left to the sql/%.sql pattern rule
# matching it: control.mk (auto-generated by pgxntool from cat_tools.control,
# see pgxntool/base.mk) already defines its OWN recipe for
# $(EXTENSION_VERSION_FILES) -- straight from cat_tools.sql, no .sql.in layer,
# no version seds -- and GNU Make always prefers an explicit rule over a
# pattern rule for the same target. Overriding it here is the only way to
# route that target through the same .sql.in / version-sed pipeline as
# everything else; its "overriding recipe" warning is expected. Both final
# steps build $@.tmp then move it into place atomically.
#
# TODO: refactor the version handling into a function.
# ----------------------------------------------------------------------------

# @generated@ becomes the "-- GENERATED FILE! DO NOT EDIT!" marker below via a
# plain, unanchored substring match -- it also fires on a handful of
# coincidental @generated@ occurrences inside real-code comments in
# cat_tools.sql.in, which is harmless (already inside a -- comment).
sql/%.sql: sql/%.sql.in pgxntool/safesed
(echo @generated@ && cat $< && echo @generated@) | sed -e 's#@generated@#-- GENERATED FILE! DO NOT EDIT! See $<#' > $@.tmp
$(_apply_version_seds)
mv $@.tmp $@

# Make the current version's .sql.in by copying the base source; the pattern
# rule above then turns it into the final .sql with SED substitutions applied.
# (EXTENSION_VERSION_FILES is just sql/cat_tools--<current version>.sql)
# Appends " VERSIONED FILE!" after every @generated@ occurrence; the pattern
# rule above resolves the leading @generated@ either way, so the tag rides
# through into the final marker text untouched.
$(EXTENSION_VERSION_FILES:.sql=.sql.in): sql/cat_tools.sql.in cat_tools.control
cp $< $@
sed -e 's/@generated@/@generated@ VERSIONED FILE!/' $< > $@

# Override control.mk's rule (which builds EXTENSION_VERSION_FILES straight from
# cat_tools.sql, skipping SED) so we build from the .sql.in above instead, with
# version-conditional substitutions applied. GNU Make's "overriding recipe"
# warning for this target is expected.
# See the overview above for why this duplicates the pattern rule's recipe.
$(EXTENSION_VERSION_FILES): $(EXTENSION_VERSION_FILES:.sql=.sql.in) pgxntool/safesed
(echo @generated@ && cat $< && echo @generated@) | sed -e 's#@generated@#-- GENERATED FILE! DO NOT EDIT! See $<#' > $@.tmp
$(_apply_version_seds)
Expand Down
Loading
Loading