diff --git a/.gitignore b/.gitignore index 96ef6c0b9..2e049011e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +.idea/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 5bbfd7ac2..3ae7b4610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dioxus-cli" -version = "0.1.2" +version = "0.1.3" authors = ["Jonathan Kelley"] edition = "2018" description = "CLI tool for developing, testing, and publishing Dioxus apps" @@ -9,31 +9,34 @@ license = "MIT/Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -thiserror = "1.0.23" -log = "0.4.13" -fern = { version = "0.6.0", features = ["colored"] } +# cli core +clap = {version = "3.0.14", features = ["derive"]} +thiserror = "1.0.30" wasm-bindgen-cli-support = "0.2.79" -anyhow = "1.0.38" -serde = { version = "1.0.133", features = ["derive"] } -serde_json = "1" +# features +log = "0.4.14" +fern = { version = "0.6.0", features = ["colored"] } +serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0.79" toml = "0.5.8" fs_extra = "1.2.0" -cargo_toml = "0.10.0" -futures = "0.3.12" +cargo_toml = "0.11.4" +futures = "0.3.21" notify = { version = "5.0.0-pre.13", features = ["serde"] } html_parser = "0.6.2" binary-install = "0.0.2" convert_case = "0.5.0" -structopt = "0.3.25" cargo_metadata = "0.14.1" -tokio = { version = "1.15.0", features = ["full"] } +tokio = { version = "1.16.1", features = ["full"] } atty = "0.2.14" regex = "1.5.4" chrono = "0.4.19" +anyhow = "1.0.53" +hyper = "0.14.17" -axum = { version = "0.4.4", features = ["ws", "headers"] } -tower-http = { version = "0.2.0", features = ["fs", "trace"] } -headers = "0.3" +axum = { version = "0.4.5", features = ["ws", "headers"] } +tower-http = { version = "0.2.2", features = ["fs", "trace"] } +headers = "0.3.7" # hyper = { version = "0.14.11", features = ["full"] } [[bin]] diff --git a/README.md b/README.md index 75e05b3cf..a939dfcaf 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,51 @@

๐Ÿ“ฆโœจ dioxus-cli

-

- Tooling to supercharge dioxus projects -

+

Tooling to supercharge dioxus projects

