Add link generation to bootstrap command

This commit is contained in:
Nathan Fisher 2022-12-25 19:30:36 -05:00
parent d190050798
commit 1af14e7ff7
2 changed files with 73 additions and 39 deletions

View File

@ -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<PathBuf> {
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");
fn links(&self, prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>> {
println!("Generating links:");
let soft = cmd.get_flag("soft");
self.items
.iter()
.try_for_each(|cmd| cmd.link(prefix, usr, soft))?;
Ok(())
}
path.push("bin");
}
Some(crate::Path::UsrSbin) => {
if usr {
path.push("usr");
}
path.push("sbin");
}
None => return None,
}
path.push(name);
Some(path)
}
*/

View File

@ -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<dyn Error>>;
fn path(&self) -> Option<crate::Path>;
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf> {
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<dyn Error>> {
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(())
}
}