feat: add init command

This commit is contained in:
mrxiaozhuox committed 2022-01-23 01:29:36 +08:00
1 parent d18a93f129
commit 0e2c05be66
15 files changed
+151 -192

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
use std::{process::{Command, Stdio}, fs::File, path::PathBuf, io::Write};
use structopt::StructOpt;
use crate::{error::{Error, Result}, cargo};
/// Build the Rust WASM app and all of its assets.
#[derive(Clone, Debug, StructOpt)]
#[structopt(name = "init")]
pub struct Init {
/// Init project path
#[structopt(default_value = ".")]
path: String,
/// Template path
#[structopt(default_value = "default", long)]
template: String,
}
impl Init {
pub fn init(self) -> Result<()> {
log::info!("🔧 Start to init a new project '{}'.", self.path);
let project_path = PathBuf::from(&self.path);
let output = Command::new("cargo")
.arg("init")
.arg(&self.path)
.arg("--bin")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?
;
if !output.status.success() {
return Err(Error::CargoError("Cargo init failed".into()));
}
// get the template code
let template_str = match self.template {
_ => include_str!("../../template/default.rs"),
};
let main_rs_file = project_path.join("src").join("main.rs");
if !main_rs_file.is_file() {
return Err(Error::FailedToWrite);
}
let mut file = File::create(main_rs_file)?;
file.write_all(&template_str.as_bytes())?;
// log::info!("🎯 Project initialization completed.");
Ok(())
}
}
+6 -2
View File
@@ -5,6 +5,7 @@ pub mod cfg;
pub mod clean;
pub mod serve;
pub mod translate;
pub mod init;
/// Build, bundle, & ship your Dioxus app.
///
@@ -27,12 +28,15 @@ pub struct Cli {
#[derive(StructOpt)]
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),
/// Translate some source file into Dioxus code.
Translate(translate::Translate),
// /// Build, watch & serve the Rust WASM app and all of its assets.
/// Build, watch & serve the Rust WASM app and all of its assets.
Serve(serve::Serve),
/// Init a new project for Dioxus.
Init(init::Init),
// /// Clean output artifacts.
// Clean(clean::Clean),
-145
View File
@@ -1,145 +0,0 @@
// use crate::{cli::DevelopOptions, config::CrateConfig, error::Result};
// use async_std::prelude::FutureExt;
// use log::info;
// use notify::{RecommendedWatcher, RecursiveMode, Watcher};
// use std::path::PathBuf;
// use std::sync::atomic::AtomicBool;
// use std::sync::Arc;
// use tide::http::mime::HTML;
// use tide::http::Mime;
// pub struct DevelopState {
// //
// reload_on_change: bool,
// }
// pub async fn develop(options: DevelopOptions) -> Result<()> {
// //
// log::info!("Starting development server 🚀");
// let mut cfg = CrateConfig::new()?;
// cfg.with_develop_options(&options);
// let out_dir = cfg.out_dir.clone();
// let is_err = Arc::new(AtomicBool::new(false));
// // Spawn the server onto a seperate task
// // This lets the task progress while we handle file updates
// let server = async_std::task::spawn(launch_server(out_dir, is_err.clone()));
// let watcher = async_std::task::spawn(watch_directory(cfg.clone(), is_err.clone()));
// match server.race(watcher).await {
// Err(e) => log::warn!("Error running development server, {:?}", e),
// _ => {}
// }
// Ok(())
// }
// async fn watch_directory(config: CrateConfig, is_err: ErrStatus) -> Result<()> {
// // Create a channel to receive the events.
// let (watcher_tx, watcher_rx) = async_std::channel::bounded(100);
// // Automatically select the best implementation for your platform.
// // You can also access each implementation directly e.g. INotifyWatcher.
// let mut watcher: RecommendedWatcher = Watcher::new(move |res| {
// async_std::task::block_on(watcher_tx.send(res));
// // send an event
// let _ = async_std::task::block_on(watcher_tx.send(res));
// })
// .expect("failed to make watcher");
// let src_dir = crate::cargo::crate_root()?;
// // Add a path to be watched. All files and directories at that path and
// // below will be monitored for changes.
// watcher
// .watch(&src_dir.join("src"), RecursiveMode::Recursive)
// .expect("Failed to watch dir");
// match watcher.watch(&src_dir.join("examples"), RecursiveMode::Recursive) {
// Ok(_) => {}
// Err(e) => log::warn!("Failed to watch examples dir, {:?}", e),
// }
// 'run: loop {
// match crate::builder::build(&config) {
// Ok(_) => {
// is_err.store(false, std::sync::atomic::Ordering::Relaxed);
// async_std::task::sleep(std::time::Duration::from_millis(500)).await;
// }
// Err(err) => is_err.store(true, std::sync::atomic::Ordering::Relaxed),
// };
// let mut msg = None;
// loop {
// let new_msg = watcher_rx.recv().await.unwrap().unwrap();
// if !watcher_rx.is_empty() {
// msg = Some(new_msg);
// break;
// }
// }
// info!("File updated, rebuilding app");
// }
// Ok(())
// }
// async fn launch_server(outdir: PathBuf, is_err: ErrStatus) -> Result<()> {
// let _crate_dir = crate::cargo::crate_root()?;
// let _workspace_dir = crate::cargo::workspace_root()?;
// let mut app = tide::with_state(ServerState::new(outdir.to_owned(), is_err));
// let file_path = format!("{}/index.html", outdir.display());
// log::info!("Serving {}", file_path);
// let p = outdir.display().to_string();
// app.at("/")
// .get(|req: tide::Request<ServerState>| async move {
// log::info!("Connected to development server");
// let state = req.state();
// match state.is_err.load(std::sync::atomic::Ordering::Relaxed) {
// true => {
// //
// let mut resp =
// tide::Body::from_string(format!(include_str!("../err.html"), err = "_"));
// resp.set_mime(HTML);
// Ok(resp)
// }
// false => {
// Ok(tide::Body::from_file(state.serv_path.clone().join("index.html")).await?)
// }
// }
// })
// .serve_dir(p)?;
// // .serve_file(file_path)
// // .unwrap();
// let port = "8080";
// let serve_addr = format!("127.0.0.1:{}", port);
// info!("App available at http://{}/", serve_addr);
// app.listen(serve_addr).await?;
// Ok(())
// }
// /// https://github.com/http-rs/tide/blob/main/examples/state.rs
// /// Tide seems to prefer using state instead of injecting into the app closure
// /// The app closure needs to be static and
// #[derive(Clone)]
// struct ServerState {
// serv_path: PathBuf,
// is_err: ErrStatus,
// }
// type ErrStatus = Arc<AtomicBool>;
// impl ServerState {
// fn new(serv_path: PathBuf, is_err: ErrStatus) -> Self {
// Self { serv_path, is_err }
// }
// }
View File
Whitespace-only changes.
-3
View File
@@ -2,8 +2,6 @@ use crate::{cfg::ConfigOptsServe, server};
use std::io::Write;
use structopt::StructOpt;
mod develop;
/// Run the WASM project on dev-server
#[derive(Clone, Debug, StructOpt)]
#[structopt(name = "serve")]
@@ -14,7 +12,6 @@ pub struct Serve {
impl Serve {
pub async fn serve(self) -> anyhow::Result<()> {
let mut crate_config = crate::CrateConfig::new()?;
// change the relase state.
crate_config.with_release(self.serve.release);
+1
View File
@@ -4,6 +4,7 @@
//! - [ ] Extracts svgs
//! - [ ] Attempts to extract lists
#[allow(unused_imports)]
use std::{
fmt::{Display, Formatter},
io::Write,