forked from 1b-agent/opencadstudio-upstream
fix(plugins): gate on_load behind API v5
BREAKING CHANGE: plugins using on_load must target API v5 and declare api_version = 5. Refs #901
This commit is contained in:
1 parent
c527466791
commit
2842f6dc58
9 files changed
+43
-30
No files matched your search
@@ -299,14 +299,12 @@ pub trait BuiltinPlugin: Send + Sync {
|
||||
/// API major 4 or newer.
|
||||
fn on_notification(&mut self, _command_id: Option<u64>, _notification: HostNotification) {}
|
||||
|
||||
/// Lifecycle callback invoked once after the plugin has been loaded and its
|
||||
/// manifest/ribbon have been accepted by the host. The plugin receives the
|
||||
/// active document tab's `HostApi` so it can set up worker threads or cache
|
||||
/// `plugin_request_sender()` before any user command runs.
|
||||
/// Lifecycle callback invoked once after the runner connects. The plugin
|
||||
/// receives the active document tab's `HostApi` so it can set up worker
|
||||
/// threads or cache `plugin_request_sender()` before any user command runs.
|
||||
///
|
||||
/// Added after API v4. The default implementation does nothing, so existing
|
||||
/// plugins remain source-compatible. The runner only calls this for plugins
|
||||
/// that report API major 4 or newer.
|
||||
/// Added in API v5. The runner only calls this for plugins that report API
|
||||
/// major 5 or newer.
|
||||
fn on_load(&mut self, _host: &mut dyn HostApi) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
/// `document()` / `document_mut()` to local cached copies for out-of-process
|
||||
/// plugins and appends `document_reader` / `document_view` at the end of the
|
||||
/// vtable so API v2 plugins keep working. v4 adds full-duplex notifications on
|
||||
/// a multiplexed socket while leaving the V2/V3 ABI and protocol untouched.
|
||||
pub const API_VERSION: u32 = 4;
|
||||
/// a multiplexed socket while leaving the V2/V3 ABI and protocol untouched. v5
|
||||
/// adds the `BuiltinPlugin::on_load` lifecycle callback.
|
||||
pub const API_VERSION: u32 = 5;
|
||||
|
||||
/// Oldest plugin API major the current host still loads. This keeps previously
|
||||
/// compiled cdylibs usable as long as their vtable layout is a prefix of the
|
||||
@@ -26,9 +27,8 @@ pub const API_VERSION: u32 = 4;
|
||||
pub const API_VERSION_MIN_SUPPORTED: u32 = 2;
|
||||
|
||||
/// Environment variable that caps the API major accepted by the host at
|
||||
/// runtime. Set to `3` to disable V4 plugins while keeping V2/V3 plugins
|
||||
/// working; set to `2` for V2-only mode. The same mechanism will apply to
|
||||
/// future API majors.
|
||||
/// runtime. Set to `4` to disable V5 plugins, `3` to disable V4, or `2` for
|
||||
/// V2-only mode.
|
||||
pub const MAX_API_VERSION_ENV: &str = "OCS_PLUGIN_MAX_API_VERSION";
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
|
||||
@@ -56,9 +56,9 @@ pub fn run(socket_name: &str, cdylib_path: &Path) -> Result<(), Box<dyn std::err
|
||||
|
||||
if version >= 4 {
|
||||
let client = V4Client::connect_handshake(socket_name, &token)?;
|
||||
// Give the plugin a chance to set up worker threads / cache the request
|
||||
// sender before the host starts dispatching user commands.
|
||||
invoke_on_load(&mut *plugin, &client, &interactive);
|
||||
if version >= 5 {
|
||||
invoke_on_load(&mut *plugin, &client, &interactive)?;
|
||||
}
|
||||
run_v4(&mut *plugin, &interactive, client)
|
||||
} else {
|
||||
let client = IpcClient::connect(socket_name)?;
|
||||
@@ -70,11 +70,17 @@ pub fn run(socket_name: &str, cdylib_path: &Path) -> Result<(), Box<dyn std::err
|
||||
}
|
||||
}
|
||||
|
||||
fn invoke_on_load(plugin: &mut dyn BuiltinPlugin, client: &V4Client, interactive: &InteractiveRegistry) {
|
||||
fn invoke_on_load(
|
||||
plugin: &mut dyn BuiltinPlugin,
|
||||
client: &V4Client,
|
||||
interactive: &InteractiveRegistry,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut proxy = client.plugin_host_api(0, interactive.clone());
|
||||
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
plugin.on_load(&mut proxy)
|
||||
}));
|
||||
}))
|
||||
.map_err(|_| std::io::Error::other("plugin on_load() panicked"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_v3(
|
||||
|
||||
@@ -147,7 +147,7 @@ mod tests {
|
||||
value["ocs_plugin_api_version"].as_str(),
|
||||
Some(env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
assert_eq!(value["api_version"].as_i64(), Some(4));
|
||||
assert_eq!(value["api_version"].as_i64(), Some(5));
|
||||
assert_eq!(value["api_version_min_supported"].as_i64(), Some(2));
|
||||
|
||||
// acadrust_version should have a patch component (e.g. "0.4.0").
|
||||
|
||||
Reference in new issue
Block a user