From 686a5cefadfeeda4f24e1f58b7671d2715f5f982 Mon Sep 17 00:00:00 2001 From: steven-omaha <35634100+steven-omaha@users.noreply.github.com> Date: Wed, 11 Jan 2023 14:49:03 +0100 Subject: [PATCH] add import --- Cargo.lock | 19 +++++++++++++++++++ Cargo.toml | 1 + src/action.rs | 1 + src/args.rs | 21 ++++++++++++++++++++- src/core.rs | 29 +++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9f8c80e..68bf883 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,9 +349,28 @@ dependencies = [ "anyhow", "clap", "criterion", + "path-absolutize", "serde_json", ] +[[package]] +name = "path-absolutize" +version = "3.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1d4993b16f7325d90c18c3c6a3327db7808752db8d208cea0acee0abd52c52" +dependencies = [ + "path-dedot", +] + +[[package]] +name = "path-dedot" +version = "3.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a81540d94551664b72b72829b12bd167c73c9d25fbac0e04fafa8023f7e4901" +dependencies = [ + "once_cell", +] + [[package]] name = "pkg-config" version = "0.3.26" diff --git a/Cargo.toml b/Cargo.toml index 64a7275..1b382d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ alpm = "*" anyhow = "*" # clap 4 until (at least) 4.0.32 have scrapped actual color support. we stay on 3.x until that's fixed. clap = "3.*" +path-absolutize = "*" serde_json = "1.0.91" [profile.release] diff --git a/src/action.rs b/src/action.rs index 8820d42..e365702 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,6 +1,7 @@ pub(crate) const CLEAN: &str = "clean"; pub(crate) const EDIT: &str = "edit"; pub(crate) const GROUPS: &str = "groups"; +pub(crate) const IMPORT: &str = "import"; pub(crate) const SHOW: &str = "show"; pub(crate) const SYNC: &str = "sync"; pub(crate) const UNMANAGED: &str = "unmanaged"; diff --git a/src/args.rs b/src/args.rs index cb1d219..87b2b3e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,4 +1,7 @@ -use clap::{Arg, Command}; +use std::path::PathBuf; + +use clap::{Arg, ArgMatches, Command}; +use path_absolutize::Absolutize; use crate::action::*; @@ -16,6 +19,12 @@ fn get_arg_parser() -> Command<'static> { .arg(Arg::new("group").multiple_values(true)), ) .subcommand(Command::new(GROUPS).about("show names of imported groups")) + .subcommand( + Command::new(IMPORT) + .about("import one or more group files") + .arg_required_else_help(true) + .arg(Arg::new("files").multiple_values(true)), + ) .subcommand( Command::new(SHOW) .about("show packages under an imported group") @@ -35,3 +44,13 @@ fn get_arg_parser() -> Command<'static> { pub fn get() -> clap::ArgMatches { get_arg_parser().get_matches() } + +pub(crate) fn get_file_paths(arg_match: &ArgMatches) -> Vec { + arg_match + .get_many::("files") + .unwrap() + .cloned() + .map(PathBuf::from) + .map(|path| path.absolutize().unwrap().into_owned()) + .collect() +} diff --git a/src/core.rs b/src/core.rs index cbfec5b..08df291 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,12 +1,15 @@ use std::collections::HashSet; +use std::os::unix::fs::symlink; use anyhow::{ensure, Context, Result}; use clap::ArgMatches; use crate::action; +use crate::args; use crate::backend::{Backend, Backends, ToDoPerBackend}; use crate::cmd::run_edit_command; use crate::env::get_single_var; +use crate::path::get_pacdef_group_dir; use crate::ui::get_user_confirmation; use crate::Group; @@ -34,6 +37,7 @@ impl Pacdef { self.edit_group_files(groups).context("editing group files") } Some((action::GROUPS, _)) => Ok(self.show_groups()), + Some((action::IMPORT, files)) => self.import_groups(files).context("importing groups"), Some((action::SHOW, groups)) => { self.show_group_content(groups).context("showing groups") } @@ -167,6 +171,31 @@ impl Pacdef { } Ok(()) } + + fn import_groups(&self, args: &ArgMatches) -> Result<()> { + let files = args::get_file_paths(args); + let groups_dir = get_pacdef_group_dir()?; + + for target in files { + let target_name = target.file_name().unwrap().to_str().unwrap(); + + if !target.exists() { + println!("file {target_name} does not exist, skipping"); + continue; + } + + let mut link = groups_dir.clone(); + link.push(target_name); + + if link.exists() { + println!("group {target_name} already exists, skipping"); + } else { + symlink(target, link)?; + } + } + + Ok(()) + } } fn show_error(error: anyhow::Error, backend: Box) {