diff --git a/src/commands/internals.rs b/src/commands/internals.rs index c68b4c71..aeff0e3c 100644 --- a/src/commands/internals.rs +++ b/src/commands/internals.rs @@ -9,21 +9,16 @@ use std::path::Path; use std::process::Command as ProcessCommand; use std::os::unix::fs::PermissionsExt; -#[cfg(feature = "development")] -// TODO: Re-enable when implementing real file operations -// use { -// cap_std::fs::Dir, -// cap_std_ext::cap_tempfile, -// }; /// Internals command - Internal system commands for advanced operations pub struct InternalsCommand; impl InternalsCommand { pub fn new() -> Self { - Self + InternalsCommand } } +#[cfg(feature = "development")] impl Command for InternalsCommand { fn execute(&self, args: &[String]) -> AptOstreeResult<()> { if args.is_empty() || args.contains(&"--help".to_string()) || args.contains(&"-h".to_string()) { diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2049cfaf..ae0c658e 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -111,9 +111,7 @@ impl CommandRegistry { self.register(Box::new(container::ContainerCommand::new())); // Development commands (hidden) - self.register(Box::new(testutils::TestutilsCommand::new())); - self.register(Box::new(shlib_backend::ShlibBackendCommand::new())); - self.register(Box::new(internals::InternalsCommand::new())); + self.register_development_commands(); // Legacy aliases - register the same command under multiple names self.register_alias("update", "upgrade"); @@ -161,6 +159,15 @@ impl CommandRegistry { )) } } + + pub fn register_development_commands(&mut self) { + #[cfg(feature = "development")] + { + self.register(Box::new(testutils::TestutilsCommand::new())); + self.register(Box::new(shlib_backend::ShlibBackendCommand::new())); + self.register(Box::new(internals::InternalsCommand::new())); + } + } } impl Default for CommandRegistry { diff --git a/src/commands/shlib_backend.rs b/src/commands/shlib_backend.rs index d6d57063..67fdaeab 100644 --- a/src/commands/shlib_backend.rs +++ b/src/commands/shlib_backend.rs @@ -5,22 +5,16 @@ use apt_ostree::lib::error::{AptOstreeError, AptOstreeResult}; use std::process::Command as ProcessCommand; -#[cfg(feature = "development")] -// TODO: Re-enable when implementing real IPC operations -// use { -// cap_std::fs::Dir, -// cap_std_ext::cap_tempfile, -// std::os::unix::io::FromRawFd, -// }; /// ShlibBackend command - Shared library backend for IPC operations and package management pub struct ShlibBackendCommand; impl ShlibBackendCommand { pub fn new() -> Self { - Self + ShlibBackendCommand } } +#[cfg(feature = "development")] impl Command for ShlibBackendCommand { fn execute(&self, args: &[String]) -> AptOstreeResult<()> { if args.is_empty() || args.contains(&"--help".to_string()) || args.contains(&"-h".to_string()) { diff --git a/src/commands/testutils.rs b/src/commands/testutils.rs index c8e1d686..2f49c110 100644 --- a/src/commands/testutils.rs +++ b/src/commands/testutils.rs @@ -1,4 +1,4 @@ -//! Development debugging tools for apt-ostree +//! Test utilities for development and debugging use crate::commands::Command; use apt_ostree::lib::error::{AptOstreeError, AptOstreeResult}; @@ -7,38 +7,25 @@ use apt_ostree::lib::apt::AptManager; use std::fs; use std::path::Path; use std::process::Command as ProcessCommand; +use std::os::unix::fs::PermissionsExt; #[cfg(feature = "development")] use { - tempfile::TempDir, - goblin::Object, - rand::Rng, - // TODO: Re-enable when implementing real OSTree operations - // cap_std::fs::Dir, - // cap_std_ext::cap_tempfile, - // std::os::unix::io::FromRawFd, + goblin, + rand, + tempfile, }; -// Import OSTree types for real implementation -// TODO: Re-enable when implementing real OSTree operations -// use ostree::{Repo, glib::Variant}; -// use ostree::glib; - -// Type definitions for inject-pkglist functionality -type OstreeRepo = String; // Simplified for now -type OstreeCommit = String; // Simplified for now -type OstreeCommitMetadata = String; // Simplified for now -type AptPkglistVariant = String; // Simplified for now - -/// Testutils command - Development debugging tool for testing and development workflows +/// Testutils command - Development and debugging utilities pub struct TestutilsCommand; impl TestutilsCommand { pub fn new() -> Self { - Self + TestutilsCommand } } +#[cfg(feature = "development")] impl Command for TestutilsCommand { fn execute(&self, args: &[String]) -> AptOstreeResult<()> { if args.is_empty() || args.contains(&"--help".to_string()) || args.contains(&"-h".to_string()) { @@ -696,7 +683,7 @@ impl TestutilsCommand { println!("Mutation percentage: {}%", percentage); // Create temporary directory for ELF manipulation - let temp_dir = TempDir::new() + let temp_dir = tempfile::TempDir::new() .map_err(|e| AptOstreeError::System(format!("Failed to create temp directory: {}", e)))?; println!("Created temporary directory: {}", temp_dir.path().display()); @@ -718,7 +705,7 @@ impl TestutilsCommand { if rand::thread_rng().gen_range(1..=100) <= percentage { if let Ok(data) = fs::read(&path) { // Try to parse as ELF - if let Ok(Object::Elf(_)) = Object::parse(&data) { + if let Ok(goblin::Object::Elf(_)) = goblin::Object::parse(&data) { println!(" Mutating ELF file: {}", path.display()); mutated_files += 1; @@ -770,56 +757,56 @@ impl TestutilsCommand { } } - fn open_ostree_repo(&self, repo_path: &str) -> AptOstreeResult { + fn open_ostree_repo(&self, repo_path: &str) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real OSTree repository opening Ok(repo_path.to_string()) } - fn resolve_reference(&self, _repo: &OstreeRepo, refspec: &str) -> AptOstreeResult { + fn resolve_reference(&self, _repo: &String, refspec: &str) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real reference resolution let ref_name = refspec.split(':').next_back().ok_or_else(|| AptOstreeError::InvalidArgument("Invalid refspec format".to_string()))?; Ok(ref_name.to_string()) } - fn load_commit(&self, _repo: &OstreeRepo, checksum: &str) -> AptOstreeResult { + fn load_commit(&self, _repo: &String, checksum: &str) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real commit loading Ok(checksum.to_string()) } - fn has_pkglist_metadata(&self, _commit: &OstreeCommit) -> AptOstreeResult { + fn has_pkglist_metadata(&self, _commit: &String) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real pkglist metadata checking Ok(false) // No metadata in this stub } - fn create_apt_pkglist_variant(&self, _repo: &OstreeRepo, _checksum: &str) -> AptOstreeResult { + fn create_apt_pkglist_variant(&self, _repo: &String, _checksum: &str) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real APT package list creation Ok("simulated_package_list".to_string()) } - fn count_packages_in_pkglist(&self, pkglist: &AptPkglistVariant) -> AptOstreeResult { + fn count_packages_in_pkglist(&self, pkglist: &String) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real package counting Ok(pkglist.len()) } - fn add_pkglist_to_metadata(&self, _commit: &OstreeCommit, pkglist: &AptPkglistVariant) -> AptOstreeResult { + fn add_pkglist_to_metadata(&self, _commit: &String, pkglist: &String) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement real metadata modification Ok(pkglist.to_string()) } - fn write_new_commit(&self, _repo: &OstreeRepo, parent_checksum: &str, _metadata: &OstreeCommitMetadata) -> AptOstreeResult { + fn write_new_commit(&self, _repo: &String, parent_checksum: &str, _metadata: &String) -> AptOstreeResult { // Simplified implementation for now // TODO: Implement proper commit writing Ok(format!("{}_modified", parent_checksum)) } - fn update_reference(&self, _repo: &OstreeRepo, remote: &str, ref_name: &str, new_checksum: &str) -> AptOstreeResult<()> { + fn update_reference(&self, _repo: &String, remote: &str, ref_name: &str, new_checksum: &str) -> AptOstreeResult<()> { // Simplified implementation for now // TODO: Implement proper reference updating println!("Would update reference '{}:{}' to '{}'", remote, ref_name, new_checksum); diff --git a/src/main.rs b/src/main.rs index dbe346cc..20ad3b30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -214,96 +214,120 @@ async fn main() { commands::container::ContainerCommand::new().execute(&args_vec) }, cli::Commands::Testutils(args) => { - match &args.subcommand { - cli::TestutilsSubcommands::InjectPkglist(inject_args) => { - let args_vec = vec!["inject-pkglist".to_string(), inject_args.repo.clone(), inject_args.refspec.clone()]; - commands::testutils::TestutilsCommand::new().execute(&args_vec) - } - cli::TestutilsSubcommands::ScriptShell(shell_args) => { - let mut args_vec = vec!["script-shell".to_string()]; - args_vec.push(shell_args.script.clone()); - args_vec.extend(shell_args.args.clone()); - - // Add rootpath - args_vec.push(shell_args.rootpath.clone()); - - // Add optional flags - if shell_args.read_only { - args_vec.push("--read-only".to_string()); - } - if let Some(ref user) = shell_args.user { - args_vec.push(format!("--user={}", user)); - } - if let Some(ref group) = shell_args.group { - args_vec.push(format!("--group={}", group)); - } - if let Some(ref cwd) = shell_args.cwd { - args_vec.push(format!("--cwd={}", cwd)); - } - for env_var in &shell_args.env { - args_vec.push(format!("--env={}", env_var)); - } - - commands::testutils::TestutilsCommand::new().execute(&args_vec) - } - cli::TestutilsSubcommands::GenerateSyntheticUpgrade(upgrade_args) => { - let mut args_vec = vec!["generate-synthetic-upgrade".to_string()]; - args_vec.push(format!("--repo={}", upgrade_args.repo)); - if let Some(ref src_ref) = upgrade_args.src_ref { - args_vec.push(format!("--srcref={}", src_ref)); - } - args_vec.push(format!("--ref={}", upgrade_args.ostref)); - args_vec.push(format!("--percentage={}", upgrade_args.percentage)); - if let Some(ref version) = upgrade_args.commit_version { - args_vec.push(format!("--commit-version={}", version)); - } - commands::testutils::TestutilsCommand::new().execute(&args_vec) - } - cli::TestutilsSubcommands::IntegrationReadOnly => { - let args_vec = vec!["integration-read-only".to_string()]; - commands::testutils::TestutilsCommand::new().execute(&args_vec) - } - cli::TestutilsSubcommands::CUnits => { - let args_vec = vec!["c-units".to_string()]; - commands::testutils::TestutilsCommand::new().execute(&args_vec) - } - cli::TestutilsSubcommands::Moo => { - let args_vec = vec!["moo".to_string()]; - commands::testutils::TestutilsCommand::new().execute(&args_vec) + #[cfg(feature = "development")] + { + match &args.subcommand { + cli::TestutilsSubcommands::InjectPkglist(inject_args) => { + let args_vec = vec!["inject-pkglist".to_string(), inject_args.repo.clone(), inject_args.refspec.clone()]; + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } + cli::TestutilsSubcommands::ScriptShell(shell_args) => { + let mut args_vec = vec!["script-shell".to_string()]; + args_vec.push(shell_args.script.clone()); + args_vec.extend(shell_args.args.clone()); + + // Add rootpath + args_vec.push(shell_args.rootpath.clone()); + + // Add optional flags + if shell_args.read_only { + args_vec.push("--read-only".to_string()); + } + if let Some(ref user) = shell_args.user { + args_vec.push(format!("--user={}", user)); + } + if let Some(ref group) = shell_args.group { + args_vec.push(format!("--group={}", group)); + } + if let Some(ref cwd) = shell_args.cwd { + args_vec.push(format!("--cwd={}", cwd)); + } + for env_var in &shell_args.env { + args_vec.push(format!("--env={}", env_var)); + } + + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } + cli::TestutilsSubcommands::GenerateSyntheticUpgrade(upgrade_args) => { + let mut args_vec = vec!["generate-synthetic-upgrade".to_string()]; + args_vec.push(format!("--repo={}", upgrade_args.repo)); + if let Some(ref src_ref) = upgrade_args.src_ref { + args_vec.push(format!("--srcref={}", src_ref)); + } + args_vec.push(format!("--ref={}", upgrade_args.ostref)); + args_vec.push(format!("--percentage={}", upgrade_args.percentage)); + if let Some(ref version) = upgrade_args.commit_version { + args_vec.push(format!("--commit-version={}", version)); + } + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } + cli::TestutilsSubcommands::IntegrationReadOnly => { + let args_vec = vec!["integration-read-only".to_string()]; + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } + cli::TestutilsSubcommands::CUnits => { + let args_vec = vec!["c-units".to_string()]; + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } + cli::TestutilsSubcommands::Moo => { + let args_vec = vec!["moo".to_string()]; + commands::testutils::TestutilsCommand::new().execute(&args_vec) + } } } + #[cfg(not(feature = "development"))] + { + eprintln!("Development commands are not available. Build with --features development"); + std::process::exit(1); + } }, cli::Commands::ShlibBackend(args) => { - match &args.subcommand { - cli::ShlibBackendSubcommands::GetBasearch => { - let args_vec = vec!["get-basearch".to_string()]; - commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) - } - cli::ShlibBackendSubcommands::VarsubstBasearch { source } => { - let args_vec = vec!["varsubst-basearch".to_string(), source.clone()]; - commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) - } - cli::ShlibBackendSubcommands::PackagelistFromCommit { commit } => { - let args_vec = vec!["packagelist-from-commit".to_string(), commit.clone()]; - commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) + #[cfg(feature = "development")] + { + match &args.subcommand { + cli::ShlibBackendSubcommands::GetBasearch => { + let args_vec = vec!["get-basearch".to_string()]; + commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) + } + cli::ShlibBackendSubcommands::VarsubstBasearch { source } => { + let args_vec = vec!["varsubst-basearch".to_string(), source.clone()]; + commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) + } + cli::ShlibBackendSubcommands::PackagelistFromCommit { commit } => { + let args_vec = vec!["packagelist-from-commit".to_string(), commit.clone()]; + commands::shlib_backend::ShlibBackendCommand::new().execute(&args_vec) + } } } + #[cfg(not(feature = "development"))] + { + eprintln!("Development commands are not available. Build with --features development"); + std::process::exit(1); + } }, cli::Commands::Internals(args) => { - match &args.subcommand { - cli::InternalsSubcommands::Diagnostics => { - let args_vec = vec!["diagnostics".to_string()]; - commands::internals::InternalsCommand::new().execute(&args_vec) - } - cli::InternalsSubcommands::ValidateState => { - let args_vec = vec!["validate-state".to_string()]; - commands::internals::InternalsCommand::new().execute(&args_vec) - } - cli::InternalsSubcommands::DebugDump => { - let args_vec = vec!["debug-dump".to_string()]; - commands::internals::InternalsCommand::new().execute(&args_vec) + #[cfg(feature = "development")] + { + match &args.subcommand { + cli::InternalsSubcommands::Diagnostics => { + let args_vec = vec!["diagnostics".to_string()]; + commands::internals::InternalsCommand::new().execute(&args_vec) + } + cli::InternalsSubcommands::ValidateState => { + let args_vec = vec!["validate-state".to_string()]; + commands::internals::InternalsCommand::new().execute(&args_vec) + } + cli::InternalsSubcommands::DebugDump => { + let args_vec = vec!["debug-dump".to_string()]; + commands::internals::InternalsCommand::new().execute(&args_vec) + } } } + #[cfg(not(feature = "development"))] + { + eprintln!("Development commands are not available. Build with --features development"); + std::process::exit(1); + } }, };