-![Dioxus Logo](https://dioxuslabs.com/guide/images/dioxuslogo_full.png) - - -# About - dioxus-cli (inspired by wasm-pack and webpack) is a tool to help get dioxus projects off the ground. It handles all the build, development, bundling, and publishing to make web development simple. - ## Installation -``` +```shell +# for stable $ cargo install dioxus-cli +# for latest +$ cargo install --git https://github.com/DioxusLabs/cli +# for developing +$ cargo install --path . --debug ``` -Now, `dioxus` is in your path. \ No newline at end of file +Now, `dioxus` is in your path, you can use `dioxus --help` to get the help document. + +``` +dioxus 0.1.2 +Build, bundle, & ship your Dioxus app + +USAGE: + dioxus [FLAGS] + +FLAGS: + -h, --help Prints help information + -v Enable verbose logging + -V, --version Prints version information + +SUBCOMMANDS: + build Build the Rust WASM app and all of its assets + clean Clean output artifacts + config Dioxus config file controls + create Init a new project for Dioxus + help Prints this message or the help of the given subcommand(s) + serve Build, watch & serve the Rust WASM app and all of its assets + translate Translate some source file into Dioxus code +``` + +## Get Started + +You can use the `dioxus create project_name` to init a dioxus project, its will be clone from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template). + +or you can assign the template path: + +``` +dioxus create hello --template gh:dioxuslabs/dioxus-template +``` diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 000000000..9071fb4b5 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,8 @@ +version = "Two" +edition = "2018" + +imports_granularity = "Crate" +#use_small_heuristics = "Max" +#control_brace_style = "ClosingNextLine" +normalize_comments = true +format_code_in_doc_comments = true \ No newline at end of file diff --git a/src/assets/dioxus.toml b/src/assets/dioxus.toml index 717b070e2..d3f160242 100644 --- a/src/assets/dioxus.toml +++ b/src/assets/dioxus.toml @@ -1,23 +1,24 @@ [application] -# App (Project) Name +# dioxus project name name = "{{project-name}}" -# Dioxus App Support Platform -# desktop, web, mobile, ssr -platforms = ["web"] +# default platfrom +# you can also use `dioxus serve/build --platform XXX` to use other platform +# value: web | desktop +default_platform = "web" # Web `build` & `serve` dist path out_dir = "dist" +# resource (static) file folder +asset_dir = "public" + [web.app] # HTML title tag content title = "dioxus | โ›บ" -# resource (static) file folder -public_dir = "public" - [web.watcher] watch_path = ["src"] diff --git a/src/builder.rs b/src/builder.rs index 257072a6a..708e1ce69 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -5,25 +5,24 @@ use crate::{ }; use std::{ fs::{copy, create_dir_all, remove_dir_all}, + panic, path::PathBuf, process::Command, }; use wasm_bindgen_cli_support::Bindgen; pub fn build(config: &CrateConfig) -> Result<()> { - /* - [1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?) - [2] Generate the appropriate build folders - [3] Wasm-bindgen the .wasm fiile, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm - [4] Wasm-opt the .wasm file with whatever optimizations need to be done - [5] Link up the html page to the wasm module - */ + // [1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?) + // [2] Generate the appropriate build folders + // [3] Wasm-bindgen the .wasm fiile, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm + // [4] Wasm-opt the .wasm file with whatever optimizations need to be done + // [5] Link up the html page to the wasm module let CrateConfig { out_dir, crate_dir, target_dir, - public_dir, + asset_dir, executable, dioxus_config, .. @@ -62,9 +61,6 @@ pub fn build(config: &CrateConfig) -> Result<()> { // [2] Establish the output directory structure let bindgen_outdir = out_dir.join("assets").join("dioxus"); - // [3] Bindgen the final binary for use easy linking - let mut bindgen_builder = Bindgen::new(); - let release_type = match config.release { true => "release", false => "debug", @@ -80,17 +76,27 @@ pub fn build(config: &CrateConfig) -> Result<()> { .join(format!("{}.wasm", name)), }; - bindgen_builder - .input_path(input_path) - .web(true)? - .debug(true) - .demangle(true) - .keep_debug(true) - .remove_name_section(false) - .remove_producers_section(false) - .out_name(&dioxus_config.application.name) - .generate(&bindgen_outdir)?; + let bindgen_result = panic::catch_unwind(move || { + // [3] Bindgen the final binary for use easy linking + let mut bindgen_builder = Bindgen::new(); + bindgen_builder + .input_path(input_path) + .web(true).unwrap() + .debug(true) + .demangle(true) + .keep_debug(true) + .remove_name_section(false) + .remove_producers_section(false) + .out_name(&dioxus_config.application.name) + .generate(&bindgen_outdir).unwrap(); + }); + if bindgen_result.is_err() { + log::error!("Bindgen build failed! \nThis is probably due to the Bindgen version, dioxus-cli using `0.2.79` Bindgen crate."); + } + + + // this code will copy all public file to the output dir let copy_options = fs_extra::dir::CopyOptions { overwrite: true, skip_exist: false, @@ -99,8 +105,8 @@ pub fn build(config: &CrateConfig) -> Result<()> { content_only: false, depth: 0, }; - if public_dir.is_dir() { - for entry in std::fs::read_dir(&public_dir)? { + if asset_dir.is_dir() { + for entry in std::fs::read_dir(&asset_dir)? { let path = entry?.path(); if path.is_file() { std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?; @@ -120,7 +126,7 @@ pub fn build(config: &CrateConfig) -> Result<()> { Ok(()) } -pub fn build_desktop(config: &CrateConfig) -> Result<()> { +pub fn build_desktop(config: &CrateConfig, is_serve: bool) -> Result<()> { log::info!("๐Ÿš… Running build [Desktop] command..."); let mut cmd = Command::new("cargo"); @@ -146,7 +152,9 @@ pub fn build_desktop(config: &CrateConfig) -> Result<()> { } if output.status.success() { - if config.out_dir.is_dir() { + // this code will clean the output dir. + // if using the serve, we will not clean the out_dir. + if config.out_dir.is_dir() && !is_serve { remove_dir_all(&config.out_dir)?; } @@ -181,9 +189,37 @@ pub fn build_desktop(config: &CrateConfig) -> Result<()> { file_name }; - create_dir_all(&config.out_dir)?; + if !config.out_dir.is_dir() { + create_dir_all(&config.out_dir)?; + } copy(res_path, &config.out_dir.join(target_file))?; + // this code will copy all public file to the output dir + if config.asset_dir.is_dir() { + let copy_options = fs_extra::dir::CopyOptions { + overwrite: true, + skip_exist: false, + buffer_size: 64000, + copy_inside: false, + content_only: false, + depth: 0, + }; + + for entry in std::fs::read_dir(&config.asset_dir)? { + let path = entry?.path(); + if path.is_file() { + std::fs::copy(&path, &config.out_dir.join(path.file_name().unwrap()))?; + } else { + match fs_extra::dir::copy(&path, &config.out_dir, ©_options) { + Ok(_) => {} + Err(e) => { + log::warn!("Error copying dir: {}", e); + } + } + } + } + } + log::info!( "๐Ÿšฉ Build completed: [./{}]", config diff --git a/src/cli/build/mod.rs b/src/cli/build/mod.rs index 684cec58c..4c043091f 100644 --- a/src/cli/build/mod.rs +++ b/src/cli/build/mod.rs @@ -1,36 +1,41 @@ -use std::{io::Write, path::PathBuf}; - -use crate::{cfg::ConfigOptsBuild, gen_page}; -use structopt::StructOpt; +use super::*; /// Build the Rust WASM app and all of its assets. -#[derive(Clone, Debug, StructOpt)] -#[structopt(name = "build")] +#[derive(Clone, Debug, Parser)] +#[clap(name = "build")] pub struct Build { - #[structopt(flatten)] + #[clap(flatten)] pub build: ConfigOptsBuild, } impl Build { - pub fn build(self) -> anyhow::Result<()> { + pub fn build(self) -> Result<()> { let mut crate_config = crate::CrateConfig::new()?; - // change the relase state. + // change the release state. crate_config.with_release(self.build.release); if self.build.example.is_some() { crate_config.as_example(self.build.example.unwrap()); } - match self.build.platform.as_str() { + let platform = self.build.platform.unwrap_or_else(|| { + crate_config + .dioxus_config + .application + .default_platform + .clone() + }); + + match platform.as_str() { "web" => { crate::builder::build(&crate_config)?; } "desktop" => { - crate::builder::build_desktop(&crate_config)?; + crate::builder::build_desktop(&crate_config, false)?; } _ => { - return Err(anyhow::anyhow!("Unsoppurt platform target.")); + return custom_error!("Unsoppurt platform target."); } } diff --git a/src/cli/cfg.rs b/src/cli/cfg.rs index ece00e07e..f5ee45b87 100644 --- a/src/cli/cfg.rs +++ b/src/cli/cfg.rs @@ -1,47 +1,44 @@ -use std::path::PathBuf; -use structopt::StructOpt; - -use serde::Deserialize; +use super::*; /// Config options for the build system. -#[derive(Clone, Debug, Default, Deserialize, StructOpt)] +#[derive(Clone, Debug, Default, Deserialize, Parser)] pub struct ConfigOptsBuild { /// The index HTML file to drive the bundling process [default: index.html] - #[structopt(parse(from_os_str))] + #[clap(parse(from_os_str))] pub target: Option, /// Build in release mode [default: false] - #[structopt(long)] + #[clap(long)] #[serde(default)] pub release: bool, /// Build a example [default: ""] - #[structopt(long)] + #[clap(long)] pub example: Option, - /// Build platform: support Web & Desktop [default: "web"] - #[structopt(long, default_value = "web")] - pub platform: String, + /// Build platform: support Web & Desktop [default: "default_platform"] + #[clap(long)] + pub platform: Option, } -#[derive(Clone, Debug, Default, Deserialize, StructOpt)] +#[derive(Clone, Debug, Default, Deserialize, Parser)] pub struct ConfigOptsServe { /// The index HTML file to drive the bundling process [default: index.html] - #[structopt(parse(from_os_str))] + #[clap(parse(from_os_str))] pub target: Option, /// Build a example [default: ""] - #[structopt(long)] + #[clap(long)] pub example: Option, /// Build in release mode [default: false] - #[structopt(long)] + #[clap(long)] #[serde(default)] pub release: bool, - /// Build platform: support Web & Desktop [default: "web"] - #[structopt(long, default_value = "web")] - pub platform: String, + /// Build platform: support Web & Desktop [default: "default_platform"] + #[clap(long)] + pub platform: Option, } /// Ensure the given value for `--public-url` is formatted correctly. diff --git a/src/cli/clean/mod.rs b/src/cli/clean/mod.rs index 62593b1ee..74a99fec2 100644 --- a/src/cli/clean/mod.rs +++ b/src/cli/clean/mod.rs @@ -1,18 +1,12 @@ -use std::{ - fs::remove_dir_all, - path::PathBuf, - process::{Command, Stdio}, -}; - -use structopt::StructOpt; +use super::*; /// Build the Rust WASM app and all of its assets. -#[derive(Clone, Debug, StructOpt)] -#[structopt(name = "clean")] +#[derive(Clone, Debug, Parser)] +#[clap(name = "clean")] pub struct Clean {} impl Clean { - pub fn clean(self) -> anyhow::Result<()> { + pub fn clean(self) -> Result<()> { let crate_config = crate::CrateConfig::new()?; let output = Command::new("cargo") diff --git a/src/cli/config/mod.rs b/src/cli/config/mod.rs index d5291a7d6..6d672b7a5 100644 --- a/src/cli/config/mod.rs +++ b/src/cli/config/mod.rs @@ -1,11 +1,8 @@ -use std::{fs::File, io::Write}; - -use serde::Deserialize; -use structopt::StructOpt; +use super::*; /// Build the Rust WASM app and all of its assets. -#[derive(Clone, Debug, Deserialize, StructOpt)] -#[structopt(name = "config")] +#[derive(Clone, Debug, Deserialize, Subcommand)] +#[clap(name = "config")] pub enum Config { /// Init `Dioxus.toml` for project/folder. Init { @@ -13,14 +10,14 @@ pub enum Config { name: String, /// Cover old config - #[structopt(long)] + #[clap(long)] #[serde(default)] force: bool, }, } impl Config { - pub fn config(self) -> anyhow::Result<()> { + pub fn config(self) -> Result<()> { let crate_root = crate::cargo::crate_root()?; match self { Config::Init { name, force } => { diff --git a/src/cli/create/mod.rs b/src/cli/create/mod.rs index fa553c55a..f00bc5dd9 100644 --- a/src/cli/create/mod.rs +++ b/src/cli/create/mod.rs @@ -1,26 +1,16 @@ -use std::{ - fs::File, - io::{Read, Write}, - path::PathBuf, - process::{Command, Stdio}, -}; - -use regex::Regex; -use serde::Deserialize; -use structopt::StructOpt; - -use crate::{error::Result, Error}; +use super::*; +use crate::custom_error; /// Build the Rust WASM app and all of its assets. -#[derive(Clone, Debug, Default, Deserialize, StructOpt)] -#[structopt(name = "create")] +#[derive(Clone, Debug, Default, Deserialize, Parser)] +#[clap(name = "create")] pub struct Create { /// Init project name - #[structopt(default_value = ".")] + #[clap(default_value = ".")] name: String, /// Template path - #[structopt(default_value = "gh:dioxuslabs/dioxus-template", long)] + #[clap(default_value = "gh:dioxuslabs/dioxus-template", long)] template: String, } @@ -34,10 +24,7 @@ impl Create { let project_path = PathBuf::from(&self.name); if project_path.join("Dioxus.toml").is_file() || project_path.join("Cargo.toml").is_file() { - return Err(Error::Other(anyhow::anyhow!( - "๐Ÿงจ Folder '{}' is initialized.", - &self.name - ))); + return custom_error!("๐Ÿงจ Folder '{}' is initialized.", &self.name); } log::info!("๐Ÿ”ง Start to create a new project '{}'.", self.name); @@ -58,9 +45,7 @@ impl Create { .stderr(Stdio::inherit()) .output()?; if !install_output.status.success() { - return Err(Error::Other(anyhow::anyhow!( - "Try to install cargo-generate failed." - ))); + return custom_error!("Try to install cargo-generate failed."); } } @@ -74,7 +59,7 @@ impl Create { .output()?; if !generate_output.status.success() { - return Err(Error::Other(anyhow::anyhow!("Generate project failed."))); + return custom_error!("Generate project failed."); } let mut dioxus_file = File::open(project_path.join("Dioxus.toml"))?; diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 4a72e00ac..1b5ba0be7 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,5 +1,3 @@ -use structopt::StructOpt; - pub mod build; pub mod cfg; pub mod clean; @@ -8,26 +6,41 @@ pub mod create; pub mod serve; pub mod translate; +use crate::{ + cfg::{ConfigOptsBuild, ConfigOptsServe}, + custom_error, + error::Result, + gen_page, server, CrateConfig, Error, +}; +use clap::{Parser, Subcommand}; +use html_parser::{Dom, Element, Node}; +use regex::Regex; +use serde::Deserialize; +use std::{ + fmt::{Display, Formatter}, + fs::{remove_dir_all, File}, + io::{Read, Write}, + path::PathBuf, + process::{exit, Command, Stdio}, +}; + /// Build, bundle, & ship your Dioxus app. -/// -/// -#[derive(StructOpt)] -#[structopt(name = "dioxus")] +#[derive(Parser)] +#[clap(name = "dioxus")] pub struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] pub action: Commands, /// Enable verbose logging. - #[structopt(short)] + #[clap(short)] pub v: bool, - // // // note: dioxus is still roughly compatible with trunk // /// Path to the Trunk config file [default: Trunk.toml] - // #[structopt(long, parse(from_os_str), env = "TRUNK_CONFIG")] + // #[clap(long, parse(from_os_str), env = "TRUNK_CONFIG")] // pub config: Option, } -#[derive(StructOpt)] +#[derive(Parser)] pub enum Commands { /// Build the Rust WASM app and all of its assets. Build(build::Build), @@ -40,5 +53,6 @@ pub enum Commands { /// Clean output artifacts. Clean(clean::Clean), /// Dioxus config file controls. + #[clap(subcommand)] Config(config::Config), } diff --git a/src/cli/serve/mod.rs b/src/cli/serve/mod.rs index 8f26e0f30..21d29cd93 100644 --- a/src/cli/serve/mod.rs +++ b/src/cli/serve/mod.rs @@ -1,17 +1,20 @@ -use crate::{cfg::ConfigOptsServe, gen_page, server, CrateConfig}; -use std::{io::Write, path::PathBuf, process::{Command, Stdio}}; -use structopt::StructOpt; +use std::{ + io::Write, + path::PathBuf, + process::{Command, Stdio}, +}; +use super::*; /// Run the WASM project on dev-server -#[derive(Clone, Debug, StructOpt)] -#[structopt(name = "serve")] +#[derive(Clone, Debug, Parser)] +#[clap(name = "serve")] pub struct Serve { - #[structopt(flatten)] + #[clap(flatten)] pub serve: ConfigOptsServe, } impl Serve { - pub async fn serve(self) -> anyhow::Result<()> { + pub async fn serve(self) -> Result<()> { let mut crate_config = crate::CrateConfig::new()?; // change the relase state. @@ -21,12 +24,20 @@ impl Serve { crate_config.as_example(self.serve.example.unwrap()); } - match self.serve.platform.as_str() { + let platform = self.serve.platform.unwrap_or_else(|| { + crate_config + .dioxus_config + .application + .default_platform + .clone() + }); + + match platform.as_str() { "web" => { crate::builder::build(&crate_config)?; } "desktop" => { - crate::builder::build_desktop(&crate_config)?; + crate::builder::build_desktop(&crate_config, true)?; match &crate_config.executable { crate::ExecutableType::Binary(name) @@ -51,7 +62,7 @@ impl Serve { return Ok(()); } _ => { - return Err(anyhow::anyhow!("Unsoppurt platform target.")); + return custom_error!("Unsoppurt platform target."); } } @@ -64,7 +75,7 @@ impl Serve { Ok(()) } - pub fn regen_dev_page(crate_config: &CrateConfig) -> anyhow::Result<()> { + pub fn regen_dev_page(crate_config: &CrateConfig) -> Result<()> { let serve_html = gen_page(&crate_config.dioxus_config, true); let mut file = std::fs::File::create( diff --git a/src/cli/translate/mod.rs b/src/cli/translate/mod.rs index 3e1f1057c..e239ce318 100644 --- a/src/cli/translate/mod.rs +++ b/src/cli/translate/mod.rs @@ -1,34 +1,25 @@ -use anyhow::Result; -use html_parser::Dom; -use html_parser::Element; -use html_parser::Node; -#[allow(unused_imports)] -use std::fmt::{Display, Formatter}; -use std::io::Read; -use std::path::PathBuf; -use std::process::exit; -use structopt::StructOpt; +use super::*; /// Build the Rust WASM app and all of its assets. -#[derive(Clone, Debug, StructOpt)] -#[structopt(name = "translate")] +#[derive(Clone, Debug, Parser)] +#[clap(name = "translate")] pub struct Translate { /// Activate debug mode // short and long flags (-d, --debug) will be deduced from the field's name - #[structopt(short, long)] + #[clap(short, long)] pub component: bool, /// Input file - #[structopt(short, long)] + #[clap(short, long)] pub file: Option, /// Output file, stdout if not present - #[structopt(short, long)] + #[clap(parse(from_os_str))] pub output: Option, } impl Translate { - pub fn translate(self) -> anyhow::Result<()> { + pub fn translate(self) -> Result<()> { let Translate { component, output, diff --git a/src/config.rs b/src/config.rs index 1151445ef..ba0427191 100644 --- a/src/config.rs +++ b/src/config.rs @@ -31,13 +31,13 @@ impl Default for DioxusConfig { Self { application: ApplicationConfig { name: "dioxus".into(), - platforms: vec![String::from("web")], + default_platform: "web".to_string(), out_dir: Some(PathBuf::from("dist")), + asset_dir: Some(PathBuf::from("public")), }, web: WebConfig { app: WebAppConfing { title: Some("dioxus | โ›บ".into()), - public_dir: Some(PathBuf::from("public")), }, watcher: WebWatcherConfing { watch_path: Some(vec![PathBuf::from("src")]), @@ -59,8 +59,9 @@ impl Default for DioxusConfig { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationConfig { pub name: String, - pub platforms: Vec, + pub default_platform: String, pub out_dir: Option, + pub asset_dir: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -73,7 +74,6 @@ pub struct WebConfig { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WebAppConfing { pub title: Option, - pub public_dir: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -101,7 +101,7 @@ pub struct CrateConfig { pub crate_dir: PathBuf, pub workspace_dir: PathBuf, pub target_dir: PathBuf, - pub public_dir: PathBuf, + pub asset_dir: PathBuf, pub manifest: cargo_toml::Manifest, pub executable: ExecutableType, pub dioxus_config: DioxusConfig, @@ -130,7 +130,7 @@ impl CrateConfig { let cargo_def = &crate_dir.join("Cargo.toml"); - let public_dir = match dioxus_config.web.app.public_dir { + let asset_dir = match dioxus_config.application.asset_dir { Some(ref v) => crate_dir.join(v), None => crate_dir.join("public"), }; @@ -154,7 +154,7 @@ impl CrateConfig { crate_dir, workspace_dir, target_dir, - public_dir, + asset_dir, manifest, executable, release, diff --git a/src/error.rs b/src/error.rs index 8684abf74..d40868333 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,6 +11,15 @@ pub enum Error { #[error("I/O Error: {0}")] IO(#[from] std::io::Error), + #[error("Format Error: {0}")] + FormatError(#[from] std::fmt::Error), + + #[error("Format failed: {0}")] + ParseError(String), + + #[error("Runtime Error: {0}")] + RuntimeError(String), + #[error("Failed to write error")] FailedToWrite, @@ -20,6 +29,9 @@ pub enum Error { #[error("Failed to write error")] CargoError(String), + #[error("{0}")] + CustomError(String), + #[error(transparent)] Other(#[from] anyhow::Error), } @@ -35,3 +47,28 @@ impl From for Error { Error::Unique(s) } } + +impl From for Error { + fn from(e: html_parser::Error) -> Self { + Self::ParseError(e.to_string()) + } +} + +impl From for Error { + fn from(e: hyper::Error) -> Self { + Self::RuntimeError(e.to_string()) + } +} + +#[macro_export] +macro_rules! custom_error { + ($msg:literal $(,)?) => { + Err(Error::CustomError($msg.to_string())) + }; + ($err:expr $(,)?) => { + Err(Error::from($err)) + }; + ($fmt:expr, $($arg:tt)*) => { + Err(Error::CustomError(format!($fmt, $($arg)*))) + }; +} diff --git a/src/main.rs b/src/main.rs index 6b8c177db..97d4a3bb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ +use clap::Parser; use dioxus_cli::*; -use structopt::StructOpt; #[tokio::main] async fn main() -> Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); set_up_logging(); match args.action { diff --git a/src/server/mod.rs b/src/server/mod.rs index 880f25ceb..38e37d60b 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -10,14 +10,14 @@ use notify::{RecommendedWatcher, Watcher}; use std::{path::PathBuf, sync::Arc}; use tower_http::services::ServeDir; -use crate::{builder, serve::Serve, CrateConfig}; +use crate::{builder, serve::Serve, CrateConfig, Result}; use tokio::sync::broadcast; struct WsRelodState { update: broadcast::Sender, } -pub async fn startup(config: CrateConfig) -> anyhow::Result<()> { +pub async fn startup(config: CrateConfig) -> Result<()> { log::info!("๐Ÿš€ Starting development server..."); let dist_path = config.out_dir.clone(); diff --git a/tests/main.rs b/tests/main.rs new file mode 100644 index 000000000..1849f5dc8 --- /dev/null +++ b/tests/main.rs @@ -0,0 +1,4 @@ +#[test] +fn ready() { + println!("Compiled successfully!") +}