This commit is contained in:
Thomas Forgione 2020-11-25 14:28:07 +01:00
parent 470c723fcf
commit 153d28170b
1 changed files with 71 additions and 33 deletions

View File

@ -1,41 +1,29 @@
use std::fmt; use std::fmt;
use std::process::Command; use std::process::Command;
/// A command to run. /// Helper to create commands in one line.
pub struct CommandLine { pub fn command(program: &str, args: &[&str]) -> Command {
program: String, let mut command = Command::new(program);
args: Vec<String>, command.args(args);
}
impl CommandLine {
/// Creates a new command line.
pub fn new(program: &str, args: &[&str]) -> CommandLine {
CommandLine {
program: program.to_string(),
args: args.iter().map(|x| String::from(*x)).collect::<Vec<_>>(),
}
}
/// Creates the command from the command line.
pub fn command(self) -> Command {
let mut command = Command::new(self.program);
command.args(&self.args);
command command
}
} }
/// The supported package manager. /// The supported package manager.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum PackageManager { pub enum PackageManager {
/// The apt manager, availble on Debian, Ubuntu and others.
Apt, Apt,
/// The pacman manager, available on ArchLinux, Manjaro and others.
Pacman, Pacman,
} }
impl PackageManager { impl PackageManager {
pub fn install<'a>(&self, package: &'a str) -> CommandLine { /// Returns the command to install a page using the right package manager.
pub fn install<'a>(&self, package: &'a str) -> Command {
match self { match self {
PackageManager::Apt => CommandLine::new("sudo", &["apt", "install", package]), PackageManager::Apt => command("sudo", &["apt", "install", package]),
PackageManager::Pacman => CommandLine::new("sudo", &["pacman", "-S", package]), PackageManager::Pacman => command("sudo", &["pacman", "-S", package]),
} }
} }
} }
@ -43,21 +31,23 @@ impl PackageManager {
/// All the installable components. /// All the installable components.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Component { pub enum Component {
/// Whether the user is allowed to run sudo commands.
Sudo, Sudo,
/// Git enables to clone repository, which is necessary for many components.
Git, Git,
/// The configuration uses the zsh shell.
Zsh, Zsh,
/// The configuration files.
Dotfiles, Dotfiles,
} }
impl Component { impl Component {
/// List all components. /// List all components.
pub fn all() -> Vec<Component> { pub fn all() -> Vec<Component> {
vec![ vec![Component::Git, Component::Zsh, Component::Dotfiles]
Component::Sudo,
Component::Git,
Component::Zsh,
Component::Dotfiles,
]
} }
/// Installs a component. /// Installs a component.
@ -70,6 +60,16 @@ impl Component {
} }
} }
/// Returns a command that tests if a component is installed.
pub fn is_installed(self) -> bool {
match self {
Component::Sudo => panic!("can't use is_installed() on Component::Sudo"),
Component::Git => todo!(),
Component::Zsh => todo!(),
Component::Dotfiles => todo!(),
}
}
/// Returns the dependencies of each component. /// Returns the dependencies of each component.
pub fn dependencies(self) -> &'static [Component] { pub fn dependencies(self) -> &'static [Component] {
match self { match self {
@ -84,7 +84,7 @@ impl Component {
impl fmt::Display for Component { impl fmt::Display for Component {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Component::Sudo => write!(fmt, "root"), Component::Sudo => write!(fmt, "sudo"),
Component::Git => write!(fmt, "git"), Component::Git => write!(fmt, "git"),
Component::Zsh => write!(fmt, "zsh"), Component::Zsh => write!(fmt, "zsh"),
Component::Dotfiles => write!(fmt, "dotfiles"), Component::Dotfiles => write!(fmt, "dotfiles"),
@ -93,12 +93,47 @@ impl fmt::Display for Component {
} }
/// The struct that holds the information about the install. /// The struct that holds the information about the install.
pub struct Installer; pub struct Installer {
/// All the components to install, and whether the users want to install them.
components: Vec<(Component, bool)>,
/// Where the users cursor is.
cursor: usize,
}
impl Installer { impl Installer {
/// Creates a new installer. /// Creates a new installer.
pub fn new() -> Installer { pub fn new() -> Installer {
Installer Installer {
components: Component::all().into_iter().map(|x| (x, true)).collect(),
cursor: 0,
}
}
/// Prints the installer.
pub fn print(&self) {
print!("{}", self);
}
}
impl fmt::Display for Installer {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for (index, (component, to_install)) in self.components.iter().enumerate() {
writeln!(
fmt,
"{} [{}] {} (requires {})",
if self.cursor == index { ">" } else { " " },
if *to_install { "x" } else { " " },
component,
component
.dependencies()
.into_iter()
.map(|x| format!("{}", x))
.collect::<Vec<_>>()
.join(", ")
)?;
}
Ok(())
} }
} }
@ -111,9 +146,12 @@ impl fmt::Display for Error {
} }
} }
/// The result type of this library.
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
/// Runs the installer /// Runs the installer
pub fn main() -> Result<()> { pub fn main() -> Result<()> {
let installer = Installer::new();
installer.print();
Ok(()) Ok(())
} }