Fix built-in template rename order
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use regex::Regex;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
@@ -47,7 +47,7 @@ impl TemplateEngine {
|
||||
let config_path = template_dir.join("template.toml");
|
||||
let content = fs::read_to_string(&config_path)?;
|
||||
let config: TemplateConfig = toml::from_str(&content)?;
|
||||
|
||||
|
||||
Ok(Self {
|
||||
config,
|
||||
variables: HashMap::new(),
|
||||
@@ -62,7 +62,7 @@ impl TemplateEngine {
|
||||
for (key, var_config) in &self.config.variables {
|
||||
if var_config.required && !self.variables.contains_key(key) {
|
||||
return Err(crate::error::CliError::InvalidInput(format!(
|
||||
"缺少必需的变量: {} ({})",
|
||||
"missing required template variable: {} ({})",
|
||||
key, var_config.description
|
||||
)));
|
||||
}
|
||||
@@ -72,31 +72,19 @@ impl TemplateEngine {
|
||||
|
||||
pub fn process_directory(&self, dir: &Path) -> crate::error::Result<()> {
|
||||
self.validate_variables()?;
|
||||
|
||||
self.replace_in_files(dir)?;
|
||||
|
||||
self.apply_renames(dir)?;
|
||||
|
||||
self.verify_no_placeholders(dir)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_in_files(&self, dir: &Path) -> crate::error::Result<()> {
|
||||
let placeholder_regex = Regex::new(r"\{\{(\w+)\}\}").unwrap();
|
||||
let placeholder_regex = placeholder_regex();
|
||||
|
||||
for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path();
|
||||
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ext) = path.extension().and_then(|s| s.to_str()) {
|
||||
if !self.config.process.file_extensions.contains(&ext.to_string()) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if !path.is_file() || !self.should_process(path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -105,8 +93,8 @@ impl TemplateEngine {
|
||||
|
||||
for cap in placeholder_regex.captures_iter(&content) {
|
||||
let placeholder = &cap[0];
|
||||
let var_name = &cap[1];
|
||||
|
||||
let var_name = placeholder_name(&cap);
|
||||
|
||||
if let Some(value) = self.variables.get(var_name) {
|
||||
updated = updated.replace(placeholder, value);
|
||||
}
|
||||
@@ -114,7 +102,7 @@ impl TemplateEngine {
|
||||
|
||||
if updated != content {
|
||||
fs::write(path, updated)?;
|
||||
println!(" - 处理文件: {}", path.display());
|
||||
println!(" - processed template file: {}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,9 +110,9 @@ impl TemplateEngine {
|
||||
}
|
||||
|
||||
fn apply_renames(&self, dir: &Path) -> crate::error::Result<()> {
|
||||
for rule in self.config.renames.iter().rev() {
|
||||
for rule in &self.config.renames {
|
||||
let from_path = dir.join(&rule.from);
|
||||
|
||||
|
||||
if !from_path.exists() {
|
||||
continue;
|
||||
}
|
||||
@@ -137,20 +125,20 @@ impl TemplateEngine {
|
||||
}
|
||||
|
||||
fs::rename(&from_path, &to_path)?;
|
||||
println!(" - 重命名: {} -> {}", rule.from, to_path_str);
|
||||
println!(" - renamed: {} -> {}", rule.from, to_path_str);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_placeholders(&self, text: &str) -> String {
|
||||
let placeholder_regex = Regex::new(r"\{\{(\w+)\}\}").unwrap();
|
||||
let placeholder_regex = placeholder_regex();
|
||||
let mut result = text.to_string();
|
||||
|
||||
for cap in placeholder_regex.captures_iter(text) {
|
||||
let placeholder = &cap[0];
|
||||
let var_name = &cap[1];
|
||||
|
||||
let var_name = placeholder_name(&cap);
|
||||
|
||||
if let Some(value) = self.variables.get(var_name) {
|
||||
result = result.replace(placeholder, value);
|
||||
}
|
||||
@@ -160,39 +148,58 @@ impl TemplateEngine {
|
||||
}
|
||||
|
||||
fn verify_no_placeholders(&self, dir: &Path) -> crate::error::Result<()> {
|
||||
let placeholder_regex = Regex::new(r"\{\{(\w+)\}\}").unwrap();
|
||||
let placeholder_regex = placeholder_regex();
|
||||
let mut found_placeholders = Vec::new();
|
||||
|
||||
for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path();
|
||||
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ext) = path.extension().and_then(|s| s.to_str()) {
|
||||
if !self.config.process.file_extensions.contains(&ext.to_string()) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if !path.is_file() || !self.should_process(path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(path)?;
|
||||
|
||||
|
||||
for cap in placeholder_regex.captures_iter(&content) {
|
||||
let var_name = &cap[1];
|
||||
let var_name = placeholder_name(&cap);
|
||||
if !self.config.variables.contains_key(var_name) {
|
||||
continue;
|
||||
}
|
||||
found_placeholders.push(format!("{}:{}", path.display(), var_name));
|
||||
}
|
||||
}
|
||||
|
||||
if !found_placeholders.is_empty() {
|
||||
eprintln!("警告: 发现未替换的占位符:");
|
||||
for placeholder in found_placeholders {
|
||||
eprintln!(" - {}", placeholder);
|
||||
}
|
||||
return Err(crate::error::CliError::InvalidData(format!(
|
||||
"unresolved template placeholders: {}",
|
||||
found_placeholders.join(", ")
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn should_process(&self, path: &Path) -> bool {
|
||||
path.extension()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(|ext| {
|
||||
self.config
|
||||
.process
|
||||
.file_extensions
|
||||
.iter()
|
||||
.any(|configured| configured == ext)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn placeholder_regex() -> Regex {
|
||||
Regex::new(r"\{\{(\w+)\}\}|__(\w+)__").unwrap()
|
||||
}
|
||||
|
||||
fn placeholder_name<'a>(cap: &'a regex::Captures<'a>) -> &'a str {
|
||||
cap.get(1)
|
||||
.or_else(|| cap.get(2))
|
||||
.expect("placeholder capture is missing")
|
||||
.as_str()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user