Skip to content

feat: batch renames, Python import rewrites and repairs of existing rule failures in sqb rename and sqb mv - #1229

Merged
kvlonge merged 3 commits into
mainfrom
feat/rename-move-batch
Oct 23, 2026
Merged

kvlonge merged 3 commits into
mainfrom
feat/rename-move-batch

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Why

Restructuring a project with sqb rename and sqb mv should be safe enough to do in one step. Renames had to run one per command, moved Python macros left broken imports, a project already failing a layout rule could not be repaired with sqb mv, and some failures printed nothing useful with --json.

Changes

  • sqb rename takes several model TARGET NEW_NAME pairs or --from-file: one compile before, one verification after, all or nothing, with migrate_from (and an old-name view) for each. Column renames and --cascade stay single; name reuse stays refused.
  • The scratch copy and the real write apply changes in the same order, so a chained move cannot lose a file after verification passed.
  • sqb mv rewrites project Python imports of moved Python files (direct, aliased, grouped, from-package, relative) through a reusable function in sqlbuild-pysource, and refuses with file and line when an import cannot be rewritten safely, or while a project Python file is not UTF-8.
  • Existing rule failures no longer block planning; SQL tests are still planned, as sqb compile does. A result failure is existing only with the same code, place and message, or when only its numbers fell. Anything else, and every non-rule error, blocks. Output and --dry-run explain before and after; JSON adds rule_baseline.
  • Input-stage failures such as a duplicate macro name are refused cleanly. With --json, a project that does not compile, or an invalid request, prints an error document on stdout.
  • Docs updated.

Verification

  • cargo test -p sqlbuild-refactor -p sqlbuild-pysource -p sqlbuild-cli.
  • DuckDB E2E for each change, including refusals: pytest tests/e2e/src/sqlbuild/cli/commands/main/refactor tests/integration/src/sqlbuild/cli/commands/_helpers/refactor -n 8 --dist loadfile (108 passed).
  • uv sync --all-extras && make check-ci passed.

…ting rule failures in sqb rename and sqb mv

sqb rename takes several model TARGET NEW_NAME pairs, or --from-file, and plans
and verifies them together like batch moves: one compile before, one of the
edited project after, all or nothing. Each renamed model gets its own
migrate_from, so every old name keeps a compatibility view. Column renames and
--cascade stay single and are refused in batch form; name reuse stays refused.

The scratch copy and the real write now apply changes in the same order: write
every change, then remove only the moved sources no change writes to, so a
chained move cannot lose a file in the real write while verification passes.

sqb mv rewrites project Python imports of the Python files it moves (direct,
aliased, grouped, from-package and relative imports) through a reusable
import-rewrite function, and refuses with the file and line when an import
cannot be rewritten safely: an unaliased import, a star import from the moved
module's package, a dynamic import naming it, or a mixed from-package import.

A project that already fails project rules can be refactored: existing rule
failures no longer block planning, and the edited project is compared with
them. New or worse rule failures, and every other error, still block. Text and
JSON output, including --dry-run, explain the failures before and after.

Projects failing at the input stage, such as a duplicate macro name, are
refused cleanly with their compile error, and --json prints an error document
on stdout when the project does not compile or the request is invalid.
…h in a rule failure

With rule failures in the project, the compiles of sqb rename and sqb mv
skipped SQL-test planning, so a planning error could pass verification.
They now plan SQL tests whenever the only errors are rule failures, as
sqb compile does; planning errors block.

A rule failure of the edited project is existing only with the same code,
place and message, or when only its numbers changed and none grew. Any
other change blocks, wherever it is reported, so a failure reported at a
sample file can no longer grow unnoticed. Nothing counts as resolved when
another error may have kept rules from running.

Python import rewriting also refuses importing a moved module by name from
a package whose __init__.py binds that name, or when the move renames the
module, and refuses a move while a project Python file is not UTF-8.

sqb rename with a target and no new name, or with nothing, is again a
usage error with exit code 2.
@kvlonge
kvlonge enabled auto-merge (squash) October 23, 2026 04:22
@kvlonge
kvlonge merged commit 39fef4b into main Oct 23, 2026
46 checks passed
@kvlonge
kvlonge deleted the feat/rename-move-batch branch October 23, 2026 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant