diff --git a/examples/plugin/init.lua b/examples/plugin/init.lua index 564a8ba94..7d6b710ef 100644 --- a/examples/plugin/init.lua +++ b/examples/plugin/init.lua @@ -1,4 +1,4 @@ -local Api = require("interface") +local Api = require("./interface") local log = Api.log; local manager = { diff --git a/src/main.rs b/src/main.rs index 39b360f7d..bc36e1071 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,18 @@ use clap::Parser; -use dioxus_cli::*; +use dioxus_cli::{*, plugin::{PluginManager, PluginConfig}}; #[tokio::main] async fn main() -> Result<()> { let args = Cli::parse(); set_up_logging(); + let plugin_manager = PluginManager::init(&PluginConfig { + available: true, + required: vec![], + }).unwrap(); + + plugin_manager.load_all_plugins().unwrap(); + match args.action { Commands::Translate(opts) => { if let Err(e) = opts.translate() { diff --git a/src/plugin/interface.rs b/src/plugin/interface.rs index ac2005319..399b6919f 100644 --- a/src/plugin/interface.rs +++ b/src/plugin/interface.rs @@ -1,7 +1,7 @@ use mlua::{FromLua, Function}; pub struct PluginInfo<'lua> { - name: String, + pub name: String, repository: String, author: String, diff --git a/src/plugin/log.rs b/src/plugin/logger.rs similarity index 100% rename from src/plugin/log.rs rename to src/plugin/logger.rs diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index da312aa00..c69fb620b 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -1,21 +1,21 @@ -use std::{fs::create_dir_all, path::PathBuf, io::Read}; +use std::{fs::create_dir_all, io::Read, path::PathBuf}; -use mlua::Lua; +use mlua::{Lua, Table}; use serde::{Deserialize, Serialize}; use walkdir::WalkDir; -use crate::tools::app_path; +use crate::tools::{app_path, clone_repo}; -use self::{log::PluginLogger, interface::PluginInfo}; +use self::{interface::PluginInfo, logger::PluginLogger}; -pub mod log; +pub mod logger; mod interface; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PluginConfig { - available: bool, - required: Vec, + pub available: bool, + pub required: Vec, } pub struct PluginManager { @@ -24,18 +24,19 @@ pub struct PluginManager { impl PluginManager { pub fn init(config: &PluginConfig) -> Option { - if config.available { + if !config.available { return None; } let lua = Lua::new(); - let manager = lua.create_table().ok()?; + let manager = lua.create_table().unwrap(); lua.globals().set("plugin_logger", PluginLogger).unwrap(); let plugin_dir = Self::init_plugin_dir(); let mut index = 0; + println!("{plugin_dir:?}"); for entry in WalkDir::new(plugin_dir).into_iter().filter_map(|e| e.ok()) { let plugin_dir = entry.path().to_path_buf(); if plugin_dir.is_dir() { @@ -51,16 +52,32 @@ impl PluginManager { } } - lua.globals().set("manager", manager).ok()?; + lua.globals().set("manager", manager).unwrap(); Some(Self { lua }) } + pub fn load_all_plugins(&self) -> anyhow::Result<()> { + let lua = &self.lua; + let manager = lua.globals().get::<_, Table>("manager")?; + println!("{:?}", manager.len()); + for i in 0..(manager.len()? as i32) { + let v = manager.get::(i)?; + println!("{:?}", v.name); + let code = format!("manager[{i}].onLoad()"); + lua.load(&code).exec()?; + } + Ok(()) + } + fn init_plugin_dir() -> PathBuf { + log::info!("📖 Start to init plugin library ..."); + let app_path = app_path(); let plugin_path = app_path.join("plugins"); if !plugin_path.is_dir() { - create_dir_all(&plugin_path).unwrap(); + let url = "https://github.com/DioxusLabs/cli-plugin-library"; + clone_repo(&plugin_path, url).unwrap(); } plugin_path } diff --git a/src/tools.rs b/src/tools.rs index dc922050a..3f95ccac1 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -1,8 +1,8 @@ use std::{ fs::{create_dir_all, File}, + io::{Read, Write}, path::{Path, PathBuf}, process::Command, - io::{Read, Write} }; use anyhow::Context; @@ -40,6 +40,16 @@ pub fn temp_path() -> PathBuf { temp_path } +pub fn clone_repo(dir: &Path, url: &str) -> anyhow::Result<()> { + let target_dir = dir.parent().unwrap(); + let dir_name = dir.file_name().unwrap(); + + let mut cmd = Command::new("git"); + let cmd = cmd.current_dir(target_dir); + let _res = cmd.arg("clone").arg(url).arg(dir_name).output()?; + Ok(()) +} + pub fn tools_path() -> PathBuf { let app_path = app_path(); let temp_path = app_path.join("tools"); @@ -121,15 +131,9 @@ impl Tool { /// get tool version pub fn tool_version(&self) -> &str { match self { - Self::Binaryen => { - "version_105" - } - Self::Sass => { - "1.51.0" - } - Self::Tailwind => { - "v3.1.6" - } + Self::Binaryen => "version_105", + Self::Sass => "1.51.0", + Self::Tailwind => "v3.1.6", } } @@ -154,7 +158,7 @@ impl Tool { Self::Tailwind => { let windows_extension = match self.target_platform() { "windows" => ".exe", - _ => "" + _ => "", }; format!( "https://github.com/tailwindlabs/tailwindcss/releases/download/{version}/tailwindcss-{target}-x64{optional_ext}", @@ -177,7 +181,7 @@ impl Tool { "tar.gz" } } - Self::Tailwind => "bin" + Self::Tailwind => "bin", } } @@ -218,7 +222,7 @@ impl Tool { let dir_name = match self { Self::Binaryen => format!("binaryen-{}", self.tool_version()), Self::Sass => "dart-sass".to_string(), - Self::Tailwind => self.name().to_string() + Self::Tailwind => self.name().to_string(), }; if self.extension() == "tar.gz" { @@ -234,14 +238,14 @@ impl Tool { } else if self.extension() == "bin" { let bin_path = match self.target_platform() { "windows" => tool_path.join(&dir_name).join(self.name()).join(".exe"), - _ => tool_path.join(&dir_name).join(self.name()) - } ; + _ => tool_path.join(&dir_name).join(self.name()), + }; // Manualy creating tool directory because we directly download the binary via Github - std::fs::create_dir( tool_path.join(dir_name))?; + std::fs::create_dir(tool_path.join(dir_name))?; let mut final_file = std::fs::File::create(&bin_path)?; let mut temp_file = File::open(&temp_path)?; - let mut content = Vec::new(); + let mut content = Vec::new(); temp_file.read_to_end(&mut content)?; final_file.write_all(&content)?;