diff --git a/.github/workflows/draft.yml b/.github/workflows/draft.yml index 18dcdf966..a546cc92f 100644 --- a/.github/workflows/draft.yml +++ b/.github/workflows/draft.yml @@ -203,16 +203,24 @@ jobs: runs-on: ubuntu-latest needs: [build-unix, build-windows, build-musl, build-snap] steps: - - uses: actions/download-artifact@v4 - with: - merge-multiple: true - - run: | echo 'NIGHTLY_BODY<> $GITHUB_ENV echo "From commit: ${GITHUB_SHA:0:8}" >> $GITHUB_ENV echo "Generated on: $(date -u +"%Y-%m-%d %H:%M") UTC" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + merge-multiple: true + + - name: Update the tag + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag --force nightly && git push --force origin tag nightly + - name: Nightly uses: softprops/action-gh-release@v1 with: @@ -223,3 +231,4 @@ jobs: yazi-*.snap name: Nightly Build body: ${{ env.NIGHTLY_BODY }} + target_commitish: ${{ github.sha }} diff --git a/yazi-fm/src/app/commands/accept_payload.rs b/yazi-fm/src/app/commands/accept_payload.rs index 96b633518..536e3f517 100644 --- a/yazi-fm/src/app/commands/accept_payload.rs +++ b/yazi-fm/src/app/commands/accept_payload.rs @@ -1,7 +1,7 @@ use mlua::IntoLua; use tracing::error; use yazi_dds::{LOCAL, Payload, REMOTE}; -use yazi_plugin::{LUA, RtRef}; +use yazi_plugin::{LUA, RtRefMut}; use yazi_shared::event::CmdCow; use crate::{app::App, lives::Lives}; @@ -27,11 +27,11 @@ impl App { _ = Lives::scope(&self.cx, || { let body = payload.body.into_lua(&LUA)?; for (id, cb) in handlers { - LUA.named_registry_value::("rt")?.push(&id); + LUA.named_registry_value::("rt")?.push(&id); if let Err(e) = cb.call::<()>(body.clone()) { error!("Failed to run `{kind}` event handler in your `{id}` plugin: {e}"); } - LUA.named_registry_value::("rt")?.pop(); + LUA.named_registry_value::("rt")?.pop(); } Ok(()) }); diff --git a/yazi-fm/src/app/commands/plugin.rs b/yazi-fm/src/app/commands/plugin.rs index 8839ce76e..812ade655 100644 --- a/yazi-fm/src/app/commands/plugin.rs +++ b/yazi-fm/src/app/commands/plugin.rs @@ -2,9 +2,9 @@ use std::fmt::Display; use mlua::ObjectLike; use scopeguard::defer; -use tracing::warn; +use tracing::{error, warn}; use yazi_dds::Sendable; -use yazi_plugin::{LUA, RtRef, loader::LOADER}; +use yazi_plugin::{LUA, RtRefMut, loader::LOADER}; use yazi_proxy::{AppProxy, options::{PluginMode, PluginOpt}}; use crate::{app::App, lives::Lives}; @@ -50,11 +50,11 @@ impl App { return self.cx.tasks.plugin_micro(opt); } - match LUA.named_registry_value::("rt") { + match LUA.named_registry_value::("rt") { Ok(mut r) => r.push(&opt.id), Err(e) => return warn!("{e}"), } - defer! { _ = LUA.named_registry_value::("rt").map(|mut r| r.pop()) } + defer! { _ = LUA.named_registry_value::("rt").map(|mut r| r.pop()) } let plugin = match LOADER.load_with(&LUA, &opt.id, chunk) { Ok(plugin) => plugin, @@ -62,14 +62,16 @@ impl App { }; drop(loader); - _ = Lives::scope(&self.cx, || { + let result = Lives::scope(&self.cx, || { if let Some(cb) = opt.cb { cb(&LUA, plugin) } else { let job = LUA.create_table_from([("args", Sendable::args_to_table(&LUA, opt.args)?)])?; - plugin.call_method("entry", job) } }); + if let Err(e) = result { + error!("Sync plugin `{}` failed: {e}", opt.id); + } } } diff --git a/yazi-plugin/src/isolate/seek.rs b/yazi-plugin/src/isolate/seek.rs index 73d739892..1941e8b01 100644 --- a/yazi-plugin/src/isolate/seek.rs +++ b/yazi-plugin/src/isolate/seek.rs @@ -5,7 +5,7 @@ use yazi_shared::event::Cmd; use crate::{bindings::Cast, elements::Rect, file::File}; -pub fn seek_sync(cmd: &Cmd, file: yazi_fs::File, units: i16) { +pub fn seek_sync(cmd: &'static Cmd, file: yazi_fs::File, units: i16) { let cb: PluginCallback = Box::new(move |lua, plugin| { let job = lua.create_table_from([ ("file", File::cast(lua, file)?.into_lua(lua)?), diff --git a/yazi-plugin/src/loader/require.rs b/yazi-plugin/src/loader/require.rs index 8f45bea26..78f9203c5 100644 --- a/yazi-plugin/src/loader/require.rs +++ b/yazi-plugin/src/loader/require.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use mlua::{ExternalResult, Function, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, Table, Value}; use super::LOADER; -use crate::RtRef; +use crate::RtRefMut; pub(super) struct Require; @@ -15,9 +15,9 @@ impl Require { let s = &id.to_str()?; futures::executor::block_on(LOADER.ensure(s)).into_lua_err()?; - lua.named_registry_value::("rt")?.push(s); + lua.named_registry_value::("rt")?.push(s); let mod_ = LOADER.load(lua, s); - lua.named_registry_value::("rt")?.pop(); + lua.named_registry_value::("rt")?.pop(); Self::create_mt(lua, s, mod_?, true) })?, @@ -31,9 +31,9 @@ impl Require { let s = &id.to_str()?; LOADER.ensure(s).await.into_lua_err()?; - lua.named_registry_value::("rt")?.push(s); + lua.named_registry_value::("rt")?.push(s); let mod_ = LOADER.load(&lua, s); - lua.named_registry_value::("rt")?.pop(); + lua.named_registry_value::("rt")?.pop(); Self::create_mt(&lua, s, mod_?, false) })?, @@ -73,9 +73,9 @@ impl Require { if sync { lua.create_function(move |lua, args: MultiValue| { let (mod_, args) = Self::split_mod_and_args(lua, &id, args)?; - lua.named_registry_value::("rt")?.push(&id); + lua.named_registry_value::("rt")?.push(&id); let result = mod_.call_function::(&f, args); - lua.named_registry_value::("rt")?.pop(); + lua.named_registry_value::("rt")?.pop(); result }) } else { @@ -83,9 +83,9 @@ impl Require { let (id, f) = (id.clone(), f.clone()); async move { let (mod_, args) = Self::split_mod_and_args(&lua, &id, args)?; - lua.named_registry_value::("rt")?.push(&id); + lua.named_registry_value::("rt")?.push(&id); let result = mod_.call_async_function::(&f, args).await; - lua.named_registry_value::("rt")?.pop(); + lua.named_registry_value::("rt")?.pop(); result } }) diff --git a/yazi-plugin/src/runtime.rs b/yazi-plugin/src/runtime.rs index 3f4c8957c..2d0280400 100644 --- a/yazi-plugin/src/runtime.rs +++ b/yazi-plugin/src/runtime.rs @@ -2,18 +2,20 @@ use std::collections::{HashMap, VecDeque}; use mlua::{Function, UserData}; -#[derive(Default)] +#[derive(Debug, Default)] pub struct Runtime { frames: VecDeque, blocks: HashMap>, } +#[derive(Debug)] struct RuntimeFrame { id: String, calls: usize, } -pub type RtRef = mlua::UserDataRefMut; +pub type RtRef = mlua::UserDataRef; +pub type RtRefMut = mlua::UserDataRefMut; impl Runtime { pub fn new(id: &str) -> Self { @@ -31,6 +33,8 @@ impl Runtime { pub fn current(&self) -> Option<&str> { self.frames.back().map(|f| f.id.as_str()) } + pub fn current_owned(&self) -> Option { self.current().map(ToOwned::to_owned) } + pub fn next_block(&mut self) -> Option { self.frames.back_mut().map(|f| { f.calls += 1; diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 625352c3f..084ccde53 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -6,32 +6,31 @@ use yazi_proxy::{AppProxy, options::{PluginCallback, PluginOpt}}; use yazi_shared::event::Data; use super::Utils; -use crate::{bindings::{MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx}, loader::LOADER, runtime::RtRef}; +use crate::{RtRefMut, bindings::{MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx}, loader::LOADER, runtime::RtRef}; impl Utils { pub(super) fn sync(lua: &Lua, isolate: bool) -> mlua::Result { if isolate { lua.create_function(|lua, ()| { - let Some(block) = lua.named_registry_value::("rt")?.next_block() else { + let Some(block) = lua.named_registry_value::("rt")?.next_block() else { return Err("`ya.sync()` must be called in a plugin").into_lua_err(); }; lua.create_async_function(move |lua, args: MultiValue| async move { - if let Some(cur) = lua.named_registry_value::("rt")?.current() { - Sendable::list_to_values(&lua, Self::retrieve(cur, block, args).await?) - } else { - Err("block spawned by `ya.sync()` must be called in a plugin").into_lua_err() - } + let Some(cur) = lua.named_registry_value::("rt")?.current_owned() else { + return Err("block spawned by `ya.sync()` must be called in a plugin").into_lua_err(); + }; + Sendable::list_to_values(&lua, Self::retrieve(cur, block, args).await?) }) }) } else { lua.create_function(|lua, f: Function| { - let mut rt = lua.named_registry_value::("rt")?; + let mut rt = lua.named_registry_value::("rt")?; if !rt.put_block(f.clone()) { return Err("`ya.sync()` must be called in a plugin").into_lua_err(); } - let cur = rt.current().unwrap().to_owned(); + let cur = rt.current_owned().unwrap(); lua.create_function(move |lua, mut args: MultiValue| { args.push_front(Value::Table(LOADER.try_load(lua, &cur)?)); f.call::(args) @@ -78,14 +77,14 @@ impl Utils { lua.create_async_function(|_lua, _futs: MultiValue| async move { Ok(()) }) } - async fn retrieve(id: &str, calls: usize, args: MultiValue) -> mlua::Result> { + async fn retrieve(id: String, calls: usize, args: MultiValue) -> mlua::Result> { let args = Sendable::values_to_list(args)?; let (tx, rx) = oneshot::channel::>(); let callback: PluginCallback = { - let id = id.to_owned(); + let id_ = id.clone(); Box::new(move |lua, plugin| { - let Some(block) = lua.named_registry_value::("rt")?.get_block(&id, calls) else { + let Some(block) = lua.named_registry_value::("rt")?.get_block(&id_, calls) else { return Err("sync block not found".into_lua_err()); }; @@ -99,7 +98,7 @@ impl Utils { }) }; - AppProxy::plugin(PluginOpt::new_callback(id, callback)); + AppProxy::plugin(PluginOpt::new_callback(id.clone(), callback)); rx.await .map_err(|_| format!("Failed to execute sync block-{calls} in `{id}` plugin").into_lua_err()) diff --git a/yazi-proxy/src/options/plugin.rs b/yazi-proxy/src/options/plugin.rs index 79a031e0d..f3dfd57ba 100644 --- a/yazi-proxy/src/options/plugin.rs +++ b/yazi-proxy/src/options/plugin.rs @@ -49,8 +49,8 @@ impl Debug for PluginOpt { } impl PluginOpt { - pub fn new_callback(id: &str, cb: PluginCallback) -> Self { - Self { id: id.to_owned().into(), mode: PluginMode::Sync, cb: Some(cb), ..Default::default() } + pub fn new_callback(id: impl Into>, cb: PluginCallback) -> Self { + Self { id: id.into(), mode: PluginMode::Sync, cb: Some(cb), ..Default::default() } } }