diff --git a/diesel_cli/src/main.rs b/diesel_cli/src/main.rs index 045248292c85..a0ae06a971a3 100644 --- a/diesel_cli/src/main.rs +++ b/diesel_cli/src/main.rs @@ -96,8 +96,8 @@ where #[tracing::instrument] fn run_setup_command(matches: &ArgMatches) -> Result<(), crate::errors::Error> { - create_config_file(matches)?; let migrations_dir = create_migrations_dir(matches)?; + create_config_file(matches, &migrations_dir)?; database::setup_database(matches, &migrations_dir)?; Ok(()) @@ -136,12 +136,22 @@ fn create_migrations_dir(matches: &ArgMatches) -> Result Result<(), crate::errors::Error> { +fn create_config_file( + matches: &ArgMatches, + migrations_dir: &Path, +) -> Result<(), crate::errors::Error> { use std::io::Write; let path = Config::file_path(matches); if !path.exists() { + let source_content = include_str!("default_files/diesel.toml").to_string(); + // convert the path to a valid toml string (escaping backslashes on windows) + let migrations_dir_toml_string = migrations_dir.display().to_string().replace('\\', "\\\\"); + let modified_content = source_content.replace( + "dir = \"migrations\"", + &format!("dir = \"{}\"", migrations_dir_toml_string), + ); let mut file = fs::File::create(path)?; - file.write_all(include_bytes!("default_files/diesel.toml"))?; + file.write_all(modified_content.as_bytes())?; } Ok(()) @@ -183,7 +193,7 @@ fn generate_completions_command(matches: &ArgMatches) { /// Returns a `DatabaseError::ProjectRootNotFound` if no Cargo.toml is found. fn create_migrations_directory(path: &Path) -> Result { println!("Creating migrations directory at: {}", path.display()); - fs::create_dir(path)?; + fs::create_dir_all(path)?; fs::File::create(path.join(".keep"))?; Ok(path.to_owned()) } diff --git a/diesel_cli/tests/database_setup.rs b/diesel_cli/tests/database_setup.rs index ffedc1630a20..947ee706b149 100644 --- a/diesel_cli/tests/database_setup.rs +++ b/diesel_cli/tests/database_setup.rs @@ -152,6 +152,39 @@ fn database_setup_respects_migration_dir_by_arg() { assert!(db.table_exists("users")); } +#[test] +fn database_setup_respects_migration_nested_dir_by_arg() { + let p = project("database_setup_respects_migration_nested_dir_by_arg") + .folder("foo/bar") + .build(); + let db = database(&p.database_url()); + + p.create_migration_in_directory( + "foo/bar", + "12345_create_users_table", + "CREATE TABLE users ( id INTEGER )", + Some("DROP TABLE users"), + None, + ); + + // sanity check + assert!(!db.exists()); + + let result = p + .command("database") + .arg("setup") + .arg("--migration-dir=foo/bar") + .run(); + + assert!(result.is_success(), "Result was unsuccessful {:?}", result); + assert!( + result.stdout().contains("Running migration 12345"), + "Unexpected stdout {}", + result.stdout() + ); + assert!(db.table_exists("users")); +} + #[test] fn database_setup_respects_migration_dir_by_env() { let p = project("database_setup_respects_migration_dir_by_env") diff --git a/diesel_cli/tests/setup.rs b/diesel_cli/tests/setup.rs index d0bab07b5b17..a65a0d39ff28 100644 --- a/diesel_cli/tests/setup.rs +++ b/diesel_cli/tests/setup.rs @@ -170,6 +170,41 @@ fn setup_works_with_migration_dir_by_arg() { assert!(p.has_file("foo")); } +#[test] +fn setup_writes_migration_dir_by_arg_to_config_file() { + let p = project("setup_writes_migration_dir_by_arg_to_config_file").build(); + + // make sure the project builder doesn't create it for us + assert!(!p.has_file("migrations")); + assert!(!p.has_file("foo")); + + let result = p.command("setup").arg("--migration-dir=foo").run(); + + assert!(result.is_success(), "Result was unsuccessful {:?}", result); + assert!(!p.has_file("migrations")); + assert!(p.has_file("foo")); + assert!(p.file_contents("diesel.toml").contains("dir = \"foo\"")); +} + +#[test] +#[cfg(windows)] +fn setup_writes_migration_dir_by_arg_to_config_file_win() { + let p = project("setup_writes_migration_dir_by_arg_to_config_file_win").build(); + + // make sure the project builder doesn't create it for us + assert!(!p.has_file("migrations")); + assert!(!p.has_file("foo")); + + let result = p.command("setup").arg("--migration-dir=foo\\bar").run(); + + assert!(result.is_success(), "Result was unsuccessful {:?}", result); + assert!(!p.has_file("migrations")); + assert!(p.has_file("foo")); + assert!(p + .file_contents("diesel.toml") + .contains("dir = \"foo\\\\bar\"")); +} + #[test] fn setup_works_with_migration_dir_by_env() { let p = project("setup_works_with_migration_dir_by_env").build(); diff --git a/diesel_cli/tests/support/project_builder.rs b/diesel_cli/tests/support/project_builder.rs index c1199b1aba17..5110e409c599 100644 --- a/diesel_cli/tests/support/project_builder.rs +++ b/diesel_cli/tests/support/project_builder.rs @@ -45,7 +45,7 @@ impl ProjectBuilder { File::create(tempdir.path().join("Cargo.toml")).unwrap(); for folder in self.folders { - fs::create_dir(tempdir.path().join(folder)).unwrap(); + fs::create_dir_all(tempdir.path().join(folder)).unwrap(); } for (file, contents) in self.files {