Fix bootstrap
for all commands
This commit is contained in:
parent
423592973f
commit
888cc3272b
@ -162,7 +162,7 @@ impl Cmd for Bootstrap {
|
|||||||
fs::create_dir_all(&outpath)?;
|
fs::create_dir_all(&outpath)?;
|
||||||
println!(" mkdir: {}", outpath.display());
|
println!(" mkdir: {}", outpath.display());
|
||||||
}
|
}
|
||||||
outpath.push(env!("CARGO_PKG_NAME"));
|
outpath.push(&shitbox::progname().unwrap());
|
||||||
fs::copy(&progpath, &outpath)?;
|
fs::copy(&progpath, &outpath)?;
|
||||||
println!(
|
println!(
|
||||||
" install: {} -> {}",
|
" install: {} -> {}",
|
||||||
@ -175,15 +175,15 @@ impl Cmd for Bootstrap {
|
|||||||
links(prefix, usr, matches)?;
|
links(prefix, usr, matches)?;
|
||||||
}
|
}
|
||||||
Some(("manpages", _matches)) => {
|
Some(("manpages", _matches)) => {
|
||||||
manpages(prefix)?;
|
manpages(prefix, usr)?;
|
||||||
}
|
}
|
||||||
Some(("completions", matches)) => {
|
Some(("completions", matches)) => {
|
||||||
completions(prefix, matches)?;
|
completions(prefix, matches, usr)?;
|
||||||
}
|
}
|
||||||
Some(("all", matches)) => {
|
Some(("all", matches)) => {
|
||||||
links(prefix, usr, matches)?;
|
links(prefix, usr, matches)?;
|
||||||
manpages(prefix)?;
|
manpages(prefix, usr)?;
|
||||||
completions(prefix, matches)?;
|
completions(prefix, matches, usr)?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ pub trait BootstrapCmd {
|
|||||||
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error>;
|
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error>;
|
||||||
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf>;
|
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf>;
|
||||||
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>>;
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>>;
|
||||||
fn manpage(&self, prefix: &str) -> Result<(), io::Error>;
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BootstrapCmd for dyn Cmd {
|
impl BootstrapCmd for dyn Cmd {
|
||||||
@ -237,31 +237,33 @@ impl BootstrapCmd for dyn Cmd {
|
|||||||
|
|
||||||
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>> {
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>> {
|
||||||
if let Some(linkpath) = self.linkpath(prefix, usr) {
|
if let Some(linkpath) = self.linkpath(prefix, usr) {
|
||||||
|
let progname = shitbox::progname().unwrap();
|
||||||
if soft {
|
if soft {
|
||||||
let binpath = match self.path().unwrap() {
|
let binpath = match self.path().unwrap() {
|
||||||
shitbox::Path::Bin => "shitbox",
|
shitbox::Path::Bin => progname,
|
||||||
shitbox::Path::Sbin => "../bin/shitbox",
|
shitbox::Path::Sbin => format!("../bin/{progname}"),
|
||||||
shitbox::Path::UsrBin => {
|
shitbox::Path::UsrBin => {
|
||||||
if usr {
|
if usr {
|
||||||
"../../bin/shitbox"
|
format!("../../bin/{progname}")
|
||||||
} else {
|
} else {
|
||||||
"shitbox"
|
progname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shitbox::Path::UsrSbin => {
|
shitbox::Path::UsrSbin => {
|
||||||
if usr {
|
if usr {
|
||||||
"../../bin/shitbox"
|
format!("../../bin/{progname}")
|
||||||
} else {
|
} else {
|
||||||
"../bin/shitbox"
|
format!("../bin/{progname}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
symlink(binpath, &linkpath)?;
|
symlink(&binpath, &linkpath)?;
|
||||||
println!(" symlink: {binpath} -> {}", linkpath.display());
|
println!(" symlink: {binpath} -> {}", linkpath.display());
|
||||||
} else {
|
} else {
|
||||||
let mut binpath = PathBuf::from(prefix);
|
let mut binpath = PathBuf::from(prefix);
|
||||||
binpath.push("bin");
|
binpath.push("bin");
|
||||||
binpath.push(env!("CARGO_PKG_NAME"));
|
binpath.push(env!("CARGO_PKG_NAME"));
|
||||||
|
println!("Generating link for {}", self.cli().get_name());
|
||||||
fs::hard_link(&binpath, &linkpath)?;
|
fs::hard_link(&binpath, &linkpath)?;
|
||||||
println!(" link: {} -> {}", binpath.display(), linkpath.display());
|
println!(" link: {} -> {}", binpath.display(), linkpath.display());
|
||||||
}
|
}
|
||||||
@ -269,13 +271,17 @@ impl BootstrapCmd for dyn Cmd {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manpage(&self, prefix: &str) -> Result<(), io::Error> {
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
let command = self.cli();
|
let command = self.cli();
|
||||||
let fname = match command.get_name() {
|
let fname = match command.get_name() {
|
||||||
"bootstrap" => "shitbox-bootstrap.1".to_string(),
|
"bootstrap" => format!("{}-bootstrap.1", shitbox::progname().unwrap()),
|
||||||
s => format!("{s}.1"),
|
s => format!("{s}.1"),
|
||||||
};
|
};
|
||||||
let outdir: PathBuf = [prefix, "usr", "share", "man", "man1"].iter().collect();
|
let outdir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share", "man", "man1"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share", "man", "man1"].iter().collect()
|
||||||
|
};
|
||||||
if !outdir.exists() {
|
if !outdir.exists() {
|
||||||
fs::create_dir_all(&outdir)?;
|
fs::create_dir_all(&outdir)?;
|
||||||
}
|
}
|
||||||
@ -290,48 +296,61 @@ impl BootstrapCmd for dyn Cmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manpages(prefix: &str) -> Result<(), io::Error> {
|
fn manpages(prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
println!("Generating Unix man pages:");
|
println!("Generating Unix man pages:");
|
||||||
COMMANDS
|
COMMANDS
|
||||||
.iter()
|
.iter()
|
||||||
.try_for_each(|cmd| super::get(cmd).unwrap().manpage(prefix))?;
|
.try_for_each(|cmd| super::get(cmd).unwrap().manpage(prefix, usr))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn completions(prefix: &str, matches: &ArgMatches) -> Result<(), io::Error> {
|
fn completions(prefix: &str, matches: &ArgMatches, usr: bool) -> Result<(), io::Error> {
|
||||||
println!("Generating completions:");
|
println!("Generating completions:");
|
||||||
|
let basedir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share"].iter().collect()
|
||||||
|
};
|
||||||
if matches.get_flag("bash") || matches.get_flag("all") {
|
if matches.get_flag("bash") || matches.get_flag("all") {
|
||||||
let outdir: PathBuf = [prefix, "share", "bash-completion", "completion"]
|
let mut outdir = basedir.clone();
|
||||||
.iter()
|
outdir.push("bash-completion");
|
||||||
.collect();
|
outdir.push("completion");
|
||||||
COMMANDS.iter().try_for_each(|cmd| {
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
let cmd = super::get(cmd).unwrap();
|
let cmd = super::get(cmd).unwrap();
|
||||||
cmd.completion(&outdir, "bash")
|
cmd.completion(&outdir, "bash")
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
if matches.get_flag("fish") || matches.get_flag("all") {
|
if matches.get_flag("fish") || matches.get_flag("all") {
|
||||||
let outdir: PathBuf = [prefix, "share", "fish", "completions"].iter().collect();
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("fish");
|
||||||
|
outdir.push("completions");
|
||||||
COMMANDS.iter().try_for_each(|cmd| {
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
let cmd = super::get(cmd).unwrap();
|
let cmd = super::get(cmd).unwrap();
|
||||||
cmd.completion(&outdir, "fish")
|
cmd.completion(&outdir, "fish")
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
if matches.get_flag("nu") || matches.get_flag("all") {
|
if matches.get_flag("nu") || matches.get_flag("all") {
|
||||||
let outdir: PathBuf = [prefix, "share", "nu", "completions"].iter().collect();
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("nu");
|
||||||
|
outdir.push("completions");
|
||||||
COMMANDS.iter().try_for_each(|cmd| {
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
let cmd = super::get(cmd).unwrap();
|
let cmd = super::get(cmd).unwrap();
|
||||||
cmd.completion(&outdir, "nu")
|
cmd.completion(&outdir, "nu")
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
if matches.get_flag("pwsh") || matches.get_flag("all") {
|
if matches.get_flag("pwsh") || matches.get_flag("all") {
|
||||||
let outdir: PathBuf = [prefix, "share", "pwsh", "completions"].iter().collect();
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("pwsh");
|
||||||
|
outdir.push("completions");
|
||||||
COMMANDS.iter().try_for_each(|cmd| {
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
let cmd = super::get(cmd).unwrap();
|
let cmd = super::get(cmd).unwrap();
|
||||||
cmd.completion(&outdir, "pwsh")
|
cmd.completion(&outdir, "pwsh")
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
if matches.get_flag("zsh") || matches.get_flag("all") {
|
if matches.get_flag("zsh") || matches.get_flag("all") {
|
||||||
let outdir: PathBuf = [prefix, "share", "zsh", "site-functions"].iter().collect();
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("zsh");
|
||||||
|
outdir.push("site-functions");
|
||||||
COMMANDS.iter().try_for_each(|cmd| {
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
let cmd = super::get(cmd).unwrap();
|
let cmd = super::get(cmd).unwrap();
|
||||||
cmd.completion(&outdir, "zsh")
|
cmd.completion(&outdir, "zsh")
|
||||||
@ -376,3 +395,4 @@ fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>
|
|||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
398
hashbox/commands/bootstrap/mod.rs
Normal file
398
hashbox/commands/bootstrap/mod.rs
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
use super::{Cmd, COMMANDS};
|
||||||
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
|
use clap_complete::{generate_to, shells};
|
||||||
|
use clap_complete_nushell::Nushell;
|
||||||
|
use clap_mangen::Man;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
fs, io,
|
||||||
|
os::unix::fs::symlink,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Bootstrap;
|
||||||
|
|
||||||
|
impl Bootstrap {
|
||||||
|
fn all() -> clap::Command {
|
||||||
|
Command::new("all").about("Install everything").args([
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("all")
|
||||||
|
.help("Install completions for all supported shells")
|
||||||
|
.short('a')
|
||||||
|
.long("all")
|
||||||
|
.conflicts_with_all(["bash", "fish", "nu", "pwsh", "zsh"])
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("bash")
|
||||||
|
.help("Bash shell completions")
|
||||||
|
.short('b')
|
||||||
|
.long("bash")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("fish")
|
||||||
|
.help("Fish shell completions")
|
||||||
|
.short('f')
|
||||||
|
.long("fish")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("nu")
|
||||||
|
.help("Nushell completions")
|
||||||
|
.short('n')
|
||||||
|
.long("nu")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("pwsh")
|
||||||
|
.help("PowerShell completions")
|
||||||
|
.short('p')
|
||||||
|
.long("pwsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("zsh")
|
||||||
|
.help("Zshell completions")
|
||||||
|
.short('z')
|
||||||
|
.long("zsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn links() -> clap::Command {
|
||||||
|
Command::new("links")
|
||||||
|
.about("Install links for each applet")
|
||||||
|
.arg(
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpages() -> clap::Command {
|
||||||
|
Command::new("manpages")
|
||||||
|
.about("Install Unix man pages")
|
||||||
|
.alias("man")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completions() -> clap::Command {
|
||||||
|
Command::new("completions")
|
||||||
|
.about("Install shell completions")
|
||||||
|
.alias("comp")
|
||||||
|
.args([
|
||||||
|
Arg::new("all")
|
||||||
|
.help("Install completions for all supported shells")
|
||||||
|
.short('a')
|
||||||
|
.long("all")
|
||||||
|
.exclusive(true)
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("bash")
|
||||||
|
.help("Bash shell completions")
|
||||||
|
.short('b')
|
||||||
|
.long("bash")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("fish")
|
||||||
|
.help("Fish shell completions")
|
||||||
|
.short('f')
|
||||||
|
.long("fish")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("nu")
|
||||||
|
.help("Nushell completions")
|
||||||
|
.short('n')
|
||||||
|
.long("nu")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("pwsh")
|
||||||
|
.help("PowerShell completions")
|
||||||
|
.short('p')
|
||||||
|
.long("pwsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("zsh")
|
||||||
|
.help("Zshell completions")
|
||||||
|
.short('z')
|
||||||
|
.long("zsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cmd for Bootstrap {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("bootstrap")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.about("Install shitbox into the filesystem")
|
||||||
|
.long_about("Install symlinks, manpages and shell completions")
|
||||||
|
.args([
|
||||||
|
Arg::new("prefix")
|
||||||
|
.help("The directory path under which to install")
|
||||||
|
.short('p')
|
||||||
|
.long("prefix")
|
||||||
|
.num_args(1)
|
||||||
|
.default_value("/")
|
||||||
|
.required(false),
|
||||||
|
Arg::new("usr")
|
||||||
|
.help("Use /usr")
|
||||||
|
.long_help(
|
||||||
|
"Split the installation so that some applets go into /bin | /sbin\n\
|
||||||
|
while others are placed into /usr/bin | /usr/sbin",
|
||||||
|
)
|
||||||
|
.short('u')
|
||||||
|
.long("usr")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
.subcommands([
|
||||||
|
Self::all(),
|
||||||
|
Self::links(),
|
||||||
|
Self::manpages(),
|
||||||
|
Self::completions(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||||
|
if let Some(prefix) = matches.get_one::<String>("prefix") {
|
||||||
|
let usr = matches.get_flag("usr");
|
||||||
|
if let Some(progpath) = shitbox::progpath() {
|
||||||
|
let mut outpath = PathBuf::from(prefix);
|
||||||
|
outpath.push("bin");
|
||||||
|
println!("Installing binary:");
|
||||||
|
if !outpath.exists() {
|
||||||
|
fs::create_dir_all(&outpath)?;
|
||||||
|
println!(" mkdir: {}", outpath.display());
|
||||||
|
}
|
||||||
|
outpath.push(&shitbox::progname().unwrap());
|
||||||
|
fs::copy(&progpath, &outpath)?;
|
||||||
|
println!(
|
||||||
|
" install: {} -> {}",
|
||||||
|
progpath.display(),
|
||||||
|
outpath.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
match matches.subcommand() {
|
||||||
|
Some(("links", matches)) => {
|
||||||
|
links(prefix, usr, matches)?;
|
||||||
|
}
|
||||||
|
Some(("manpages", _matches)) => {
|
||||||
|
manpages(prefix, usr)?;
|
||||||
|
}
|
||||||
|
Some(("completions", matches)) => {
|
||||||
|
completions(prefix, matches, usr)?;
|
||||||
|
}
|
||||||
|
Some(("all", matches)) => {
|
||||||
|
links(prefix, usr, matches)?;
|
||||||
|
manpages(prefix, usr)?;
|
||||||
|
completions(prefix, matches, usr)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<shitbox::Path> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::module_name_repetitions)]
|
||||||
|
pub trait BootstrapCmd {
|
||||||
|
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error>;
|
||||||
|
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf>;
|
||||||
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>>;
|
||||||
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BootstrapCmd for dyn Cmd {
|
||||||
|
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error> {
|
||||||
|
let cmd = self.cli();
|
||||||
|
let name = cmd.get_name();
|
||||||
|
let mut cmd = self.cli();
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(outdir)?;
|
||||||
|
}
|
||||||
|
let path = match gen {
|
||||||
|
"bash" => generate_to(shells::Bash, &mut cmd, name, outdir)?,
|
||||||
|
"fish" => generate_to(shells::Fish, &mut cmd, name, outdir)?,
|
||||||
|
"nu" => generate_to(Nushell, &mut cmd, name, outdir)?,
|
||||||
|
"pwsh" => generate_to(shells::PowerShell, &mut cmd, name, outdir)?,
|
||||||
|
"zsh" => generate_to(shells::Zsh, &mut cmd, name, outdir)?,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
println!(" {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf> {
|
||||||
|
let mut path = PathBuf::from(prefix);
|
||||||
|
let binpath = self.path();
|
||||||
|
match binpath {
|
||||||
|
Some(p) => path.push(p.to_str(usr)),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
path.push(self.cli().get_name());
|
||||||
|
Some(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>> {
|
||||||
|
if let Some(linkpath) = self.linkpath(prefix, usr) {
|
||||||
|
let progname = shitbox::progname().unwrap();
|
||||||
|
if soft {
|
||||||
|
let binpath = match self.path().unwrap() {
|
||||||
|
shitbox::Path::Bin => progname,
|
||||||
|
shitbox::Path::Sbin => format!("../bin/{progname}"),
|
||||||
|
shitbox::Path::UsrBin => {
|
||||||
|
if usr {
|
||||||
|
format!("../../bin/{progname}")
|
||||||
|
} else {
|
||||||
|
progname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shitbox::Path::UsrSbin => {
|
||||||
|
if usr {
|
||||||
|
format!("../../bin/{progname}")
|
||||||
|
} else {
|
||||||
|
format!("../bin/{progname}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
symlink(&binpath, &linkpath)?;
|
||||||
|
println!(" symlink: {binpath} -> {}", linkpath.display());
|
||||||
|
} else {
|
||||||
|
let mut binpath = PathBuf::from(prefix);
|
||||||
|
binpath.push("bin");
|
||||||
|
binpath.push(env!("CARGO_PKG_NAME"));
|
||||||
|
println!("Generating link for {}", self.cli().get_name());
|
||||||
|
fs::hard_link(&binpath, &linkpath)?;
|
||||||
|
println!(" link: {} -> {}", binpath.display(), linkpath.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
|
let command = self.cli();
|
||||||
|
let fname = match command.get_name() {
|
||||||
|
"bootstrap" => format!("{}-bootstrap.1", shitbox::progname().unwrap()),
|
||||||
|
s => format!("{s}.1"),
|
||||||
|
};
|
||||||
|
let outdir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share", "man", "man1"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share", "man", "man1"].iter().collect()
|
||||||
|
};
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(&outdir)?;
|
||||||
|
}
|
||||||
|
let mut outfile = outdir;
|
||||||
|
outfile.push(fname);
|
||||||
|
let man = Man::new(command);
|
||||||
|
let mut buffer: Vec<u8> = vec![];
|
||||||
|
man.render(&mut buffer)?;
|
||||||
|
fs::write(&outfile, buffer)?;
|
||||||
|
println!(" {}", outfile.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpages(prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
|
println!("Generating Unix man pages:");
|
||||||
|
COMMANDS
|
||||||
|
.iter()
|
||||||
|
.try_for_each(|cmd| super::get(cmd).unwrap().manpage(prefix, usr))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completions(prefix: &str, matches: &ArgMatches, usr: bool) -> Result<(), io::Error> {
|
||||||
|
println!("Generating completions:");
|
||||||
|
let basedir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share"].iter().collect()
|
||||||
|
};
|
||||||
|
if matches.get_flag("bash") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("bash-completion");
|
||||||
|
outdir.push("completion");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "bash")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("fish") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("fish");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "fish")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("nu") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("nu");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "nu")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("pwsh") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("pwsh");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "pwsh")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("zsh") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("zsh");
|
||||||
|
outdir.push("site-functions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "zsh")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||||
|
println!("Generating links:");
|
||||||
|
let mut binpath = PathBuf::from(prefix);
|
||||||
|
binpath.push("bin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("sbin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
if usr {
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("usr");
|
||||||
|
binpath.push("bin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("sbin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let soft = cmd.get_flag("soft");
|
||||||
|
COMMANDS.iter().try_for_each(|c| {
|
||||||
|
let cmd = super::get(c).unwrap();
|
||||||
|
cmd.link(prefix, usr, soft)
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
use shitbox::Cmd;
|
use shitbox::Cmd;
|
||||||
|
|
||||||
mod b2sum;
|
mod b2sum;
|
||||||
|
mod bootstrap;
|
||||||
mod hashbox;
|
mod hashbox;
|
||||||
mod md5sum;
|
mod md5sum;
|
||||||
mod sha1sum;
|
mod sha1sum;
|
||||||
@ -15,6 +16,7 @@ mod sha512sum;
|
|||||||
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||||
match name {
|
match name {
|
||||||
"b2sum" => Some(Box::new(b2sum::B2sum::default())),
|
"b2sum" => Some(Box::new(b2sum::B2sum::default())),
|
||||||
|
"bootstrap" => Some(Box::new(bootstrap::Bootstrap::default())),
|
||||||
"hashbox" => Some(Box::new(hashbox::Hashbox::default())),
|
"hashbox" => Some(Box::new(hashbox::Hashbox::default())),
|
||||||
"md5sum" => Some(Box::new(md5sum::Md5sum::default())),
|
"md5sum" => Some(Box::new(md5sum::Md5sum::default())),
|
||||||
"sha1sum" => Some(Box::new(sha1sum::Sha1sum::default())),
|
"sha1sum" => Some(Box::new(sha1sum::Sha1sum::default())),
|
||||||
@ -26,8 +28,9 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 7] = [
|
pub static COMMANDS: [&str; 8] = [
|
||||||
"b2sum",
|
"b2sum",
|
||||||
|
"bootstrap",
|
||||||
"md5sum",
|
"md5sum",
|
||||||
"sha1sum",
|
"sha1sum",
|
||||||
"sha224sum",
|
"sha224sum",
|
||||||
|
398
utilbox/commands/bootstrap/mod.rs
Normal file
398
utilbox/commands/bootstrap/mod.rs
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
use super::{Cmd, COMMANDS};
|
||||||
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
|
use clap_complete::{generate_to, shells};
|
||||||
|
use clap_complete_nushell::Nushell;
|
||||||
|
use clap_mangen::Man;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
fs, io,
|
||||||
|
os::unix::fs::symlink,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Bootstrap;
|
||||||
|
|
||||||
|
impl Bootstrap {
|
||||||
|
fn all() -> clap::Command {
|
||||||
|
Command::new("all").about("Install everything").args([
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("all")
|
||||||
|
.help("Install completions for all supported shells")
|
||||||
|
.short('a')
|
||||||
|
.long("all")
|
||||||
|
.conflicts_with_all(["bash", "fish", "nu", "pwsh", "zsh"])
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("bash")
|
||||||
|
.help("Bash shell completions")
|
||||||
|
.short('b')
|
||||||
|
.long("bash")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("fish")
|
||||||
|
.help("Fish shell completions")
|
||||||
|
.short('f')
|
||||||
|
.long("fish")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("nu")
|
||||||
|
.help("Nushell completions")
|
||||||
|
.short('n')
|
||||||
|
.long("nu")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("pwsh")
|
||||||
|
.help("PowerShell completions")
|
||||||
|
.short('p')
|
||||||
|
.long("pwsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("zsh")
|
||||||
|
.help("Zshell completions")
|
||||||
|
.short('z')
|
||||||
|
.long("zsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn links() -> clap::Command {
|
||||||
|
Command::new("links")
|
||||||
|
.about("Install links for each applet")
|
||||||
|
.arg(
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpages() -> clap::Command {
|
||||||
|
Command::new("manpages")
|
||||||
|
.about("Install Unix man pages")
|
||||||
|
.alias("man")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completions() -> clap::Command {
|
||||||
|
Command::new("completions")
|
||||||
|
.about("Install shell completions")
|
||||||
|
.alias("comp")
|
||||||
|
.args([
|
||||||
|
Arg::new("all")
|
||||||
|
.help("Install completions for all supported shells")
|
||||||
|
.short('a')
|
||||||
|
.long("all")
|
||||||
|
.exclusive(true)
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("bash")
|
||||||
|
.help("Bash shell completions")
|
||||||
|
.short('b')
|
||||||
|
.long("bash")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("fish")
|
||||||
|
.help("Fish shell completions")
|
||||||
|
.short('f')
|
||||||
|
.long("fish")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("nu")
|
||||||
|
.help("Nushell completions")
|
||||||
|
.short('n')
|
||||||
|
.long("nu")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("pwsh")
|
||||||
|
.help("PowerShell completions")
|
||||||
|
.short('p')
|
||||||
|
.long("pwsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("zsh")
|
||||||
|
.help("Zshell completions")
|
||||||
|
.short('z')
|
||||||
|
.long("zsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cmd for Bootstrap {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("bootstrap")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.about("Install shitbox into the filesystem")
|
||||||
|
.long_about("Install symlinks, manpages and shell completions")
|
||||||
|
.args([
|
||||||
|
Arg::new("prefix")
|
||||||
|
.help("The directory path under which to install")
|
||||||
|
.short('p')
|
||||||
|
.long("prefix")
|
||||||
|
.num_args(1)
|
||||||
|
.default_value("/")
|
||||||
|
.required(false),
|
||||||
|
Arg::new("usr")
|
||||||
|
.help("Use /usr")
|
||||||
|
.long_help(
|
||||||
|
"Split the installation so that some applets go into /bin | /sbin\n\
|
||||||
|
while others are placed into /usr/bin | /usr/sbin",
|
||||||
|
)
|
||||||
|
.short('u')
|
||||||
|
.long("usr")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("soft")
|
||||||
|
.help("Install soft links instead of hardlinks")
|
||||||
|
.short('s')
|
||||||
|
.long("soft")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
.subcommands([
|
||||||
|
Self::all(),
|
||||||
|
Self::links(),
|
||||||
|
Self::manpages(),
|
||||||
|
Self::completions(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||||
|
if let Some(prefix) = matches.get_one::<String>("prefix") {
|
||||||
|
let usr = matches.get_flag("usr");
|
||||||
|
if let Some(progpath) = shitbox::progpath() {
|
||||||
|
let mut outpath = PathBuf::from(prefix);
|
||||||
|
outpath.push("bin");
|
||||||
|
println!("Installing binary:");
|
||||||
|
if !outpath.exists() {
|
||||||
|
fs::create_dir_all(&outpath)?;
|
||||||
|
println!(" mkdir: {}", outpath.display());
|
||||||
|
}
|
||||||
|
outpath.push(&shitbox::progname().unwrap());
|
||||||
|
fs::copy(&progpath, &outpath)?;
|
||||||
|
println!(
|
||||||
|
" install: {} -> {}",
|
||||||
|
progpath.display(),
|
||||||
|
outpath.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
match matches.subcommand() {
|
||||||
|
Some(("links", matches)) => {
|
||||||
|
links(prefix, usr, matches)?;
|
||||||
|
}
|
||||||
|
Some(("manpages", _matches)) => {
|
||||||
|
manpages(prefix, usr)?;
|
||||||
|
}
|
||||||
|
Some(("completions", matches)) => {
|
||||||
|
completions(prefix, matches, usr)?;
|
||||||
|
}
|
||||||
|
Some(("all", matches)) => {
|
||||||
|
links(prefix, usr, matches)?;
|
||||||
|
manpages(prefix, usr)?;
|
||||||
|
completions(prefix, matches, usr)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<shitbox::Path> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::module_name_repetitions)]
|
||||||
|
pub trait BootstrapCmd {
|
||||||
|
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error>;
|
||||||
|
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf>;
|
||||||
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>>;
|
||||||
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BootstrapCmd for dyn Cmd {
|
||||||
|
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error> {
|
||||||
|
let cmd = self.cli();
|
||||||
|
let name = cmd.get_name();
|
||||||
|
let mut cmd = self.cli();
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(outdir)?;
|
||||||
|
}
|
||||||
|
let path = match gen {
|
||||||
|
"bash" => generate_to(shells::Bash, &mut cmd, name, outdir)?,
|
||||||
|
"fish" => generate_to(shells::Fish, &mut cmd, name, outdir)?,
|
||||||
|
"nu" => generate_to(Nushell, &mut cmd, name, outdir)?,
|
||||||
|
"pwsh" => generate_to(shells::PowerShell, &mut cmd, name, outdir)?,
|
||||||
|
"zsh" => generate_to(shells::Zsh, &mut cmd, name, outdir)?,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
println!(" {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linkpath(&self, prefix: &str, usr: bool) -> Option<PathBuf> {
|
||||||
|
let mut path = PathBuf::from(prefix);
|
||||||
|
let binpath = self.path();
|
||||||
|
match binpath {
|
||||||
|
Some(p) => path.push(p.to_str(usr)),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
path.push(self.cli().get_name());
|
||||||
|
Some(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn link(&self, prefix: &str, usr: bool, soft: bool) -> Result<(), Box<dyn Error>> {
|
||||||
|
if let Some(linkpath) = self.linkpath(prefix, usr) {
|
||||||
|
let progname = shitbox::progname().unwrap();
|
||||||
|
if soft {
|
||||||
|
let binpath = match self.path().unwrap() {
|
||||||
|
shitbox::Path::Bin => progname,
|
||||||
|
shitbox::Path::Sbin => format!("../bin/{progname}"),
|
||||||
|
shitbox::Path::UsrBin => {
|
||||||
|
if usr {
|
||||||
|
format!("../../bin/{progname}")
|
||||||
|
} else {
|
||||||
|
progname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shitbox::Path::UsrSbin => {
|
||||||
|
if usr {
|
||||||
|
format!("../../bin/{progname}")
|
||||||
|
} else {
|
||||||
|
format!("../bin/{progname}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
symlink(&binpath, &linkpath)?;
|
||||||
|
println!(" symlink: {binpath} -> {}", linkpath.display());
|
||||||
|
} else {
|
||||||
|
let mut binpath = PathBuf::from(prefix);
|
||||||
|
binpath.push("bin");
|
||||||
|
binpath.push(env!("CARGO_PKG_NAME"));
|
||||||
|
println!("Generating link for {}", self.cli().get_name());
|
||||||
|
fs::hard_link(&binpath, &linkpath)?;
|
||||||
|
println!(" link: {} -> {}", binpath.display(), linkpath.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpage(&self, prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
|
let command = self.cli();
|
||||||
|
let fname = match command.get_name() {
|
||||||
|
"bootstrap" => format!("{}-bootstrap.1", shitbox::progname().unwrap()),
|
||||||
|
s => format!("{s}.1"),
|
||||||
|
};
|
||||||
|
let outdir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share", "man", "man1"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share", "man", "man1"].iter().collect()
|
||||||
|
};
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(&outdir)?;
|
||||||
|
}
|
||||||
|
let mut outfile = outdir;
|
||||||
|
outfile.push(fname);
|
||||||
|
let man = Man::new(command);
|
||||||
|
let mut buffer: Vec<u8> = vec![];
|
||||||
|
man.render(&mut buffer)?;
|
||||||
|
fs::write(&outfile, buffer)?;
|
||||||
|
println!(" {}", outfile.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manpages(prefix: &str, usr: bool) -> Result<(), io::Error> {
|
||||||
|
println!("Generating Unix man pages:");
|
||||||
|
COMMANDS
|
||||||
|
.iter()
|
||||||
|
.try_for_each(|cmd| super::get(cmd).unwrap().manpage(prefix, usr))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completions(prefix: &str, matches: &ArgMatches, usr: bool) -> Result<(), io::Error> {
|
||||||
|
println!("Generating completions:");
|
||||||
|
let basedir: PathBuf = if usr {
|
||||||
|
[prefix, "usr", "share"].iter().collect()
|
||||||
|
} else {
|
||||||
|
[prefix, "share"].iter().collect()
|
||||||
|
};
|
||||||
|
if matches.get_flag("bash") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("bash-completion");
|
||||||
|
outdir.push("completion");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "bash")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("fish") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("fish");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "fish")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("nu") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("nu");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "nu")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("pwsh") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("pwsh");
|
||||||
|
outdir.push("completions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "pwsh")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("zsh") || matches.get_flag("all") {
|
||||||
|
let mut outdir = basedir.clone();
|
||||||
|
outdir.push("zsh");
|
||||||
|
outdir.push("site-functions");
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
let cmd = super::get(cmd).unwrap();
|
||||||
|
cmd.completion(&outdir, "zsh")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||||
|
println!("Generating links:");
|
||||||
|
let mut binpath = PathBuf::from(prefix);
|
||||||
|
binpath.push("bin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("sbin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
if usr {
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("usr");
|
||||||
|
binpath.push("bin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
binpath.pop();
|
||||||
|
binpath.push("sbin");
|
||||||
|
if !binpath.exists() {
|
||||||
|
fs::create_dir_all(&binpath)?;
|
||||||
|
println!(" mkdir: {}", binpath.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let soft = cmd.get_flag("soft");
|
||||||
|
COMMANDS.iter().try_for_each(|c| {
|
||||||
|
let cmd = super::get(c).unwrap();
|
||||||
|
cmd.link(prefix, usr, soft)
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
use shitbox::Cmd;
|
use shitbox::Cmd;
|
||||||
|
|
||||||
mod blkid;
|
mod blkid;
|
||||||
|
mod bootstrap;
|
||||||
mod clear;
|
mod clear;
|
||||||
mod mount;
|
mod mount;
|
||||||
mod mountpoint;
|
mod mountpoint;
|
||||||
@ -15,6 +16,7 @@ mod utilbox;
|
|||||||
#[allow(clippy::box_default)]
|
#[allow(clippy::box_default)]
|
||||||
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||||
match name {
|
match name {
|
||||||
|
"bootstrap" => Some(Box::new(bootstrap::Bootstrap::default())),
|
||||||
"clear" => Some(Box::new(clear::Clear::default())),
|
"clear" => Some(Box::new(clear::Clear::default())),
|
||||||
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
||||||
"swaplabel" => Some(Box::new(swaplabel::Swaplabel::default())),
|
"swaplabel" => Some(Box::new(swaplabel::Swaplabel::default())),
|
||||||
@ -25,7 +27,8 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 6] = [
|
pub static COMMANDS: [&str; 7] = [
|
||||||
|
"bootstrap",
|
||||||
"clear",
|
"clear",
|
||||||
"mountpoint",
|
"mountpoint",
|
||||||
"swaplabel",
|
"swaplabel",
|
||||||
|
Loading…
Reference in New Issue
Block a user