Merge branch 'fix/pluginArgs' into 'main'

fix: wrap single plugin cmd parts in single quotes

See merge request gabmus/envision!111
This commit is contained in:
GabMus 2025-01-26 10:41:48 +00:00
commit 209b65b293
3 changed files with 39 additions and 53 deletions

View file

@ -248,15 +248,17 @@ impl App {
.plugins .plugins
.values() .values()
.filter_map(|cp| { .filter_map(|cp| {
if cp.plugin.plugin_type.launches_directly() && cp.enabled && cp.plugin.validate() { if cp.enabled && cp.plugin.validate() {
if let Err(e) = cp.plugin.mark_as_executable() { if let Err(e) = cp.plugin.mark_as_executable() {
error!( error!(
"failed to mark plugin {} as executable: {e}", "failed to mark plugin {} as executable: {e}",
cp.plugin.appid cp.plugin.appid
); );
None None
} else if !cp.plugin.plugin_type.launches_directly() {
None
} else { } else {
Some(format!("'{}'", { Some({
let mut cmd_parts = vec![cp let mut cmd_parts = vec![cp
.plugin .plugin
.executable() .executable()
@ -264,8 +266,12 @@ impl App {
.to_string_lossy() .to_string_lossy()
.to_string()]; .to_string()];
cmd_parts.extend(cp.plugin.args.clone().unwrap_or_default()); cmd_parts.extend(cp.plugin.args.clone().unwrap_or_default());
cmd_parts.join(" ") cmd_parts
})) .iter()
.map(|part| format!("'{part}'"))
.collect::<Vec<String>>()
.join(" ")
})
} }
} else { } else {
None None

View file

@ -49,15 +49,13 @@ pub enum PluginStoreMsg {
Refresh, Refresh,
/// called by Refresh /// called by Refresh
DoRefresh, DoRefresh,
Install(Plugin, relm4::Sender<StoreRowModelMsg>), Install(Plugin),
InstallFromDetails(Plugin), InstallDownload(Vec<Plugin>),
InstallDownload(Vec<Plugin>, relm4::Sender<StoreRowModelMsg>),
Remove(Plugin), Remove(Plugin),
SetEnabled(PluginStoreSignalSource, Plugin, bool), SetEnabled(PluginStoreSignalSource, Plugin, bool),
ShowDetails(usize), ShowDetails(usize),
ShowPluginList, ShowPluginList,
PresentAddCustomPluginWin, PresentAddCustomPluginWin,
AddPluginToConfig(Plugin),
AddCustomPlugin(Plugin), AddCustomPlugin(Plugin),
} }
@ -89,6 +87,16 @@ impl PluginStore {
}); });
}); });
} }
fn add_plugin_to_config(&mut self, sender: &relm4::AsyncComponentSender<Self>, plugin: Plugin) {
self.config_plugins
.insert(plugin.appid.clone(), PluginConfig::from(&plugin));
sender
.output(PluginStoreOutMsg::UpdateConfigPlugins(
self.config_plugins.clone(),
))
.expect(SENDER_IO_ERR_MSG);
}
} }
#[relm4::component(pub async)] #[relm4::component(pub async)]
@ -227,18 +235,9 @@ impl AsyncComponent for PluginStore {
); );
return; return;
} }
sender.input(Self::Input::AddPluginToConfig(plugin)); self.add_plugin_to_config(&sender, plugin);
sender.input(Self::Input::Refresh); sender.input(Self::Input::Refresh);
} }
Self::Input::AddPluginToConfig(plugin) => {
self.config_plugins
.insert(plugin.appid.clone(), PluginConfig::from(&plugin));
sender
.output(Self::Output::UpdateConfigPlugins(
self.config_plugins.clone(),
))
.expect(SENDER_IO_ERR_MSG);
}
Self::Input::PresentAddCustomPluginWin => { Self::Input::PresentAddCustomPluginWin => {
let add_win = AddCustomPluginWin::builder() let add_win = AddCustomPluginWin::builder()
.launch(AddCustomPluginWinInit { .launch(AddCustomPluginWinInit {
@ -291,22 +290,7 @@ impl AsyncComponent for PluginStore {
self.refresh_plugin_rows(); self.refresh_plugin_rows();
self.set_refreshing(false); self.set_refreshing(false);
} }
Self::Input::InstallFromDetails(plugin) => { Self::Input::Install(plugin) => {
if let Some(row) = self
.plugin_rows
.as_mut()
.unwrap()
.guard()
.iter()
.find(|row| row.is_some_and(|row| row.plugin.appid == plugin.appid))
.flatten()
{
sender.input(Self::Input::Install(plugin, row.input_sender.clone()))
} else {
error!("could not find corresponding listbox row")
}
}
Self::Input::Install(plugin, row_sender) => {
self.set_locked(true); self.set_locked(true);
let mut plugins = vec![plugin]; let mut plugins = vec![plugin];
for dep in plugins[0].dependencies.clone().unwrap_or_default() { for dep in plugins[0].dependencies.clone().unwrap_or_default() {
@ -333,9 +317,9 @@ impl AsyncComponent for PluginStore {
return; return;
} }
} }
sender.input(Self::Input::InstallDownload(plugins, row_sender)) sender.input(Self::Input::InstallDownload(plugins))
} }
Self::Input::InstallDownload(plugins, row_sender) => { Self::Input::InstallDownload(plugins) => {
for plugin in plugins { for plugin in plugins {
let mut plugin = plugin.clone(); let mut plugin = plugin.clone();
match plugin.exec_url.as_ref() { match plugin.exec_url.as_ref() {
@ -367,22 +351,22 @@ impl AsyncComponent for PluginStore {
); );
return; return;
} }
sender.input(Self::Input::AddPluginToConfig(plugin.clone())); self.add_plugin_to_config(&sender, plugin.clone());
} }
} }
None => { None => {
alert( alert(
"Download failed", "Download failed",
Some(&format!( Some(&format!(
"Downloading {} {} failed:\n\nNo executable url provided for this plugin, this is likely a bug!", "Downloading {} {} failed:\n\nNo executable url provided for this plugin, this is likely a bug!",
plugin.name, plugin.name,
plugin.version.as_ref().unwrap_or(&"(no version)".to_string())) plugin.version.as_ref().unwrap_or(&"(no version)".to_string()))
), ),
Some(&self.win.as_ref().unwrap().clone().upcast::<gtk::Window>()) Some(&self.win.as_ref().unwrap().clone().upcast::<gtk::Window>())
); );
} }
}; };
row_sender.emit(StoreRowModelMsg::Refresh(true, false)); self.refresh_plugin_rows();
self.details self.details
.emit(StoreDetailMsg::Refresh(plugin.appid, true, false)); .emit(StoreDetailMsg::Refresh(plugin.appid, true, false));
} }
@ -534,7 +518,7 @@ impl AsyncComponent for PluginStore {
.launch(()) .launch(())
.forward(sender.input_sender(), move |msg| match msg { .forward(sender.input_sender(), move |msg| match msg {
StoreDetailOutMsg::GoBack => Self::Input::ShowPluginList, StoreDetailOutMsg::GoBack => Self::Input::ShowPluginList,
StoreDetailOutMsg::Install(plugin) => Self::Input::InstallFromDetails(plugin), StoreDetailOutMsg::Install(plugin) => Self::Input::Install(plugin),
StoreDetailOutMsg::Remove(plugin) => Self::Input::Remove(plugin), StoreDetailOutMsg::Remove(plugin) => Self::Input::Remove(plugin),
StoreDetailOutMsg::SetEnabled(plugin, enabled) => { StoreDetailOutMsg::SetEnabled(plugin, enabled) => {
Self::Input::SetEnabled(PluginStoreSignalSource::Detail, plugin, enabled) Self::Input::SetEnabled(PluginStoreSignalSource::Detail, plugin, enabled)
@ -554,9 +538,7 @@ impl AsyncComponent for PluginStore {
AsyncFactoryVecDeque::builder() AsyncFactoryVecDeque::builder()
.launch(widgets.listbox.clone()) .launch(widgets.listbox.clone())
.forward(sender.input_sender(), move |msg| match msg { .forward(sender.input_sender(), move |msg| match msg {
StoreRowModelOutMsg::Install(appid, row_sender) => { StoreRowModelOutMsg::Install(appid) => Self::Input::Install(appid),
Self::Input::Install(appid, row_sender)
}
StoreRowModelOutMsg::Remove(appid) => Self::Input::Remove(appid), StoreRowModelOutMsg::Remove(appid) => Self::Input::Remove(appid),
StoreRowModelOutMsg::SetEnabled(plugin, enabled) => { StoreRowModelOutMsg::SetEnabled(plugin, enabled) => {
Self::Input::SetEnabled(PluginStoreSignalSource::Row, plugin, enabled) Self::Input::SetEnabled(PluginStoreSignalSource::Row, plugin, enabled)

View file

@ -36,7 +36,7 @@ pub enum StoreRowModelMsg {
#[derive(Debug)] #[derive(Debug)]
pub enum StoreRowModelOutMsg { pub enum StoreRowModelOutMsg {
Install(Plugin, relm4::Sender<StoreRowModelMsg>), Install(Plugin),
Remove(Plugin), Remove(Plugin),
SetEnabled(Plugin, bool), SetEnabled(Plugin, bool),
} }
@ -104,7 +104,6 @@ impl AsyncFactoryComponent for StoreRowModel {
sender sender
.output(Self::Output::Install( .output(Self::Output::Install(
plugin.clone(), plugin.clone(),
sender.input_sender().clone()
)) ))
.expect(SENDER_IO_ERR_MSG); .expect(SENDER_IO_ERR_MSG);
} }
@ -142,7 +141,6 @@ impl AsyncFactoryComponent for StoreRowModel {
sender sender
.output(Self::Output::Install( .output(Self::Output::Install(
plugin.clone(), plugin.clone(),
sender.input_sender().clone()
)) ))
.expect(SENDER_IO_ERR_MSG); .expect(SENDER_IO_ERR_MSG);
} }