From 60894f1271293c2802c1779e3260aa218294efe3 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Thu, 6 Nov 2025 22:06:15 +0800 Subject: feat: enhance build and publishing system - Add file copy configurations in .cargo/config.toml - Extend exporter to support copying additional files - Create bin directory for organized binary distribution - Add support for copying shell scripts and completion files --- crates/build_helper/src/bin/exporter.rs | 88 +++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 10 deletions(-) (limited to 'crates/build_helper/src') diff --git a/crates/build_helper/src/bin/exporter.rs b/crates/build_helper/src/bin/exporter.rs index 4a35de5..bc98497 100644 --- a/crates/build_helper/src/bin/exporter.rs +++ b/crates/build_helper/src/bin/exporter.rs @@ -10,9 +10,10 @@ fn main() -> Result<(), Box> { let target_dir = current_target_dir().expect("Failed to get target directory"); let publish_dir = current_publish_dir().expect("Failed to get publish directory"); let publish_binaries = publish_binaries().expect("Failed to get publish binaries"); + let copy_configs = copy_configs().expect("Failed to get copy configurations"); // Final, export binaries to publish directory - let copied_files = export(target_dir, publish_dir, publish_binaries)?; + let copied_files = export(target_dir, publish_dir, publish_binaries, copy_configs)?; let duration = start_time.elapsed(); println!(); @@ -31,6 +32,7 @@ fn export( target_dir: std::path::PathBuf, publish_dir: std::path::PathBuf, publish_binaries: Vec, + copy_configs: Vec, ) -> Result> { let mut copied_files = 0; @@ -39,6 +41,11 @@ fn export( } std::fs::create_dir_all(&publish_dir)?; + // Create bin directory for binaries + let bin_dir = publish_dir.join("bin"); + std::fs::create_dir_all(&bin_dir)?; + + // Copy binaries to bin directory let mut queue = VecDeque::new(); queue.push_back(target_dir); @@ -63,22 +70,15 @@ fn export( if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) && publish_binaries.contains(&file_name.to_string()) { - let parent_dir_name = path - .parent() - .and_then(|p| p.file_name()) - .and_then(|n| n.to_str()) - .unwrap_or(""); - - let dest_path = publish_dir.join(parent_dir_name).join(file_name); + let dest_path = bin_dir.join(file_name); if let Some(parent) = dest_path.parent() { std::fs::create_dir_all(parent)?; } println!( - " {} `{}/{}` ({})", + " {} `{}` ({})", "Copy".green().bold(), - parent_dir_name, file_name, path.display() ); @@ -88,9 +88,45 @@ fn export( } } + // Copy additional files based on configuration + let current = current_dir()?; + for config in copy_configs { + let source_path = current.join(&config.from); + let dest_path = publish_dir.join(&config.to); + + if let Some(parent) = dest_path.parent() { + std::fs::create_dir_all(parent)?; + } + + if source_path.exists() { + println!( + " {} `{}` -> `{}` ({})", + "Copy".green().bold(), + config.from, + config.to, + source_path.display() + ); + std::fs::copy(&source_path, &dest_path)?; + copied_files += 1; + } else { + println!( + " {} `{}` (file not found)", + "Warning".yellow().bold(), + config.from + ); + } + } + Ok(copied_files) } +/// Copy configuration structure +#[derive(Debug)] +struct CopyConfig { + from: String, + to: String, +} + /// Get a target directory from the cargo config /// Returns the complete path relative to the current directory fn get_target_dir(section: &str) -> Result { @@ -137,6 +173,38 @@ fn get_array(section: &str, array_name: &str) -> Result, std::io::Er } } +/// Get the copy configurations from the cargo config +/// Returns a vector of CopyConfig structs +fn copy_configs() -> Result, std::io::Error> { + let current = current_dir()?; + let config_file = current.join(".cargo").join("config.toml"); + let config_content = std::fs::read_to_string(&config_file)?; + let config: toml::Value = toml::from_str(&config_content).map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + format!("Failed to parse config.toml: {}", e), + ) + })?; + + let mut copy_configs = Vec::new(); + + if let Some(copies) = config.get("copies") { + if let Some(tables) = copies.as_table() { + for (_, table) in tables { + if let Some(from) = table.get("from").and_then(|v| v.as_str()) { + let to = table.get("to").and_then(|v| v.as_str()).unwrap_or(""); + copy_configs.push(CopyConfig { + from: from.to_string(), + to: to.to_string(), + }); + } + } + } + } + + Ok(copy_configs) +} + /// Get the target directory of the current project /// By reading the `build.target-dir` configuration item in the `.cargo/config.toml` file /// Returns the complete path relative to the current directory -- cgit