Commit Graph
227 Commits
Author SHA1 Message Date
warkanum e1df3b7cee fix(writers): drop version stamps from generated output
Generated files carried the RelSpec version and build date, so every
rebuild produced a diff even when the schema was unchanged.

- bun, gorm, drizzle: remove the GeneratedBy template field and line
- pgsql, mssql, sqlite: emit a constant "-- Generated by RelSpec"
- bun: replace the version header test with a version-free assertion

pkg/buildinfo is unchanged and still backs the CLI version.
2026-09-24 15:40:37 +02:00
warkanum f7b5d5f054 chore(release): update package version to 1.0.83
Release / pkg-deb (push) Successful in 1m47s
Release / test (push) Successful in 59s
Release / release (push) Successful in 2m0s
Release / pkg-aur (push) Successful in 54s
Release / pkg-rpm (push) Successful in 1m56s
v1.0.83
2026-09-23 18:52:48 +02:00
warkanum 99fc4b0944 Merge pull request 'Fix/dbml commented refs duplicate indexes' (#31) from fix/dbml-commented-refs-duplicate-indexes into master
Reviewed-on: #31
2026-09-23 16:48:54 +00:00
warkanum 278d488363 chore(lint): use strings.EqualFold in jobs output format check 2026-09-23 18:48:07 +02:00
warkanum 2f69205aa0 fix(dbml): resolve commented cross-file // Ref: lines
Commented refs are collected per file and resolved against the combined
model after all inputs are loaded (directory, --from-list, merge, jobs).
Matched refs become FKs and relationships; duplicates of existing FKs are
skipped; missing targets are skipped with a warning; column type
mismatches warn.

Also keep reused index names within a DBML table instead of overwriting,
give a second FK to the same table a distinct relationship name, and make
the pgsql writer match relationships to FKs by name first.
2026-09-23 18:48:07 +02:00
warkanum b91985c493 feat(inspector): fail on duplicate index names per schema
PostgreSQL index names share the schema-wide relation namespace, so a
reused name makes CREATE INDEX IF NOT EXISTS silently skip the duplicate.
Add duplicate_index_name rule (enforce by default) covering indexes and
PK/unique constraint backing indexes.
2026-09-23 18:48:07 +02:00
warkanum 80a3453233 Merge pull request 'fix(jobs): preserve writer and template output options' (#30) from issue-29-job-manifest-options into master
Reviewed-on: #30
Reviewed-by: Warky <2+warkanum@noreply@warky.dev>
2026-09-21 04:00:50 +00:00
SG Command ade71b75fa fix(jobs): preserve writer and template output options 2026-09-20 23:16:41 +02:00
warkanum 799b7feb53 ci(rpm): update RPM builder to avoid transient mirrors 2026-09-20 21:41:52 +02:00
warkanum eb40201b59 chore(release): update package version to 1.0.82
Release / release (push) Successful in 1m50s
Release / pkg-aur (push) Successful in 1m0s
Release / pkg-deb (push) Successful in 1m17s
Release / test (push) Successful in 53s
Release / pkg-rpm (push) Failing after 16s
v1.0.82
2026-09-20 20:37:41 +02:00
warkanum 1461f8f69f chore(release): update version to 1.0.81 and metadata 2026-09-20 20:37:09 +02:00
warkanum ea70e19a46 feat(jobs): expand environment variables in paths 2026-09-20 20:08:20 +02:00
warkanum 52f4642d97 feat(models): add support for generated and identity columns
Release / test (push) Successful in 3m13s
Release / release (push) Successful in 1m52s
Release / pkg-aur (push) Successful in 1m39s
Release / pkg-deb (push) Successful in 2m15s
Release / pkg-rpm (push) Failing after 46s
* extend Column struct with Generated, GenerationExpression, Identity, and IdentityGeneration fields
* update queryColumns to handle new column properties
* modify migration writer to avoid altering generated and identity columns
* add tests to ensure correct handling of generated and identity columns
v1.0.81
2026-09-20 18:33:12 +02:00
warkanum a84592374c Merge pull request 'Feat generated headers column order' (#28) from feat-generated-headers-column-order into master
Release / pkg-rpm (push) Successful in 3m58s
Release / release (push) Successful in 1m54s
Release / test (push) Successful in 5m49s
Release / pkg-aur (push) Successful in 7m13s
Release / pkg-deb (push) Successful in 5m8s
Reviewed-on: #28
v1.0.80
2026-09-10 20:22:50 +00:00
warkanum ca226e83df feat(release): update release process to include linting and testing 2026-09-10 22:21:40 +02:00
warkanum 19a2cc1fe3 feat(writers): stamp RelSpec version in generated headers; preserve DBML column order
- Add pkg/buildinfo with Version/BuildDate (set via ldflags, VCS fallback);
  cmd/relspec now sources version info from it
- Emit "RelSpec <version> (built: <date>)" in generated file headers for
  bun, gorm, drizzle, pgsql (incl. migration), mssql, sqlite writers
- pgsql writer: getSortedColumns now sorts by Sequence then Name so the
  streaming WriteSchema/WriteDatabase path preserves source column order
- dbml reader: mergeTable re-bases merged-in column Sequence values past the
  existing max, fixing colliding sequences (and alphabetical fallback) when a
  table is split across multiple DBML files
- Tests for bun/gorm header + column order, and dbml multi-file merge ordering
2026-09-10 22:08:49 +02:00
warkanum 58e46e5b59 feat(dbml): support case-insensitive table note parsing
Release / test (push) Successful in 4m15s
Release / release (push) Successful in 5m29s
Release / pkg-rpm (push) Successful in 2m10s
Release / pkg-deb (push) Successful in 2m27s
Release / pkg-aur (push) Successful in 5m52s
v1.0.79
2026-09-09 22:31:00 +02:00
warkanum 161ac317f0 feat(dbml): support multiline table notes in DBML
Release / test (push) Successful in 1m45s
Release / release (push) Successful in 12m24s
Release / pkg-rpm (push) Successful in 2m3s
Release / pkg-deb (push) Successful in 2m17s
Release / pkg-aur (push) Successful in 2m47s
* Add parsing for triple-quoted table notes in DBML
* Update writer to format multiline notes correctly
* Enhance tests for multiline table notes handling
v1.0.78
2026-09-09 21:38:11 +02:00
warkanum ee5c009234 feat(main): add silent mode to suppress output messages
* implement --silent flag to control output verbosity
* update error handling to restore stderr after silent mode
* enhance progress reporting in PostgreSQL reader
2026-09-09 21:30:15 +02:00
warkanum 9e9a17d578 Merge pull request 'feat(dbml): @postgres/@sqlite dialect directives (#19)' (#27) from issue-19-dbml-directives into master
Release / test (push) Successful in 58s
Release / release (push) Successful in 5m13s
Release / pkg-aur (push) Successful in 1m0s
Release / pkg-rpm (push) Successful in 2m55s
Release / pkg-deb (push) Successful in 3m21s
Reviewed-on: #27
v1.0.77
2026-09-08 14:19:02 +00:00
warkanum 7b628b888c Merge pull request 'feat(job): complete deferred job-file features (#20)' (#26) from issue-20-complete-job-files into master
Reviewed-on: #26
2026-09-08 14:18:57 +00:00
HeinandClaude Sonnet 5 ce3b615b0a feat(dbml): @postgres/@sqlite dialect directives (#19)
Add parseable `@<namespace>[(<target>)]: <args>` directives embedded in DBML.
They are stored losslessly on each object's Metadata, round-trip unchanged
through the DBML writer, and are translated to SQL only by the writer for the
matching dialect.

- models: Directive type + catalog; Metadata map added to Column and Index
- dbml reader: parse and attach directives at database/table/column/index
  level; line-numbered errors; repeatable by default with singleton duplicate
  detection. Fixes a preexisting bug where an `indexes {}` closing brace ended
  the table early, dropping trailing Note: and directive lines.
- dbml writer: re-emit directives at their location; idempotent output
- pgsql writer: PARTITION BY / INHERITS / WITH / TABLESPACE (table),
  STORAGE / COMPRESSION / identity (column), WITH / TABLESPACE (index)
- sqlite writer: WITHOUT ROWID / STRICT (table), COLLATE (column)
- --strict-directives flag on ReaderOptions and WriterOptions
- docs/DBML_DIRECTIVES.md + reader/writer READMEs

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ss2MY5J11cRGwEz86ZXk7d
2026-09-08 16:17:37 +02:00
Hein 84a6b31873 feat(job): complete deferred job-file features
Implements the remaining items from issue #20:

- version is now forward-permissive: any value >= 1 is accepted; a
  newer-than-known version loads best-effort (unknown fields ignored,
  warning printed) instead of hard-failing on "must be 1"
- from_job input reference: `inputs: [{ from_job: <job> }]` resolves to
  that job's single-file output + format and implies a dependency edge;
  combined depends_on + from_job graph gets topological ordering and
  cycle detection
- logfile size-rotation, on by default (5MB, keep 3), overridable per
  job (log_max_size / log_keep) or file-wide via a top-level defaults block
- new commands: split (schema/table subsetting via select:), inspect
  (rule validation -> markdown/json report, fails job on enforced-rule
  errors), diff (compare exactly two schemas, never fails), scripts-exec
  (run SQL script dirs against a live PostgreSQL database)
- atomic single-file output/report writes (temp file + rename)
- symlink-escape hardening in SafeJoin via EvalSymlinks preflight

Updates docs/JOB_FILES.md and examples/jobs/relspec.yml accordingly.
2026-09-08 14:32:07 +02:00
warkanum f968e3d4a6 Merge pull request 'feat(job): support templ command' (#25) from issue-20-templ-job-command into master
Reviewed-on: #25
2026-09-08 11:04:33 +00:00
SG Command 3d57c947cd feat(job): support templ command 2026-09-08 06:17:45 +02:00
warkanum cdd066dafe fix(sqltypes): serialize SqlTimeStamp as RFC3339
Release / test (push) Successful in 2m22s
Release / pkg-rpm (push) Successful in 1m37s
Release / release (push) Successful in 8m23s
Release / pkg-aur (push) Successful in 48s
Release / pkg-deb (push) Successful in 1m31s
Marshal JSON/YAML/XML and driver Value now emit time.RFC3339 instead of
the offset-less "2006-01-02T15:04:05" layout; zero-time guards compare
against the RFC3339 zero value. Parsing is unchanged and still accepts
bare datetimes.
v1.0.76
2026-09-03 22:12:36 +02:00
warkanum 5c25f333b7 fix(go.mod): update Go version to 1.25.13 2026-09-03 21:39:56 +02:00
warkanum 77e6e72f5a fix(ci): don't capture tool-download noise as a formatting diff
The gofumpt check merged stderr into the diff variable, so 'go:
downloading ...' lines made it always fail. Move tool installation into
its own step (adding GOPATH/bin to PATH) and capture only stdout.
2026-09-03 21:33:12 +02:00
warkanum 4d4bc09b86 fix(ci): run lint tools via 'go run' to match the toolchain
Installed staticcheck/govulncheck binaries can fail when built with an
older Go than the module targets, and GOPATH/bin is not always on PATH.
Compile them on demand with 'go run <tool>@latest' in both the workflow
and the Makefile.
2026-09-03 21:25:27 +02:00
warkanum 96281c9f03 chore(ci): add govulncheck, staticcheck, go vet, gofumpt gates
Release / release (push) Skipped
Release / pkg-aur (push) Skipped
Release / pkg-deb (push) Skipped
Release / pkg-rpm (push) Skipped
Release / test (push) Failing after 2m20s
* Add lint/format checks to the Gitea release workflow and Makefile
  (targets: vet, fmt, fmt-check, staticcheck, govulncheck, check)
* Switch .golangci.json formatter from gofmt to gofumpt (extra.group-params)
* Bump golang.org/x/text 0.37.0 -> 0.39.0 for GO-2026-5970; re-vendor
* Fix staticcheck S1011 in pkg/diff; drop unused pgsql writer helpers
* Fix gocritic unnamedResult (pkg/diff) and rangeValCopy (pkg/pgsql)
* Apply gofumpt + goimports formatting across the tree
v1.0.75
2026-09-03 21:17:03 +02:00
warkanum d6d0200938 Merge pull request 'feat(job): declarative YAML job files for named relspec workflows (#20)' (#24) from issue-20-job-files into master
Reviewed-on: #24
2026-09-02 04:16:39 +00:00
SG CommandandClaude Sonnet 5 4d299fda98 feat(job): declarative YAML job files for named relspec workflows
Add `relspec job list` and `relspec job run <name>` driven by YAML job
manifests (relspec.yml / relspec.<name>.yml), so multi-file merge and
conversion workflows can be expressed declaratively instead of as long
shell command lines.

v1 contract (see docs/JOB_FILES.md):
- `command` is a closed allow-list (convert, merge, scripts-list); no
  field accepts a shell string or executable path.
- Deterministic discovery: default file first, then named files sorted
  lexically; all files merged into one namespace; duplicate job names
  across files are a hard error.
- Every path resolves relative to the job file's directory; absolute,
  home-relative and directory-escaping paths are rejected at validation.
- Database credentials referenced by env-var name via `conn_env:`;
  connection strings are never stored and are redacted from logs/plan.
- Full validation (version, unknown fields, command/format, per-command
  input/output shape, path traversal, depends_on targets, dependency
  cycles) runs before anything is read, written or executed; per-job
  pre-flight then checks input existence, script dirs, env vars and the
  output overwrite policy for the whole plan.
- `depends_on` closure runs in deterministic topological order;
  `--no-deps` runs only the named job.
- `--dry-run` (alias `--plan`) prints the resolved plan and exits 0
  without touching inputs, outputs or databases.
- A failing job propagates the underlying non-zero exit status, logs
  FAILED (never OK), and writes no success marker.

pkg/jobs is side-effect free (discovery/parse/validate/plan only);
execution adapters live in cmd/relspec/job.go. Includes unit tests for
discovery, validation, planning and path safety, plus CLI tests for
end-to-end convert/merge, scripts-list across multiple directories,
dry-run, dependency chains, exit-code propagation and log redaction.

Deferred: live `scripts execute` from jobs, split/inspect/diff/templ
commands, job-to-job output wiring, log rotation/retention.

Refs #20

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 00:44:38 +02:00
warkanum 4115a11845 Merge pull request 'Fix PostgreSQL DBML diff round-trip' (#23) from issue-21-diff-roundtrip into master
Reviewed-on: #23
2026-08-31 04:10:17 +00:00
SG Command e8ac0e8c35 fix diff round-trip comparison 2026-08-31 02:05:32 +02:00
warkanum 098e927760 chore(release): update package version to 1.0.74
Release / test (push) Successful in 29s
Release / release (push) Successful in 38m38s
Release / pkg-deb (push) Successful in 3m58s
Release / pkg-rpm (push) Successful in 4m34s
Release / pkg-aur (push) Successful in 48s
v1.0.74
2026-08-29 20:40:45 +02:00
warkanum ab3c9217df feat(pgsql): support vector and PostGIS indexes with extensions
* Add handling for pgvector and PostGIS extensions in migration scripts
* Implement operator class and storage parameters for vector indexes
* Update tests to validate new index behaviors and extension creation
2026-08-29 20:39:57 +02:00
Hein 16af529120 chore(release): update package version to 1.0.73
Release / test (push) Successful in 1m57s
Release / release (push) Successful in 3m49s
Release / pkg-aur (push) Successful in 1m0s
Release / pkg-rpm (push) Successful in 1m43s
Release / pkg-deb (push) Successful in 1m46s
v1.0.73
2026-08-24 12:59:50 +02:00
Hein 7fb343596a fix(dbml): honor composite [pk] in Indexes blocks, preserve column order
A composite [pk] entry inside an Indexes block (e.g. (a, b) [pk]) was
silently dropped: models.Index has no way to represent a primary key,
so the attribute was parsed and ignored, producing neither a PK nor a
meaningful index. It's now converted into a PrimaryKeyConstraint.

Also, Column.Sequence was never set by the DBML reader, so composite
PKs assembled from column-level [pk] attributes fell back to
alphabetical Name sorting instead of declaration order. Columns now
get a per-table sequence counter reflecting the order they were
declared.
2026-08-24 12:59:18 +02:00
Hein 241bfc2302 feat(cli): always print version header first, add --no-version flag
Previously the version banner only printed via PersistentPreRun, which
Cobra skips for --help and bare invocations. It now prints from main()
before Cobra parses anything, so it's the first line for every command.
Suppressible with --no-version; skipped for the version subcommand to
avoid duplicating its own output.
2026-08-24 12:59:14 +02:00
Hein 92d5df9a64 fix(release): chmod deb control dir to fix dpkg-deb permission error
dpkg-deb rejects a control directory with permissions above 0775;
the Gitea runner's umask left mkdir -p at 0777.
2026-08-24 12:59:11 +02:00
Hein b440d50b66 chore(release): update package version to 1.0.72
Release / test (push) Successful in 1m38s
Release / release (push) Successful in 2m37s
Release / pkg-deb (push) Failing after 22s
Release / pkg-aur (push) Successful in 38s
Release / pkg-rpm (push) Successful in 1m33s
v1.0.72
2026-08-24 12:06:00 +02:00
Hein 052d6f5fac fix(sqlite): remove unnecessary newline in writeCheckConstraints 2026-08-24 12:05:50 +02:00
Hein 9066d36e71 chore(release): update package version to 1.0.71
Release / release (push) Successful in 2m54s
Release / pkg-deb (push) Failing after 23s
Release / pkg-aur (push) Successful in 1m6s
Release / pkg-rpm (push) Successful in 4m40s
Release / test (push) Successful in 30s
v1.0.71
2026-08-24 12:03:41 +02:00
Hein 76b8321065 feat(pgsql): add support for concurrent index creation
* Implemented `Concurrent` field in index model
* Updated index creation template to support `CREATE INDEX CONCURRENTLY`
* Added tests for concurrent index creation in migration writer
2026-08-24 12:03:30 +02:00
Hein 2b6bb7f948 fix(sqlite): emit inline foreign keys, bare-name default schema, direct exec
SQLite can't ALTER TABLE ADD CONSTRAINT, so foreign keys are now written
as inline FOREIGN KEY clauses in CREATE TABLE instead of commented-out
ALTER statements. The default schema (public/main) now produces bare
table names instead of a "public_" prefix; other schemas are still
prefixed to avoid collisions. Also adds direct-to-file execution: the
sqlite writer can now apply generated DDL straight to a .db file via
Metadata["connection_string"], wired into `relspec merge --output-conn`.
2026-08-24 11:52:24 +02:00
warkanum 51b63f659e Merge pull request 'feat: include SQL scripts in schema diff' (#17) from issue-16-migration-script-count into master
Reviewed-on: #17
2026-08-18 11:52:25 +00:00
Hein ae0efdc008 chore(release): update package version to 1.0.70
Release / test (push) Successful in 17s
Release / release (push) Successful in 2m43s
Release / pkg-deb (push) Failing after 37s
Release / pkg-aur (push) Successful in 52s
Release / pkg-rpm (push) Successful in 1m19s
v1.0.70
2026-08-18 13:43:04 +02:00
Hein be08c8199f fix(merge,pgsql): treat serial types as their base integer in diffs, unquote bare keyword defaults
Merge conflict detection compared bigserial (DBML) against bigint (live
PostgreSQL read of an existing serial column) as incompatible types, since
serial is sugar over an integer column plus a sequence default and
PostgreSQL always reports back the underlying integer type. Add
SerialUnderlyingType and use it when comparing column types for conflicts.

QuoteDefaultValue also wrapped bare keyword expressions like CURRENT_DATE
in string quotes because they contain no parentheses, unlike function-call
defaults such as now(). Recognize known bare keyword defaults and leave
them unquoted across CREATE TABLE, ALTER TABLE ADD COLUMN, and
ALTER COLUMN SET DEFAULT generation.
2026-08-18 13:42:34 +02:00
SG Command 5ba20e0581 feat: include SQL scripts in schema diff 2026-08-18 00:16:35 +02:00
warkanum 19b592820c chore(release): update package version to 1.0.69
Release / test (push) Successful in 4m9s
Release / release (push) Successful in 2m11s
Release / pkg-deb (push) Failing after 1m46s
Release / pkg-aur (push) Successful in 2m5s
Release / pkg-rpm (push) Successful in 2m36s
v1.0.69
2026-08-17 22:36:35 +02:00