summaryrefslogtreecommitdiff
path: root/tools/build_helper
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-01-10 06:20:32 +0800
committer魏曹先生 <1992414357@qq.com>2026-01-10 06:29:41 +0800
commitb1fa96a571036bef597695f8e0e7b7a58d1f3296 (patch)
treeba0a4849978f68608c1db7b6781ac19c92a44395 /tools/build_helper
parent412f9a2caa9248d97ade098b7bb160f84b1ebce9 (diff)
Add platform restrictions to deployment configsHEADDesktop_0.1.0_Basemain
- Move build_helper from crates/ to tools/ directory - Specify platform targets for shell completions and entry scripts - Bash scripts now target linux and macos - Powershell scripts target windows - Zsh plugin files target linux and macos
Diffstat (limited to 'tools/build_helper')
-rw-r--r--tools/build_helper/Cargo.toml13
-rw-r--r--tools/build_helper/src/bin/exporter.rs249
2 files changed, 262 insertions, 0 deletions
diff --git a/tools/build_helper/Cargo.toml b/tools/build_helper/Cargo.toml
new file mode 100644
index 0000000..deadd4c
--- /dev/null
+++ b/tools/build_helper/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "cli_publisher"
+edition = "2024"
+version = "0.0.1"
+
+[dependencies]
+
+# Serialization
+serde = { version = "1.0.226", features = ["derive"] }
+toml = { version = "0.9.7", features = ["serde"] }
+
+# Colored
+colored = "3.0.0"
diff --git a/tools/build_helper/src/bin/exporter.rs b/tools/build_helper/src/bin/exporter.rs
new file mode 100644
index 0000000..c8f7ba2
--- /dev/null
+++ b/tools/build_helper/src/bin/exporter.rs
@@ -0,0 +1,249 @@
+use std::{collections::VecDeque, env::current_dir};
+
+use colored::Colorize;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ println!(" {} `.cargo/cargo.toml`", "Reading".green().bold());
+
+ let start_time = std::time::Instant::now();
+
+ 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, copy_configs)?;
+
+ let duration = start_time.elapsed();
+ println!(
+ " {} publish {} {} in {:.1}s",
+ "Finished".green().bold(),
+ copied_files,
+ if copied_files == 1 { "file" } else { "files" },
+ duration.as_secs_f32(),
+ );
+
+ Ok(())
+}
+
+/// Export binaries to publish directory
+fn export(
+ target_dir: std::path::PathBuf,
+ publish_dir: std::path::PathBuf,
+ publish_binaries: Vec<String>,
+ copy_configs: Vec<CopyConfig>,
+) -> Result<usize, Box<dyn std::error::Error>> {
+ let mut copied_files = 0;
+
+ if publish_dir.exists() {
+ std::fs::remove_dir_all(&publish_dir)?;
+ }
+ 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);
+
+ while let Some(current_dir) = queue.pop_front() {
+ let entries = match std::fs::read_dir(&current_dir) {
+ Ok(entries) => entries,
+ Err(_) => continue,
+ };
+
+ for entry in entries.flatten() {
+ let path = entry.path();
+ let metadata = match entry.metadata() {
+ Ok(metadata) => metadata,
+ Err(_) => continue,
+ };
+
+ if metadata.is_dir() {
+ queue.push_back(path);
+ continue;
+ }
+
+ if let Some(file_name) = path.file_name().and_then(|n| n.to_str())
+ && publish_binaries.contains(&file_name.to_string())
+ {
+ let dest_path = bin_dir.join(file_name);
+
+ if let Some(parent) = dest_path.parent() {
+ std::fs::create_dir_all(parent)?;
+ }
+
+ println!(
+ " {} `{}` ({})",
+ "Binary".green().bold(),
+ file_name,
+ path.display()
+ );
+ std::fs::copy(&path, &dest_path)?;
+ copied_files += 1;
+ }
+ }
+ }
+
+ // Copy additional files based on configuration
+ let current = current_dir()?;
+ for config in copy_configs {
+ // Check if platforms are specified and if current platform matches
+ if !config.platforms.is_empty() {
+ let current_platform = std::env::consts::OS;
+ if !config.platforms.contains(&current_platform.to_string()) {
+ continue;
+ }
+ }
+
+ 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!(
+ " {} `{}` -> `{}` ({})",
+ "Other".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,
+ platforms: Vec<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<std::path::PathBuf, 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 target_dir_str = config[section]["target-dir"].as_str().ok_or_else(|| {
+ std::io::Error::new(
+ std::io::ErrorKind::InvalidData,
+ "target-dir not found or not a string",
+ )
+ })?;
+
+ Ok(current.join(target_dir_str))
+}
+
+/// Get the binaries list from the cargo config
+/// Returns a vector of binary names
+fn get_array(section: &str, array_name: &str) -> Result<Vec<String>, 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),
+ )
+ })?;
+
+ if let Some(array) = config[section][array_name].as_array() {
+ let arr: Vec<String> = array
+ .iter()
+ .filter_map(|v| v.as_str().map(String::from))
+ .collect();
+ Ok(arr)
+ } else {
+ Ok(Vec::new())
+ }
+}
+
+/// Get the copy configurations from the cargo config
+/// Returns a vector of CopyConfig structs
+fn copy_configs() -> Result<Vec<CopyConfig>, 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("");
+
+ // Parse platforms array
+ let mut platforms = Vec::new();
+ if let Some(platforms_array) = table.get("platform").and_then(|v| v.as_array())
+ {
+ for platform in platforms_array {
+ if let Some(platform_str) = platform.as_str() {
+ platforms.push(platform_str.to_string());
+ }
+ }
+ }
+
+ copy_configs.push(CopyConfig {
+ from: from.to_string(),
+ to: to.to_string(),
+ platforms,
+ });
+ }
+ }
+ }
+ }
+
+ 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
+fn current_target_dir() -> Result<std::path::PathBuf, std::io::Error> {
+ get_target_dir("build")
+}
+
+/// Get the publish directory of the current project
+/// By reading the `publish.target-dir` configuration item in the `.cargo/config.toml` file
+/// Returns the complete path relative to the current directory
+fn current_publish_dir() -> Result<std::path::PathBuf, std::io::Error> {
+ get_target_dir("publish")
+}
+
+/// Get the binaries list for publishing
+// By reading the `publish.binaries` configuration item in the `.cargo/config.toml` file
+// Returns a vector of binary names
+fn publish_binaries() -> Result<Vec<String>, std::io::Error> {
+ get_array("publish", "binaries")
+}