Add new crate to workspace members (#2775)
* Add new crate to workspace members * Replace DioxusCrate with cargo metadata * Skip initializing git repo in already existing workspace * Fix init in workspace * Fix naming issues with new packages Changes how we parse names so `dx new packages/blah`creates a subdirectory instead --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
e4abe79276
commit
0042430a36
2 files changed
+92
-11
No files matched your search
@@ -1,5 +1,7 @@
|
||||
use super::*;
|
||||
use cargo_generate::{GenerateArgs, TemplatePath};
|
||||
use cargo_metadata::Metadata;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) static DEFAULT_TEMPLATE: &str = "gh:dioxuslabs/dioxus-template";
|
||||
|
||||
@@ -8,26 +10,70 @@ pub(crate) static DEFAULT_TEMPLATE: &str = "gh:dioxuslabs/dioxus-template";
|
||||
pub struct Create {
|
||||
/// Project name (required when `--yes` is used)
|
||||
name: Option<String>,
|
||||
|
||||
/// Generate the template directly at the given path.
|
||||
#[arg(long, value_parser)]
|
||||
destination: Option<PathBuf>,
|
||||
|
||||
/// Generate the template directly into the current dir. No subfolder will be created and no vcs is initialized.
|
||||
#[arg(long, action)]
|
||||
init: bool,
|
||||
|
||||
/// Template path
|
||||
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
|
||||
template: String,
|
||||
|
||||
/// Pass <option>=<value> for the used template (e.g., `foo=bar`)
|
||||
#[clap(short, long)]
|
||||
option: Vec<String>,
|
||||
|
||||
/// Specify a sub-template within the template repository to be used as the actual template
|
||||
#[clap(long)]
|
||||
subtemplate: Option<String>,
|
||||
|
||||
/// Skip user interaction by using the default values for the used template.
|
||||
/// Default values can be overridden with `--option`
|
||||
#[clap(short, long)]
|
||||
yes: bool,
|
||||
// TODO: turn on/off cargo-generate's output (now is invisible)
|
||||
// #[clap(default_value = "false", short, long)]
|
||||
// silent: bool,
|
||||
}
|
||||
|
||||
impl Create {
|
||||
pub fn create(self) -> Result<()> {
|
||||
pub fn create(mut self) -> Result<()> {
|
||||
let metadata = cargo_metadata::MetadataCommand::new().exec().ok();
|
||||
|
||||
// If we're getting pass a `.` name, that's actually a path
|
||||
// We're actually running an init - we should clear the name
|
||||
if self.name.as_deref() == Some(".") {
|
||||
self.name = None;
|
||||
self.init = true;
|
||||
}
|
||||
|
||||
// A default destination is set for nameless projects
|
||||
if self.name.is_none() {
|
||||
self.destination = Some(PathBuf::from("."));
|
||||
}
|
||||
|
||||
// Split the name into path components
|
||||
// such that dx new packages/app will create a directory called packages/app
|
||||
let destination = self.destination.unwrap_or_else(|| {
|
||||
let mut path = PathBuf::from(self.name.as_deref().unwrap());
|
||||
|
||||
if path.is_relative() {
|
||||
path = std::env::current_dir().unwrap().join(path);
|
||||
}
|
||||
|
||||
// split the path into the parent and the name
|
||||
let parent = path.parent().unwrap();
|
||||
let name = path.file_name().unwrap();
|
||||
self.name = Some(name.to_str().unwrap().to_string());
|
||||
|
||||
// create the parent directory if it doesn't exist
|
||||
std::fs::create_dir_all(parent).unwrap();
|
||||
|
||||
// And then the "destination" is the parent directory
|
||||
parent.to_path_buf()
|
||||
});
|
||||
|
||||
let args = GenerateArgs {
|
||||
define: self.option,
|
||||
name: self.name,
|
||||
@@ -37,11 +83,20 @@ impl Create {
|
||||
subfolder: self.subtemplate,
|
||||
..Default::default()
|
||||
},
|
||||
init: self.init,
|
||||
destination: Some(destination),
|
||||
vcs: if metadata.is_some() {
|
||||
Some(cargo_generate::Vcs::None)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if self.yes && args.name.is_none() {
|
||||
return Err("You have to provide the project's name when using `--yes` option.".into());
|
||||
}
|
||||
|
||||
// https://github.com/console-rs/dialoguer/issues/294
|
||||
ctrlc::set_handler(move || {
|
||||
let _ = console::Term::stdout().show_cursor();
|
||||
@@ -49,13 +104,32 @@ impl Create {
|
||||
})
|
||||
.expect("ctrlc::set_handler");
|
||||
let path = cargo_generate::generate(args)?;
|
||||
post_create(&path)
|
||||
|
||||
post_create(&path, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
// being also used by `init`
|
||||
pub fn post_create(path: &PathBuf) -> Result<()> {
|
||||
// first run cargo fmt
|
||||
/// Post-creation actions for newly setup crates.
|
||||
// Also used by `init`.
|
||||
pub fn post_create(path: &Path, metadata: Option<Metadata>) -> Result<()> {
|
||||
// 1. Add the new project to the workspace, if it exists.
|
||||
// This must be executed first in order to run `cargo fmt` on the new project.
|
||||
metadata.and_then(|metadata| {
|
||||
let cargo_toml_path = &metadata.workspace_root.join("Cargo.toml");
|
||||
let cargo_toml_str = std::fs::read_to_string(cargo_toml_path).ok()?;
|
||||
let relative_path = path.strip_prefix(metadata.workspace_root).ok()?;
|
||||
|
||||
let mut cargo_toml: toml_edit::DocumentMut = cargo_toml_str.parse().ok()?;
|
||||
cargo_toml
|
||||
.get_mut("workspace")?
|
||||
.get_mut("members")?
|
||||
.as_array_mut()?
|
||||
.push(relative_path.display().to_string());
|
||||
|
||||
std::fs::write(cargo_toml_path, cargo_toml.to_string()).ok()
|
||||
});
|
||||
|
||||
// 2. Run `cargo fmt` on the new project.
|
||||
let mut cmd = Command::new("cargo");
|
||||
let cmd = cmd.arg("fmt").current_dir(path);
|
||||
let output = cmd.output().expect("failed to execute process");
|
||||
@@ -65,7 +139,7 @@ pub fn post_create(path: &PathBuf) -> Result<()> {
|
||||
tracing::error!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||
}
|
||||
|
||||
// then format the toml
|
||||
// 3. Format the `Cargo.toml` and `Dioxus.toml` files.
|
||||
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)?;
|
||||
@@ -85,7 +159,7 @@ pub fn post_create(path: &PathBuf) -> Result<()> {
|
||||
file.write_all(new_string.as_bytes())?;
|
||||
}
|
||||
|
||||
// remove any triple newlines from the readme
|
||||
// 4. Remove any triple newlines from the readme.
|
||||
let readme_path = path.join("README.md");
|
||||
let readme = std::fs::read_to_string(&readme_path)?;
|
||||
let new_readme = remove_triple_newlines(&readme);
|
||||
|
||||
@@ -25,6 +25,8 @@ pub struct Init {
|
||||
|
||||
impl Init {
|
||||
pub fn init(self) -> Result<()> {
|
||||
let metadata = cargo_metadata::MetadataCommand::new().exec().ok();
|
||||
|
||||
// Get directory name.
|
||||
let name = std::env::current_dir()?
|
||||
.file_name()
|
||||
@@ -45,9 +47,14 @@ impl Init {
|
||||
subfolder: self.subtemplate,
|
||||
..Default::default()
|
||||
},
|
||||
vcs: if metadata.is_some() {
|
||||
Some(cargo_generate::Vcs::None)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let path = cargo_generate::generate(args)?;
|
||||
create::post_create(&path)
|
||||
create::post_create(&path, metadata)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user