Skip to content

Commit 783631d

Browse files
committed
feat(cli): add --config override to all relevant commands
1 parent a67bb1b commit 783631d

File tree

3 files changed

+101
-21
lines changed

3 files changed

+101
-21
lines changed

sqlx-cli/src/lib.rs

+27-20
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,19 @@ pub async fn run(opt: Opt) -> Result<()> {
5454
}
5555

5656
async fn do_run(opt: Opt) -> Result<()> {
57-
let config = config_from_current_dir().await?;
58-
5957
match opt.command {
6058
Command::Migrate(migrate) => match migrate.command {
61-
MigrateCommand::Add(opts) => migrate::add(config, opts).await?,
59+
MigrateCommand::Add(opts) => migrate::add(opts).await?,
6260
MigrateCommand::Run {
6361
source,
62+
config,
6463
dry_run,
6564
ignore_missing,
6665
mut connect_opts,
6766
target_version,
6867
} => {
68+
let config = config.load_config().await?;
69+
6970
connect_opts.populate_db_url(config)?;
7071

7172
migrate::run(
@@ -80,11 +81,14 @@ async fn do_run(opt: Opt) -> Result<()> {
8081
}
8182
MigrateCommand::Revert {
8283
source,
84+
config,
8385
dry_run,
8486
ignore_missing,
8587
mut connect_opts,
8688
target_version,
8789
} => {
90+
let config = config.load_config().await?;
91+
8892
connect_opts.populate_db_url(config)?;
8993

9094
migrate::revert(
@@ -99,43 +103,59 @@ async fn do_run(opt: Opt) -> Result<()> {
99103
}
100104
MigrateCommand::Info {
101105
source,
106+
config,
102107
mut connect_opts,
103108
} => {
109+
let config = config.load_config().await?;
110+
104111
connect_opts.populate_db_url(config)?;
105112

106113
migrate::info(config, &source, &connect_opts).await?
107114
}
108-
MigrateCommand::BuildScript { source, force } => {
115+
MigrateCommand::BuildScript { source, config, force } => {
116+
let config = config.load_config().await?;
117+
109118
migrate::build_script(config, &source, force)?
110119
}
111120
},
112121

113122
Command::Database(database) => match database.command {
114-
DatabaseCommand::Create { mut connect_opts } => {
123+
DatabaseCommand::Create { config, mut connect_opts } => {
124+
let config = config.load_config().await?;
125+
115126
connect_opts.populate_db_url(config)?;
116127
database::create(&connect_opts).await?
117128
}
118129
DatabaseCommand::Drop {
119130
confirmation,
131+
config,
120132
mut connect_opts,
121133
force,
122134
} => {
135+
let config = config.load_config().await?;
136+
123137
connect_opts.populate_db_url(config)?;
124138
database::drop(&connect_opts, !confirmation.yes, force).await?
125139
}
126140
DatabaseCommand::Reset {
127141
confirmation,
128142
source,
143+
config,
129144
mut connect_opts,
130145
force,
131146
} => {
147+
let config = config.load_config().await?;
148+
132149
connect_opts.populate_db_url(config)?;
133150
database::reset(config, &source, &connect_opts, !confirmation.yes, force).await?
134151
}
135152
DatabaseCommand::Setup {
136153
source,
154+
config,
137155
mut connect_opts,
138156
} => {
157+
let config = config.load_config().await?;
158+
139159
connect_opts.populate_db_url(config)?;
140160
database::setup(config, &source, &connect_opts).await?
141161
}
@@ -147,7 +167,9 @@ async fn do_run(opt: Opt) -> Result<()> {
147167
workspace,
148168
mut connect_opts,
149169
args,
170+
config,
150171
} => {
172+
let config = config.load_config().await?;
151173
connect_opts.populate_db_url(config)?;
152174
prepare::run(check, all, workspace, connect_opts, args).await?
153175
}
@@ -203,18 +225,3 @@ where
203225
)
204226
.await
205227
}
206-
207-
async fn config_from_current_dir() -> anyhow::Result<&'static Config> {
208-
// Tokio does file I/O on a background task anyway
209-
tokio::task::spawn_blocking(|| {
210-
let path = PathBuf::from("sqlx.toml");
211-
212-
if path.exists() {
213-
eprintln!("Found `sqlx.toml` in current directory; reading...");
214-
}
215-
216-
Config::read_with_or_default(move || Ok(path))
217-
})
218-
.await
219-
.context("unexpected error loading config")
220-
}

sqlx-cli/src/migrate.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use std::fs::{self, File};
1313
use std::path::Path;
1414
use std::time::Duration;
1515

16-
pub async fn add(config: &Config, opts: AddMigrationOpts) -> anyhow::Result<()> {
16+
pub async fn add(opts: AddMigrationOpts) -> anyhow::Result<()> {
17+
let config = opts.config.load_config().await?;
18+
1719
let source = opts.source.resolve(config);
1820

1921
fs::create_dir_all(source).context("Unable to create migrations directory")?;

sqlx-cli/src/opt.rs

+71
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use clap_complete::Shell;
1111
use sqlx::migrate::Migrator;
1212
use std::env;
1313
use std::ops::{Deref, Not};
14+
use std::path::PathBuf;
1415

1516
const HELP_STYLES: Styles = Styles::styled()
1617
.header(AnsiColor::Blue.on_default().bold())
@@ -67,6 +68,9 @@ pub enum Command {
6768

6869
#[clap(flatten)]
6970
connect_opts: ConnectOpts,
71+
72+
#[clap(flatten)]
73+
config: ConfigOpt,
7074
},
7175

7276
#[clap(alias = "mig")]
@@ -90,16 +94,23 @@ pub enum DatabaseCommand {
9094
Create {
9195
#[clap(flatten)]
9296
connect_opts: ConnectOpts,
97+
98+
#[clap(flatten)]
99+
config: ConfigOpt,
93100
},
94101

95102
/// Drops the database specified in your DATABASE_URL.
96103
Drop {
97104
#[clap(flatten)]
98105
confirmation: Confirmation,
99106

107+
#[clap(flatten)]
108+
config: ConfigOpt,
109+
100110
#[clap(flatten)]
101111
connect_opts: ConnectOpts,
102112

113+
103114
/// PostgreSQL only: force drops the database.
104115
#[clap(long, short, default_value = "false")]
105116
force: bool,
@@ -113,6 +124,9 @@ pub enum DatabaseCommand {
113124
#[clap(flatten)]
114125
source: MigrationSourceOpt,
115126

127+
#[clap(flatten)]
128+
config: ConfigOpt,
129+
116130
#[clap(flatten)]
117131
connect_opts: ConnectOpts,
118132

@@ -126,6 +140,9 @@ pub enum DatabaseCommand {
126140
#[clap(flatten)]
127141
source: MigrationSourceOpt,
128142

143+
#[clap(flatten)]
144+
config: ConfigOpt,
145+
129146
#[clap(flatten)]
130147
connect_opts: ConnectOpts,
131148
},
@@ -212,6 +229,9 @@ pub enum MigrateCommand {
212229
#[clap(flatten)]
213230
source: MigrationSourceOpt,
214231

232+
#[clap(flatten)]
233+
config: ConfigOpt,
234+
215235
/// List all the migrations to be run without applying
216236
#[clap(long)]
217237
dry_run: bool,
@@ -233,6 +253,9 @@ pub enum MigrateCommand {
233253
#[clap(flatten)]
234254
source: MigrationSourceOpt,
235255

256+
#[clap(flatten)]
257+
config: ConfigOpt,
258+
236259
/// List the migration to be reverted without applying
237260
#[clap(long)]
238261
dry_run: bool,
@@ -255,6 +278,9 @@ pub enum MigrateCommand {
255278
#[clap(flatten)]
256279
source: MigrationSourceOpt,
257280

281+
#[clap(flatten)]
282+
config: ConfigOpt,
283+
258284
#[clap(flatten)]
259285
connect_opts: ConnectOpts,
260286
},
@@ -266,6 +292,9 @@ pub enum MigrateCommand {
266292
#[clap(flatten)]
267293
source: MigrationSourceOpt,
268294

295+
#[clap(flatten)]
296+
config: ConfigOpt,
297+
269298
/// Overwrite the build script if it already exists.
270299
#[clap(long)]
271300
force: bool,
@@ -279,6 +308,9 @@ pub struct AddMigrationOpts {
279308
#[clap(flatten)]
280309
pub source: MigrationSourceOpt,
281310

311+
#[clap(flatten)]
312+
pub config: ConfigOpt,
313+
282314
/// If set, create an up-migration only. Conflicts with `--reversible`.
283315
#[clap(long, conflicts_with = "reversible")]
284316
simple: bool,
@@ -358,6 +390,20 @@ pub struct NoDotenvOpt {
358390
pub no_dotenv: bool,
359391
}
360392

393+
#[derive(Args, Debug)]
394+
pub struct ConfigOpt {
395+
/// Override the path to the config file.
396+
///
397+
/// Defaults to `sqlx.toml` in the current directory, if it exists.
398+
///
399+
/// Configuration file loading may be bypassed with `--config=/dev/null` on Linux,
400+
/// or `--config=NUL` on Windows.
401+
///
402+
/// Config file loading is enabled by the `sqlx-toml` feature.
403+
#[clap(long)]
404+
pub config: Option<PathBuf>,
405+
}
406+
361407
impl ConnectOpts {
362408
/// Require a database URL to be provided, otherwise
363409
/// return an error.
@@ -401,6 +447,31 @@ impl ConnectOpts {
401447
}
402448
}
403449

450+
impl ConfigOpt {
451+
pub async fn load_config(&self) -> anyhow::Result<&'static Config> {
452+
let path = self.config.clone();
453+
454+
// Tokio does file I/O on a background task anyway
455+
tokio::task::spawn_blocking(|| {
456+
if let Some(path) = path {
457+
let err_str = format!("error reading config from {path:?}");
458+
Config::try_read_with(|| Ok(path))
459+
.context(err_str)
460+
} else {
461+
let path = PathBuf::from("sqlx.toml");
462+
463+
if path.exists() {
464+
eprintln!("Found `sqlx.toml` in current directory; reading...");
465+
}
466+
467+
Ok(Config::read_with_or_default(move || Ok(path)))
468+
}
469+
})
470+
.await
471+
.context("unexpected error loading config")?
472+
}
473+
}
474+
404475
/// Argument for automatic confirmation.
405476
#[derive(Args, Copy, Clone, Debug)]
406477
pub struct Confirmation {

0 commit comments

Comments
 (0)