Merge pull request #156 from Demonthos/create-dioxus-app

Make Dioxus create interactive
This commit is contained in:
Jon Kelley authored and GitHub committed 2023-06-28 16:56:38 -07:00
commit 737910f8ae
7 files changed
+1381 -516

No files matched your search

Generated
+1311 -443
View File
File diff suppressed because it is too large. Load diff
+8 -6
View File
@@ -11,7 +11,7 @@ license = "MIT/Apache-2.0"
[dependencies]
# cli core
clap = { version = "3.0.14", features = ["derive"] }
clap = { version = "4.2", features = ["derive"] }
thiserror = "1.0.30"
wasm-bindgen-cli-support = "0.2"
colored = "2.0.0"
@@ -77,12 +77,14 @@ ctrlc = "3.2.3"
# dioxus-rsx = "0.0.1"
gitignore = "1.0.7"
dioxus-rsx = { version = "0.0.3" }
dioxus-html = { version = "0.3", features = ["hot-reload-context"] }
dioxus-core = { version = "0.3", features = ["serialize"] }
dioxus-autofmt = "0.3.0"
rsx-rosetta = { version = "0.3" }
dioxus-rsx = { git = "https://github.com/DioxusLabs/dioxus" }
dioxus-html = { git = "https://github.com/DioxusLabs/dioxus", features = ["hot-reload-context"] }
dioxus-core = { git = "https://github.com/DioxusLabs/dioxus", features = ["serialize"] }
dioxus-autofmt = { git = "https://github.com/DioxusLabs/dioxus" }
rsx-rosetta = { git = "https://github.com/DioxusLabs/dioxus" }
open = "4.1.0"
cargo-generate = "0.18.3"
toml_edit = "0.19.11"
[[bin]]
path = "src/main.rs"
+2 -2
View File
@@ -4,7 +4,7 @@ use super::*;
#[derive(Clone, Debug, Default, Deserialize, Parser)]
pub struct ConfigOptsBuild {
/// The index HTML file to drive the bundling process [default: index.html]
#[clap(parse(from_os_str))]
#[arg(long)]
pub target: Option<PathBuf>,
/// Build in release mode [default: false]
@@ -37,7 +37,7 @@ pub struct ConfigOptsBuild {
#[derive(Clone, Debug, Default, Deserialize, Parser)]
pub struct ConfigOptsServe {
/// The index HTML file to drive the bundling process [default: index.html]
#[clap(parse(from_os_str))]
#[arg(short, long)]
pub target: Option<PathBuf>,
/// Port of dev server
+49 -57
View File
@@ -1,14 +1,9 @@
use super::*;
use crate::custom_error;
use cargo_generate::{GenerateArgs, TemplatePath};
/// Build the Rust WASM app and all of its assets.
#[derive(Clone, Debug, Default, Deserialize, Parser)]
#[clap(name = "create")]
pub struct Create {
/// Init project name
#[clap(default_value = ".")]
name: String,
/// Template path
#[clap(default_value = "gh:dioxuslabs/dioxus-template", long)]
template: String,
@@ -16,69 +11,66 @@ pub struct Create {
impl Create {
pub fn create(self) -> Result<()> {
if Self::name_valid_check(self.name.clone()) {
return custom_error!("❗Unsupported project name: '{}'.", &self.name);
}
let mut args = GenerateArgs::default();
args.template_path = TemplatePath {
auto_path: Some(self.template),
..Default::default()
};
let project_path = PathBuf::from(&self.name);
if project_path.join("Dioxus.toml").is_file() || project_path.join("Cargo.toml").is_file() {
return custom_error!("🧨 Folder '{}' is initialized.", &self.name);
}
log::info!("🔧 Start: Creating new project '{}'.", self.name);
let output = Command::new("cargo")
.arg("generate")
.arg("--help")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?;
let path = cargo_generate::generate(args)?;
// first run cargo fmt
let mut cmd = Command::new("cargo");
let cmd = cmd.arg("fmt").current_dir(&path);
let output = cmd.output().expect("failed to execute process");
if !output.status.success() {
log::warn!("Tool is not installed: cargo-generate, try to install it.");
let install_output = Command::new("cargo")
.arg("install")
.arg("cargo-generate")
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()?;
if !install_output.status.success() {
return custom_error!("Try to install cargo-generate failed.");
}
log::error!("cargo fmt failed");
log::error!("stdout: {}", String::from_utf8_lossy(&output.stdout));
log::error!("stderr: {}", String::from_utf8_lossy(&output.stderr));
}
let generate_output = Command::new("cargo")
.arg("generate")
.arg(&self.template)
.arg("--name")
.arg(&self.name)
.arg("--force")
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.output()?;
// then format the toml
let toml_paths = [path.join("Cargo.toml"), path.join("Dioxus.toml")];
for toml_path in &toml_paths {
let toml = std::fs::read_to_string(toml_path)?;
let mut toml = toml.parse::<toml_edit::Document>().map_err(|e| {
anyhow::anyhow!(
"failed to parse toml at {}: {}",
toml_path.display(),
e.to_string()
)
})?;
if !generate_output.status.success() {
return custom_error!("Generate project failed. Try to update cargo-generate.");
toml.as_table_mut().fmt();
let as_string = toml.to_string();
let new_string = remove_tripple_newlines(&as_string);
let mut file = std::fs::File::create(toml_path)?;
file.write_all(new_string.as_bytes())?;
}
let mut dioxus_file = File::open(project_path.join("Dioxus.toml"))?;
let mut meta_file = String::new();
dioxus_file.read_to_string(&mut meta_file)?;
meta_file = meta_file.replace("{{project-name}}", &self.name);
meta_file = meta_file.replace("{{default-platform}}", "web");
File::create(project_path.join("Dioxus.toml"))?.write_all(meta_file.as_bytes())?;
// remove any tripple newlines from the readme
let readme_path = path.join("README.md");
let readme = std::fs::read_to_string(&readme_path)?;
let new_readme = remove_tripple_newlines(&readme);
let mut file = std::fs::File::create(readme_path)?;
file.write_all(new_readme.as_bytes())?;
println!();
log::info!("💡 Project initialized:");
log::info!("🎯> cd ./{}", self.name);
log::info!("🎯> dioxus serve");
log::info!("Generated project at {}", path.display());
Ok(())
}
}
fn name_valid_check(name: String) -> bool {
let r = Regex::new(r"^[a-zA-Z][a-zA-Z0-9\-_]$").unwrap();
r.is_match(&name)
fn remove_tripple_newlines(string: &str) -> String {
let mut new_string = String::new();
for char in string.chars() {
if char == '\n' {
if new_string.ends_with("\n\n") {
continue;
}
}
new_string.push(char);
}
new_string
}
-1
View File
@@ -17,7 +17,6 @@ use crate::{
};
use clap::{Parser, Subcommand};
use html_parser::Dom;
use regex::Regex;
use serde::Deserialize;
use std::{
fs::{remove_dir_all, File},
+1 -1
View File
@@ -22,7 +22,7 @@ pub struct Translate {
pub raw: Option<String>,
/// Output file, stdout if not present
#[clap(parse(from_os_str))]
#[arg(short, long)]
pub output: Option<PathBuf>,
}
+10 -6
View File
@@ -150,10 +150,11 @@ pub async fn startup_hot_reload(
let dist_path = config.out_dir.clone();
let (reload_tx, _) = broadcast::channel(100);
let map = FileMap::<HtmlCtx>::new(config.crate_dir.clone());
// for err in errors {
// log::error!("{}", err);
// }
let FileMapBuildResult { map, errors } =
FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
for err in errors {
log::error!("{}", err);
}
let file_map = Arc::new(Mutex::new(map));
let build_manager = Arc::new(BuildManager {
config: config.clone(),
@@ -219,10 +220,10 @@ pub async fn startup_hot_reload(
let mut map = file_map.lock().unwrap();
match map.update_rsx(&path, &crate_dir) {
UpdateResult::UpdatedRsx(msgs) => {
Ok(UpdateResult::UpdatedRsx(msgs)) => {
messages.extend(msgs);
}
UpdateResult::NeedsRebuild => {
Ok(UpdateResult::NeedsRebuild) => {
match build_manager.rebuild() {
Ok(res) => {
print_console_info(
@@ -242,6 +243,9 @@ pub async fn startup_hot_reload(
}
return;
}
Err(err) => {
log::error!("{}", err);
}
}
}
for msg in messages {