mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-23 11:05:01 +01:00
Compare commits
2 Commits
yaak-cli-0
...
yaak-cli-0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aef826a80 | ||
|
|
50c7992b42 |
43
.github/workflows/release-cli-npm.yml
vendored
43
.github/workflows/release-cli-npm.yml
vendored
@@ -14,8 +14,45 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
prepare-vendored-assets:
|
||||
name: Prepare vendored plugin assets
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: npm run bootstrap:install-wasm-pack
|
||||
|
||||
- name: Build plugin assets
|
||||
run: |
|
||||
npm run build-plugins
|
||||
npm run vendor:vendor-plugins
|
||||
|
||||
- name: Upload vendored assets
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vendored-assets
|
||||
path: |
|
||||
crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs
|
||||
crates-tauri/yaak-app/vendored/plugins
|
||||
if-no-files-found: error
|
||||
|
||||
build-binaries:
|
||||
name: Build ${{ matrix.pkg }}
|
||||
needs: prepare-vendored-assets
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -67,6 +104,12 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y pkg-config libdbus-1-dev
|
||||
|
||||
- name: Download vendored assets
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: vendored-assets
|
||||
path: crates-tauri/yaak-app/vendored
|
||||
|
||||
- name: Build yaak
|
||||
run: cargo build --locked --release -p yaak-cli --bin yaak --target ${{ matrix.target }}
|
||||
|
||||
|
||||
@@ -51,38 +51,23 @@ impl CliContext {
|
||||
.expect("Failed to prepare embedded plugin runtime")
|
||||
});
|
||||
|
||||
let plugin_manager = Arc::new(
|
||||
PluginManager::new(
|
||||
vendored_plugin_dir,
|
||||
installed_plugin_dir,
|
||||
node_bin_path,
|
||||
plugin_runtime_main,
|
||||
false,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
match PluginManager::new(
|
||||
vendored_plugin_dir,
|
||||
installed_plugin_dir,
|
||||
node_bin_path,
|
||||
plugin_runtime_main,
|
||||
&query_manager,
|
||||
&PluginContext::new_empty(),
|
||||
false,
|
||||
)
|
||||
.await
|
||||
{
|
||||
let db = query_manager.connect();
|
||||
if let Err(err) = plugin_manager.ensure_bundled_plugins_registered(&db).await {
|
||||
eprintln!("Warning: Failed to register bundled plugins: {err}");
|
||||
Ok(plugin_manager) => Some(Arc::new(plugin_manager)),
|
||||
Err(err) => {
|
||||
eprintln!("Warning: Failed to initialize plugins: {err}");
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let plugins = query_manager.connect().list_plugins().unwrap_or_default();
|
||||
if !plugins.is_empty() {
|
||||
let errors = plugin_manager
|
||||
.initialize_all_plugins(plugins, &PluginContext::new_empty())
|
||||
.await;
|
||||
for (plugin_dir, error_msg) in errors {
|
||||
eprintln!(
|
||||
"Warning: Failed to initialize plugin '{}': {}",
|
||||
plugin_dir, error_msg
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Some(plugin_manager)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ use yaak_plugins::api::{
|
||||
PluginNameVersion, PluginSearchResponse, PluginUpdatesResponse, check_plugin_updates,
|
||||
search_plugins,
|
||||
};
|
||||
use yaak_plugins::events::{Color, Icon, PluginContext, ShowToastRequest};
|
||||
use yaak_plugins::events::PluginContext;
|
||||
use yaak_plugins::install::{delete_and_uninstall, download_and_install};
|
||||
use yaak_plugins::manager::PluginManager;
|
||||
use yaak_plugins::plugin_meta::get_plugin_meta;
|
||||
@@ -267,6 +267,8 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
.join("index.cjs");
|
||||
|
||||
let dev_mode = is_dev();
|
||||
let query_manager =
|
||||
app_handle.state::<yaak_models::query_manager::QueryManager>().inner().clone();
|
||||
|
||||
// Create plugin manager asynchronously
|
||||
let app_handle_clone = app_handle.clone();
|
||||
@@ -276,36 +278,12 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
installed_plugin_dir,
|
||||
node_bin_path,
|
||||
plugin_runtime_main,
|
||||
&query_manager,
|
||||
&PluginContext::new_empty(),
|
||||
dev_mode,
|
||||
)
|
||||
.await;
|
||||
|
||||
let db = app_handle_clone.db();
|
||||
manager
|
||||
.ensure_bundled_plugins_registered(&db)
|
||||
.await
|
||||
.expect("Failed to register bundled plugins");
|
||||
|
||||
// Get all plugins from database and initialize
|
||||
let plugins = db.list_plugins().expect("Failed to list plugins from database");
|
||||
drop(db); // Explicitly drop the connection before await
|
||||
|
||||
let errors =
|
||||
manager.initialize_all_plugins(plugins, &PluginContext::new_empty()).await;
|
||||
|
||||
// Show toast for any failed plugins
|
||||
for (plugin_dir, error_msg) in errors {
|
||||
let plugin_name = plugin_dir.split('/').last().unwrap_or(&plugin_dir);
|
||||
let toast = ShowToastRequest {
|
||||
message: format!("Failed to start plugin '{}': {}", plugin_name, error_msg),
|
||||
color: Some(Color::Danger),
|
||||
icon: Some(Icon::AlertTriangle),
|
||||
timeout: Some(10000),
|
||||
};
|
||||
if let Err(emit_err) = app_handle_clone.emit("show_toast", toast) {
|
||||
error!("Failed to emit toast for plugin error: {emit_err:?}");
|
||||
}
|
||||
}
|
||||
.await
|
||||
.expect("Failed to initialize plugins");
|
||||
|
||||
app_handle_clone.manage(manager);
|
||||
});
|
||||
|
||||
@@ -33,8 +33,8 @@ use tokio::net::TcpListener;
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use tokio::sync::{Mutex, mpsc, oneshot};
|
||||
use tokio::time::{Instant, timeout};
|
||||
use yaak_models::db_context::DbContext;
|
||||
use yaak_models::models::Plugin;
|
||||
use yaak_models::query_manager::QueryManager;
|
||||
use yaak_models::util::{UpdateSource, generate_id};
|
||||
use yaak_templates::error::Error::RenderError;
|
||||
use yaak_templates::error::Result as TemplateResult;
|
||||
@@ -62,14 +62,18 @@ impl PluginManager {
|
||||
/// * `installed_plugin_dir` - Path to installed plugins directory
|
||||
/// * `node_bin_path` - Path to the yaaknode binary
|
||||
/// * `plugin_runtime_main` - Path to the plugin runtime index.cjs
|
||||
/// * `query_manager` - Query manager for bundled plugin registration and loading
|
||||
/// * `plugin_context` - Context to use while initializing plugins
|
||||
/// * `dev_mode` - Whether the app is in dev mode (affects plugin loading)
|
||||
pub async fn new(
|
||||
vendored_plugin_dir: PathBuf,
|
||||
installed_plugin_dir: PathBuf,
|
||||
node_bin_path: PathBuf,
|
||||
plugin_runtime_main: PathBuf,
|
||||
query_manager: &QueryManager,
|
||||
plugin_context: &PluginContext,
|
||||
dev_mode: bool,
|
||||
) -> PluginManager {
|
||||
) -> Result<PluginManager> {
|
||||
let (events_tx, mut events_rx) = mpsc::channel(2048);
|
||||
let (kill_server_tx, kill_server_rx) = tokio::sync::watch::channel(false);
|
||||
let (killed_tx, killed_rx) = oneshot::channel();
|
||||
@@ -152,12 +156,40 @@ impl PluginManager {
|
||||
&kill_server_rx,
|
||||
killed_tx,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
.await?;
|
||||
info!("Waiting for plugins to initialize");
|
||||
init_plugins_task.await.unwrap();
|
||||
init_plugins_task.await.map_err(|e| PluginErr(e.to_string()))?;
|
||||
|
||||
plugin_manager
|
||||
let bundled_dirs = plugin_manager.list_bundled_plugin_dirs().await?;
|
||||
let db = query_manager.connect();
|
||||
for dir in bundled_dirs {
|
||||
if db.get_plugin_by_directory(&dir).is_none() {
|
||||
db.upsert_plugin(
|
||||
&Plugin {
|
||||
directory: dir,
|
||||
enabled: true,
|
||||
url: None,
|
||||
..Default::default()
|
||||
},
|
||||
&UpdateSource::Background,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
let plugins = db.list_plugins()?;
|
||||
drop(db);
|
||||
|
||||
let init_errors = plugin_manager.initialize_all_plugins(plugins, plugin_context).await;
|
||||
if !init_errors.is_empty() {
|
||||
let joined = init_errors
|
||||
.into_iter()
|
||||
.map(|(dir, err)| format!("{dir}: {err}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("; ");
|
||||
return Err(PluginErr(format!("Failed to initialize plugin(s): {joined}")));
|
||||
}
|
||||
|
||||
Ok(plugin_manager)
|
||||
}
|
||||
|
||||
/// Get the vendored plugin directory path (resolves dev mode path if applicable)
|
||||
@@ -181,33 +213,6 @@ impl PluginManager {
|
||||
read_plugins_dir(&plugins_dir).await
|
||||
}
|
||||
|
||||
/// Ensure all bundled plugin directories are present in the plugins table.
|
||||
/// Returns a list of newly registered plugin directories.
|
||||
pub async fn ensure_bundled_plugins_registered(
|
||||
&self,
|
||||
db: &DbContext<'_>,
|
||||
) -> Result<Vec<String>> {
|
||||
let bundled_dirs = self.list_bundled_plugin_dirs().await?;
|
||||
let mut registered = Vec::new();
|
||||
|
||||
for dir in bundled_dirs {
|
||||
if db.get_plugin_by_directory(&dir).is_none() {
|
||||
db.upsert_plugin(
|
||||
&Plugin {
|
||||
directory: dir.clone(),
|
||||
enabled: true,
|
||||
url: None,
|
||||
..Default::default()
|
||||
},
|
||||
&UpdateSource::Background,
|
||||
)?;
|
||||
registered.push(dir);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(registered)
|
||||
}
|
||||
|
||||
pub async fn uninstall(&self, plugin_context: &PluginContext, dir: &str) -> Result<()> {
|
||||
let plugin = self.get_plugin_by_dir(dir).await.ok_or(PluginNotFoundErr(dir.to_string()))?;
|
||||
self.remove_plugin(plugin_context, &plugin).await
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { readdirSync, cpSync, existsSync } = require('node:fs');
|
||||
const { readdirSync, cpSync, existsSync, mkdirSync } = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const pluginsDir = path.join(__dirname, '..', 'plugins');
|
||||
@@ -24,6 +24,7 @@ for (const name of readdirSync(pluginsDir)) {
|
||||
continue;
|
||||
}
|
||||
const destDir = path.join(__dirname, '../crates-tauri/yaak-app/vendored/plugins/', name);
|
||||
mkdirSync(destDir, { recursive: true });
|
||||
console.log(`Copying ${name} to ${destDir}`);
|
||||
cpSync(path.join(dir, 'package.json'), path.join(destDir, 'package.json'));
|
||||
cpSync(path.join(dir, 'build'), path.join(destDir, 'build'), { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user