Fix compilation errors for development commands

- Fix feature gate placement for development commands
- Make struct definitions always available, only gate implementations
- Fix Self constructor usage in unit structs
- Ensure development commands compile without development feature enabled
- Fix CLI argument handling for development commands
- Project now compiles successfully in CI/CD environment
This commit is contained in:
robojerk 2025-08-18 11:53:14 -07:00
parent 3dec23f8f7
commit 45b319046f
5 changed files with 137 additions and 130 deletions

View file

@ -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()) {

View file

@ -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 {

View file

@ -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()) {

View file

@ -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<OstreeRepo> {
fn open_ostree_repo(&self, repo_path: &str) -> AptOstreeResult<String> {
// Simplified implementation for now
// TODO: Implement real OSTree repository opening
Ok(repo_path.to_string())
}
fn resolve_reference(&self, _repo: &OstreeRepo, refspec: &str) -> AptOstreeResult<String> {
fn resolve_reference(&self, _repo: &String, refspec: &str) -> AptOstreeResult<String> {
// 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<OstreeCommit> {
fn load_commit(&self, _repo: &String, checksum: &str) -> AptOstreeResult<String> {
// Simplified implementation for now
// TODO: Implement real commit loading
Ok(checksum.to_string())
}
fn has_pkglist_metadata(&self, _commit: &OstreeCommit) -> AptOstreeResult<bool> {
fn has_pkglist_metadata(&self, _commit: &String) -> AptOstreeResult<bool> {
// 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<AptPkglistVariant> {
fn create_apt_pkglist_variant(&self, _repo: &String, _checksum: &str) -> AptOstreeResult<String> {
// 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<usize> {
fn count_packages_in_pkglist(&self, pkglist: &String) -> AptOstreeResult<usize> {
// Simplified implementation for now
// TODO: Implement real package counting
Ok(pkglist.len())
}
fn add_pkglist_to_metadata(&self, _commit: &OstreeCommit, pkglist: &AptPkglistVariant) -> AptOstreeResult<OstreeCommitMetadata> {
fn add_pkglist_to_metadata(&self, _commit: &String, pkglist: &String) -> AptOstreeResult<String> {
// 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<String> {
fn write_new_commit(&self, _repo: &String, parent_checksum: &str, _metadata: &String) -> AptOstreeResult<String> {
// 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);

View file

@ -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());
#[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 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));
}
// 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));
commands::testutils::TestutilsCommand::new().execute(&args_vec)
}
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));
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)
}
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);
}
},
};