diff options
| author | 2026-02-26 12:40:51 -0500 | |
|---|---|---|
| committer | 2026-02-26 12:40:51 -0500 | |
| commit | 8c411011aadfd96e7189366f20dda87b26a50cbf (patch) | |
| tree | 766b0d2e6d75c63c3fca1ffc0d3359064e83c0fe /src | |
| parent | updates to add, remove and list (diff) | |
add build support
Diffstat (limited to '')
| -rw-r--r-- | src/action.rs | 67 | ||||
| -rw-r--r-- | src/config.rs | 25 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/util.rs | 22 |
4 files changed, 83 insertions, 32 deletions
diff --git a/src/action.rs b/src/action.rs index cd3b32b..b94c8b3 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,7 +1,11 @@ -use crate::util::{TEMP_CONFIG_PATH, create_config, dir_size, get_editor, is_root, open_in_editor, yn_prompt}; +use crate::config::Config; +use crate::util::{ + TEMP_CONFIG_PATH, create_config, 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"; @@ -74,6 +78,32 @@ 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()); @@ -85,10 +115,7 @@ fn add(url: &str) -> Result<(), String> { }; let config_name = format!("{repo_name}.toml"); - println!( - "Creating config: {}", - config_name - ); + println!("Creating config: {}", config_name); create_config(repo_name)?; let editor = get_editor(); @@ -96,26 +123,29 @@ fn add(url: &str) -> Result<(), String> { open_in_editor(&editor, &config_temp)?; let clone_path = PathBuf::from(BASE_REPO_PATH).join(repo_name); - let repo = Repository::clone(url, &clone_path).map_err(|e| { - format!("failed to clone {}: {}", repo_name, e) - })?; + let repo = Repository::clone(url, &clone_path) + .map_err(|e| format!("failed to clone {}: {}", repo_name, e))?; let mut config_path = PathBuf::from(BASE_CONFIG_PATH); if !config_path.exists() { - fs::create_dir_all(&config_path).map_err(|e| { - format!("failed to create config directory: {}", e) - })?; + fs::create_dir_all(&config_path) + .map_err(|e| format!("failed to create config directory: {}", e))?; } config_path.push(config_name); - fs::rename(config_temp, config_path).map_err(|e| format!("failed to place config in system directory: {}", e))?; + fs::rename(config_temp, &config_path) + .map_err(|e| format!("failed to place config in system directory: {}", e))?; println!( - "New package initialized at: {}", + "New package initialized at: {}\n", repo.path().to_str().unwrap() ); + if yn_prompt("Run build and install commands?") { + build(config_path, clone_path)?; + } + Ok(()) } @@ -174,12 +204,8 @@ fn remove(packages: Vec<String>) -> Result<(), String> { if yn_prompt("Proceed with removal?") { for (name, path, cfg_path) in package_paths { - 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) - })?; + 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); } } @@ -190,7 +216,8 @@ fn remove(packages: Vec<String>) -> Result<(), String> { fn list() -> Result<(), String> { let config_path = Path::new(BASE_CONFIG_PATH); for entry in fs::read_dir(config_path) - .map_err(|e| format!("failed to iterate package directory: {}", e))? { + .map_err(|e| format!("failed to iterate package directory: {}", e))? + { let entry = entry.map_err(|e| e.to_string())?; let path = entry.path(); if path.is_file() { diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..f168b27 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,25 @@ +use serde::Deserialize; +use std::fs; +use std::path::Path; + +#[derive(Deserialize)] +pub struct Config { + pub update: Option<String>, + pub build: Option<String>, + pub install: Option<String>, + pub dependencies: Option<Vec<String>>, +} + +impl Config { + pub fn new<P: AsRef<Path>>(filepath: P) -> Option<Self> { + let contents = match fs::read_to_string(filepath) { + Ok(c) => c, + Err(_) => { + eprintln!("no package config found"); + return None; + } + }; + let config: Config = toml::from_str(&contents).expect("failed to parse config"); + Some(config) + } +} diff --git a/src/main.rs b/src/main.rs index ff71155..fa0ee11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::{env, fs}; use crate::util::TEMP_CONFIG_PATH; mod action; +mod config; mod util; fn main() { diff --git a/src/util.rs b/src/util.rs index ae114d0..caa2c73 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,3 +1,4 @@ +use libc; use std::env; use std::fs; use std::io; @@ -5,7 +6,6 @@ use std::io::Write; use std::path::Path; use std::path::PathBuf; use std::process::Command; -use libc; pub const TEMP_CONFIG_PATH: &str = "/var/lib/forge/.tmp"; @@ -14,9 +14,8 @@ pub fn create_config(package: &str) -> Result<(), String> { 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) - })?; + fs::create_dir_all(&path) + .map_err(|e| format!("failed to create temp config directory: {}", e))?; } path.push(filename); @@ -25,14 +24,12 @@ pub fn create_config(package: &str) -> Result<(), String> { r#"# {package} configuration update = "tagged" # no | live | tagged build = "make" -dependencies = [] install = "make install" +dependencies = [] "# ); - fs::write(path, template).map_err(|e| { - format!("failed to create config: {}", e) - })?; + fs::write(path, template).map_err(|e| format!("failed to create config: {}", e))?; Ok(()) } @@ -60,13 +57,14 @@ pub fn get_editor() -> String { } pub fn is_root() -> bool { - unsafe { libc::geteuid() == 0} + unsafe { libc::geteuid() == 0 } } pub fn open_in_editor(editor: &str, file: &str) -> Result<(), String> { - let status = Command::new(editor).arg(file).status().map_err(|e| { - format!("failed to execute editor: {}", e) - })?; + let status = Command::new(editor) + .arg(file) + .status() + .map_err(|e| format!("failed to execute editor: {}", e))?; if !status.success() { return Err(format!("editor exited with non-zero status: {}", status)); |
