use {UserCache, Error, ResultExt};
use symlink;
use std::{fs, env};
use std::process::Command;
use std::os::unix::process::CommandExt;
pub struct Config {
pub shell_path: String,
}
pub struct Shell<'a> {
user_cache: &'a mut UserCache<'a>,
config: Config,
}
impl<'a> Shell<'a> {
pub fn create(user_cache: &'a mut UserCache<'a>, config: Config) -> Result<Self, Error> {
let home_path = user_cache.home_path();
if !home_path.exists() {
fs::create_dir_all(&home_path)?;
}
let mut shell = Shell {
user_cache: user_cache,
config: config,
};
shell.build_symlinks()?;
Ok(shell)
}
pub fn exec(&self) -> Result<(), Error> {
let home_path = self.user_cache.home_path();
let err: Error = Command::new(&self.config.shell_path)
.current_dir(&home_path.display().to_string())
.env("HOME", home_path.display().to_string())
.exec()
.into();
Err(err).chain_err(|| "could not exec into shell")
}
fn build_symlinks(&mut self) -> Result<(), Error> {
let verbose = false;
let home_path = self.user_cache.home_path();
self.user_cache.link_ext(&symlink::Config {
home_path: home_path,
}, verbose)
}
}
impl Default for Config {
fn default() -> Config {
Config {
shell_path: env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_owned()),
}
}
}