diff options
| author | 2026-02-26 16:23:29 -0500 | |
|---|---|---|
| committer | 2026-02-26 16:23:29 -0500 | |
| commit | aa1b4b75d0070c417f8c02bf35588c195b2d8254 (patch) | |
| tree | d2725b9a668d0587161e516160033432101b0d14 | |
| parent | add build support (diff) | |
proper config command handling
| -rw-r--r-- | src/action.rs | 39 | ||||
| -rw-r--r-- | src/config.rs | 69 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | src/util.rs | 28 |
4 files changed, 76 insertions, 62 deletions
diff --git a/src/action.rs b/src/action.rs index b94c8b3..1aeefb6 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,11 +1,8 @@ -use crate::config::Config; -use crate::util::{ - TEMP_CONFIG_PATH, create_config, dir_size, get_editor, is_root, open_in_editor, yn_prompt, -}; +use crate::config::{self, ConfigCommand, TEMP_CONFIG_PATH, create_config}; +use crate::util::{dir_size, get_editor, is_root, open_in_editor, yn_prompt}; use git2::Repository; use std::fs; use std::path::{Path, PathBuf}; -use std::process::Command; const BASE_REPO_PATH: &str = "/var/db/forge"; const BASE_CONFIG_PATH: &str = "/etc/forge/packages"; @@ -78,32 +75,6 @@ impl Action { } } -//========================================= -// command helpers -//========================================= - -fn build(config_path: PathBuf, repo_path: PathBuf) -> Result<(), String> { - let config = Config::new(config_path); - if let Some(bld) = config.unwrap().build { - let status = Command::new(bld) - .current_dir(repo_path) - .status() - .map_err(|e| format!("failed to execute editor: {}", e))?; - - if !status.success() { - return Err(format!("editor exited with non-zero status: {}", status)); - } - } else { - return Err("no build command found".to_string()); - } - - Ok(()) -} - -//========================================= -// commands -//========================================= - fn add(url: &str) -> Result<(), String> { if !is_root() { return Err("add must be run as root".to_string()); @@ -143,7 +114,10 @@ fn add(url: &str) -> Result<(), String> { ); if yn_prompt("Run build and install commands?") { - build(config_path, clone_path)?; + println!("Building..."); + config::run_config_command(&config_path, &clone_path, ConfigCommand::Build)?; + println!("Installing..."); + config::run_config_command(&config_path, &clone_path, ConfigCommand::Install)?; } Ok(()) @@ -204,6 +178,7 @@ fn remove(packages: Vec<String>) -> Result<(), String> { if yn_prompt("Proceed with removal?") { for (name, path, cfg_path) in package_paths { + config::run_config_command(&cfg_path, &path, ConfigCommand::Uninstall)?; fs::remove_dir_all(&path).map_err(|e| format!("failed to remove {}: {}", name, e))?; fs::remove_file(&cfg_path).map_err(|e| format!("failed to remove {}: {}", name, e))?; println!("Removed {}", name); diff --git a/src/config.rs b/src/config.rs index f168b27..7c6cf2b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,12 +1,22 @@ use serde::Deserialize; use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::process::Command; + +pub const TEMP_CONFIG_PATH: &str = "/var/lib/forge/.tmp"; + +pub enum ConfigCommand { + Build, + Install, + Uninstall, +} #[derive(Deserialize)] pub struct Config { pub update: Option<String>, pub build: Option<String>, pub install: Option<String>, + pub uninstall: Option<String>, pub dependencies: Option<Vec<String>>, } @@ -23,3 +33,60 @@ impl Config { Some(config) } } + +pub fn create_config(package: &str) -> Result<(), String> { + let filename = format!("{package}.toml"); + let mut path = PathBuf::from(TEMP_CONFIG_PATH); + + if !path.exists() { + fs::create_dir_all(&path) + .map_err(|e| format!("failed to create temp config directory: {}", e))?; + } + + path.push(filename); + + let template = format!( + r#"# {package} configuration +update = "tagged" # no | live | tagged +build = "make" +install = "make install" +uninstall = "make uninstall" +dependencies = [] + "# + ); + + fs::write(path, template).map_err(|e| format!("failed to create config: {}", e))?; + + Ok(()) +} + +pub fn run_config_command( + config_path: &Path, + repo_path: &Path, + command: ConfigCommand, +) -> Result<(), String> { + let config = Config::new(config_path).ok_or("config not found".to_string())?; + let cmd = match command { + ConfigCommand::Build => config.build, + ConfigCommand::Install => config.install, + ConfigCommand::Uninstall => config.uninstall, + }; + + if let Some(c) = cmd { + let mut parts = c.split_whitespace(); + let cmd_base = parts.next().ok_or("empty command".to_string())?; + let args: Vec<&str> = parts.collect(); + + let status = Command::new(cmd_base) + .args(&args) + .current_dir(repo_path) + .status() + .map_err(|e| format!("failed to execute command: {}", e))?; + + if !status.success() { + return Err(format!("command exited with non-zero status: {}", status)); + } + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index fa0ee11..529b875 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use action::Action; use std::{env, fs}; -use crate::util::TEMP_CONFIG_PATH; +use crate::config::TEMP_CONFIG_PATH; mod action; mod config; diff --git a/src/util.rs b/src/util.rs index caa2c73..90aacb6 100644 --- a/src/util.rs +++ b/src/util.rs @@ -4,36 +4,8 @@ use std::fs; use std::io; use std::io::Write; use std::path::Path; -use std::path::PathBuf; use std::process::Command; -pub const TEMP_CONFIG_PATH: &str = "/var/lib/forge/.tmp"; - -pub fn create_config(package: &str) -> Result<(), String> { - let filename = format!("{package}.toml"); - let mut path = PathBuf::from(TEMP_CONFIG_PATH); - - if !path.exists() { - fs::create_dir_all(&path) - .map_err(|e| format!("failed to create temp config directory: {}", e))?; - } - - path.push(filename); - - let template = format!( - r#"# {package} configuration -update = "tagged" # no | live | tagged -build = "make" -install = "make install" -dependencies = [] - "# - ); - - fs::write(path, template).map_err(|e| format!("failed to create config: {}", e))?; - - Ok(()) -} - pub fn dir_size(path: &Path) -> std::io::Result<u64> { let mut size = 0; if path.is_dir() { |
