diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-07 02:25:27 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-07 02:25:27 +0800 |
| commit | 81528b273c18693ebd3f05c6f8057ff8e632f4a0 (patch) | |
| tree | 85026c27535337c0123d4650c844ae364bc9780a /mling/src/project_installer.rs | |
| parent | e41e8bda221b44d09d7e93ffc43675147ab60a6d (diff) | |
Refactor mling to use new program architecture and install scripts
Diffstat (limited to 'mling/src/project_installer.rs')
| -rw-r--r-- | mling/src/project_installer.rs | 162 |
1 files changed, 0 insertions, 162 deletions
diff --git a/mling/src/project_installer.rs b/mling/src/project_installer.rs deleted file mode 100644 index 983307f..0000000 --- a/mling/src/project_installer.rs +++ /dev/null @@ -1,162 +0,0 @@ -use mingling::{ShellFlag, build::build_comp_script_to}; - -use crate::{ - namespace_manager::{bin_dir, comp_dir, exe_path, working_dir}, - project_solver::solve, -}; - -const SCRIPT_LOAD_BASH: &str = include_str!("../tmpl/load.sh"); -const SCRIPT_LOAD_FISH: &str = include_str!("../tmpl/load.fish"); -const SCRIPT_LOAD_PWSH: &str = include_str!("../tmpl/load.ps1"); - -#[derive(serde::Deserialize)] -struct CargoToml { - package: Package, -} - -#[derive(serde::Deserialize)] -struct Package { - name: String, -} - -/// Installs all projects and shell scripts. -/// -/// # Errors -/// -/// Returns an `io::Error` if the current directory cannot be determined, if the project -/// installation fails, or if the shell scripts cannot be installed. -pub fn install_all(clean_before_build: bool) -> Result<(), std::io::Error> { - let current = std::env::current_dir()?; - install_this_project(¤t, clean_before_build)?; - install_shell_scripts()?; - Ok(()) -} - -/// Installs a project from the given path. -/// -/// # Errors -/// -/// Returns an `io::Error` if the project installation fails, e.g., if `cargo build` -/// fails, the Cargo.toml cannot be parsed, or file operations (copy, create dir) fail. -pub fn install_this_project( - current: &std::path::PathBuf, - clean_before_build: bool, -) -> Result<(), std::io::Error> { - // Obtain context data - let solved = solve(current)?; - - let workspace_root = &solved.workspace_root; - - // If clean_before_build, execute cargo clean in workspace_root first - if clean_before_build { - let status = std::process::Command::new("cargo") - .arg("clean") - .current_dir(workspace_root) - .status()?; - if !status.success() { - return Err(std::io::Error::other("exec `cargo clean` failed")); - } - } - - // Execute cargo build --release in workspace_root - let status = std::process::Command::new("cargo") - .args(["build", "--release"]) - .current_dir(workspace_root) - .status()?; - if !status.success() { - return Err(std::io::Error::other("cargo build --release failed")); - } - - // Parse package.name from workspace_root's Cargo.toml as namespace - let cargo_toml_content = std::fs::read_to_string(workspace_root.join("Cargo.toml"))?; - let cargo_toml: CargoToml = toml::from_str(&cargo_toml_content).map_err(|e| { - std::io::Error::new( - std::io::ErrorKind::InvalidData, - format!("failed to parse Cargo.toml: {e}"), - ) - })?; - let namespace = cargo_toml.package.name; - - // Ensure destination directories exist - std::fs::create_dir_all(bin_dir(namespace.clone()))?; - std::fs::create_dir_all(comp_dir(namespace.clone()))?; - - // Copy binaries to corresponding exe_path - for bin in &solved.binaries { - let dst = exe_path(namespace.clone(), bin.name.clone()); - std::fs::copy(&bin.path, &dst)?; - } - - // Copy all completion scripts containing _comp from target/release to comp_dir - let target_dir = &solved.target_dir; - let release_dir = target_dir.join("release"); - if release_dir.exists() { - for entry in std::fs::read_dir(&release_dir)? { - let entry = entry?; - let file_name = entry.file_name(); - let file_name_str = file_name.to_string_lossy(); - if file_name_str.contains("_comp") { - let dest = comp_dir(namespace.clone()).join(file_name.as_os_str()); - std::fs::copy(entry.path(), &dest)?; - } - } - } - - Ok(()) -} - -/// Installs shell completion scripts for the `mling` command. -/// -/// # Errors -/// -/// Returns an `io::Error` if the shell scripts cannot be built or installed. -pub fn install_shell_scripts() -> Result<(), std::io::Error> { - // Get the working directory (mingling data dir) - let wdir = working_dir(); - std::fs::create_dir_all(&wdir)?; - - // Build shell completion scripts for the "mling" command based on the current OS - let mling_comp = if cfg!(target_os = "windows") { - vec![ShellFlag::Powershell] - } else if cfg!(target_os = "macos") || cfg!(target_os = "linux") { - vec![ShellFlag::Bash, ShellFlag::Zsh, ShellFlag::Fish] - } else { - vec![ShellFlag::Bash] - }; - - for flag in mling_comp { - build_comp_script_to( - &flag, - "mling", - wdir.join(".comp").display().to_string().as_str(), - )?; - } - - // Determine which scripts to write based on platform - let scripts: Vec<(&str, &str)> = if cfg!(target_os = "windows") { - vec![("load.ps1", SCRIPT_LOAD_PWSH)] - } else if cfg!(target_os = "macos") || cfg!(target_os = "linux") { - vec![ - ("load.sh", SCRIPT_LOAD_BASH), - ("load.fish", SCRIPT_LOAD_FISH), - ] - } else { - // Fallback: write bash script - vec![("load.sh", SCRIPT_LOAD_BASH)] - }; - - for (filename, content) in scripts { - let dest = wdir.join(filename); - std::fs::write(&dest, content)?; - if cfg!(target_os = "linux") { - let status = std::process::Command::new("chmod") - .args(["+x", &dest.to_string_lossy()]) - .status()?; - if !status.success() { - eprintln!("Failed to chmod {filename}"); - } - } - } - - Ok(()) -} |
