Caravela.Gen.Migration (Caravela v0.13.1)

Copy Markdown View Source

Generates a single Ecto migration file for every entity in a Caravela.Schema.Domain.

Returns {path, source} — the caller writes the file. The migration file name is timestamped so subsequent runs produce a distinct file.

Deterministic output

By default the migration's filename prefix is now() in UTC. For snapshot tests, demos, or any scenario where you want byte-stable output across runs, pass :timestamp:

Caravela.Gen.Migration.render(domain, timestamp: "00000000000000")

Without this pin, every render produces a new path and snapshot diffs always appear as "add + remove".

Summary

Functions

Locate an existing migration file for the domain's create-tables step, relative to root.

Decide which timestamp render/2 should use given the current filesystem state

Render the migration for the domain.

Functions

existing_migration_basename(domain, root)

@spec existing_migration_basename(Caravela.Schema.Domain.t(), Path.t()) ::
  String.t() | nil

Locate an existing migration file for the domain's create-tables step, relative to root.

Returns the file's basename (e.g. "20260417094708_create_library_tables.exs") when a prior migration with the same stem exists, or nil when none does. Reuse its 14-digit timestamp prefix to overwrite the same file on regeneration instead of appending a duplicate (see reconcile_timestamp/2).

When more than one matching migration is present (a symptom of prior regenerations that didn't reconcile), the oldest one is returned — regenerating against it lets the caller consolidate state while still surfacing the duplicates for manual cleanup.

reconcile_timestamp(domain, root)

@spec reconcile_timestamp(Caravela.Schema.Domain.t(), Path.t()) ::
  {String.t(), [String.t()]}

Decide which timestamp render/2 should use given the current filesystem state:

  • No matching migration on disk → default_timestamp/0.
  • Exactly one matching migration → reuse its timestamp, so render/2 produces the same path (idempotent regeneration).
  • More than one matching migration → reuse the oldest timestamp and return the extras so the caller can warn about the drift.

Returns {timestamp, duplicates} where duplicates is a list of basenames callers should flag or clean up.

render(domain, opts \\ [])

Render the migration for the domain.

Options:

  • :timestamp — override the numeric prefix (defaults to now())