mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-23 09:24:31 +02:00
migrate --stop-before: validate names and fix legacy compatibility
An unknown --stop-before value previously matched nothing and every migration was silently applied, including the one the user meant to stop before. The CLI now errors unless each value matches a known migration. The CLI also always passed stop_before as a list, but older duck-typed sqlite-migrate Migrations objects compare it against a single string name - so the flag was silently ignored for exactly the migration files the compatibility shim exists to support. Legacy sets now receive a single string, with an error if multiple values target one legacy set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UnLnhsH25Nnv7LHhekUfPd
This commit is contained in:
parent
fd867282b3
commit
0bad21280f
3 changed files with 158 additions and 4 deletions
|
|
@ -3400,11 +3400,38 @@ def migrate(db_path, migrations, stop_before, list_, verbose):
|
|||
click.echo("\nSchema before:\n")
|
||||
click.echo(textwrap.indent(prev_schema, " ") or " (empty)")
|
||||
click.echo()
|
||||
if stop_before:
|
||||
# Every --stop-before value must match at least one known migration
|
||||
known_names = set()
|
||||
for migration_set in migration_sets:
|
||||
names = {m.name for m in migration_set.pending(db)}
|
||||
names.update(m.name for m in migration_set.applied(db))
|
||||
known_names.update(names)
|
||||
known_names.update(
|
||||
"{}:{}".format(migration_set.name, name) for name in names
|
||||
)
|
||||
unknown = [value for value in stop_before if value not in known_names]
|
||||
if unknown:
|
||||
raise click.ClickException(
|
||||
"--stop-before did not match any migrations: {}".format(
|
||||
", ".join(unknown)
|
||||
)
|
||||
)
|
||||
for migration_set in migration_sets:
|
||||
migration_set.apply(
|
||||
db,
|
||||
stop_before=_stop_before_for_migration_set(stop_before, migration_set.name),
|
||||
)
|
||||
matches = _stop_before_for_migration_set(stop_before, migration_set.name)
|
||||
if isinstance(migration_set, sqlite_utils.Migrations):
|
||||
migration_set.apply(db, stop_before=matches)
|
||||
else:
|
||||
# Legacy sqlite-migrate Migrations objects take a single string
|
||||
# for stop_before, not a list
|
||||
distinct = list(dict.fromkeys(matches))
|
||||
if len(distinct) > 1:
|
||||
raise click.ClickException(
|
||||
"Migration set '{}' uses the older sqlite-migrate class, "
|
||||
"which only supports a single --stop-before value - "
|
||||
"got: {}".format(migration_set.name, ", ".join(distinct))
|
||||
)
|
||||
migration_set.apply(db, stop_before=distinct[0] if distinct else None)
|
||||
if verbose:
|
||||
click.echo("Schema after:\n")
|
||||
post_schema = db.schema
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue