diff --git a/.cargo/config.toml b/.cargo/config.toml index 50178909..76750cb6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,4 @@ [alias] build-install = "run --package xtask-build-install --" package-build = "run --package xtask-package-build --" -xtest = "run --package xtask-test-runner --" +xtest = "test --features integration-tests" diff --git a/CHANGELOG.md b/CHANGELOG.md index b689e926..3419ae79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ### Added - The metadata repositories can now contain source files. +### Changes +- The test environment now uses a fresh environment for each test and can be used in parallel. + ### Fixed - Fix `LocalMetadataExistence` verifier fix not updating the last refresh and update state in the register. - Fix OS version detection not extracting the Linux kernel version correctly. diff --git a/Cargo.lock b/Cargo.lock index 382b66bd..137bd787 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2911,13 +2911,6 @@ dependencies = [ "tar", ] -[[package]] -name = "xtask-test-runner" -version = "0.0.0" -dependencies = [ - "toml", -] - [[package]] name = "yoke" version = "0.8.3" diff --git a/docs/tests.md b/docs/tests.md index 57000c55..caf97145 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -12,15 +12,13 @@ cargo test ``` ## Integration tests -Cargo test doesn't have support for a general setup or clean up before and after the integration tests. That's why Packit uses an xtask `xtask-test-runner` which wraps around the `cargo test` command. -The arguments to `xtest` are passed along to `cargo test`, so test flags can still be used. -Run the following command to run the integration tests: +Packits integration tests make use of `integration-tests` feature flag, to manage the integration test environment. The following shortcut can be used: ``` cargo xtest ``` -For the setup this wrapper first checks for the `TestConfig.toml`, which is located next to the `Config.toml`. The `TestConfig.toml` is used if it exists, otherwise a default test config is created. The default test config uses `/test` as the prefix directory, where `` is the 'normal' prefix directory. Lastly the test prefix is created, containing an empty `Register.toml`. +Each integration test creates a new test environment. The (temporary) test directory is passed to packit with the `--config-path` flag. When the test is done the test directory will get out of scope and be dropped, which will trigger the cleanup function. ->Note that the setup fails if the test prefix already exists, because this could mean that the 'normal' prefix was used instead. +To use a custom config the `TestConfig.toml` can be used. If this file is present in the prefix directory it will be used for the `url` and `provider` type. Other fields are ignored. -After the setup is done, the test can be ran. A cleanup function removes everything which didn't exist before the test execution. So if the `TestConfig.toml` already existed it will not be deleted. +The environment supports parallel testing. diff --git a/src/cli/commands.rs b/src/cli/commands.rs index fc56c244..9f51ad83 100644 --- a/src/cli/commands.rs +++ b/src/cli/commands.rs @@ -15,6 +15,9 @@ mod unlink; mod update; mod util; +#[cfg(feature = "integration-tests")] +use std::sync::OnceLock; + use std::process::exit; use clap::{Parser, Subcommand, builder::Styles}; @@ -33,6 +36,9 @@ use crate::{ utils::packit_version::{packit_version, packit_version_name}, }; +#[cfg(feature = "integration-tests")] +pub static TEST_CONFIG_PATH: OnceLock = OnceLock::new(); + /// Represents the CLI interface with clap. #[derive(Parser, Debug)] #[command(name = "Packit", version, about)] @@ -41,6 +47,10 @@ use crate::{ pub struct Cli { #[command(subcommand)] command: Commands, + + #[cfg(feature = "integration-tests")] + #[arg(long)] + config_path: String, } #[derive(Subcommand, Debug)] @@ -109,7 +119,7 @@ impl Cli { } // Parse command - match Cli::try_parse() { + let cli = match Cli::try_parse() { Ok(cli) => cli, Err(e) => { let styles = Styles::default(); @@ -127,7 +137,13 @@ impl Cli { exit(e.exit_code()) }, - } + }; + + // Set the `TEST_CONFIG_PATH` when doing integration tests + #[cfg(feature = "integration-tests")] + TEST_CONFIG_PATH.set(cli.config_path.clone()).expect("Expected single initialization"); + + cli } /// Reads and handles the command. diff --git a/src/cli/commands/info.rs b/src/cli/commands/info.rs index 39230883..cb4fa48e 100644 --- a/src/cli/commands/info.rs +++ b/src/cli/commands/info.rs @@ -2,7 +2,7 @@ use crate::{ cli::display::{standard_print::DisplayJoined, styled::MapStyled}, installer::types::PackageName, - platforms::{DEFAULT_CONFIG_DIR, OsVersion, Target}, + platforms::{OsVersion, Target, get_default_config_dir}, register::metadata::LocalMetaHandler, repositories::manager::RepositoryManager, utils::packit_version::{current_packit_version, packit_version_name}, @@ -142,7 +142,7 @@ impl InfoArgs { println!("{}", packit_version_name!().italic().cyan()); let mut pair_aligner = PairAligner::new(); - pair_aligner.add("Config directory", DEFAULT_CONFIG_DIR); + pair_aligner.add("Config directory", get_default_config_dir()); pair_aligner.add("Prefix directory", config.prefix_directory.display()); pair_aligner.add("Multiuser mode", config.multiuser); pair_aligner.add("Installed packages", register.iterate_all().count()); diff --git a/src/cli/commands/init.rs b/src/cli/commands/init.rs index 59125423..e5ea7571 100644 --- a/src/cli/commands/init.rs +++ b/src/cli/commands/init.rs @@ -19,7 +19,7 @@ use crate::{ Symlinker, types::{PackageId, PackageName, Version}, }, - platforms::{DEFAULT_CONFIG_DIR, DEFAULT_PREFIX, permissions}, + platforms::{DEFAULT_PREFIX, get_default_config_dir, permissions}, register::{ installed_package_version::InstalledPackageVersion, metadata::{LocalMetaHandler, LocalMetaPackageHandler, LocalMetadata}, @@ -68,15 +68,16 @@ impl HandleCommand for InitArgs { } // Check if config directory exists - let config_dir = Path::new(DEFAULT_CONFIG_DIR); + let default_config_dir = get_default_config_dir(); + let config_dir = Path::new(default_config_dir); if !config_dir.exists() { - error!(msg: "Packit cannot be initialized: the config directory at '{DEFAULT_CONFIG_DIR}' does not exist yet, please create it first"); + error!(msg: "Packit cannot be initialized: the config directory at '{default_config_dir}' does not exist yet, please create it first"); exit(1); } // Check if config directory is writable if !permissions::is_writable(config_dir).unwrap_or_exit_msg("Unable to check if config directory is writable", 1) { - error!(msg: "Packit cannot be initialized: the config directory at '{DEFAULT_CONFIG_DIR}' is not writable, please set the correct permissions"); + error!(msg: "Packit cannot be initialized: the config directory at '{default_config_dir}' is not writable, please set the correct permissions"); exit(1); } diff --git a/src/config.rs b/src/config.rs index bb48fbb1..eadaa01b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,7 +17,7 @@ use crate::{ logging::warning, standard_print::{self, DisplayOption}, }, - platforms::{DEFAULT_CONFIG_DIR, DEFAULT_PREFIX}, + platforms::{DEFAULT_PREFIX, get_default_config_dir}, repositories::metadata::DEFAULT_METADATA_PROVIDER_ID, utils::{ constants::{ @@ -143,7 +143,7 @@ impl Config { /// Gets the default path of the Packit config file. pub fn get_default_path() -> PathBuf { - Path::new(DEFAULT_CONFIG_DIR).join(CONFIG_FILENAME) + Path::new(get_default_config_dir()).join(CONFIG_FILENAME) } fn default_prefix_directory() -> PathBuf { diff --git a/src/platforms/defaults.rs b/src/platforms/defaults.rs index 55060501..7d9dc54b 100644 --- a/src/platforms/defaults.rs +++ b/src/platforms/defaults.rs @@ -9,11 +9,24 @@ pub const DEFAULT_PREFIX: &str = "/opt/packit"; #[cfg(target_os = "windows")] pub const DEFAULT_PREFIX: &str = "C:\\Program Files\\packit"; -#[cfg(target_os = "linux")] -pub const DEFAULT_CONFIG_DIR: &str = "/etc/packit"; +#[cfg(all(target_os = "linux", not(feature = "integration-tests")))] +const DEFAULT_CONFIG_DIR: &str = "/etc/packit"; -#[cfg(target_os = "macos")] -pub const DEFAULT_CONFIG_DIR: &str = "/Library/Application Support/packit"; +#[cfg(all(target_os = "macos", not(feature = "integration-tests")))] +const DEFAULT_CONFIG_DIR: &str = "/Library/Application Support/packit"; -#[cfg(target_os = "windows")] -pub const DEFAULT_CONFIG_DIR: &str = "C:\\Program Files\\packit"; +#[cfg(all(target_os = "windows", not(feature = "integration-tests")))] +const DEFAULT_CONFIG_DIR: &str = "C:\\Program Files\\packit"; + +/// Returns the default config directory. It returns the constant defined above if the `integration-tests` feature is not enabled. +/// Otherwise the value from `TEST_CONFIG_PATH` (given by the test call) is used. +pub fn get_default_config_dir() -> &'static str { + #[cfg(not(feature = "integration-tests"))] + return DEFAULT_CONFIG_DIR; + + #[cfg(feature = "integration-tests")] + { + use crate::cli::commands::TEST_CONFIG_PATH; + TEST_CONFIG_PATH.get().expect("Expected initialized config path") + } +} diff --git a/src/platforms/mod.rs b/src/platforms/mod.rs index e4285e2a..5f8f9cf4 100644 --- a/src/platforms/mod.rs +++ b/src/platforms/mod.rs @@ -7,8 +7,8 @@ mod target; mod target_architecture; pub mod tool_detection; -pub use defaults::DEFAULT_CONFIG_DIR; pub use defaults::DEFAULT_PREFIX; +pub use defaults::get_default_config_dir; pub use os::Os; pub use os::OsVersion; diff --git a/src/utils/constants.rs b/src/utils/constants.rs index de748054..7aaafc80 100644 --- a/src/utils/constants.rs +++ b/src/utils/constants.rs @@ -6,11 +6,6 @@ use crate::repositories::metadata::WEB_METADATA_PROVIDER_ID; pub const REGISTER_FILENAME: &str = "Register.toml"; -/// Note that when the `integration-tests` feature flag is enabled `CONFIG_FILENAME` is compiled differently. -#[cfg(feature = "integration-tests")] -pub const CONFIG_FILENAME: &str = "TestConfig.toml"; - -#[cfg(not(feature = "integration-tests"))] pub const CONFIG_FILENAME: &str = "Config.toml"; pub const DEFAULT_METADATA_REPOSITORY_NAME: &str = "packit-core"; diff --git a/tests/README.md b/tests/README.md index d2b3af3c..9e541995 100644 --- a/tests/README.md +++ b/tests/README.md @@ -12,4 +12,6 @@ cargo test Run the following command to run the integration tests: ``` cargo xtest -``` \ No newline at end of file +``` + +Find out more about the test environment [here](../docs/tests.md). diff --git a/tests/integration/cli.rs b/tests/integration/cli.rs index 3811883b..f6a94919 100644 --- a/tests/integration/cli.rs +++ b/tests/integration/cli.rs @@ -1,28 +1,31 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::packit; +use crate::{common::environment::Environment, packit}; #[test] fn version() { - packit!("--version").assert().success(); + let env = Environment::init(); + packit!(env, "--version").assert().success(); + env.clean(); } #[test] fn info_requirements() { + let env = Environment::init(); + // Install simple package for test - _ = packit!("install", "simple@0.0.1", "--build").ok(); + _ = packit!(env, "install", "simple@0.0.1", "--build").assert().success(); - packit!("info", "--tree").assert().failure(); - packit!("info", "--active").assert().failure(); - packit!("info", "--tree --active").assert().failure(); - packit!("info", "simple", "--tree").assert().failure(); + packit!(env, "info", "--tree").assert().failure(); + packit!(env, "info", "--active").assert().failure(); + packit!(env, "info", "--tree --active").assert().failure(); + packit!(env, "info", "simple", "--tree").assert().failure(); - packit!("info").assert().success(); - packit!("info", "simple").assert().success(); - packit!("info", "simple@0.0.1").assert().success(); - packit!("info", "simple@0.0.1", "--tree").assert().success(); - packit!("info", "simple", "--active").assert().success(); - packit!("info", "simple", "--tree", "--active").assert().success(); + packit!(env, "info").assert().success(); + packit!(env, "info", "simple").assert().success(); + packit!(env, "info", "simple@0.0.1").assert().success(); + packit!(env, "info", "simple@0.0.1", "--tree").assert().success(); + packit!(env, "info", "simple", "--active").assert().success(); + packit!(env, "info", "simple", "--tree", "--active").assert().success(); - // Cleanup simple package after test - _ = packit!("uninstall", "simple").ok(); + env.clean(); } diff --git a/tests/integration/common/environment.rs b/tests/integration/common/environment.rs new file mode 100644 index 00000000..accc369c --- /dev/null +++ b/tests/integration/common/environment.rs @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-3.0-only +use std::{ + fs::{self, File}, + path::PathBuf, + process::exit, + str::FromStr, +}; +use toml::{Value, map::Map}; + +use tempfile::{TempDir, tempdir}; + +// Test constants +#[cfg(target_os = "linux")] +pub const DEFAULT_CONFIG_DIR: &str = "/etc/packit"; + +#[cfg(target_os = "macos")] +pub const DEFAULT_CONFIG_DIR: &str = "/Library/Application Support/packit"; + +#[cfg(target_os = "windows")] +pub const DEFAULT_CONFIG_DIR: &str = "C:\\Program Files\\packit"; + +/// Contains the test information about the test environment and how to clean it up. +pub struct Environment { + _temp_directory: TempDir, // Never used, but kept to keep the temporary directory in scope, so it doesn't get removed + pub test_directory: PathBuf, +} + +impl Environment { + fn new() -> Self { + // Keep `temp_directory` in scope, so it doesn't get removed + let temp_directory = tempdir().expect("Failed to create test directory"); + let test_directory = temp_directory.path().to_path_buf(); + Self { + _temp_directory: temp_directory, + test_directory, + } + } + + /// Creates a new `Environment` and calls setup. + pub fn init() -> Self { + let environment = Self::new(); + environment.setup(); + environment + } + + /// Does the setup of the test environment using the created temporary directory. + fn setup(&self) { + let mut url = String::from("https://raw.githubusercontent.com/pack-it/test-repository/main/"); + let mut provider = String::from("web"); + + // Check if `TestConfig.toml` exists in the default config directory + let test_config_file = PathBuf::from_str(DEFAULT_CONFIG_DIR).expect("Expected valid default").join("TestConfig.toml"); + if let Ok(true) = fs::exists(&test_config_file) { + println!("Using TestConfig.toml"); + + let config_table = self.get_config_table(&test_config_file); + if let Some(config_url) = config_table.get("url") { + url = config_url.to_string().trim_matches('"').to_string(); + } + + if let Some(config_provider) = config_table.get("provider") { + provider = config_provider.to_string().trim_matches('"').to_string(); + } + } + + self.create_test_config(&url, &provider); + + // Create the `Register.toml` + let register_file = self.test_directory.join("Register.toml"); + if let Err(e) = fs::write(®ister_file, "# DO NOT EDIT THIS FILE") { + eprintln!("Failed to create test 'Register.toml' at '{}'", register_file.display()); + eprintln!("Error: {e}"); + exit(1); + } + } + + /// Gets the config table from the given config path. + fn get_config_table(&self, config_path: &PathBuf) -> Map { + let config_content = match fs::read_to_string(&config_path) { + Ok(content) => content, + Err(e) => { + eprintln!("Failed to read '{}'", config_path.display()); + eprintln!("Error: {e}"); + exit(1); + }, + }; + + let config_content: Value = match toml::from_str(&config_content) { + Ok(content) => content, + Err(e) => { + eprintln!("Failed to parse as toml file:\n'{config_content}'\n"); + eprintln!("Error: {e}"); + exit(1); + }, + }; + + let Some(config_content) = config_content.as_table() else { + eprintln!("Failed to extract table from config file with the following content:\n'{config_content}'\n"); + exit(1); + }; + + config_content.clone() + } + + /// Creates the test config. + fn create_test_config(&self, repository_url: &str, repository_provider: &str) { + let config_dir = self.test_directory.join("Config.toml"); + if let Err(e) = File::create(&config_dir) { + eprintln!("Failed to create 'Config.toml' at '{}'", config_dir.display()); + eprintln!("Error: {e}"); + exit(1); + } + + let mut config = Map::new(); + config.insert("repositories_rank".into(), Value::Array(vec!["test".into()])); + config.insert( + "prefix_directory".into(), + self.test_directory.to_str().expect("Expected valid unicode").into(), + ); + + let mut repositories = Map::new(); + let mut test_repository = Map::new(); + test_repository.insert("url".into(), Value::String(repository_url.into())); + test_repository.insert("provider".into(), repository_provider.into()); + + repositories.insert("test".into(), Value::Table(test_repository)); + config.insert("repositories".into(), Value::Table(repositories)); + + let config_content = Value::Table(config); + let toml_string = match toml::to_string_pretty(&config_content) { + Ok(string) => string, + Err(e) => { + eprintln!("Failed to create toml string from:\n{config_content}\n"); + eprintln!("Error: {e}"); + exit(1); + }, + }; + + if let Err(e) = std::fs::write(&config_dir, &toml_string) { + eprintln!("Failed to write the following to '{}':\n{toml_string}\n", config_dir.display()); + eprintln!("Error: {e}"); + exit(1); + } + } + + /// Cleans up after the tests. + pub fn clean(&self) { + println!("Running cleanup"); + + if self.test_directory.exists() { + println!("Test directory already cleaned"); + return; + } + + // Remove the test directory + if let Err(e) = fs::remove_dir_all(&self.test_directory) { + eprintln!("Failed to remove test directory'{}'", self.test_directory.display()); + eprintln!("Error: {e}"); + exit(1); + } + + println!("Running cleanup successful"); + } +} + +// Implement drop to make sure the cleanup is still ran, even if a test panics +impl Drop for Environment { + fn drop(&mut self) { + self.clean(); + } +} diff --git a/tests/integration/common/mod.rs b/tests/integration/common/mod.rs index a74df793..d474cb50 100644 --- a/tests/integration/common/mod.rs +++ b/tests/integration/common/mod.rs @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-3.0-only +pub mod environment; + #[macro_export] macro_rules! packit { - () => { - assert_cmd::Command::cargo_bin("packit").unwrap() + ($env:expr) => { + assert_cmd::Command::cargo_bin("packit").unwrap().arg("--config-path").arg(&$env.test_directory) }; - ($($args:tt)*) => { - assert_cmd::Command::cargo_bin("packit").unwrap().args([$($args)*]) + ($env:expr, $($args:tt)*) => { + assert_cmd::Command::cargo_bin("packit").unwrap().arg("--config-path").arg(&$env.test_directory).args([$($args)*]) }; } diff --git a/xtasks/xtask-test-runner/Cargo.toml b/xtasks/xtask-test-runner/Cargo.toml deleted file mode 100644 index 075ed58d..00000000 --- a/xtasks/xtask-test-runner/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "xtask-test-runner" -description = "Utility to run Packit integration tests" -version = "0.0.0" -publish = false -edition.workspace = true -rust-version.workspace = true - -[dependencies] -toml = "1.1.6" diff --git a/xtasks/xtask-test-runner/src/main.rs b/xtasks/xtask-test-runner/src/main.rs deleted file mode 100644 index 928caf0d..00000000 --- a/xtasks/xtask-test-runner/src/main.rs +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -use std::{ - env, - fs::{self, File}, - path::PathBuf, - process::{ExitCode, exit}, -}; -use toml::{Value, map::Map}; - -#[cfg(any(target_os = "macos", target_os = "linux"))] -pub const DEFAULT_PREFIX: &str = "/opt/packit/test"; - -#[cfg(target_os = "windows")] -pub const DEFAULT_PREFIX: &str = "C:\\Program Files\\packit\\test"; - -#[cfg(target_os = "linux")] -pub const DEFAULT_CONFIG_DIR: &str = "/etc/packit"; - -#[cfg(target_os = "macos")] -pub const DEFAULT_CONFIG_DIR: &str = "/Library/Application Support/packit"; - -#[cfg(target_os = "windows")] -pub const DEFAULT_CONFIG_DIR: &str = "C:\\Program Files\\packit"; - -/// Contains the necessary information for the cleanup. -struct Cleanup { - existing_config: bool, - prefix: PathBuf, -} - -impl Cleanup { - /// Cleans up after the tests. - pub fn clean(&self) { - println!("Running cleanup"); - - // Only remove the config if it was auto-generated - let config_dir = PathBuf::from(DEFAULT_CONFIG_DIR).join("TestConfig.toml"); - if !self.existing_config { - if let Err(e) = fs::remove_file(config_dir) { - eprintln!("Failed to remove 'TestConfig.toml'"); - eprintln!("Error: {e}"); - exit(1); - } - } - - // Remove the test prefix - if let Err(e) = fs::remove_dir_all(&self.prefix) { - eprintln!("Failed to remove test prefix '{}'", self.prefix.display()); - eprintln!("Error: {e}"); - exit(1); - } - - println!("Running cleanup successful"); - } -} - -// Implement drop to make sure the cleanup is still ran, even if a test panics -impl Drop for Cleanup { - fn drop(&mut self) { - self.clean(); - } -} - -/// Wraps around the `cargo test` command to handle the setup and cleanup. -/// Returns an `ExitCode`. -fn main() -> ExitCode { - // Execute setup, which will partially determine how the cleanup is executed - let _cleanup = setup(); - - // Gather command arguments, and pass them to cargo test (the first argument is the program name) - let args: Vec = env::args().skip(1).collect(); - - let status = std::process::Command::new("cargo") - .args(["test", "--features", "integration-tests", "--", "--test-threads=1"]) - .args(args) - .status() - .expect("failed to run cargo test"); - - ExitCode::from(status.code().unwrap_or(1) as u8) -} - -/// Handles the test setup. Creates the `TestConfig.toml` if necessary and a new test prefix. -/// Returns `Cleanup` containing setup info. -fn setup() -> Cleanup { - let mut existing_config = true; - let config_dir = PathBuf::from(DEFAULT_CONFIG_DIR).join("TestConfig.toml"); - if !config_dir.exists() { - println!("Using autogenerated 'TestConfig.toml'"); - create_default_test_config(&config_dir); - existing_config = false; - } - - // Get test config content - let config_content = match fs::read_to_string(&config_dir) { - Ok(content) => content, - Err(e) => { - eprintln!("Failed to read '{}'", config_dir.display()); - eprintln!("Error: {e}"); - exit(1); - }, - }; - - let config_content: Value = match toml::from_str(&config_content) { - Ok(content) => content, - Err(e) => { - eprintln!("Failed to parse as toml file:\n'{config_content}'\n"); - eprintln!("Error: {e}"); - exit(1); - }, - }; - - let Some(config_content) = config_content.as_table() else { - eprintln!("Failed to extract table from config file with the following content:\n'{config_content}'\n"); - exit(1); - }; - - // Get the test prefix - let Some(prefix) = config_content.get("prefix_directory") else { - eprintln!("Couldn't find 'prefix_directory' in 'TestConfig.toml'"); - exit(1); - }; - - let Some(prefix) = prefix.as_str() else { - eprintln!("Invalid string value for 'prefix_directory' in 'TestConfig.toml'"); - exit(1); - }; - - let prefix = PathBuf::from(prefix); - let register_file = prefix.join("Register.toml"); - println!("Using prefix: {}", prefix.display()); - - // Return an error if the prefix already exists, this could mean it's a 'normal' Packit prefix - if prefix.exists() { - eprintln!("Test prefix '{}' specified in 'TestConfig.toml' already exists", prefix.display()); - exit(1); - } - - if let Err(e) = fs::create_dir_all(&prefix) { - eprintln!("Failed to create test prefix '{}'", prefix.display()); - eprintln!("Error: {e}"); - exit(1); - } - - if let Err(e) = fs::write(®ister_file, "# DO NOT EDIT THIS FILE") { - eprintln!("Failed to create test 'Register.toml' at '{}'", register_file.display()); - eprintln!("Error: {e}"); - exit(1); - } - - Cleanup { existing_config, prefix } -} - -/// Creates the default test config. -fn create_default_test_config(config_dir: &PathBuf) { - let Some(parent) = config_dir.parent() else { - eprintln!("Couldn't get config directory parent"); - exit(1); - }; - - if let Err(e) = fs::create_dir_all(parent) { - eprintln!("Failed to create directory '{}'", parent.display()); - eprintln!("Error: {e}"); - exit(1); - } - - if let Err(e) = File::create(config_dir) { - eprintln!("Failed to create 'TestConfig.toml' at '{}'", config_dir.display()); - eprintln!("Error: {e}"); - exit(1); - } - - let mut config = Map::new(); - config.insert("repositories_rank".into(), Value::Array(vec!["test".into()])); - config.insert("prefix_directory".into(), DEFAULT_PREFIX.into()); - - let mut repositories = Map::new(); - let mut test_repository = Map::new(); - test_repository.insert( - "url".into(), - Value::String("https://raw.githubusercontent.com/pack-it/test-repository/main/".into()), - ); - test_repository.insert("provider".into(), "web".into()); - - repositories.insert("test".into(), Value::Table(test_repository)); - config.insert("repositories".into(), Value::Table(repositories)); - - let config_content = Value::Table(config); - let toml_string = match toml::to_string_pretty(&config_content) { - Ok(string) => string, - Err(e) => { - eprintln!("Failed to create toml string from:\n{config_content}\n"); - eprintln!("Error: {e}"); - exit(1); - }, - }; - - if let Err(e) = std::fs::write(config_dir, &toml_string) { - eprintln!("Failed to write the following to '{}':\n{toml_string}\n", config_dir.display()); - eprintln!("Error: {e}"); - exit(1); - } -}