Repository: launchbadge/sqlx
File: sqlx-cli/src/opt.rs (Rust)

Code before:
    #[clap(subcommand)]
    pub command: MigrateCommand,
}

#[derive(Parser, Debug)]
pub enum MigrateCommand {
    /// Create a new migration with the given description,
    /// and (by default) the current time as the version.
    Add {
        description: String,

        #[clap(flatten)]
        source: Source,

        /// If true, creates a pair of up and down migration files with same version
        /// else creates a single sql file
        #[clap(short)]
        reversible: bool,

        /// If true, migrations are named sequentially instead of timestamp
        #[clap(short)]
        sequential: bool,
    },

    /// Run all pending migrations.
    Run {
        #[clap(flatten)]
        source: Source,

        /// List all the migrations to be run without applying
        #[clap(long)]
        dry_run: bool,

        #[clap(flatten)]
        ignore_missing: IgnoreMissing,

        #[clap(flatten)]
        connect_opts: ConnectOpts,
    },

    /// Revert the latest migration with a down file.
    Revert {
        #[clap(flatten)]
        source: Source,

        /// List the migration to be reverted without applying
        #[clap(long)]
        dry_run: bool,

        #[clap(flatten)]
        ignore_missing: IgnoreMissing,

Review comment (suggestion):
I'd like us to figure out a better naming for this flag.

I hate unintuitively named short flags in CLIs and I feel like if I wanted sequential versioning I'd _constantly_ forget `-s`, but having to specify `--sequential` is also annoyingly verbose.

A coworker suggested `--inc` for "increment" but I don't really like that either. Maybe `-i`/`--increment`, but I don't think that's much better.

We could theoretically infer the style by looking at previous migrations, e.g.:

* Allow the user to override the behavior by supplying either `--timestamp` or `--sequential` (mutually exclusive).
* If there's at least two migrations, compare the last two: if their version numbers differ by 1, infer sequential.
    * This allows changing styles after the start of a project, which is something I've done before--using sequential
       for "baseline" migrations and timestamps for everything after the production database is created.
* If there's only one existing migration, infer sequential if the version number is 0 or 1.
    * I like using version 0 for a boilerplate/setup migration that gets copied from project to project.
* Otherwise, default to timestamp.

The more I think about inferring the style, the more I like it. It has the potential to cause the least friction because it errs on the side of consistency.

Code after:
    #[clap(subcommand)]
    pub command: MigrateCommand,
}

#[derive(Parser, Debug)]
pub enum MigrateCommand {
    /// Create a new migration with the given description.
    ///
    /// A version number will be automatically assigned to the migration.
    ///
    /// For convenience, this command will attempt to detect if sequential versioning is in use,
    /// and if so, continue the sequence.
    ///
    /// Sequential versioning is inferred if:
    ///
    /// * The version numbers of the last two migrations differ by exactly 1, or:
    ///
    /// * only one migration exists and its version number is either 0 or 1.
    ///
    /// Otherwise timestamp versioning is assumed.
    ///
    /// This behavior can overridden by `--sequential` or `--timestamp`, respectively.
    Add {
        description: String,

        #[clap(flatten)]
        source: Source,

        /// If true, creates a pair of up and down migration files with same version
        /// else creates a single sql file
        #[clap(short)]
        reversible: bool,

        /// If set, use timestamp versioning for the new migration. Conflicts with `--sequential`.
        #[clap(short, long)]
        timestamp: bool,

        /// If set, use timestamp versioning for the new migration. Conflicts with `--timestamp`.
        #[clap(short, long, conflicts_with = "timestamp")]
        sequential: bool,
    },

    /// Run all pending migrations.
    Run {
        #[clap(flatten)]
        source: Source,

        /// List all the migrations to be run without applying
        #[clap(long)]
        dry_run: bool,