fix(main): Refactor src/main.rs by splitting one massive main function into commands.rs (#829)

* fix(main): Remove unnecessary pub visibility from the main function in `src/main.rs`
* fix(main): Avoid unnecessary if-evaluations in the main function of `src/main.rs`
* fix(commands): Simplify kill_all_sessions
This commit is contained in:
Ken Matsui 2021-11-06 06:59:45 +09:00 committed by GitHub
parent 6e7f44a8e8
commit 510feb3040
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 282 additions and 227 deletions

36
Cargo.lock generated
View file

@ -400,6 +400,21 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "console"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]] [[package]]
name = "cranelift-bforest" name = "cranelift-bforest"
version = "0.68.0" version = "0.68.0"
@ -653,6 +668,18 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "dialoguer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb"
dependencies = [
"console 0.15.0",
"lazy_static",
"tempfile",
"zeroize",
]
[[package]] [[package]]
name = "directories-next" name = "directories-next"
version = "2.0.0" version = "2.0.0"
@ -1048,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e" checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"console", "console 0.14.1",
"lazy_static", "lazy_static",
"serde", "serde",
"serde_json", "serde_json",
@ -2835,6 +2862,7 @@ name = "zellij"
version = "0.20.0" version = "0.20.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dialoguer",
"insta", "insta",
"log", "log",
"names", "names",
@ -2933,3 +2961,9 @@ dependencies = [
"vte", "vte",
"zellij-tile", "zellij-tile",
] ]
[[package]]
name = "zeroize"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"

View file

@ -20,6 +20,7 @@ zellij-client = { path = "zellij-client/", version = "0.20.0" }
zellij-server = { path = "zellij-server/", version = "0.20.0" } zellij-server = { path = "zellij-server/", version = "0.20.0" }
zellij-utils = { path = "zellij-utils/", version = "0.20.0" } zellij-utils = { path = "zellij-utils/", version = "0.20.0" }
log = "0.4.14" log = "0.4.14"
dialoguer = "0.9.0"
[dev-dependencies] [dev-dependencies]
insta = { version = "1.6.0", features = ["backtrace"] } insta = { version = "1.6.0", features = ["backtrace"] }

234
src/commands.rs Normal file
View file

