diff --git a/README.md b/README.md index ab4cf1225..33d1d4932 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,10 @@

📦✨ 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 @@ -24,4 +16,36 @@ $ cargo install --git https://github.com/DioxusLabs/cli $ 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.exe [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 crate 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 +``` \ 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 f3090f85d..708e1ce69 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -5,6 +5,7 @@ use crate::{ }; use std::{ fs::{copy, create_dir_all, remove_dir_all}, + panic, path::PathBuf, process::Command, }; @@ -21,7 +22,7 @@ pub fn build(config: &CrateConfig) -> Result<()> { out_dir, crate_dir, target_dir, - public_dir, + asset_dir, executable, dioxus_config, .. @@ -60,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", @@ -78,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, @@ -97,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()))?; @@ -118,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"); @@ -144,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)?; } @@ -179,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 1c665abd3..4c043091f 100644 --- a/src/cli/build/mod.rs +++ b/src/cli/build/mod.rs @@ -19,12 +19,20 @@ impl Build { 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 custom_error!("Unsoppurt platform target."); diff --git a/src/cli/cfg.rs b/src/cli/cfg.rs index f1e3d0845..f5ee45b87 100644 --- a/src/cli/cfg.rs +++ b/src/cli/cfg.rs @@ -16,9 +16,9 @@ pub struct ConfigOptsBuild { #[clap(long)] pub example: Option, - /// Build platform: support Web & Desktop [default: "web"] - #[clap(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, Parser)] @@ -36,9 +36,9 @@ pub struct ConfigOptsServe { #[serde(default)] pub release: bool, - /// Build platform: support Web & Desktop [default: "web"] - #[clap(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/serve/mod.rs b/src/cli/serve/mod.rs index d627ace47..21d29cd93 100644 --- a/src/cli/serve/mod.rs +++ b/src/cli/serve/mod.rs @@ -1,3 +1,8 @@ +use std::{ + io::Write, + path::PathBuf, + process::{Command, Stdio}, +}; use super::*; /// Run the WASM project on dev-server @@ -19,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) 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,