diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index f1722a1..322ad67 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -5,6 +5,8 @@ use rust_i18n_extract::{extractor, generator, iter}; use rust_i18n_support::{I18nConfig, MinifyKey}; use std::{collections::HashMap, path::Path}; +const I18N_CONFIG_FILE: &str = "i18n.toml"; + #[derive(Parser)] #[command(name = "cargo")] #[command(bin_name = "cargo")] @@ -96,6 +98,22 @@ fn add_translations( } } +/// Reads the configuration either from the `i18n.toml` file, if present, +/// or from the `Cargo.toml` file otherwise. +fn read_config(source_path: &str) -> std::io::Result { + let root_dir = std::path::Path::new(&source_path); + let config_file = root_dir.join(I18N_CONFIG_FILE); + + let config_file_exists = std::fs::exists(&config_file) + .unwrap_or_else(|err| panic!("Error opening '{I18N_CONFIG_FILE}': {err}")); + + if config_file_exists { + I18nConfig::load_from_file(&config_file) + } else { + I18nConfig::load(&root_dir) + } +} + fn main() -> Result<(), Error> { let CargoCli::I18n(args) = CargoCli::parse(); @@ -103,7 +121,7 @@ fn main() -> Result<(), Error> { let source_path = args.source.expect("Missing source path"); - let cfg = I18nConfig::load(std::path::Path::new(&source_path))?; + let cfg = read_config(&source_path)?; iter::iter_crate(&source_path, |path, source| { extractor::extract(&mut results, path, source, cfg.clone()) diff --git a/crates/support/src/config.rs b/crates/support/src/config.rs index ce9ba88..62ec6ec 100644 --- a/crates/support/src/config.rs +++ b/crates/support/src/config.rs @@ -54,7 +54,17 @@ impl I18nConfig { pub fn load(cargo_root: &Path) -> io::Result { let cargo_file = cargo_root.join("Cargo.toml"); let mut file = fs::File::open(&cargo_file) - .unwrap_or_else(|e| panic!("Fail to open {}, {}", cargo_file.display(), e)); + .unwrap_or_else(|e| panic!("Failed to open {}, {}", cargo_file.display(), e)); + + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + + Self::parse(&contents) + } + + pub fn load_from_file(file: &Path) -> io::Result { + let mut file = fs::File::open(file) + .unwrap_or_else(|e| panic!("Failed to open {}, {}", file.display(), e)); let mut contents = String::new(); file.read_to_string(&mut contents)?; @@ -207,3 +217,13 @@ fn test_load() { assert_eq!(cfg.default_locale, "en"); assert_eq!(cfg.available_locales, vec!["en", "zh-CN"]); } + +#[test] +fn test_load_from_file() { + let workdir = Path::new(env!["CARGO_MANIFEST_DIR"]); + let file = workdir.join("../../examples/foo/i18n.toml"); + + let cfg = I18nConfig::load_from_file(&file).unwrap(); + assert_eq!(cfg.default_locale, "en"); + assert_eq!(cfg.available_locales, vec!["en", "zh-CN"]); +} diff --git a/examples/foo/i18n.toml b/examples/foo/i18n.toml new file mode 100644 index 0000000..11d5cb3 --- /dev/null +++ b/examples/foo/i18n.toml @@ -0,0 +1,3 @@ +[i18n] +available-locales = ["en", "zh-CN"] +default-locale = "en"