diff --git a/crates/shrs/src/plugin.rs b/crates/shrs/src/plugin.rs index 8468b02c..e352962e 100644 --- a/crates/shrs/src/plugin.rs +++ b/crates/shrs/src/plugin.rs @@ -6,7 +6,7 @@ use crate::ShellConfig; #[derive(Debug)] pub struct PluginMeta { - pub name: String, + pub name: String, // should be unique pub description: String, } @@ -19,15 +19,6 @@ pub enum FailMode { Abort, } -impl Default for PluginMeta { - fn default() -> Self { - Self { - name: String::from("unnamed plugin"), - description: String::from("a plugin for shrs"), - } - } -} - /// Implement this trait to build your own plugins pub trait Plugin { /// Plugin entry point @@ -37,12 +28,7 @@ pub trait Plugin { fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()>; /// Return metadata related to the plugin - fn meta(&self) -> PluginMeta { - // TODO this is currently an optional method to make migrating all the existing plugins a - // bit easier. Could remove the default implementation in the future - warn!("Using default plugin metadata. Please specify this information for your plugin by implementing Plugin::meta()"); - PluginMeta::default() - } + fn meta(&self) -> PluginMeta; /// Get the fail mode for this plugin /// diff --git a/crates/shrs/src/shell.rs b/crates/shrs/src/shell.rs index 94d5fd37..a933f61b 100644 --- a/crates/shrs/src/shell.rs +++ b/crates/shrs/src/shell.rs @@ -75,7 +75,11 @@ pub struct ShellConfig { impl ShellBuilder { pub fn with_plugin(mut self, plugin: impl Plugin + 'static) -> Self { let mut cur_plugin = self.plugins.unwrap_or(vec![]); - cur_plugin.push(Box::new(plugin)); + if cur_plugin.iter().any(|p| p.meta().name == plugin.meta().name) { + panic!("Duplicate plugin name: {}",plugin.meta().name); + } else { + cur_plugin.push(Box::new(plugin)); + } self.plugins = Some(cur_plugin); self } diff --git a/plugins/shrs_analytics/src/lib.rs b/plugins/shrs_analytics/src/lib.rs index 8e7d15e0..43e1f5aa 100644 --- a/plugins/shrs_analytics/src/lib.rs +++ b/plugins/shrs_analytics/src/lib.rs @@ -33,6 +33,12 @@ impl AnalyticsPlugin { } impl Plugin for AnalyticsPlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "AnalyticsPlugin".into(), + description: String::new(), + } + } fn init(&self, shell: &mut ShellConfig) -> Result<()> { shell.builtins.insert("analytics", AnalyticsBuiltin); shell.hooks.register(record_dir_change); diff --git a/plugins/shrs_autocd/src/lib.rs b/plugins/shrs_autocd/src/lib.rs index 4678cce8..3b792253 100644 --- a/plugins/shrs_autocd/src/lib.rs +++ b/plugins/shrs_autocd/src/lib.rs @@ -35,6 +35,13 @@ pub fn after_command_hook( } impl Plugin for AutocdPlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "AutocdPlugin".into(), + description: String::new(), + } + } + fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()> { shell.hooks.register(after_command_hook); diff --git a/plugins/shrs_cd_stack/src/lib.rs b/plugins/shrs_cd_stack/src/lib.rs index bfd6bf05..f249c28a 100644 --- a/plugins/shrs_cd_stack/src/lib.rs +++ b/plugins/shrs_cd_stack/src/lib.rs @@ -61,6 +61,12 @@ fn change_dir_hook( pub struct CdStackPlugin; impl Plugin for CdStackPlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "CdStackPlugin".into(), + description: String::new(), + } + } fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()> { let mut cd_stack_state = CdStackState::new(); // TODO hopefully would be better to get current dir from shell, but shell isn't diff --git a/plugins/shrs_cd_tools/src/lib.rs b/plugins/shrs_cd_tools/src/lib.rs index a48058e7..7c964c71 100644 --- a/plugins/shrs_cd_tools/src/lib.rs +++ b/plugins/shrs_cd_tools/src/lib.rs @@ -95,6 +95,12 @@ fn update_modules(sh_ctx: &mut Context, sh_rt: &mut Runtime) -> anyhow::Result<( } impl Plugin for DirParsePlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "DirParsePlugin".into(), + description: String::new(), + } + } fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()> { // TODO let user pass in their own modules list let modules = HashMap::from_iter([ diff --git a/plugins/shrs_command_timer/src/lib.rs b/plugins/shrs_command_timer/src/lib.rs index fac7532a..b63dec40 100644 --- a/plugins/shrs_command_timer/src/lib.rs +++ b/plugins/shrs_command_timer/src/lib.rs @@ -45,6 +45,12 @@ impl CommandTimerState { pub struct CommandTimerPlugin; impl Plugin for CommandTimerPlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "CommandTimerPlugin".into(), + description: String::new(), + } + } fn init(&self, shell: &mut shrs::ShellConfig) -> anyhow::Result<()> { shell.hooks.register(before_command_hook); shell.hooks.register(after_command_hook); diff --git a/plugins/shrs_mux/src/lib.rs b/plugins/shrs_mux/src/lib.rs index 55848ac2..823a81ec 100644 --- a/plugins/shrs_mux/src/lib.rs +++ b/plugins/shrs_mux/src/lib.rs @@ -76,6 +76,13 @@ impl MuxPlugin { } impl Plugin for MuxPlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "MuxPlugin".into(), + description: String::new(), + } + } + fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()> { // This might be able to be indexed by typeid? let langs: Vec<(String, Box)> = vec![ diff --git a/plugins/shrs_output_capture/src/lib.rs b/plugins/shrs_output_capture/src/lib.rs index f4fab95b..23114a63 100644 --- a/plugins/shrs_output_capture/src/lib.rs +++ b/plugins/shrs_output_capture/src/lib.rs @@ -25,6 +25,12 @@ impl OutputCaptureState { pub struct OutputCapturePlugin; impl Plugin for OutputCapturePlugin { + fn meta(&self) -> PluginMeta { + PluginMeta { + name: "OutputCapturePlugin".into(), + description: String::new(), + } + } fn init(&self, shell: &mut shrs::ShellConfig) -> anyhow::Result<()> { shell.hooks.register(after_command_hook); shell.builtins.insert("again", AgainBuiltin::new());