Merge branch 'master' of https://github.com/jkelleyrtp/dioxus-studio
This commit is contained in:
commit
1e24b5b416
19 files changed
+292
-179
No files matched your search
@@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
.idea/
|
||||||
+17
-14
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "dioxus-cli"
|
name = "dioxus-cli"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
authors = ["Jonathan Kelley"]
|
authors = ["Jonathan Kelley"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "CLI tool for developing, testing, and publishing Dioxus apps"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = "1.0.23"
|
# cli core
|
||||||
log = "0.4.13"
|
clap = {version = "3.0.14", features = ["derive"]}
|
||||||
fern = { version = "0.6.0", features = ["colored"] }
|
thiserror = "1.0.30"
|
||||||
wasm-bindgen-cli-support = "0.2.79"
|
wasm-bindgen-cli-support = "0.2.79"
|
||||||
anyhow = "1.0.38"
|
# features
|
||||||
serde = { version = "1.0.133", features = ["derive"] }
|
log = "0.4.14"
|
||||||
serde_json = "1"
|
fern = { version = "0.6.0", features = ["colored"] }
|
||||||
|
serde = { version = "1.0.136", features = ["derive"] }
|
||||||
|
serde_json = "1.0.79"
|
||||||
toml = "0.5.8"
|
toml = "0.5.8"
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
cargo_toml = "0.10.0"
|
cargo_toml = "0.11.4"
|
||||||
futures = "0.3.12"
|
futures = "0.3.21"
|
||||||
notify = { version = "5.0.0-pre.13", features = ["serde"] }
|
notify = { version = "5.0.0-pre.13", features = ["serde"] }
|
||||||
html_parser = "0.6.2"
|
html_parser = "0.6.2"
|
||||||
binary-install = "0.0.2"
|
binary-install = "0.0.2"
|
||||||
convert_case = "0.5.0"
|
convert_case = "0.5.0"
|
||||||
structopt = "0.3.25"
|
|
||||||
cargo_metadata = "0.14.1"
|
cargo_metadata = "0.14.1"
|
||||||
tokio = { version = "1.15.0", features = ["full"] }
|
tokio = { version = "1.16.1", features = ["full"] }
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
regex = "1.5.4"
|
regex = "1.5.4"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
|
anyhow = "1.0.53"
|
||||||
|
hyper = "0.14.17"
|
||||||
|
|
||||||
axum = { version = "0.4.4", features = ["ws", "headers"] }
|
axum = { version = "0.4.5", features = ["ws", "headers"] }
|
||||||
tower-http = { version = "0.2.0", features = ["fs", "trace"] }
|
tower-http = { version = "0.2.2", features = ["fs", "trace"] }
|
||||||
headers = "0.3"
|
headers = "0.3.7"
|
||||||
# hyper = { version = "0.14.11", features = ["full"] }
|
# hyper = { version = "0.14.11", features = ["full"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|||||||
@@ -1,22 +1,51 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<h1>📦✨ dioxus-cli </h1>
|
<h1>📦✨ dioxus-cli </h1>
|
||||||
<p>
|
<p><strong>Tooling to supercharge dioxus projects</strong></p>
|
||||||
<strong>Tooling to supercharge dioxus projects</strong>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
# 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.
|
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
|
## Installation
|
||||||
|
|
||||||
```
|
```shell
|
||||||
|
# for stable
|
||||||
$ cargo install dioxus-cli
|
$ 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.
|
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] <SUBCOMMAND>
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
@@ -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
|
||||||
@@ -1,23 +1,24 @@
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
# App (Project) Name
|
# dioxus project name
|
||||||
name = "{{project-name}}"
|
name = "{{project-name}}"
|
||||||
|
|
||||||
# Dioxus App Support Platform
|
# default platfrom
|
||||||
# desktop, web, mobile, ssr
|
# you can also use `dioxus serve/build --platform XXX` to use other platform
|
||||||
platforms = ["web"]
|
# value: web | desktop
|
||||||
|
default_platform = "web"
|
||||||
|
|
||||||
# Web `build` & `serve` dist path
|
# Web `build` & `serve` dist path
|
||||||
out_dir = "dist"
|
out_dir = "dist"
|
||||||
|
|
||||||
|
# resource (static) file folder
|
||||||
|
asset_dir = "public"
|
||||||
|
|
||||||
[web.app]
|
[web.app]
|
||||||
|
|
||||||
# HTML title tag content
|
# HTML title tag content
|
||||||
title = "dioxus | ⛺"
|
title = "dioxus | ⛺"
|
||||||
|
|
||||||
# resource (static) file folder
|
|
||||||
public_dir = "public"
|
|
||||||
|
|
||||||
[web.watcher]
|
[web.watcher]
|
||||||
|
|
||||||
watch_path = ["src"]
|
watch_path = ["src"]
|
||||||
|
|||||||
+62
-26
@@ -5,25 +5,24 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{copy, create_dir_all, remove_dir_all},
|
fs::{copy, create_dir_all, remove_dir_all},
|
||||||
|
panic,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
use wasm_bindgen_cli_support::Bindgen;
|
use wasm_bindgen_cli_support::Bindgen;
|
||||||
|
|
||||||
pub fn build(config: &CrateConfig) -> Result<()> {
|
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?)
|
||||||
[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
|
||||||
[2] Generate the appropriate build folders
|
// [3] Wasm-bindgen the .wasm fiile, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm
|
||||||
[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
|
||||||
[4] Wasm-opt the .wasm file with whatever optimizations need to be done
|
// [5] Link up the html page to the wasm module
|
||||||
[5] Link up the html page to the wasm module
|
|
||||||
*/
|
|
||||||
|
|
||||||
let CrateConfig {
|
let CrateConfig {
|
||||||
out_dir,
|
out_dir,
|
||||||
crate_dir,
|
crate_dir,
|
||||||
target_dir,
|
target_dir,
|
||||||
public_dir,
|
asset_dir,
|
||||||
executable,
|
executable,
|
||||||
dioxus_config,
|
dioxus_config,
|
||||||
..
|
..
|
||||||
@@ -62,9 +61,6 @@ pub fn build(config: &CrateConfig) -> Result<()> {
|
|||||||
// [2] Establish the output directory structure
|
// [2] Establish the output directory structure
|
||||||
let bindgen_outdir = out_dir.join("assets").join("dioxus");
|
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 {
|
let release_type = match config.release {
|
||||||
true => "release",
|
true => "release",
|
||||||
false => "debug",
|
false => "debug",
|
||||||
@@ -80,17 +76,27 @@ pub fn build(config: &CrateConfig) -> Result<()> {
|
|||||||
.join(format!("{}.wasm", name)),
|
.join(format!("{}.wasm", name)),
|
||||||
};
|
};
|
||||||
|
|
||||||
bindgen_builder
|
let bindgen_result = panic::catch_unwind(move || {
|
||||||
.input_path(input_path)
|
// [3] Bindgen the final binary for use easy linking
|
||||||
.web(true)?
|
let mut bindgen_builder = Bindgen::new();
|
||||||
.debug(true)
|
|
||||||
.demangle(true)
|
|
||||||
.keep_debug(true)
|
|
||||||
.remove_name_section(false)
|
|
||||||
.remove_producers_section(false)
|
|
||||||
.out_name(&dioxus_config.application.name)
|
|
||||||
.generate(&bindgen_outdir)?;
|
|
||||||
|
|
||||||
|
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 {
|
let copy_options = fs_extra::dir::CopyOptions {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
skip_exist: false,
|
skip_exist: false,
|
||||||
@@ -99,8 +105,8 @@ pub fn build(config: &CrateConfig) -> Result<()> {
|
|||||||
content_only: false,
|
content_only: false,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
};
|
};
|
||||||
if public_dir.is_dir() {
|
if asset_dir.is_dir() {
|
||||||
for entry in std::fs::read_dir(&public_dir)? {
|
for entry in std::fs::read_dir(&asset_dir)? {
|
||||||
let path = entry?.path();
|
let path = entry?.path();
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?;
|
std::fs::copy(&path, out_dir.join(path.file_name().unwrap()))?;
|
||||||
@@ -120,7 +126,7 @@ pub fn build(config: &CrateConfig) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_desktop(config: &CrateConfig) -> Result<()> {
|
pub fn build_desktop(config: &CrateConfig, is_serve: bool) -> Result<()> {
|
||||||
log::info!("🚅 Running build [Desktop] command...");
|
log::info!("🚅 Running build [Desktop] command...");
|
||||||
|
|
||||||
let mut cmd = Command::new("cargo");
|
let mut cmd = Command::new("cargo");
|
||||||
@@ -146,7 +152,9 @@ pub fn build_desktop(config: &CrateConfig) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if output.status.success() {
|
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)?;
|
remove_dir_all(&config.out_dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,9 +189,37 @@ pub fn build_desktop(config: &CrateConfig) -> Result<()> {
|
|||||||
file_name
|
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))?;
|
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!(
|
log::info!(
|
||||||
"🚩 Build completed: [./{}]",
|
"🚩 Build completed: [./{}]",
|
||||||
config
|
config
|
||||||
|
|||||||
+17
-12
@@ -1,36 +1,41 @@
|
|||||||
use std::{io::Write, path::PathBuf};
|
use super::*;
|
||||||
|
|
||||||
use crate::{cfg::ConfigOptsBuild, gen_page};
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
#[derive(Clone, Debug, StructOpt)]
|
#[derive(Clone, Debug, Parser)]
|
||||||
#[structopt(name = "build")]
|
#[clap(name = "build")]
|
||||||
pub struct Build {
|
pub struct Build {
|
||||||
#[structopt(flatten)]
|
#[clap(flatten)]
|
||||||
pub build: ConfigOptsBuild,
|
pub build: ConfigOptsBuild,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Build {
|
impl Build {
|
||||||
pub fn build(self) -> anyhow::Result<()> {
|
pub fn build(self) -> Result<()> {
|
||||||
let mut crate_config = crate::CrateConfig::new()?;
|
let mut crate_config = crate::CrateConfig::new()?;
|
||||||
|
|
||||||
// change the relase state.
|
// change the release state.
|
||||||
crate_config.with_release(self.build.release);
|
crate_config.with_release(self.build.release);
|
||||||
|
|
||||||
if self.build.example.is_some() {
|
if self.build.example.is_some() {
|
||||||
crate_config.as_example(self.build.example.unwrap());
|
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" => {
|
"web" => {
|
||||||
crate::builder::build(&crate_config)?;
|
crate::builder::build(&crate_config)?;
|
||||||
}
|
}
|
||||||
"desktop" => {
|
"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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-18
@@ -1,47 +1,44 @@
|
|||||||
use std::path::PathBuf;
|
use super::*;
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
/// Config options for the build system.
|
/// Config options for the build system.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, StructOpt)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
pub struct ConfigOptsBuild {
|
pub struct ConfigOptsBuild {
|
||||||
/// The index HTML file to drive the bundling process [default: index.html]
|
/// 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<PathBuf>,
|
pub target: Option<PathBuf>,
|
||||||
|
|
||||||
/// Build in release mode [default: false]
|
/// Build in release mode [default: false]
|
||||||
#[structopt(long)]
|
#[clap(long)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
|
|
||||||
/// Build a example [default: ""]
|
/// Build a example [default: ""]
|
||||||
#[structopt(long)]
|
#[clap(long)]
|
||||||
pub example: Option<String>,
|
pub example: Option<String>,
|
||||||
|
|
||||||
/// Build platform: support Web & Desktop [default: "web"]
|
/// Build platform: support Web & Desktop [default: "default_platform"]
|
||||||
#[structopt(long, default_value = "web")]
|
#[clap(long)]
|
||||||
pub platform: String,
|
pub platform: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, StructOpt)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
pub struct ConfigOptsServe {
|
pub struct ConfigOptsServe {
|
||||||
/// The index HTML file to drive the bundling process [default: index.html]
|
/// 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<PathBuf>,
|
pub target: Option<PathBuf>,
|
||||||
|
|
||||||
/// Build a example [default: ""]
|
/// Build a example [default: ""]
|
||||||
#[structopt(long)]
|
#[clap(long)]
|
||||||
pub example: Option<String>,
|
pub example: Option<String>,
|
||||||
|
|
||||||
/// Build in release mode [default: false]
|
/// Build in release mode [default: false]
|
||||||
#[structopt(long)]
|
#[clap(long)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub release: bool,
|
pub release: bool,
|
||||||
|
|
||||||
/// Build platform: support Web & Desktop [default: "web"]
|
/// Build platform: support Web & Desktop [default: "default_platform"]
|
||||||
#[structopt(long, default_value = "web")]
|
#[clap(long)]
|
||||||
pub platform: String,
|
pub platform: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure the given value for `--public-url` is formatted correctly.
|
/// Ensure the given value for `--public-url` is formatted correctly.
|
||||||
|
|||||||
+4
-10
@@ -1,18 +1,12 @@
|
|||||||
use std::{
|
use super::*;
|
||||||
fs::remove_dir_all,
|
|
||||||
path::PathBuf,
|
|
||||||
process::{Command, Stdio},
|
|
||||||
};
|
|
||||||
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
#[derive(Clone, Debug, StructOpt)]
|
#[derive(Clone, Debug, Parser)]
|
||||||
#[structopt(name = "clean")]
|
#[clap(name = "clean")]
|
||||||
pub struct Clean {}
|
pub struct Clean {}
|
||||||
|
|
||||||
impl Clean {
|
impl Clean {
|
||||||
pub fn clean(self) -> anyhow::Result<()> {
|
pub fn clean(self) -> Result<()> {
|
||||||
let crate_config = crate::CrateConfig::new()?;
|
let crate_config = crate::CrateConfig::new()?;
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let output = Command::new("cargo")
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
use std::{fs::File, io::Write};
|
use super::*;
|
||||||
|
|
||||||
use serde::Deserialize;
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
#[derive(Clone, Debug, Deserialize, StructOpt)]
|
#[derive(Clone, Debug, Deserialize, Subcommand)]
|
||||||
#[structopt(name = "config")]
|
#[clap(name = "config")]
|
||||||
pub enum Config {
|
pub enum Config {
|
||||||
/// Init `Dioxus.toml` for project/folder.
|
/// Init `Dioxus.toml` for project/folder.
|
||||||
Init {
|
Init {
|
||||||
@@ -13,14 +10,14 @@ pub enum Config {
|
|||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
/// Cover old config
|
/// Cover old config
|
||||||
#[structopt(long)]
|
#[clap(long)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
force: bool,
|
force: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn config(self) -> anyhow::Result<()> {
|
pub fn config(self) -> Result<()> {
|
||||||
let crate_root = crate::cargo::crate_root()?;
|
let crate_root = crate::cargo::crate_root()?;
|
||||||
match self {
|
match self {
|
||||||
Config::Init { name, force } => {
|
Config::Init { name, force } => {
|
||||||
|
|||||||
+9
-24
@@ -1,26 +1,16 @@
|
|||||||
use std::{
|
use super::*;
|
||||||
fs::File,
|
use crate::custom_error;
|
||||||
io::{Read, Write},
|
|
||||||
path::PathBuf,
|
|
||||||
process::{Command, Stdio},
|
|
||||||
};
|
|
||||||
|
|
||||||
use regex::Regex;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
use crate::{error::Result, Error};
|
|
||||||
|
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, StructOpt)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
#[structopt(name = "create")]
|
#[clap(name = "create")]
|
||||||
pub struct Create {
|
pub struct Create {
|
||||||
/// Init project name
|
/// Init project name
|
||||||
#[structopt(default_value = ".")]
|
#[clap(default_value = ".")]
|
||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
/// Template path
|
/// Template path
|
||||||
#[structopt(default_value = "gh:dioxuslabs/dioxus-template", long)]
|
#[clap(default_value = "gh:dioxuslabs/dioxus-template", long)]
|
||||||
template: String,
|
template: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,10 +24,7 @@ impl Create {
|
|||||||
let project_path = PathBuf::from(&self.name);
|
let project_path = PathBuf::from(&self.name);
|
||||||
|
|
||||||
if project_path.join("Dioxus.toml").is_file() || project_path.join("Cargo.toml").is_file() {
|
if project_path.join("Dioxus.toml").is_file() || project_path.join("Cargo.toml").is_file() {
|
||||||
return Err(Error::Other(anyhow::anyhow!(
|
return custom_error!("🧨 Folder '{}' is initialized.", &self.name);
|
||||||
"🧨 Folder '{}' is initialized.",
|
|
||||||
&self.name
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("🔧 Start to create a new project '{}'.", self.name);
|
log::info!("🔧 Start to create a new project '{}'.", self.name);
|
||||||
@@ -58,9 +45,7 @@ impl Create {
|
|||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
.output()?;
|
.output()?;
|
||||||
if !install_output.status.success() {
|
if !install_output.status.success() {
|
||||||
return Err(Error::Other(anyhow::anyhow!(
|
return custom_error!("Try to install cargo-generate failed.");
|
||||||
"Try to install cargo-generate failed."
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +59,7 @@ impl Create {
|
|||||||
.output()?;
|
.output()?;
|
||||||
|
|
||||||
if !generate_output.status.success() {
|
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"))?;
|
let mut dioxus_file = File::open(project_path.join("Dioxus.toml"))?;
|
||||||
|
|||||||
+25
-11
@@ -1,5 +1,3 @@
|
|||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
pub mod build;
|
pub mod build;
|
||||||
pub mod cfg;
|
pub mod cfg;
|
||||||
pub mod clean;
|
pub mod clean;
|
||||||
@@ -8,26 +6,41 @@ pub mod create;
|
|||||||
pub mod serve;
|
pub mod serve;
|
||||||
pub mod translate;
|
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.
|
/// Build, bundle, & ship your Dioxus app.
|
||||||
///
|
#[derive(Parser)]
|
||||||
///
|
#[clap(name = "dioxus")]
|
||||||
#[derive(StructOpt)]
|
|
||||||
#[structopt(name = "dioxus")]
|
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
#[structopt(subcommand)]
|
#[clap(subcommand)]
|
||||||
pub action: Commands,
|
pub action: Commands,
|
||||||
|
|
||||||
/// Enable verbose logging.
|
/// Enable verbose logging.
|
||||||
#[structopt(short)]
|
#[clap(short)]
|
||||||
pub v: bool,
|
pub v: bool,
|
||||||
//
|
|
||||||
// // note: dioxus is still roughly compatible with trunk
|
// // note: dioxus is still roughly compatible with trunk
|
||||||
// /// Path to the Trunk config file [default: Trunk.toml]
|
// /// 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<PathBuf>,
|
// pub config: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(Parser)]
|
||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
Build(build::Build),
|
Build(build::Build),
|
||||||
@@ -40,5 +53,6 @@ pub enum Commands {
|
|||||||
/// Clean output artifacts.
|
/// Clean output artifacts.
|
||||||
Clean(clean::Clean),
|
Clean(clean::Clean),
|
||||||
/// Dioxus config file controls.
|
/// Dioxus config file controls.
|
||||||
|
#[clap(subcommand)]
|
||||||
Config(config::Config),
|
Config(config::Config),
|
||||||
}
|
}
|
||||||
+22
-11
@@ -1,17 +1,20 @@
|
|||||||
use crate::{cfg::ConfigOptsServe, gen_page, server, CrateConfig};
|
use std::{
|
||||||
use std::{io::Write, path::PathBuf, process::{Command, Stdio}};
|
io::Write,
|
||||||
use structopt::StructOpt;
|
path::PathBuf,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
};
|
||||||
|
use super::*;
|
||||||
|
|
||||||
/// Run the WASM project on dev-server
|
/// Run the WASM project on dev-server
|
||||||
#[derive(Clone, Debug, StructOpt)]
|
#[derive(Clone, Debug, Parser)]
|
||||||
#[structopt(name = "serve")]
|
#[clap(name = "serve")]
|
||||||
pub struct Serve {
|
pub struct Serve {
|
||||||
#[structopt(flatten)]
|
#[clap(flatten)]
|
||||||
pub serve: ConfigOptsServe,
|
pub serve: ConfigOptsServe,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serve {
|
impl Serve {
|
||||||
pub async fn serve(self) -> anyhow::Result<()> {
|
pub async fn serve(self) -> Result<()> {
|
||||||
let mut crate_config = crate::CrateConfig::new()?;
|
let mut crate_config = crate::CrateConfig::new()?;
|
||||||
|
|
||||||
// change the relase state.
|
// change the relase state.
|
||||||
@@ -21,12 +24,20 @@ impl Serve {
|
|||||||
crate_config.as_example(self.serve.example.unwrap());
|
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" => {
|
"web" => {
|
||||||
crate::builder::build(&crate_config)?;
|
crate::builder::build(&crate_config)?;
|
||||||
}
|
}
|
||||||
"desktop" => {
|
"desktop" => {
|
||||||
crate::builder::build_desktop(&crate_config)?;
|
crate::builder::build_desktop(&crate_config, true)?;
|
||||||
|
|
||||||
match &crate_config.executable {
|
match &crate_config.executable {
|
||||||
crate::ExecutableType::Binary(name)
|
crate::ExecutableType::Binary(name)
|
||||||
@@ -51,7 +62,7 @@ impl Serve {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(anyhow::anyhow!("Unsoppurt platform target."));
|
return custom_error!("Unsoppurt platform target.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +75,7 @@ impl Serve {
|
|||||||
Ok(())
|
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 serve_html = gen_page(&crate_config.dioxus_config, true);
|
||||||
|
|
||||||
let mut file = std::fs::File::create(
|
let mut file = std::fs::File::create(
|
||||||
|
|||||||
@@ -1,34 +1,25 @@
|
|||||||
use anyhow::Result;
|
use super::*;
|
||||||
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;
|
|
||||||
|
|
||||||
/// Build the Rust WASM app and all of its assets.
|
/// Build the Rust WASM app and all of its assets.
|
||||||
#[derive(Clone, Debug, StructOpt)]
|
#[derive(Clone, Debug, Parser)]
|
||||||
#[structopt(name = "translate")]
|
#[clap(name = "translate")]
|
||||||
pub struct Translate {
|
pub struct Translate {
|
||||||
/// Activate debug mode
|
/// Activate debug mode
|
||||||
// short and long flags (-d, --debug) will be deduced from the field's name
|
// short and long flags (-d, --debug) will be deduced from the field's name
|
||||||
#[structopt(short, long)]
|
#[clap(short, long)]
|
||||||
pub component: bool,
|
pub component: bool,
|
||||||
|
|
||||||
/// Input file
|
/// Input file
|
||||||
#[structopt(short, long)]
|
#[clap(short, long)]
|
||||||
pub file: Option<String>,
|
pub file: Option<String>,
|
||||||
|
|
||||||
/// Output file, stdout if not present
|
/// Output file, stdout if not present
|
||||||
#[structopt(short, long)]
|
#[clap(parse(from_os_str))]
|
||||||
pub output: Option<PathBuf>,
|
pub output: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Translate {
|
impl Translate {
|
||||||
pub fn translate(self) -> anyhow::Result<()> {
|
pub fn translate(self) -> Result<()> {
|
||||||
let Translate {
|
let Translate {
|
||||||
component,
|
component,
|
||||||
output,
|
output,
|
||||||
|
|||||||
+7
-7
@@ -31,13 +31,13 @@ impl Default for DioxusConfig {
|
|||||||
Self {
|
Self {
|
||||||
application: ApplicationConfig {
|
application: ApplicationConfig {
|
||||||
name: "dioxus".into(),
|
name: "dioxus".into(),
|
||||||
platforms: vec![String::from("web")],
|
default_platform: "web".to_string(),
|
||||||
out_dir: Some(PathBuf::from("dist")),
|
out_dir: Some(PathBuf::from("dist")),
|
||||||
|
asset_dir: Some(PathBuf::from("public")),
|
||||||
},
|
},
|
||||||
web: WebConfig {
|
web: WebConfig {
|
||||||
app: WebAppConfing {
|
app: WebAppConfing {
|
||||||
title: Some("dioxus | ⛺".into()),
|
title: Some("dioxus | ⛺".into()),
|
||||||
public_dir: Some(PathBuf::from("public")),
|
|
||||||
},
|
},
|
||||||
watcher: WebWatcherConfing {
|
watcher: WebWatcherConfing {
|
||||||
watch_path: Some(vec![PathBuf::from("src")]),
|
watch_path: Some(vec![PathBuf::from("src")]),
|
||||||
@@ -59,8 +59,9 @@ impl Default for DioxusConfig {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ApplicationConfig {
|
pub struct ApplicationConfig {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub platforms: Vec<String>,
|
pub default_platform: String,
|
||||||
pub out_dir: Option<PathBuf>,
|
pub out_dir: Option<PathBuf>,
|
||||||
|
pub asset_dir: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@@ -73,7 +74,6 @@ pub struct WebConfig {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct WebAppConfing {
|
pub struct WebAppConfing {
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
pub public_dir: Option<PathBuf>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@@ -101,7 +101,7 @@ pub struct CrateConfig {
|
|||||||
pub crate_dir: PathBuf,
|
pub crate_dir: PathBuf,
|
||||||
pub workspace_dir: PathBuf,
|
pub workspace_dir: PathBuf,
|
||||||
pub target_dir: PathBuf,
|
pub target_dir: PathBuf,
|
||||||
pub public_dir: PathBuf,
|
pub asset_dir: PathBuf,
|
||||||
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
|
||||||
pub executable: ExecutableType,
|
pub executable: ExecutableType,
|
||||||
pub dioxus_config: DioxusConfig,
|
pub dioxus_config: DioxusConfig,
|
||||||
@@ -130,7 +130,7 @@ impl CrateConfig {
|
|||||||
|
|
||||||
let cargo_def = &crate_dir.join("Cargo.toml");
|
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),
|
Some(ref v) => crate_dir.join(v),
|
||||||
None => crate_dir.join("public"),
|
None => crate_dir.join("public"),
|
||||||
};
|
};
|
||||||
@@ -154,7 +154,7 @@ impl CrateConfig {
|
|||||||
crate_dir,
|
crate_dir,
|
||||||
workspace_dir,
|
workspace_dir,
|
||||||
target_dir,
|
target_dir,
|
||||||
public_dir,
|
asset_dir,
|
||||||
manifest,
|
manifest,
|
||||||
executable,
|
executable,
|
||||||
release,
|
release,
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ pub enum Error {
|
|||||||
#[error("I/O Error: {0}")]
|
#[error("I/O Error: {0}")]
|
||||||
IO(#[from] std::io::Error),
|
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")]
|
#[error("Failed to write error")]
|
||||||
FailedToWrite,
|
FailedToWrite,
|
||||||
|
|
||||||
@@ -20,6 +29,9 @@ pub enum Error {
|
|||||||
#[error("Failed to write error")]
|
#[error("Failed to write error")]
|
||||||
CargoError(String),
|
CargoError(String),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
CustomError(String),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(#[from] anyhow::Error),
|
Other(#[from] anyhow::Error),
|
||||||
}
|
}
|
||||||
@@ -35,3 +47,28 @@ impl From<String> for Error {
|
|||||||
Error::Unique(s)
|
Error::Unique(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<html_parser::Error> for Error {
|
||||||
|
fn from(e: html_parser::Error) -> Self {
|
||||||
|
Self::ParseError(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<hyper::Error> 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)*)))
|
||||||
|
};
|
||||||
|
}
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
|
use clap::Parser;
|
||||||
use dioxus_cli::*;
|
use dioxus_cli::*;
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let args = Cli::from_args();
|
let args = Cli::parse();
|
||||||
set_up_logging();
|
set_up_logging();
|
||||||
|
|
||||||
match args.action {
|
match args.action {
|
||||||
|
|||||||
+2
-2
@@ -10,14 +10,14 @@ use notify::{RecommendedWatcher, Watcher};
|
|||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, sync::Arc};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
||||||
use crate::{builder, serve::Serve, CrateConfig};
|
use crate::{builder, serve::Serve, CrateConfig, Result};
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
|
||||||
struct WsRelodState {
|
struct WsRelodState {
|
||||||
update: broadcast::Sender<String>,
|
update: broadcast::Sender<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
|
pub async fn startup(config: CrateConfig) -> Result<()> {
|
||||||
log::info!("🚀 Starting development server...");
|
log::info!("🚀 Starting development server...");
|
||||||
|
|
||||||
let dist_path = config.out_dir.clone();
|
let dist_path = config.out_dir.clone();
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#[test]
|
||||||
|
fn ready() {
|
||||||
|
println!("Compiled successfully!")
|
||||||
|
}
|
||||||
Reference in new issue
Block a user