@ -0,0 +1,234 @@
use crate::install::populate_data_dir;
use crate::sessions::kill_session as kill_session_impl;
use crate::sessions::{
assert_session, assert_session_ne, get_active_session, get_sessions,
get_sessions_sorted_by_creation_date, print_sessions, print_sessions_with_index,
session_exists, ActiveSession,
};
use dialoguer::Confirm;
use std::path::PathBuf;
use std::process;
use zellij_client::start_client as start_client_impl;
use zellij_client::{os_input_output::get_client_os_input, ClientInfo};
use zellij_server::os_input_output::get_server_os_input;
use zellij_server::start_server as start_server_impl;
use zellij_utils::input::options::Options;
use zellij_utils::nix;
use zellij_utils::{
cli::{CliArgs, Command, SessionCommand, Sessions},
setup::{get_default_data_dir, Setup},
};
pub(crate) use crate::sessions::list_sessions;
pub(crate) fn kill_all_sessions(yes: bool) {
match get_sessions() {
Ok(sessions) => {
if sessions.is_empty() {
println!("No active zellij sessions found.");
process::exit(1);
} else {
if !yes {
println!("WARNING: this action will kill all sessions.");
if !Confirm::new()
.with_prompt("Do you want to continue?")
.interact()
.unwrap()
{
println!("Abort.");
process::exit(1);
}
}
for session in sessions.iter() {
kill_session_impl(session);
}
process::exit(0);
}
}
Err(e) => {
eprintln!("Error occurred: {:?}", e);
process::exit(1);
}
}
}
pub(crate) fn kill_session(target_session: &Option<String>) {
match target_session {
Some(target_session) => {
assert_session(target_session);
kill_session_impl(target_session);
process::exit(0);
}
None => {
println!("Please specify the session name to kill.");
process::exit(1);
}
}
}
fn get_os_input<OsInputOutput>(
fn_get_os_input: fn() -> Result<OsInputOutput, nix::Error>,
) -> OsInputOutput {
match fn_get_os_input() {
Ok(os_input) => os_input,
Err(e) => {
eprintln!("failed to open terminal:\n{}", e);
process::exit(1);
}
}
}
pub(crate) fn start_server(path: PathBuf) {
let os_input = get_os_input(get_server_os_input);
start_server_impl(Box::new(os_input), path);
}
fn create_new_client() -> ClientInfo {
ClientInfo::New(names::Generator::default().next().unwrap())
}
fn find_indexed_session(
sessions: Vec<String>,
config_options: Options,
index: usize,
create: bool,
) -> ClientInfo {
match sessions.get(index) {
Some(session) => ClientInfo::Attach(session.clone(), config_options),
None => {
if create {
create_new_client()
} else {
println!(
"No session indexed by {} found. The following sessions are active:",
index
);
print_sessions_with_index(sessions);
process::exit(1);
}
}
}
}
fn attach_with_session_index(config_options: Options, index: usize, create: bool) -> ClientInfo {
// Ignore the session_name when `--index` is provided
match get_sessions_sorted_by_creation_date() {
Ok(sessions) => {
if sessions.is_empty() {
if create {
create_new_client()
} else {
println!("No active zellij sessions found.");
process::exit(1);
}
} else {
find_indexed_session(sessions, config_options, index, create)
}
}
Err(e) => {
eprintln!("Error occurred: {:?}", e);
process::exit(1);
}
}
}
fn attach_with_session_name(
session_name: Option<String>,
config_options: Options,
create: bool,
) -> ClientInfo {
match session_name.as_ref() {
Some(session) => {
if create {
if !session_exists(session).unwrap() {
ClientInfo::New(session_name.unwrap())
} else {
ClientInfo::Attach(session_name.unwrap(), config_options)
}
} else {
assert_session(session);
ClientInfo::Attach(session_name.unwrap(), config_options)
}
}
None => match get_active_session() {
ActiveSession::None => {
if create {
create_new_client()
} else {
println!("No active zellij sessions found.");
process::exit(1);
}
}
ActiveSession::One(session_name) => ClientInfo::Attach(session_name, config_options),
ActiveSession::Many => {
println!("Please specify the session name to attach to. The following sessions are active:");
print_sessions(get_sessions().unwrap());
process::exit(1);
}
},
}
}
pub(crate) fn start_client(opts: CliArgs) {
let (config, layout, config_options) = match Setup::from_options(&opts) {
Ok(results) => results,
Err(e) => {
eprintln!("{}", e);
process::exit(1);
}
};
let os_input = get_os_input(get_client_os_input);
if let Some(Command::Sessions(Sessions::Attach {
session_name,
create,
index,
options,
})) = opts.command.clone()
{
let config_options = match options {
Some(SessionCommand::Options(o)) => config_options.merge(o),
None => config_options,
};
let client = if let Some(idx) = index {
attach_with_session_index(config_options.clone(), idx, create)
} else {
attach_with_session_name(session_name, config_options.clone(), create)
};
let attach_layout = match client {
ClientInfo::Attach(_, _) => None,
ClientInfo::New(_) => layout,
};
start_client_impl(
Box::new(os_input),
opts,
config,
config_options,
client,
attach_layout,
);
} else {
let session_name = opts
.session
.clone()
.unwrap_or_else(|| names::Generator::default().next().unwrap());
assert_session_ne(&session_name);
// Determine and initialize the data directory
let data_dir = opts.data_dir.clone().unwrap_or_else(get_default_data_dir);
#[cfg(not(disable_automatic_asset_installation))]
populate_data_dir(&data_dir);
start_client_impl(
Box::new(os_input),
opts,
config,
config_options,
ClientInfo::New(session_name),
layout,
);
}
}

View file

@ -1,244 +1,30 @@
mod commands;
mod install; mod install;
mod sessions; mod sessions;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use crate::install::populate_data_dir;
use sessions::{
assert_session, assert_session_ne, get_active_session, get_sessions,
get_sessions_sorted_by_creation_date, kill_session, list_sessions, print_sessions,
print_sessions_with_index, session_exists, ActiveSession,
};
use std::process;
use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo};
use zellij_server::{os_input_output::get_server_os_input, start_server};
use zellij_utils::{ use zellij_utils::{
cli::{CliArgs, Command, SessionCommand, Sessions}, cli::{CliArgs, Command, Sessions},
logging::*, logging::*,
setup::{get_default_data_dir, Setup},
structopt::StructOpt, structopt::StructOpt,
}; };
pub fn main() { fn main() {
configure_logger(); configure_logger();
let opts = CliArgs::from_args(); let opts = CliArgs::from_args();
if let Some(Command::Sessions(Sessions::ListSessions)) = opts.command { if let Some(Command::Sessions(Sessions::ListSessions)) = opts.command {
list_sessions(); commands::list_sessions();
} } else if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command {
commands::kill_all_sessions(yes);
if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command { } else if let Some(Command::Sessions(Sessions::KillSession { ref target_session })) =
match get_sessions() { opts.command
Ok(sessions) => {
if sessions.is_empty() {
println!("No active zellij sessions found.");
process::exit(1);
} else {
let kill_all_sessions = |sessions: Vec<std::string::String>| {
for session in sessions.iter() {
kill_session(session);
}
process::exit(0)
};
if yes {
kill_all_sessions(sessions);
} else {
use std::io::{stdin, stdout, Write};
let mut answer = String::new();
println!("WARNING: this action will kill all sessions.");
print!("Do you want to continue? [y/N] ");
let _ = stdout().flush();
stdin().read_line(&mut answer).unwrap();
match answer.as_str().trim() {
"y" | "Y" | "yes" | "Yes" => kill_all_sessions(sessions),
_ => {
println!("Abort.");
process::exit(1);
}
}
}
}
}
Err(e) => {
eprintln!("Error occurred: {:?}", e);
process::exit(1);
}
}
}
if let Some(Command::Sessions(Sessions::KillSession { target_session })) = opts.command.clone()
{ {
match target_session.as_ref() { commands::kill_session(target_session);
Some(target_session) => { } else if let Some(path) = opts.server {
assert_session(target_session); commands::start_server(path);
kill_session(target_session);
process::exit(0);
}
None => {
println!("Please specify the session name to kill.");
process::exit(1);
}
}
}
if let Some(path) = opts.server {
let os_input = match get_server_os_input() {
Ok(server_os_input) => server_os_input,
Err(e) => {
eprintln!("failed to open terminal:\n{}", e);
process::exit(1);
}
};
start_server(Box::new(os_input), path);
} else { } else {
let (config, layout, config_options) = match Setup::from_options(&opts) { commands::start_client(opts);
Ok(results) => results,
Err(e) => {
eprintln!("{}", e);
process::exit(1);
}
};
let os_input = match get_client_os_input() {
Ok(os_input) => os_input,
Err(e) => {
eprintln!("failed to open terminal:\n{}", e);
process::exit(1);
}
};
if let Some(Command::Sessions(Sessions::Attach {
session_name,
create,
index,
options,
})) = opts.command.clone()
{
let config_options = match options {
Some(SessionCommand::Options(o)) => config_options.merge(o),
None => config_options,
};
let (client, attach_layout) = if let Some(idx) = index {
// Ignore session_name when `--index` is provided
match get_sessions_sorted_by_creation_date() {
Ok(sessions) => {
if sessions.is_empty() {
if create {
(
ClientInfo::New(names::Generator::default().next().unwrap()),
layout,
)
} else {
println!("No active zellij sessions found.");
process::exit(1);
}
} else {
match sessions.get(idx) {
Some(session) => (
ClientInfo::Attach(session.clone(), config_options.clone()),
None,
),
None => {
if create {
(
ClientInfo::New(
names::Generator::default().next().unwrap(),
),
layout,
)
} else {
println!("No session indexed by {} found. The following sessions are active:", idx);
print_sessions_with_index(sessions);
process::exit(1);
}
}
}
}
}
Err(e) => {
eprintln!("Error occurred: {:?}", e);
process::exit(1);
}
}
} else {
match session_name.as_ref() {
Some(session) => {
if create {
if !session_exists(session).unwrap() {
(ClientInfo::New(session_name.unwrap()), layout)
} else {
(
ClientInfo::Attach(
session_name.unwrap(),
config_options.clone(),
),
None,
)
}
} else {
assert_session(session);
(
ClientInfo::Attach(session_name.unwrap(), config_options.clone()),
None,
)
}
}
None => match get_active_session() {
ActiveSession::None => {
if create {
(
ClientInfo::New(names::Generator::default().next().unwrap()),
layout,
)
} else {
println!("No active zellij sessions found.");
process::exit(1);
}
}
ActiveSession::One(session_name) => (
ClientInfo::Attach(session_name, config_options.clone()),
None,
),
ActiveSession::Many => {
println!("Please specify the session name to attach to. The following sessions are active:");
print_sessions(get_sessions().unwrap());
process::exit(1);
}
},
}
};
start_client(
Box::new(os_input),
opts,
config,
config_options,
client,
attach_layout,
);
} else {
let session_name = opts
.session
.clone()
.unwrap_or_else(|| names::Generator::default().next().unwrap());
assert_session_ne(&session_name);
// Determine and initialize the data directory
let data_dir = opts.data_dir.clone().unwrap_or_else(get_default_data_dir);
#[cfg(not(disable_automatic_asset_installation))]
populate_data_dir(&data_dir);
start_client(
Box::new(os_input),
opts,
config,
config_options,
ClientInfo::New(session_name),
layout,
);
}
} }
} }