Progress
This commit is contained in:
		
							parent
							
								
									470c723fcf
								
							
						
					
					
						commit
						153d28170b
					
				
							
								
								
									
										104
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								src/lib.rs
									
									
									
									
									
								
							@ -1,41 +1,29 @@
 | 
			
		||||
use std::fmt;
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
 | 
			
		||||
/// A command to run.
 | 
			
		||||
pub struct CommandLine {
 | 
			
		||||
    program: String,
 | 
			
		||||
    args: Vec<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    }
 | 
			
		||||
/// Helper to create commands in one line.
 | 
			
		||||
pub fn command(program: &str, args: &[&str]) -> Command {
 | 
			
		||||
    let mut command = Command::new(program);
 | 
			
		||||
    command.args(args);
 | 
			
		||||
    command
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The supported package manager.
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
pub enum PackageManager {
 | 
			
		||||
    /// The apt manager, availble on Debian, Ubuntu and others.
 | 
			
		||||
    Apt,
 | 
			
		||||
 | 
			
		||||
    /// The pacman manager, available on ArchLinux, Manjaro and others.
 | 
			
		||||
    Pacman,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
            PackageManager::Apt => CommandLine::new("sudo", &["apt", "install", package]),
 | 
			
		||||
            PackageManager::Pacman => CommandLine::new("sudo", &["pacman", "-S", package]),
 | 
			
		||||
            PackageManager::Apt => command("sudo", &["apt", "install", package]),
 | 
			
		||||
            PackageManager::Pacman => command("sudo", &["pacman", "-S", package]),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -43,21 +31,23 @@ impl PackageManager {
 | 
			
		||||
/// All the installable components.
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
pub enum Component {
 | 
			
		||||
    /// Whether the user is allowed to run sudo commands.
 | 
			
		||||
    Sudo,
 | 
			
		||||
 | 
			
		||||
    /// Git enables to clone repository, which is necessary for many components.
 | 
			
		||||
    Git,
 | 
			
		||||
 | 
			
		||||
    /// The configuration uses the zsh shell.
 | 
			
		||||
    Zsh,
 | 
			
		||||
 | 
			
		||||
    /// The configuration files.
 | 
			
		||||
    Dotfiles,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Component {
 | 
			
		||||
    /// List all components.
 | 
			
		||||
    pub fn all() -> Vec<Component> {
 | 
			
		||||
        vec![
 | 
			
		||||
            Component::Sudo,
 | 
			
		||||
            Component::Git,
 | 
			
		||||
            Component::Zsh,
 | 
			
		||||
            Component::Dotfiles,
 | 
			
		||||
        ]
 | 
			
		||||
        vec![Component::Git, Component::Zsh, Component::Dotfiles]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// 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.
 | 
			
		||||
    pub fn dependencies(self) -> &'static [Component] {
 | 
			
		||||
        match self {
 | 
			
		||||
@ -84,7 +84,7 @@ impl Component {
 | 
			
		||||
impl fmt::Display for Component {
 | 
			
		||||
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            Component::Sudo => write!(fmt, "root"),
 | 
			
		||||
            Component::Sudo => write!(fmt, "sudo"),
 | 
			
		||||
            Component::Git => write!(fmt, "git"),
 | 
			
		||||
            Component::Zsh => write!(fmt, "zsh"),
 | 
			
		||||
            Component::Dotfiles => write!(fmt, "dotfiles"),
 | 
			
		||||
@ -93,12 +93,47 @@ impl fmt::Display for Component {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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 {
 | 
			
		||||
    /// Creates a 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>;
 | 
			
		||||
 | 
			
		||||
/// Runs the installer
 | 
			
		||||
pub fn main() -> Result<()> {
 | 
			
		||||
    let installer = Installer::new();
 | 
			
		||||
    installer.print();
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user