Merge pull request #86 from DioxusLabs/jk/cleanups

chore: use rosetta for translate module and cleanup some top level code
This commit is contained in:
Jon Kelley authored and GitHub committed 2023-01-12 15:41:56 -08:00
commit 26307f04d2
15 files changed
+203 -382

No files matched your search

Generated
+28 -24
View File
@@ -438,16 +438,15 @@ dependencies = [
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.2" version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" checksum = "5556015fe3aad8b968e5d4124980fbe2f6aaee7aeec6b749de1faaa2ca5d0a4c"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode",
"lazy_static", "lazy_static",
"libc", "libc",
"terminal_size",
"unicode-width", "unicode-width",
"winapi", "windows-sys 0.42.0",
] ]
[[package]] [[package]]
@@ -663,7 +662,7 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-autofmt" name = "dioxus-autofmt"
version = "0.0.0" version = "0.0.0"
source = "git+https://github.com/dioxuslabs/dioxus#641488e825d861a14670ba7a15a535e76d3cee7a" source = "git+https://github.com/dioxuslabs/dioxus#04ca284704b3aa7e18cf7b4f2e573e25df3d47eb"
dependencies = [ dependencies = [
"dioxus-rsx", "dioxus-rsx",
"prettyplease", "prettyplease",
@@ -709,6 +708,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"regex", "regex",
"reqwest", "reqwest",
"rsx-rosetta",
"serde", "serde",
"serde_json", "serde_json",
"syn", "syn",
@@ -726,7 +726,7 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-core" name = "dioxus-core"
version = "0.2.1" version = "0.2.1"
source = "git+https://github.com/dioxuslabs/dioxus#641488e825d861a14670ba7a15a535e76d3cee7a" source = "git+https://github.com/dioxuslabs/dioxus#04ca284704b3aa7e18cf7b4f2e573e25df3d47eb"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"futures-channel", "futures-channel",
@@ -743,7 +743,7 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-html" name = "dioxus-html"
version = "0.2.1" version = "0.2.1"
source = "git+https://github.com/dioxuslabs/dioxus#641488e825d861a14670ba7a15a535e76d3cee7a" source = "git+https://github.com/dioxuslabs/dioxus#04ca284704b3aa7e18cf7b4f2e573e25df3d47eb"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"dioxus-core", "dioxus-core",
@@ -759,7 +759,7 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-rsx" name = "dioxus-rsx"
version = "0.0.1" version = "0.0.1"
source = "git+https://github.com/dioxuslabs/dioxus#641488e825d861a14670ba7a15a535e76d3cee7a" source = "git+https://github.com/dioxuslabs/dioxus#04ca284704b3aa7e18cf7b4f2e573e25df3d47eb"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"internment", "internment",
@@ -2018,9 +2018,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "0.3.18" version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bdd679d533107e090c2704a35982fc06302e30898e63ffa26a81155c012e92" checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
@@ -2247,6 +2247,20 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "rsx-rosetta"
version = "0.0.0"
source = "git+https://github.com/dioxuslabs/dioxus#04ca284704b3aa7e18cf7b4f2e573e25df3d47eb"
dependencies = [
"convert_case",
"dioxus-autofmt",
"dioxus-rsx",
"html_parser",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "rust-argon2" name = "rust-argon2"
version = "0.8.3" version = "0.8.3"
@@ -2379,9 +2393,9 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.151" version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@@ -2398,9 +2412,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.151" version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -2607,16 +2621,6 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.16.0" version = "0.16.0"
+1
View File
@@ -81,6 +81,7 @@ dioxus-core = { git = "https://github.com/DioxusLabs/dioxus", features = [
"serialize", "serialize",
] } ] }
dioxus-autofmt = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-autofmt = { git = "https://github.com/dioxuslabs/dioxus" }
rsx-rosetta = { git = "https://github.com/dioxuslabs/dioxus" }
[[bin]] [[bin]]
path = "src/main.rs" path = "src/main.rs"
+3 -3
View File
@@ -385,9 +385,9 @@ fn prettier_build(mut cmd: Command) -> anyhow::Result<Vec<Diagnostic>> {
let message = msg.message; let message = msg.message;
match message.level { match message.level {
cargo_metadata::diagnostic::DiagnosticLevel::Error => { cargo_metadata::diagnostic::DiagnosticLevel::Error => {
return Err(anyhow::anyhow!(message return Err(anyhow::anyhow!(
.rendered message.rendered.unwrap_or("Unknown".into())
.unwrap_or("Unknown".into()))); ));
} }
cargo_metadata::diagnostic::DiagnosticLevel::Warning => { cargo_metadata::diagnostic::DiagnosticLevel::Warning => {
warning_messages.push(message.clone()); warning_messages.push(message.clone());
+1 -2
View File
@@ -16,11 +16,10 @@ use crate::{
gen_page, server, CrateConfig, Error, gen_page, server, CrateConfig, Error,
}; };
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use html_parser::{Dom, Element, Node}; use html_parser::Dom;
use regex::Regex; use regex::Regex;
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
fmt::{Display, Formatter},
fs::{remove_dir_all, File}, fs::{remove_dir_all, File},
io::{Read, Write}, io::{Read, Write},
path::PathBuf, path::PathBuf,
+86 -262
View File
@@ -1,5 +1,9 @@
use std::process::exit; use std::process::exit;
use dioxus_rsx::{BodyNode, CallBody, Component};
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use super::*; use super::*;
/// Build the Rust WASM app and all of its assets. /// Build the Rust WASM app and all of its assets.
@@ -26,291 +30,111 @@ pub struct Translate {
impl Translate { impl Translate {
pub fn translate(self) -> Result<()> { pub fn translate(self) -> Result<()> {
let Translate { // Get the right input for the translation
component, let contents = determine_input(self.file, self.raw)?;
output,
file,
raw,
} = self;
let contents = match (file, raw) { // Ensure we're loading valid HTML
(Some(input), None) => std::fs::read_to_string(&input).unwrap_or_else(|e| { let dom = html_parser::Dom::parse(&contents)?;
log::error!("Cloud not read input file: {}.", e);
exit(0);
}),
(None, Some(raw)) => raw,
(Some(_), Some(_)) => {
log::error!("Only one of --file or --raw can be specified.");
exit(0);
}
(None, None) => {
if atty::is(atty::Stream::Stdin) {
return custom_error!("No input file, source, or stdin to translate from.");
}
let mut buffer = String::new(); // Convert the HTML to RSX
std::io::stdin().read_to_string(&mut buffer).unwrap(); let out = convert_html_to_formatted_rsx(&dom, self.component);
buffer.trim().to_string() // Write the output
} match self.output {
}; Some(output) => std::fs::write(&output, out)?,
None => print!("{}", out),
let out_buf = match component {
true => format!("{}", convert_html_to_component(&contents).unwrap()),
false => {
let mut buf = String::new();
let dom = Dom::parse(&contents).unwrap();
for child in &dom.children {
simple_render_child(&mut buf, child, 0)?;
}
buf
}
};
if let Some(output) = output {
std::fs::write(&output, out_buf)?;
} else {
print!("{}", out_buf);
} }
Ok(()) Ok(())
} }
} }
/// render without handling svgs or anything pub fn convert_html_to_formatted_rsx(dom: &Dom, component: bool) -> String {
pub fn simple_render_child( let callbody = rsx_rosetta::rsx_from_html(&dom);
f: &mut impl std::fmt::Write,
child: &Node,
il: u32,
) -> std::fmt::Result {
write_tabs(f, il)?;
match child {
Node::Text(t) => writeln!(f, "\"{}\"", t)?,
Node::Comment(e) => writeln!(f, "/* {} */", e)?,
Node::Element(el) => {
// open the tag
write!(f, "{} {{ ", &el.name)?;
// todo: dioxus will eventually support classnames match component {
// for now, just write them with a space between each true => write_callbody_with_icon_section(callbody),
let class_iter = &mut el.classes.iter(); false => dioxus_autofmt::write_block_out(callbody).unwrap(),
if let Some(first_class) = class_iter.next() {
write!(f, "class: \"{}", first_class)?;
for next_class in class_iter {
write!(f, " {}", next_class)?;
}
write!(f, "\",")?;
}
writeln!(f)?;
// write the attributes
if let Some(id) = &el.id {
write_tabs(f, il + 1)?;
writeln!(f, "id: \"{}\",", id)?;
}
for (name, value) in &el.attributes {
write_tabs(f, il + 1)?;
use convert_case::{Case, Casing};
if name.chars().any(|ch| ch.is_ascii_uppercase() || ch == '-') {
let new_name = name.to_case(Case::Snake);
match value {
Some(val) => writeln!(f, "{}: \"{}\",", new_name, val)?,
None => writeln!(f, "{}: \"\",", new_name)?,
}
} else {
if matches!(name.as_str(), "for" | "async" | "type" | "as") {
write!(f, "r#")?
}
match value {
Some(val) => writeln!(f, "{}: \"{}\",", name, val)?,
None => writeln!(f, "{}: \"\",", name)?,
}
}
}
// now the children
for child in &el.children {
simple_render_child(f, child, il + 1)?;
}
// close the tag
write_tabs(f, il)?;
writeln!(f, "}}")?;
}
};
Ok(())
}
pub fn convert_html_to_component(html: &str) -> Result<ComponentRenderer> {
Ok(ComponentRenderer {
dom: Dom::parse(html)?,
icon_index: 0,
})
}
#[allow(dead_code)]
pub struct ComponentRenderer {
dom: Dom,
icon_index: usize,
}
impl Display for ComponentRenderer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(
f,
r##"
fn component(cx: Scope) -> Element {{
cx.render(rsx!("##
)?;
let mut svg_nodes = vec![];
let mut svg_idx = 0;
for child in &self.dom.children {
render_child(f, child, 2, &mut svg_nodes, true, &mut svg_idx)?;
}
write!(
f,
r##" ))
}}"##
)?;
if svg_idx == 0 {
return Ok(());
}
writeln!(f, "\n\nmod icons {{")?;
writeln!(f, "\tuse super::*;")?;
let mut id = 0;
while let Some(svg) = svg_nodes.pop() {
writeln!(
f,
r##" pub(super) fn icon_{}(cx: Scope) -> Element {{
cx.render(rsx!("##,
id
)?;
write_tabs(f, 3)?;
render_element(f, svg, 3, &mut svg_nodes, false, &mut 0)?;
writeln!(f, "\t\t))\n\t}}")?;
id += 1;
}
writeln!(f, "}}")?;
Ok(())
} }
} }
fn render_child<'a>( fn write_callbody_with_icon_section(mut callbody: CallBody) -> String {
f: &mut Formatter<'_>, let mut svgs = vec![];
child: &'a Node,
il: u32, rsx_rosetta::collect_svgs(&mut callbody.roots, &mut svgs);
svg_buffer: &mut Vec<&'a Element>,
skip_svg: bool, let mut out = write_component_body(dioxus_autofmt::write_block_out(callbody).unwrap());
svg_idx: &mut usize,
) -> std::fmt::Result { if !svgs.is_empty() {
write_tabs(f, il)?; write_svg_section(&mut out, svgs);
match child { }
Node::Text(t) => writeln!(f, "\"{}\"", t)?,
Node::Comment(e) => writeln!(f, "/* {} */", e)?, out
Node::Element(el) => render_element(f, el, il, svg_buffer, skip_svg, svg_idx)?,
};
Ok(())
} }
fn render_element<'a>( fn write_component_body(raw: String) -> String {
f: &mut Formatter<'_>, let mut out = String::from("fn component(cx: Scope) -> Element {\n cx.render(rsx! {");
el: &'a Element, indent_and_write(&raw, 1, &mut out);
il: u32, out.push_str(" })\n}");
svg_buffer: &mut Vec<&'a Element>, out
skip_svg: bool,
svg_idx: &mut usize,
) -> std::fmt::Result {
if el.name == "svg" && skip_svg {
svg_buffer.push(el);
// todo: attach the right icon ID
writeln!(f, "icons::icon_{} {{}}", svg_idx)?;
*svg_idx += 1;
return Ok(());
}
// open the tag
write!(f, "{} {{ ", &el.name)?;
// todo: dioxus will eventually support classnames
// for now, just write them with a space between each
let class_iter = &mut el.classes.iter();
if let Some(first_class) = class_iter.next() {
write!(f, "class: \"{}", first_class)?;
for next_class in class_iter {
write!(f, " {}", next_class)?;
}
write!(f, "\",")?;
}
writeln!(f)?;
// write the attributes
if let Some(id) = &el.id {
write_tabs(f, il + 1)?;
writeln!(f, "id: \"{}\",", id)?;
}
for (name, value) in &el.attributes {
write_tabs(f, il + 1)?;
use convert_case::{Case, Casing};
if name.chars().any(|ch| ch.is_ascii_uppercase() || ch == '-') {
let new_name = name.to_case(Case::Snake);
match value {
Some(val) => writeln!(f, "{}: \"{}\",", new_name, val)?,
None => writeln!(f, "{}: \"\",", new_name)?,
}
} else {
if matches!(name.as_str(), "for" | "async" | "type" | "as") {
write!(f, "r#")?
}
match value {
Some(val) => writeln!(f, "{}: \"{}\",", name, val)?,
None => writeln!(f, "{}: \"\",", name)?,
}
}
}
// now the children
for child in &el.children {
render_child(f, child, il + 1, svg_buffer, skip_svg, svg_idx)?;
}
// close the tag
write_tabs(f, il)?;
writeln!(f, "}}")?;
Ok(())
} }
fn write_tabs(f: &mut impl std::fmt::Write, num: u32) -> std::fmt::Result { fn write_svg_section(out: &mut String, svgs: Vec<BodyNode>) {
for _ in 0..num { out.push_str("\n\nmod icons {");
write!(f, " ")? out.push_str("\n use super::*;");
for (idx, icon) in svgs.into_iter().enumerate() {
let raw = dioxus_autofmt::write_block_out(CallBody { roots: vec![icon] }).unwrap();
out.push_str("\n\n pub fn icon_");
out.push_str(&idx.to_string());
out.push_str("(cx: Scope) -> Element {\n cx.render(rsx! {");
indent_and_write(&raw, 2, out);
out.push_str(" })\n }");
} }
Ok(())
out.push_str("\n}");
}
fn indent_and_write(raw: &str, idx: usize, out: &mut String) {
for line in raw.lines() {
for _ in 0..idx {
out.push_str(" ");
}
out.push_str(line);
out.push('\n');
}
}
fn determine_input(file: Option<String>, raw: Option<String>) -> Result<String> {
// Make sure not both are specified
if file.is_some() && raw.is_some() {
log::error!("Only one of --file or --raw should be specified.");
exit(0);
}
if let Some(raw) = raw {
return Ok(raw);
}
if let Some(file) = file {
return Ok(std::fs::read_to_string(&file)?);
}
// If neither exist, we try to read from stdin
if atty::is(atty::Stream::Stdin) {
return custom_error!("No input file, source, or stdin to translate from.");
}
let mut buffer = String::new();
std::io::stdin().read_to_string(&mut buffer).unwrap();
Ok(buffer.trim().to_string())
} }
#[test] #[test]
fn generates_svgs() { fn generates_svgs() {
use std::io::Write;
let st = include_str!("../../../tests/svg.html"); let st = include_str!("../../../tests/svg.html");
let out = format!("{:}", convert_html_to_component(st).unwrap()); let out = convert_html_to_formatted_rsx(&html_parser::Dom::parse(st).unwrap(), true);
dbg!(&out);
std::fs::File::create("svg_rsx.rs") println!("{}", out);
.unwrap()
.write_all(out.as_bytes())
.unwrap();
} }
+25 -13
View File
@@ -1,10 +1,11 @@
use crate::error::Result; use crate::error::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fs::File, io::Read, path::PathBuf}; use std::{collections::HashMap, path::PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DioxusConfig { pub struct DioxusConfig {
pub application: ApplicationConfig, pub application: ApplicationConfig,
pub web: WebConfig, pub web: WebConfig,
#[serde(default = "default_plugin")] #[serde(default = "default_plugin")]
@@ -16,23 +17,34 @@ fn default_plugin() -> toml::Value {
} }
impl DioxusConfig { impl DioxusConfig {
pub fn load() -> crate::error::Result<DioxusConfig> { pub fn load() -> crate::error::Result<Option<DioxusConfig>> {
let crate_dir = crate::cargo::crate_root()?; let crate_dir = crate::cargo::crate_root()?;
if !crate_dir.join("Dioxus.toml").is_file() { // we support either `Dioxus.toml` or `Cargo.toml`
log::warn!("Config file: `Dioxus.toml` not found; using default config."); let Some(dioxus_conf_file) = acquire_dioxus_toml(crate_dir) else {
return Ok(DioxusConfig::default()); return Ok(None);
} };
let mut dioxus_conf_file = File::open(crate_dir.join("Dioxus.toml"))?; toml::from_str::<DioxusConfig>(&std::fs::read_to_string(dioxus_conf_file)?)
let mut meta_str = String::new(); .map_err(|_| crate::Error::Unique("Dioxus.toml parse failed".into()))
dioxus_conf_file.read_to_string(&mut meta_str)?; .map(Some)
toml::from_str::<DioxusConfig>(&meta_str)
.map_err(|_| crate::Error::Unique("Dioxus.toml parse failed".into()))
} }
} }
fn acquire_dioxus_toml(dir: PathBuf) -> Option<PathBuf> {
// prefer uppercase
if dir.join("Dioxus.toml").is_file() {
return Some(dir.join("Dioxus.toml"));
}
// lowercase is fine too
if dir.join("dioxus.toml").is_file() {
return Some(dir.join("Dioxus.toml"));
}
None
}
impl Default for DioxusConfig { impl Default for DioxusConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
@@ -141,7 +153,7 @@ pub enum ExecutableType {
impl CrateConfig { impl CrateConfig {
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
let dioxus_config = DioxusConfig::load()?; let dioxus_config = DioxusConfig::load()?.unwrap_or_default();
let crate_dir = if let Some(package) = &dioxus_config.application.sub_package { let crate_dir = if let Some(package) = &dioxus_config.application.sub_package {
crate::cargo::crate_root()?.join(package) crate::cargo::crate_root()?.join(package)
+41 -58
View File
@@ -1,81 +1,64 @@
use anyhow::anyhow;
use clap::Parser; use clap::Parser;
use dioxus_cli::{plugin::PluginManager, *}; use dioxus_cli::{plugin::PluginManager, *};
use std::process::exit; use Commands::*;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> anyhow::Result<()> {
let args = Cli::parse(); let args = Cli::parse();
set_up_logging(); set_up_logging();
let dioxus_config = DioxusConfig::load().unwrap_or(DioxusConfig::default()); let dioxus_config = DioxusConfig::load()
.map_err(|e| anyhow!("Failed to load `dioxus.toml` because: {e}"))?
.unwrap_or_else(|| {
log::warn!("Your `dioxus.toml` could not be found. Using the default config. To set up this crate with dioxus, use `dioxus init`.");
DioxusConfig::default()
});
let plugin_state = PluginManager::init(dioxus_config.plugin); PluginManager::init(dioxus_config.plugin)
.map_err(|e| anyhow!("🚫 Plugin system initialization failed: {e}"))?;
if let Err(e) = plugin_state {
log::error!("🚫 Plugin system initialization failed: {e}");
exit(1);
}
match args.action { match args.action {
Commands::Translate(opts) => { Translate(opts) => opts
if let Err(e) = opts.translate() { .translate()
log::error!("🚫 Translate failed: {}", e); .map_err(|e| anyhow!("🚫 Translation of HTML into RSX failed: {}", e)),
exit(1);
}
}
Commands::Build(opts) => { Build(opts) => opts
if let Err(e) = opts.build() { .build()
log::error!("🚫 Build project failed: {}", e); .map_err(|e| anyhow!("🚫 Building project failed: {}", e)),
exit(1);
}
}
Commands::Clean(opts) => { Clean(opts) => opts
if let Err(e) = opts.clean() { .clean()
log::error!("🚫 Clean project failed: {}", e); .map_err(|e| anyhow!("🚫 Cleaning project failed: {}", e)),
exit(1);
}
}
Commands::Serve(opts) => { Serve(opts) => opts
if let Err(e) = opts.serve().await { .serve()
log::error!("🚫 Serve startup failed: {}", e); .await
exit(1); .map_err(|e| anyhow!("🚫 Serving project failed: {}", e)),
}
}
Commands::Create(opts) => { Create(opts) => opts
if let Err(e) = opts.create() { .create()
log::error!("🚫 Create project failed: {}", e); .map_err(|e| anyhow!("🚫 Creating new project failed: {}", e)),
exit(1);
}
}
Commands::Config(opts) => { Config(opts) => opts
if let Err(e) = opts.config() { .config()
log::error!("config error: {}", e); .map_err(|e| anyhow!("🚫 Configuring new project failed: {}", e)),
exit(1);
}
}
Commands::Plugin(opts) => { Plugin(opts) => opts
if let Err(e) = opts.plugin().await { .plugin()
log::error!("tool error: {}", e); .await
} .map_err(|e| anyhow!("🚫 Error with plugin: {}", e)),
}
Commands::Autoformat(opts) => { Autoformat(opts) => opts
if let Err(e) = opts.autoformat() { .autoformat()
log::error!("format error: {}", e); .map_err(|e| anyhow!("🚫 Error autoformatting RSX: {}", e)),
}
}
Commands::Version(opt) => { Version(opt) => {
let version = opt.version(); let version = opt.version();
println!("{}", version); println!("{}", version);
Ok(())
} }
} }
Ok(())
} }
-1
View File
@@ -37,7 +37,6 @@ impl UserData for PluginCommander {
methods.add_function( methods.add_function(
"exec", "exec",
|_, args: (Vec<String>, StdioFromString, StdioFromString)| { |_, args: (Vec<String>, StdioFromString, StdioFromString)| {
let cmd = args.0; let cmd = args.0;
let stdout = args.1; let stdout = args.1;
let stderr = args.2; let stderr = args.2;
+1 -1
View File
@@ -10,4 +10,4 @@ impl UserData for PluginDirs {
Ok(path.to_str().unwrap().to_string()) Ok(path.to_str().unwrap().to_string())
}); });
} }
} }
+8 -10
View File
@@ -1,13 +1,13 @@
use std::{ use std::{
fs::{create_dir, create_dir_all, remove_dir_all}, fs::{create_dir, create_dir_all, remove_dir_all, File},
path::PathBuf, io::{Read, Write}, io::{Read, Write},
path::PathBuf,
}; };
use std::fs::File;
use mlua::UserData;
use flate2::read::GzDecoder;
use tar::Archive;
use crate::tools::extract_zip; use crate::tools::extract_zip;
use flate2::read::GzDecoder;
use mlua::UserData;
use tar::Archive;
pub struct PluginFileSystem; pub struct PluginFileSystem;
impl UserData for PluginFileSystem { impl UserData for PluginFileSystem {
@@ -49,9 +49,9 @@ impl UserData for PluginFileSystem {
} }
if file.unwrap().write_all(content.as_bytes()).is_err() { if file.unwrap().write_all(content.as_bytes()).is_err() {
return Ok(false) return Ok(false);
} }
Ok(true) Ok(true)
}); });
methods.add_function("unzip_file", |_, args: (String, String)| { methods.add_function("unzip_file", |_, args: (String, String)| {
@@ -64,7 +64,6 @@ impl UserData for PluginFileSystem {
Ok(true) Ok(true)
}); });
methods.add_function("untar_gz_file", |_, args: (String, String)| { methods.add_function("untar_gz_file", |_, args: (String, String)| {
let file = PathBuf::from(args.0); let file = PathBuf::from(args.0);
let target = PathBuf::from(args.1); let target = PathBuf::from(args.1);
@@ -80,7 +79,6 @@ impl UserData for PluginFileSystem {
return Ok(false); return Ok(false);
} }
Ok(true) Ok(true)
}); });
} }
+1 -1
View File
@@ -25,4 +25,4 @@ impl UserData for PluginLogger {
Ok(()) Ok(())
}); });
} }
} }
+1 -1
View File
@@ -15,4 +15,4 @@ impl UserData for PluginOS {
} }
}); });
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@ impl UserData for PluginPath {
path = path.join(i); path = path.join(i);
} }
Ok(path.to_str().unwrap().to_string()) Ok(path.to_str().unwrap().to_string())
}); });
// parent function // parent function
methods.add_function("parent", |_, path: String| { methods.add_function("parent", |_, path: String| {
+4 -3
View File
@@ -13,10 +13,9 @@ use crate::{
}; };
use self::{ use self::{
interface::PluginInfo,
interface::{ interface::{
command::PluginCommander, dirs::PluginDirs, fs::PluginFileSystem, log::PluginLogger, command::PluginCommander, dirs::PluginDirs, fs::PluginFileSystem, log::PluginLogger,
network::PluginNetwork, os::PluginOS, path::PluginPath, network::PluginNetwork, os::PluginOS, path::PluginPath, PluginInfo,
}, },
types::PluginConfig, types::PluginConfig,
}; };
@@ -143,7 +142,9 @@ impl PluginManager {
} }
} }
Ok(false) => { Ok(false) => {
log::warn!("Plugin init function result is `false`, init failed."); log::warn!(
"Plugin init function result is `false`, init failed."
);
} }
Err(e) => { Err(e) => {
log::warn!("Plugin init failed: {e}"); log::warn!("Plugin init failed: {e}");
+2 -2
View File
@@ -252,8 +252,8 @@ impl Tool {
if self.target_platform() == "linux" { if self.target_platform() == "linux" {
// This code does not update permissions idk why // This code does not update permissions idk why
/*let mut perms = final_file.metadata()?.permissions(); // let mut perms = final_file.metadata()?.permissions();
perms.set_mode(0o744);*/ // perms.set_mode(0o744);
// Adding to the binary execution rights with "chmod" // Adding to the binary execution rights with "chmod"
let mut command = Command::new("chmod"); let mut command = Command::new("chmod");