diff --git a/Cargo.toml b/Cargo.toml
index d687d74d0..c615e2e42 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,7 @@ members = [
"packages/dioxus",
"packages/core",
"packages/cli",
+ "packages/cli-config",
"packages/core-macro",
"packages/router-macro",
"packages/extension",
@@ -78,6 +79,7 @@ dioxus-native-core-macro = { path = "packages/native-core-macro", version = "0.4
rsx-rosetta = { path = "packages/rsx-rosetta", version = "0.4.0" }
dioxus-signals = { path = "packages/signals" }
generational-box = { path = "packages/generational-box" }
+dioxus-cli-config = { path = "packages/cli-config", version = "0.4.1" }
dioxus-hot-reload = { path = "packages/hot-reload", version = "0.4.0" }
dioxus-fullstack = { path = "packages/fullstack", version = "0.4.1" }
dioxus_server_macro = { path = "packages/server-macro", version = "0.4.1" }
diff --git a/packages/cli-config/.gitignore b/packages/cli-config/.gitignore
new file mode 100644
index 000000000..6700b1332
--- /dev/null
+++ b/packages/cli-config/.gitignore
@@ -0,0 +1,4 @@
+/target
+Cargo.lock
+.DS_Store
+.idea/
diff --git a/packages/cli-config/Cargo.toml b/packages/cli-config/Cargo.toml
new file mode 100644
index 000000000..d89d411fd
--- /dev/null
+++ b/packages/cli-config/Cargo.toml
@@ -0,0 +1,102 @@
+[package]
+name = "dioxus-cli-config"
+version = "0.4.1"
+authors = ["Jonathan Kelley"]
+edition = "2021"
+description = "Configuration for the Dioxus CLI"
+repository = "https://github.com/DioxusLabs/dioxus/"
+license = "MIT OR Apache-2.0"
+keywords = ["react", "gui", "cli", "dioxus", "wasm"]
+
+[dependencies]
+# cli core
+clap = { version = "4.2", features = ["derive"] }
+thiserror = { workspace = true }
+wasm-bindgen-cli-support = "0.2"
+colored = "2.0.0"
+
+# 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.16.0"
+futures = "0.3.21"
+notify = { version = "5.0.0-pre.16", features = ["serde"] }
+html_parser = { workspace = true }
+cargo_metadata = "0.15.0"
+tokio = { version = "1.16.1", features = ["fs", "sync", "rt", "macros"] }
+atty = "0.2.14"
+chrono = "0.4.19"
+anyhow = "1.0.53"
+hyper = "0.14.17"
+hyper-rustls = "0.23.2"
+indicatif = "0.17.5"
+subprocess = "0.2.9"
+
+axum = { version = "0.5.1", features = ["ws", "headers"] }
+axum-server = { version = "0.5.1", features = ["tls-rustls"] }
+tower-http = { version = "0.2.2", features = ["full"] }
+headers = "0.3.7"
+
+walkdir = "2"
+
+# tools download
+dirs = "4.0.0"
+reqwest = { version = "0.11", features = [
+ "rustls-tls",
+ "stream",
+ "trust-dns",
+ "blocking",
+] }
+flate2 = "1.0.22"
+tar = "0.4.38"
+zip = "0.6.2"
+tower = "0.4.12"
+syn = { version = "2.0", features = ["full", "extra-traits"] }
+lazy_static = "1.4.0"
+
+# plugin packages
+mlua = { version = "0.8.1", features = [
+ "lua54",
+ "vendored",
+ "async",
+ "send",
+ "macros",
+], optional = true }
+ctrlc = "3.2.3"
+open = "4.1.0"
+cargo-generate = "0.18"
+toml_edit = "0.19.11"
+
+# bundling
+tauri-bundler = { version = "=1.3.0", features = ["native-tls-vendored"] }
+tauri-utils = "=1.4.*"
+
+dioxus-autofmt = { workspace = true }
+dioxus-check = { workspace = true }
+rsx-rosetta = { workspace = true }
+dioxus-rsx = { workspace = true }
+dioxus-html = { workspace = true, features = ["hot-reload-context"] }
+dioxus-core = { workspace = true, features = ["serialize"] }
+dioxus-hot-reload = { workspace = true }
+interprocess-docfix = { version = "1.2.2" }
+
+[features]
+default = []
+plugin = ["mlua"]
+
+[[bin]]
+path = "src/main.rs"
+name = "dx"
+
+[dev-dependencies]
+tempfile = "3.3"
+
+[package.metadata.binstall]
+pkg-url = "{ repo }/releases/download/v{ version }/dx-{ target }{ archive-suffix }"
+
+[package.metadata.binstall.overrides.x86_64-pc-windows-msvc]
+pkg-fmt = "zip"
diff --git a/packages/cli-config/README.md b/packages/cli-config/README.md
new file mode 100644
index 000000000..ef2435713
--- /dev/null
+++ b/packages/cli-config/README.md
@@ -0,0 +1,5 @@
+
+
📦✨ Dioxus CLI Configuration
+
+
+The **dioxus-cli-config** contains the configuration for the **dioxus-cli**.
diff --git a/packages/cli-config/src/assets/dioxus.toml b/packages/cli-config/src/assets/dioxus.toml
new file mode 100644
index 000000000..892a6cdf8
--- /dev/null
+++ b/packages/cli-config/src/assets/dioxus.toml
@@ -0,0 +1,74 @@
+[application]
+
+# dioxus project name
+name = "{{project-name}}"
+
+# default platfrom
+# you can also use `dx serve/build --platform XXX` to use other platform
+# value: web | desktop
+default_platform = "{{default-platform}}"
+
+# Web `build` & `serve` dist path
+out_dir = "dist"
+
+# resource (static) file folder
+asset_dir = "public"
+
+[web.app]
+
+# HTML title tag content
+title = "Dioxus | An elegant GUI library for Rust"
+
+[web.watcher]
+
+index_on_404 = true
+
+watch_path = ["src", "examples"]
+
+# include `assets` in web platform
+[web.resource]
+
+# CSS style file
+style = []
+
+# Javascript code file
+script = []
+
+[web.resource.dev]
+
+# Javascript code file
+# serve: [dev-server] only
+script = []
+
+[application.plugins]
+
+available = true
+
+required = []
+
+[bundler]
+# Bundle identifier
+identifier = "io.github.{{project-name}}"
+
+# Bundle publisher
+publisher = "{{project-name}}"
+
+# Bundle icon
+icon = ["icons/icon.png"]
+
+# Bundle resources
+resources = ["public/*"]
+
+# Bundle copyright
+copyright = ""
+
+# Bundle category
+category = "Utility"
+
+# Bundle short description
+short_description = "An amazing dioxus application."
+
+# Bundle long description
+long_description = """
+An amazing dioxus application.
+"""
\ No newline at end of file
diff --git a/packages/cli/src/cargo.rs b/packages/cli-config/src/cargo.rs
similarity index 69%
rename from packages/cli/src/cargo.rs
rename to packages/cli-config/src/cargo.rs
index b52fa4b09..97e4040db 100644
--- a/packages/cli/src/cargo.rs
+++ b/packages/cli-config/src/cargo.rs
@@ -1,12 +1,33 @@
//! Utilities for working with cargo and rust files
-use crate::error::{Error, Result};
+use std::error::Error;
use std::{
- env, fs,
+ env,
+ fmt::{Display, Formatter},
+ fs,
path::{Path, PathBuf},
process::Command,
str,
};
+#[derive(Debug, Clone)]
+pub struct CargoError {
+ msg: String,
+}
+
+impl CargoError {
+ pub fn new(msg: String) -> Self {
+ Self { msg }
+ }
+}
+
+impl Display for CargoError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ write!(f, "CargoError: {}", self.msg)
+ }
+}
+
+impl Error for CargoError {}
+
/// How many parent folders are searched for a `Cargo.toml`
const MAX_ANCESTORS: u32 = 10;
@@ -19,7 +40,7 @@ pub struct Metadata {
/// Returns the root of the crate that the command is run from
///
/// If the command is run from the workspace root, this will return the top-level Cargo.toml
-pub fn crate_root() -> Result {
+pub fn crate_root() -> Result {
// From the current directory we work our way up, looking for `Cargo.toml`
env::current_dir()
.ok()
@@ -35,7 +56,7 @@ pub fn crate_root() -> Result {
None
})
.ok_or_else(|| {
- Error::CargoError("Failed to find directory containing Cargo.toml".to_string())
+ CargoError::new("Failed to find directory containing Cargo.toml".to_string())
})
}
@@ -53,11 +74,11 @@ fn contains_manifest(path: &Path) -> bool {
impl Metadata {
/// Returns the struct filled from `cargo metadata` output
/// TODO @Jon, find a different way that doesn't rely on the cargo metadata command (it's slow)
- pub fn get() -> Result {
+ pub fn get() -> Result {
let output = Command::new("cargo")
.args(["metadata"])
.output()
- .map_err(|_| Error::CargoError("Manifset".to_string()))?;
+ .map_err(|_| CargoError::new("Manifset".to_string()))?;
if !output.status.success() {
let mut msg = str::from_utf8(&output.stderr).unwrap().trim();
@@ -65,22 +86,22 @@ impl Metadata {
msg = &msg[7..];
}
- return Err(Error::CargoError(msg.to_string()));
+ return Err(CargoError::new(msg.to_string()));
}
let stdout = str::from_utf8(&output.stdout).unwrap();
if let Some(line) = stdout.lines().next() {
let meta: serde_json::Value = serde_json::from_str(line)
- .map_err(|_| Error::CargoError("InvalidOutput".to_string()))?;
+ .map_err(|_| CargoError::new("InvalidOutput".to_string()))?;
let workspace_root = meta["workspace_root"]
.as_str()
- .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))?
+ .ok_or_else(|| CargoError::new("InvalidOutput".to_string()))?
.into();
let target_directory = meta["target_directory"]
.as_str()
- .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))?
+ .ok_or_else(|| CargoError::new("InvalidOutput".to_string()))?
.into();
return Ok(Self {
@@ -89,6 +110,6 @@ impl Metadata {
});
}
- Err(Error::CargoError("InvalidOutput".to_string()))
+ Err(CargoError::new("InvalidOutput".to_string()))
}
}
diff --git a/packages/cli-config/src/config.rs b/packages/cli-config/src/config.rs
new file mode 100644
index 000000000..f7ab89124
--- /dev/null
+++ b/packages/cli-config/src/config.rs
@@ -0,0 +1,658 @@
+use clap::ValueEnum;
+use serde::{Deserialize, Serialize};
+use std::{
+ collections::HashMap,
+ fmt::{Display, Formatter},
+ path::{Path, PathBuf},
+};
+
+use crate::CargoError;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Serialize, Deserialize, Debug)]
+pub enum Platform {
+ #[clap(name = "web")]
+ #[serde(rename = "web")]
+ Web,
+ #[clap(name = "desktop")]
+ #[serde(rename = "desktop")]
+ Desktop,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct DioxusConfig {
+ pub application: ApplicationConfig,
+
+ pub web: WebConfig,
+
+ #[serde(default)]
+ pub bundle: BundleConfig,
+
+ #[serde(default = "default_plugin")]
+ pub plugin: toml::Value,
+}
+
+fn default_plugin() -> toml::Value {
+ toml::Value::Boolean(true)
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct LoadDioxusConfigError {
+ location: String,
+ error: String,
+}
+
+impl std::fmt::Display for LoadDioxusConfigError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{} {}", self.location, self.error)
+ }
+}
+
+impl std::error::Error for LoadDioxusConfigError {}
+
+impl DioxusConfig {
+ /// Load the dioxus config from a path
+ pub fn load(bin: Option) -> Result