Commit 3fc1bcb4 authored by Alexandre Pere's avatar Alexandre Pere

Adds completion

parent 43de8d72
......@@ -56,6 +56,7 @@ pub enum Exit {
RecordFeatures,
SchedulerCrashed,
SchedulerShutdown,
InstallCompletion,
}
impl std::fmt::Display for Exit {
......@@ -112,6 +113,7 @@ impl std::fmt::Display for Exit {
Exit::RecordFeatures => write!(f, "failed to record features"),
Exit::SchedulerCrashed => write!(f, "scheduler crashed"),
Exit::SchedulerShutdown => write!(f, "scheduler was shutdown"),
Exit::InstallCompletion => write!(f, "failed to install completion")
}
}
}
......@@ -167,6 +169,7 @@ impl From<Exit> for i32 {
Exit::RecordFeatures => 9945,
Exit::SchedulerCrashed => 9946,
Exit::SchedulerShutdown => 9947,
Exit::InstallCompletion => 9948,
}
}
}
......@@ -292,20 +292,7 @@ fn main(){
.arg(clap::Arg::with_name("stop-on-fail")
.long("stop-on-fail")
.help(""))
)
.subcommand(clap::SubCommand::with_name("test")
.about("Tests a remote profile")
.arg(clap::Arg::with_name("verbose")
.short("V")
.long("verbose")
.help("Print more messages"))
.arg(clap::Arg::with_name("silent")
.long("silent")
.help("Print no messages from runaway"))
.arg(clap::Arg::with_name("FILE")
.help("The yaml profile to test.")
.index(1)
.required(true)));
);
// If the completion_file already exists, we update it to account for the new available profiles
match misc::which_shell(){
......@@ -325,14 +312,12 @@ fn main(){
// We dispatch to subcommands and exit;
let output;
if let Some(_) = matches.subcommand_matches("test"){
output = Ok(Exit::AllGood);
} else if let Some(matches) = matches.subcommand_matches("exec"){
if let Some(matches) = matches.subcommand_matches("exec"){
output = subcommands::exec(matches.clone());
} else if let Some(matches) = matches.subcommand_matches("batch"){
output = subcommands::batch(matches.clone());
} else if let Some(_) = matches.subcommand_matches("install-completion"){
output = Ok(Exit::AllGood);
output = subcommands::install_completion(application);
} else if let Some(matches) = matches.subcommand_matches("sched"){
output = subcommands::sched(matches.clone());
} else {
......
//! runaway-cli/subcommands/complete.rs
//! Author: Alexandre Péré
//!
//! This module contains the batch subcommand.
//-------------------------------------------------------------------------------------------IMPORTS
use liborchestra::PROFILES_FOLDER_RPATH;
use clap;
use crate::exit::Exit;
use std::io::Write;
use tracing::{self, error, info};
use std::os::unix::fs::PermissionsExt;
//--------------------------------------------------------------------------------------- SUBCOMMAND
// Output completion for profiles.
pub fn install_completion(application: clap::App) -> Result<Exit, Exit>{
match which_shell(){
Ok(clap::Shell::Zsh) => {
info!("Zsh recognized. Proceeding.");
let res = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open(dirs::home_dir().unwrap().join(".zshrc"));
let mut file = match res{
Ok(f) => f,
Err(e) =>{
error!("Impossible to open .zshrc file: {}", e);
return Err(Exit::InstallCompletion);
}
};
file.write_all("\n# Added by Runaway for zsh completion\n".as_bytes()).unwrap();
file.write_all(format!("fpath=(~/{} $fpath)\n", PROFILES_FOLDER_RPATH).as_bytes()).unwrap();
file.write_all("autoload -U compinit\ncompinit".as_bytes()).unwrap();
generate_zsh_completion(application);
info!("Zsh completion installed. Open a new terminal to use it.");
}
Ok(clap::Shell::Bash) => {
info!("Bash recognized. Proceeding.");
let res = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open(dirs::home_dir().unwrap().join(".bashrc"));
let mut file = match res{
Ok(f) => f,
Err(e) =>{
error!("Impossible to open .bashrc file: {}", e);
return Err(Exit::InstallCompletion);
}
};
file.write_all("\n# Added by Runaway for bash completion\n".as_bytes()).unwrap();
file.write_all(format!("source ~/{}/{}.bash\n",
PROFILES_FOLDER_RPATH,
get_bin_name()).as_bytes()).unwrap();
generate_bash_completion(application);
info!("Bash completion installed. Open a new terminal to use it.");
}
Err(e) => {
error!("Shell {} is not available for completion. Use bash or zsh.", e);
return Err(Exit::InstallCompletion);
}
_ => unreachable!()
}
return Ok(Exit::AllGood)
}
// Returns current shell.
fn which_shell() -> Result<clap::Shell, String>{
let shell = std::env::var("SHELL")
.unwrap()
.split("/")
.map(|a| a.to_owned())
.last()
.unwrap();
match shell.as_ref(){
"zsh" => Ok(clap::Shell::Zsh),
"bash" => Ok(clap::Shell::Bash),
shell => Err(shell.into()),
}
}
// Returns the name of the binary.
fn get_bin_name() -> String{
std::env::args()
.next()
.unwrap()
.split("/")
.map(|a| a.to_owned())
.collect::<Vec<String>>()
.last()
.unwrap()
.to_owned()
}
// Generates zsh completion
fn generate_zsh_completion(application: clap::App) {
let bin_name = get_bin_name();
let file_path = dirs::home_dir()
.unwrap()
.join(PROFILES_FOLDER_RPATH)
.join(format!("_{}", &bin_name));
let mut application = application;
std::fs::remove_file(&file_path).unwrap();
application.gen_completions(bin_name, clap::Shell::Zsh, file_path.parent().unwrap());
std::fs::set_permissions(file_path, std::fs::Permissions::from_mode(0o755)).unwrap();
}
// Generates bash completion
fn generate_bash_completion(application: clap::App) {
let bin_name = get_bin_name();
let file_path = dirs::home_dir()
.unwrap()
.join(PROFILES_FOLDER_RPATH)
.join(format!("{}.bash", &bin_name));
let mut application = application;
std::fs::remove_file(&file_path).unwrap();
application.gen_completions(bin_name, clap::Shell::Bash, file_path.parent().unwrap());
std::fs::set_permissions(file_path, std::fs::Permissions::from_mode(0o755)).unwrap();
}
......@@ -15,4 +15,7 @@ mod batch;
pub use batch::batch;
mod sched;
pub use sched::sched;
\ No newline at end of file
pub use sched::sched;
mod complete;
pub use complete::install_completion;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment