feat: export subcommand

This commit is contained in:
2026-05-29 22:56:15 +02:00
parent f1a774951a
commit 95a75dcd76
+96 -2
View File
@@ -13,7 +13,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::path::PathBuf;
use std::{
ffi::OsStr,
io::Write,
path::PathBuf,
process::{Command, Stdio},
};
use clap::Parser;
use clap_derive::{Parser, Subcommand};
@@ -35,6 +40,8 @@ compile_error!("'yay' and 'paru' are mutually exclusive and cannot be enabled to
#[cfg(not(target_os = "linux"))]
compile_error!("Only (Arch) linux is supported!");
const PRIVLAGE_ESCELATE_COMMAND: &str = "sudo";
#[derive(Parser)]
struct Args {
#[arg(long, global = true)]
@@ -68,6 +75,10 @@ enum Commands {
#[arg(short, long)]
/// When specified, the new world file content will be writen to stdout
stdout: bool,
#[arg(short, long)]
/// When given will transfer ignore values to the new world file
persist_ignore: bool,
},
/// Writes diffrents between the world file and the system
Diff,
@@ -89,7 +100,77 @@ fn main() -> Result<()> {
match args.command {
Commands::Sync => todo!(),
Commands::Export { overwrite, stdout } => todo!(),
Commands::Export {
overwrite,
stdout,
persist_ignore,
} => {
let mut world = match World::load_from(world_path.clone()) {
Ok(x) => x,
Err(_) => World::new_empty(),
};
let mut state = get_system_state()?;
if persist_ignore {
state.ignore = world.get_packages().ignore.clone();
}
let world_state = world.get_mut_packages();
*world_state = state;
let text_world = toml::to_string_pretty(&world)?;
if stdout {
println!("{}", &text_world);
return Ok(());
}
if !overwrite && root_file_exists(world_path.as_os_str())? {
eprintln!("File Already exists!");
return Ok(());
}
if let Some(parent_path) = world_path.parent() {
let status = Command::new(PRIVLAGE_ESCELATE_COMMAND)
.arg("mkdir")
.arg("-p")
.arg(parent_path)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()?;
if !status.success() {
return Err("Making directories for the world file went unsuccessful!".into());
}
}
let mut child = Command::new(PRIVLAGE_ESCELATE_COMMAND)
.arg("tee")
.arg(world_path)
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::inherit())
.spawn()?;
let c_stdin = child.stdin.as_mut();
if c_stdin.is_none() {
return Err("Unabled to pass data to file!".into());
}
c_stdin.unwrap().write_all(text_world.as_bytes())?;
let status = child.wait()?;
if !status.success() {
return Err("Couldn't write to a file!".into());
}
if !args.quiet {
println!("State succesfully saved in the world file!");
}
}
Commands::Diff => {
let world = World::load_from(world_path).unwrap_or(World::new_empty());
let world_state = world.get_packages();
@@ -156,3 +237,16 @@ fn main() -> Result<()> {
}
Ok(())
}
fn root_file_exists(path: &OsStr) -> std::io::Result<bool> {
let status = Command::new(PRIVLAGE_ESCELATE_COMMAND)
.arg("test")
.arg("-e")
.arg(path)
.stdin(Stdio::inherit())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()?;
Ok(status.success())
}