Progress
This commit is contained in:
parent
470c723fcf
commit
153d28170b
102
src/lib.rs
102
src/lib.rs
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue