diff --git a/src/main.rs b/src/main.rs index 7143a59b..16d0e302 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ mod print; mod segment; mod utils; +use crate::module::ALL_MODULES; use clap::{App, AppSettings, Arg, SubCommand}; fn main() { @@ -91,7 +92,14 @@ fn main() { .arg( Arg::with_name("name") .help("The name of the module to be printed") - .required(true), + .required(true) + .required_unless("list"), + ) + .arg( + Arg::with_name("list") + .short("l") + .long("list") + .help("List out all supported modules"), ) .arg(&status_code_arg) .arg(&path_arg) @@ -112,8 +120,16 @@ fn main() { } ("prompt", Some(sub_m)) => print::prompt(sub_m.clone()), ("module", Some(sub_m)) => { - let module_name = sub_m.value_of("name").expect("Module name missing."); - print::module(module_name, sub_m.clone()); + if sub_m.is_present("list") { + println!("Supported modules list"); + println!("----------------------"); + for modules in ALL_MODULES { + println!("{}", modules); + } + } + if let Some(module_name) = sub_m.value_of("name") { + print::module(module_name, sub_m.clone()); + } } _ => {} } diff --git a/src/module.rs b/src/module.rs index 98f586cb..fcb1ea36 100644 --- a/src/module.rs +++ b/src/module.rs @@ -4,6 +4,25 @@ use ansi_term::Style; use ansi_term::{ANSIString, ANSIStrings}; use std::fmt; +// List of all modules +pub const ALL_MODULES: &[&str] = &[ + "battery", + "character", + "cmd_duration", + "directory", + "git_branch", + "git_status", + "golang", + "jobs", + "line_break", + "nodejs", + "package", + "python", + "ruby", + "rust", + "username", +]; + /// A module is a collection of segments showing data for a single integration /// (e.g. The git module shows the current git branch and status) pub struct Module<'a> { diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 3ab7d8b3..4aa67108 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -1,3 +1,4 @@ +// While adding out new module add out module to src/module.rs ALL_MODULES const array also. mod battery; mod character; mod cmd_duration; @@ -35,6 +36,9 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "cmd_duration" => cmd_duration::module(context), "jobs" => jobs::module(context), - _ => panic!("Unknown module: {}", module), + _ => { + eprintln!("Error: Unknown module {}. Use starship module --list to list out all supported modules.", module); + None + } } } diff --git a/src/print.rs b/src/print.rs index 0cf495f7..69c56027 100644 --- a/src/print.rs +++ b/src/print.rs @@ -5,27 +5,9 @@ use std::io::{self, Write}; use crate::config::Config; use crate::context::Context; use crate::module::Module; +use crate::module::ALL_MODULES; use crate::modules; -// List of all modules -const ALL_MODULES: &[&str] = &[ - "battery", - "character", - "cmd_duration", - "directory", - "git_branch", - "git_status", - "golang", - "jobs", - "line_break", - "nodejs", - "package", - "python", - "ruby", - "rust", - "username", -]; - // List of default prompt order // NOTE: If this const value is changed then Default prompt order subheading inside // prompt heading of config docs needs to be updated according to changes made here. diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index cbb1d9b6..bceb1403 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -6,6 +6,7 @@ mod directory; mod golang; mod jobs; mod line_break; +mod modules; mod nodejs; mod python; mod ruby; diff --git a/tests/testsuite/modules.rs b/tests/testsuite/modules.rs new file mode 100644 index 00000000..0ffcb5ca --- /dev/null +++ b/tests/testsuite/modules.rs @@ -0,0 +1,31 @@ +use std::io; + +use crate::common; + +#[test] +fn unknown_module_name() -> io::Result<()> { + let unknown_module_name = "some_random_name"; + let output = common::render_module(unknown_module_name).output()?; + let actual_stdout = String::from_utf8(output.stdout).unwrap(); + let actual_stderr = String::from_utf8(output.stderr).unwrap(); + let expected_stdout = ""; + let expected_stderr = format!( + "Error: Unknown module {}. Use starship module --list to list out all supported modules.\n", + unknown_module_name + ); + assert_eq!(expected_stdout, actual_stdout); + assert_eq!(expected_stderr, actual_stderr); + Ok(()) +} + +#[test] +fn known_module_name() -> io::Result<()> { + let output = common::render_module("line_break").output()?; + let actual_stdout = String::from_utf8(output.stdout).unwrap(); + let actual_stderr = String::from_utf8(output.stderr).unwrap(); + let expected_stdout = "\n"; + let expected_stderr = ""; + assert_eq!(expected_stdout, actual_stdout); + assert_eq!(expected_stderr, actual_stderr); + Ok(()) +}