diff --git a/src/cmd/bootstrap/mod.rs b/src/cmd/bootstrap/mod.rs index 24a27b8..ecd77d1 100644 --- a/src/cmd/bootstrap/mod.rs +++ b/src/cmd/bootstrap/mod.rs @@ -1,5 +1,5 @@ use super::{Cmd, ECHO, FALSE, HEAD, HOSTNAME, SHITBOX, SLEEP, TRUE}; -use clap::{value_parser, Arg, ArgAction, ArgMatches, Command}; +use clap::{Arg, ArgAction, ArgMatches, Command}; use clap_complete::{generate_to, shells, Generator}; use clap_complete_nushell::Nushell; use clap_mangen::Man; @@ -47,8 +47,7 @@ impl Cmd for Bootstrap { ) .short('u') .long("usr") - .default_value("true") - .value_parser(value_parser!(bool)), + .action(ArgAction::SetTrue), ]) .subcommands([ Command::new("all").about("Install everything"), @@ -108,7 +107,11 @@ impl Cmd for Bootstrap { &BOOTSTRAP, &ECHO, &FALSE, &HEAD, &HOSTNAME, &TRUE, &SLEEP, &SHITBOX, ], }; + let usr = matches.get_flag("usr"); match matches.subcommand() { + Some(("links", matches)) => { + commands.links(prefix, usr, matches)?; + } Some(("manpages", _matches)) => { commands.manpages(prefix)?; } @@ -210,40 +213,13 @@ impl<'a> Commands<'a> { } Ok(()) } -} -/* -fn get_path(prefix: &str, name: &str, usr: bool) -> Option { - let mut path = PathBuf::from(prefix); - let binpath = match name { - "bootstrap" => Bootstrap::path(), - "echo" => Echo::path(), - "false" => False::path(), - "head" => Head::path(), - "hostname" => Hostname::path(), - "true" => True::path(), - "sleep" => Sleep::path(), - "shitbox" => Shitbox::path(), - _ => todo!(), - }; - match binpath { - Some(crate::Path::Bin) => path.push("bin"), - Some(crate::Path::Sbin) => path.push("sbin"), - Some(crate::Path::UsrBin) => { - if usr { - path.push("usr"); - } - path.push("bin"); - } - Some(crate::Path::UsrSbin) => { - if usr { - path.push("usr"); - } - path.push("sbin"); - } - None => return None, + fn links(&self, prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box> { + println!("Generating links:"); + let soft = cmd.get_flag("soft"); + self.items + .iter() + .try_for_each(|cmd| cmd.link(prefix, usr, soft))?; + Ok(()) } - path.push(name); - Some(path) } -*/ diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index ea1b04d..af7664b 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -1,5 +1,5 @@ use clap::ArgMatches; -use std::error::Error; +use std::{error::Error, fs, os::unix::fs::symlink, path::PathBuf}; pub mod bootstrap; mod cat; @@ -34,10 +34,68 @@ pub use { shitbox::{Shitbox, SHITBOX}, sleep::{Sleep, SLEEP}, }; - pub trait Cmd { fn name(&self) -> &str; fn cli(&self) -> clap::Command; fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box>; fn path(&self) -> Option; + + fn linkpath(&self, prefix: &str, usr: bool) -> Option { + let mut path = PathBuf::from(prefix); + let binpath = self.path(); + match binpath { + Some(crate::Path::Bin) => path.push("bin"), + Some(crate::Path::Sbin) => path.push("sbin"), + Some(crate::Path::UsrBin) => { + if usr { + path.push("usr"); + } + path.push("bin"); + } + Some(crate::Path::UsrSbin) => { + if usr { + path.push("usr"); + } + path.push("sbin"); + } + None => return None, + } + path.push(self.name()); + Some(path) + } + + fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box> { + if let Some(linkpath) = self.linkpath(prefix, usr) { + if soft { + let binpath = match self.path().unwrap() { + crate::Path::Bin => "shitbox", + crate::Path::Sbin => "../bin/shitbox", + crate::Path::UsrBin => { + if usr { + "../../bin/shitbox" + } else { + "shitbox" + } + } + crate::Path::UsrSbin => { + if usr { + "../../bin/shitbox" + } else { + "../bin/shitbox" + } + } + }; + symlink(binpath, linkpath)?; + } else { + let mut binpath = PathBuf::from(prefix); + if usr { + binpath.push("usr"); + } + binpath.push("bin"); + binpath.push("shitbox"); + fs::hard_link(binpath, linkpath)?; + } + } + Ok(()) + } }