Fix (and rewrite) dx init/dx new (#2822)
* fix(cli)!: init subcommand now works correctly * test(cli): added tests for init subcommands * chore: moved `init` subcommand tests to its own file * removed unnecessary arguments from tested command * refactor(cli)!: new subcommand now behaves like cargo * moved the hidden cursor workaround into a function * feat(cli): added `branch` flag for init/new subcommands * feat(cli): added `revision` and `tag` options
This commit is contained in:
1 parent
a0e649ad96
commit
fca5a82e2b
5 files changed
+541
-134
No files matched your search
Generated
+61
-37
@@ -118,9 +118,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.19"
|
version = "0.2.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f"
|
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-tzdata"
|
name = "android-tzdata"
|
||||||
@@ -1740,7 +1740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2023,9 +2023,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.37"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -2295,7 +2295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2362,7 +2362,7 @@ dependencies = [
|
|||||||
"encode_unicode",
|
"encode_unicode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2599,9 +2599,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.14"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -2905,9 +2905,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.129"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cbdc8cca144dce1c4981b5c9ab748761619979e515c3d53b5df385c677d1d007"
|
checksum = "23c042a0ba58aaff55299632834d1ea53ceff73d62373f62c9ae60890ad1b942"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxxbridge-flags",
|
"cxxbridge-flags",
|
||||||
@@ -2917,13 +2917,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-build"
|
name = "cxx-build"
|
||||||
version = "1.0.129"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c5764c3142ab44fcf857101d12c0ddf09c34499900557c764f5ad0597159d1fc"
|
checksum = "45dc1c88d0fdac57518a9b1f6c4f4fb2aca8f3c30c0d03d7d8518b47ca0bcea6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"once_cell",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"scratch",
|
"scratch",
|
||||||
@@ -2932,18 +2931,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.129"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d422aff542b4fa28c2ce8e5cc202d42dbf24702345c1fba3087b2d3f8a1b90ff"
|
checksum = "aa7ed7d30b289e2592cc55bc2ccd89803a63c913e008e6eb59f06cddf45bb52f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.129"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1719100f31492cd6adeeab9a0f46cdbc846e615fdb66d7b398aa46ec7fdd06f"
|
checksum = "0b8c465d22de46b851c04630a5fc749a26005b263632ed2e0d9cc81518ead78d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"rustversion",
|
||||||
"syn 2.0.87",
|
"syn 2.0.87",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3236,6 +3236,7 @@ dependencies = [
|
|||||||
"dioxus-rsx-rosetta",
|
"dioxus-rsx-rosetta",
|
||||||
"dirs",
|
"dirs",
|
||||||
"env_logger 0.11.5",
|
"env_logger 0.11.5",
|
||||||
|
"escargot",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
@@ -3254,6 +3255,7 @@ dependencies = [
|
|||||||
"object 0.36.5",
|
"object 0.36.5",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open",
|
"open",
|
||||||
|
"path-absolutize",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
@@ -4322,6 +4324,18 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "escargot"
|
||||||
|
version = "0.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05a3ac187a16b5382fef8c69fd1bad123c67b7cf3932240a2d43dcdd32cded88"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "etcetera"
|
name = "etcetera"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -5434,7 +5448,7 @@ dependencies = [
|
|||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"bstr",
|
"bstr",
|
||||||
"log",
|
"log",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax 0.8.5",
|
"regex-syntax 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6250,7 +6264,7 @@ dependencies = [
|
|||||||
"globset",
|
"globset",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"same-file",
|
"same-file",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
@@ -6338,15 +6352,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indicatif"
|
name = "indicatif"
|
||||||
version = "0.17.8"
|
version = "0.17.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
|
checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console",
|
||||||
"instant",
|
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
|
"web-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6411,10 +6425,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instability"
|
name = "instability"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c"
|
checksum = "b829f37dead9dc39df40c2d3376c179fdfd2ac771f53f55d3c30dc096a3c0c6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"indoc",
|
||||||
|
"pretty_assertions",
|
||||||
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.87",
|
"syn 2.0.87",
|
||||||
]
|
]
|
||||||
@@ -6774,9 +6792,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "krates"
|
name = "krates"
|
||||||
version = "0.17.2"
|
version = "0.17.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50ac9a4a6857b3732e7504712e2d41d5edaad70424d3dcb7166868e57094f06c"
|
checksum = "e34c533fa7eee6063e640fd1cb059add729588f28f22f3b2a5650275e20f3ee3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"camino",
|
"camino",
|
||||||
"cfg-expr 0.17.0",
|
"cfg-expr 0.17.0",
|
||||||
@@ -9168,7 +9186,7 @@ dependencies = [
|
|||||||
"strum_macros 0.26.4",
|
"strum_macros 0.26.4",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-truncate",
|
"unicode-truncate",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -9290,7 +9308,7 @@ checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax 0.8.5",
|
"regex-syntax 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -9305,9 +9323,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.8"
|
version = "0.4.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -10032,9 +10050,9 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.214"
|
version = "1.0.215"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
@@ -10075,9 +10093,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.214"
|
version = "1.0.215"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -12156,7 +12174,7 @@ checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -12165,6 +12183,12 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ wasm-opt = { version = "0.116.1", optional = true }
|
|||||||
crossterm = { version = "0.28.0", features = ["event-stream"] }
|
crossterm = { version = "0.28.0", features = ["event-stream"] }
|
||||||
ansi-to-tui = "6.0"
|
ansi-to-tui = "6.0"
|
||||||
ansi-to-html = "0.2.1"
|
ansi-to-html = "0.2.1"
|
||||||
|
path-absolutize = "3.1"
|
||||||
ratatui = { version = "0.28.0", features = ["crossterm", "unstable"] }
|
ratatui = { version = "0.28.0", features = ["crossterm", "unstable"] }
|
||||||
|
|
||||||
# disable `log` entirely since `walrus` uses it and is *much* slower with it enableda
|
# disable `log` entirely since `walrus` uses it and is *much* slower with it enableda
|
||||||
@@ -138,6 +139,9 @@ wasm-opt = ["dep:wasm-opt"]
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
name = "dx"
|
name = "dx"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
escargot = "0.5"
|
||||||
|
|
||||||
[package.metadata.binstall]
|
[package.metadata.binstall]
|
||||||
pkg-url = "{ repo }/releases/download/v{ version }/dx-{ target }-v{ version }{ archive-suffix }"
|
pkg-url = "{ repo }/releases/download/v{ version }/dx-{ target }-v{ version }{ archive-suffix }"
|
||||||
pkg-fmt = "tgz"
|
pkg-fmt = "tgz"
|
||||||
|
|||||||
+285
-70
@@ -1,36 +1,47 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::TraceSrc;
|
use crate::TraceSrc;
|
||||||
use cargo_generate::{GenerateArgs, TemplatePath};
|
use cargo_generate::{GenerateArgs, TemplatePath};
|
||||||
use cargo_metadata::Metadata;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub(crate) static DEFAULT_TEMPLATE: &str = "gh:dioxuslabs/dioxus-template";
|
pub(crate) static DEFAULT_TEMPLATE: &str = "gh:dioxuslabs/dioxus-template";
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
pub(crate) struct Create {
|
#[clap(name = "new")]
|
||||||
/// Project name (required when `--yes` is used)
|
pub struct Create {
|
||||||
|
/// Create a new Dioxus project at PATH
|
||||||
|
path: PathBuf,
|
||||||
|
|
||||||
|
/// Project name. Defaults to directory name
|
||||||
|
#[arg(short, long)]
|
||||||
name: Option<String>,
|
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
|
/// Template path
|
||||||
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
|
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
|
||||||
template: String,
|
template: String,
|
||||||
|
|
||||||
/// Pass <option>=<value> for the used template (e.g., `foo=bar`)
|
/// Branch to select when using `template` from a git repository.
|
||||||
#[clap(short, long)]
|
/// Mutually exclusive with: `--revision`, `--tag`.
|
||||||
option: Vec<String>,
|
#[clap(long, conflicts_with_all(["revision", "tag"]))]
|
||||||
|
branch: Option<String>,
|
||||||
|
|
||||||
|
/// A commit hash to select when using `template` from a git repository.
|
||||||
|
/// Mutually exclusive with: `--branch`, `--tag`.
|
||||||
|
#[clap(long, conflicts_with_all(["branch", "tag"]))]
|
||||||
|
revision: Option<String>,
|
||||||
|
|
||||||
|
/// Tag to select when using `template` from a git repository.
|
||||||
|
/// Mutually exclusive with: `--branch`, `--revision`.
|
||||||
|
#[clap(long, conflicts_with_all(["branch", "revision"]))]
|
||||||
|
tag: Option<String>,
|
||||||
|
|
||||||
/// Specify a sub-template within the template repository to be used as the actual template
|
/// Specify a sub-template within the template repository to be used as the actual template
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
subtemplate: Option<String>,
|
subtemplate: Option<String>,
|
||||||
|
|
||||||
|
/// Pass <option>=<value> for the used template (e.g., `foo=bar`)
|
||||||
|
#[clap(short, long)]
|
||||||
|
option: Vec<String>,
|
||||||
|
|
||||||
/// Skip user interaction by using the default values for the used template.
|
/// Skip user interaction by using the default values for the used template.
|
||||||
/// Default values can be overridden with `--option`
|
/// Default values can be overridden with `--option`
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
@@ -38,82 +49,90 @@ pub(crate) struct Create {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Create {
|
impl Create {
|
||||||
pub(crate) fn create(mut self) -> Result<StructuredOutput> {
|
pub fn create(mut self) -> Result<StructuredOutput> {
|
||||||
let metadata = cargo_metadata::MetadataCommand::new().exec().ok();
|
// Project name defaults to directory name.
|
||||||
|
|
||||||
// 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() {
|
if self.name.is_none() {
|
||||||
self.destination = Some(PathBuf::from("."));
|
self.name = Some(create::name_from_path(&self.path)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
let args = GenerateArgs {
|
||||||
define: self.option,
|
define: self.option,
|
||||||
|
destination: Some(self.path),
|
||||||
|
// NOTE: destination without init means base_dir + name, with —
|
||||||
|
// means dest_dir. So use `init: true` and always handle
|
||||||
|
// the dest_dir manually and carefully.
|
||||||
|
// Cargo never adds name to the path. Name is solely for project name.
|
||||||
|
// https://github.com/cargo-generate/cargo-generate/issues/1250
|
||||||
|
init: true,
|
||||||
name: self.name,
|
name: self.name,
|
||||||
silent: self.yes,
|
silent: self.yes,
|
||||||
template_path: TemplatePath {
|
template_path: TemplatePath {
|
||||||
auto_path: Some(self.template),
|
auto_path: Some(self.template),
|
||||||
|
branch: self.branch,
|
||||||
|
revision: self.revision,
|
||||||
subfolder: self.subtemplate,
|
subfolder: self.subtemplate,
|
||||||
|
tag: self.tag,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
init: self.init,
|
|
||||||
destination: Some(destination),
|
|
||||||
vcs: if metadata.is_some() {
|
|
||||||
Some(cargo_generate::Vcs::None)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
restore_cursor_on_sigint();
|
||||||
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();
|
|
||||||
std::process::exit(0);
|
|
||||||
})
|
|
||||||
.expect("ctrlc::set_handler");
|
|
||||||
let path = cargo_generate::generate(args)?;
|
let path = cargo_generate::generate(args)?;
|
||||||
|
post_create(&path)?;
|
||||||
post_create(&path, metadata)?;
|
|
||||||
|
|
||||||
Ok(StructuredOutput::Success)
|
Ok(StructuredOutput::Success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prevent hidden cursor if Ctrl+C is pressed when interacting
|
||||||
|
/// with cargo-generate's prompts.
|
||||||
|
///
|
||||||
|
/// See https://github.com/DioxusLabs/dioxus/pull/2603.
|
||||||
|
pub(crate) fn restore_cursor_on_sigint() {
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
if let Err(err) = console::Term::stdout().show_cursor() {
|
||||||
|
eprintln!("Error showing the cursor again: {err}");
|
||||||
|
}
|
||||||
|
std::process::exit(1); // Ideally should mimic the INT signal.
|
||||||
|
})
|
||||||
|
.expect("ctrlc::set_handler");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the last directory name from the `path`.
|
||||||
|
pub(crate) fn name_from_path(path: &Path) -> Result<String> {
|
||||||
|
use path_absolutize::Absolutize;
|
||||||
|
|
||||||
|
Ok(path
|
||||||
|
.absolutize()?
|
||||||
|
.to_path_buf()
|
||||||
|
.file_name()
|
||||||
|
.ok_or("Current path does not include directory name".to_string())?
|
||||||
|
.to_str()
|
||||||
|
.ok_or("Current directory name is not a valid UTF-8 string".to_string())?
|
||||||
|
.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// Post-creation actions for newly setup crates.
|
/// Post-creation actions for newly setup crates.
|
||||||
// Also used by `init`.
|
pub(crate) fn post_create(path: &Path) -> Result<()> {
|
||||||
pub(crate) fn post_create(path: &Path, metadata: Option<Metadata>) -> Result<()> {
|
let parent_dir = path.parent();
|
||||||
|
let metadata = if parent_dir.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
match cargo_metadata::MetadataCommand::new()
|
||||||
|
.current_dir(parent_dir.unwrap())
|
||||||
|
.exec()
|
||||||
|
{
|
||||||
|
Ok(v) => Some(v),
|
||||||
|
// Only 1 error means that CWD isn't a cargo project.
|
||||||
|
Err(cargo_metadata::Error::CargoMetadata { .. }) => None,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(Error::Other(anyhow::anyhow!(
|
||||||
|
"Couldn't retrieve cargo metadata: {:?}",
|
||||||
|
err
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 1. Add the new project to the workspace, if it exists.
|
// 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.
|
// This must be executed first in order to run `cargo fmt` on the new project.
|
||||||
metadata.and_then(|metadata| {
|
metadata.and_then(|metadata| {
|
||||||
@@ -183,3 +202,199 @@ fn remove_triple_newlines(string: &str) -> String {
|
|||||||
}
|
}
|
||||||
new_string
|
new_string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) mod tests {
|
||||||
|
use escargot::{CargoBuild, CargoRun};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::fs::{create_dir_all, read_to_string};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use toml::Value;
|
||||||
|
|
||||||
|
static BINARY: Lazy<CargoRun> = Lazy::new(|| {
|
||||||
|
CargoBuild::new()
|
||||||
|
.bin(env!("CARGO_BIN_NAME"))
|
||||||
|
.current_release()
|
||||||
|
.run()
|
||||||
|
.expect("Couldn't build the binary for tests.")
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note: tests below (at least 6 of them) were written to mainly test
|
||||||
|
// correctness of project's directory and its name, because previously it
|
||||||
|
// was broken and tests bring a peace of mind. And also so that I don't have
|
||||||
|
// to run my local hand-made tests every time.
|
||||||
|
|
||||||
|
pub(crate) type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
|
pub(crate) fn subcommand(name: &str) -> Command {
|
||||||
|
let mut command = BINARY.command();
|
||||||
|
command
|
||||||
|
.arg(name)
|
||||||
|
.arg("--yes") // Skip any questions by choosing default answers.
|
||||||
|
.arg("--subtemplate")
|
||||||
|
// Probably should use some template that doesn't require specifying
|
||||||
|
// either `--subtemplate` or `--option`.
|
||||||
|
// Maybe a simple template in tests/ dir?
|
||||||
|
.arg("Fullstack");
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_cargo_toml_path(project_path: &Path) -> PathBuf {
|
||||||
|
project_path.join("Cargo.toml")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_project_name(cargo_toml_path: &Path) -> Result<String> {
|
||||||
|
Ok(toml::from_str::<Value>(&read_to_string(cargo_toml_path)?)?
|
||||||
|
.get("package")
|
||||||
|
.unwrap()
|
||||||
|
.get("name")
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subcommand_new() -> Command {
|
||||||
|
subcommand("new")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_dot_path() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = project_dir;
|
||||||
|
|
||||||
|
let temp_dir = tempdir()?;
|
||||||
|
// Make current dir's name deterministic.
|
||||||
|
let current_dir = temp_dir.path().join(project_dir);
|
||||||
|
create_dir_all(¤t_dir)?;
|
||||||
|
let project_path = ¤t_dir;
|
||||||
|
assert!(project_path.exists());
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg(".")
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(project_path);
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_1_dir_path() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = project_dir;
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg(project_dir)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_2_dir_path() -> Result<()> {
|
||||||
|
let project_dir = "a/b";
|
||||||
|
let project_name = "b";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg(project_dir)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_dot_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let temp_dir = tempdir()?;
|
||||||
|
// Make current dir's name deterministic.
|
||||||
|
let current_dir = temp_dir.path().join(project_dir);
|
||||||
|
create_dir_all(¤t_dir)?;
|
||||||
|
let project_path = ¤t_dir;
|
||||||
|
assert!(project_path.exists());
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.arg(".")
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(project_path);
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_1_dir_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg(project_dir)
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_new_with_2_dir_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "a/b";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_new()
|
||||||
|
.arg(project_dir)
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
+190
-26
@@ -3,19 +3,43 @@ use crate::cli::create::DEFAULT_TEMPLATE;
|
|||||||
use cargo_generate::{GenerateArgs, TemplatePath};
|
use cargo_generate::{GenerateArgs, TemplatePath};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
#[derive(Clone, Debug, Default, Deserialize, Parser)]
|
||||||
pub(crate) struct Init {
|
#[clap(name = "init")]
|
||||||
|
pub struct Init {
|
||||||
|
/// Create a new Dioxus project at PATH
|
||||||
|
#[arg(default_value = ".")]
|
||||||
|
path: PathBuf,
|
||||||
|
|
||||||
|
/// Project name. Defaults to directory name
|
||||||
|
#[arg(short, long)]
|
||||||
|
name: Option<String>,
|
||||||
|
|
||||||
/// Template path
|
/// Template path
|
||||||
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
|
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
|
||||||
template: String,
|
template: String,
|
||||||
|
|
||||||
/// Pass <option>=<value> for the used template (e.g., `foo=bar`)
|
/// Branch to select when using `template` from a git repository.
|
||||||
#[clap(short, long)]
|
/// Mutually exclusive with: `--revision`, `--tag`.
|
||||||
option: Vec<String>,
|
#[clap(long, conflicts_with_all(["revision", "tag"]))]
|
||||||
|
branch: Option<String>,
|
||||||
|
|
||||||
|
/// A commit hash to select when using `template` from a git repository.
|
||||||
|
/// Mutually exclusive with: `--branch`, `--tag`.
|
||||||
|
#[clap(long, conflicts_with_all(["branch", "tag"]))]
|
||||||
|
revision: Option<String>,
|
||||||
|
|
||||||
|
/// Tag to select when using `template` from a git repository.
|
||||||
|
/// Mutually exclusive with: `--branch`, `--revision`.
|
||||||
|
#[clap(long, conflicts_with_all(["branch", "revision"]))]
|
||||||
|
tag: Option<String>,
|
||||||
|
|
||||||
/// Specify a sub-template within the template repository to be used as the actual template
|
/// Specify a sub-template within the template repository to be used as the actual template
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
subtemplate: Option<String>,
|
subtemplate: Option<String>,
|
||||||
|
|
||||||
|
/// Pass <option>=<value> for the used template (e.g., `foo=bar`)
|
||||||
|
#[clap(short, long)]
|
||||||
|
option: Vec<String>,
|
||||||
|
|
||||||
/// Skip user interaction by using the default values for the used template.
|
/// Skip user interaction by using the default values for the used template.
|
||||||
/// Default values can be overridden with `--option`
|
/// Default values can be overridden with `--option`
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
@@ -23,41 +47,181 @@ pub(crate) struct Init {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Init {
|
impl Init {
|
||||||
pub(crate) fn init(self) -> Result<StructuredOutput> {
|
pub fn init(mut self) -> Result<StructuredOutput> {
|
||||||
let metadata = cargo_metadata::MetadataCommand::new().exec().ok();
|
// Project name defaults to directory name.
|
||||||
|
if self.name.is_none() {
|
||||||
// Get directory name.
|
self.name = Some(create::name_from_path(&self.path)?);
|
||||||
let name = std::env::current_dir()?
|
}
|
||||||
.file_name()
|
|
||||||
.map(|f| f.to_str().unwrap().to_string());
|
|
||||||
|
|
||||||
// https://github.com/console-rs/dialoguer/issues/294
|
|
||||||
ctrlc::set_handler(move || {
|
|
||||||
let _ = console::Term::stdout().show_cursor();
|
|
||||||
std::process::exit(0);
|
|
||||||
})
|
|
||||||
.expect("ctrlc::set_handler");
|
|
||||||
|
|
||||||
let args = GenerateArgs {
|
let args = GenerateArgs {
|
||||||
define: self.option,
|
define: self.option,
|
||||||
|
destination: Some(self.path),
|
||||||
init: true,
|
init: true,
|
||||||
name,
|
name: self.name,
|
||||||
silent: self.yes,
|
silent: self.yes,
|
||||||
template_path: TemplatePath {
|
template_path: TemplatePath {
|
||||||
auto_path: Some(self.template),
|
auto_path: Some(self.template),
|
||||||
|
branch: self.branch,
|
||||||
|
revision: self.revision,
|
||||||
subfolder: self.subtemplate,
|
subfolder: self.subtemplate,
|
||||||
|
tag: self.tag,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
vcs: if metadata.is_some() {
|
|
||||||
Some(cargo_generate::Vcs::None)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
create::restore_cursor_on_sigint();
|
||||||
let path = cargo_generate::generate(args)?;
|
let path = cargo_generate::generate(args)?;
|
||||||
create::post_create(&path, metadata)?;
|
create::post_create(&path)?;
|
||||||
|
|
||||||
Ok(StructuredOutput::Success)
|
Ok(StructuredOutput::Success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{fs::create_dir_all, process::Command};
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
use super::create::tests::*;
|
||||||
|
|
||||||
|
// Note: tests below (at least 6 of them) were written to mainly test
|
||||||
|
// correctness of project's directory and its name, because previously it
|
||||||
|
// was broken and tests bring a peace of mind. And also so that I don't have
|
||||||
|
// to run my local hand-made tests every time.
|
||||||
|
|
||||||
|
fn subcommand_init() -> Command {
|
||||||
|
subcommand("init")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_default_path() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = project_dir;
|
||||||
|
|
||||||
|
let temp_dir = tempdir()?;
|
||||||
|
// Make current dir's name deterministic.
|
||||||
|
let current_dir = temp_dir.path().join(project_dir);
|
||||||
|
create_dir_all(¤t_dir)?;
|
||||||
|
let project_path = ¤t_dir;
|
||||||
|
assert!(project_path.exists());
|
||||||
|
|
||||||
|
assert!(subcommand_init().current_dir(¤t_dir).status().is_ok());
|
||||||
|
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(project_path);
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_1_dir_path() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = project_dir;
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_init()
|
||||||
|
.arg(project_dir)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_2_dir_path() -> Result<()> {
|
||||||
|
let project_dir = "a/b";
|
||||||
|
let project_name = "b";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_init()
|
||||||
|
.arg(project_dir)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_default_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let temp_dir = tempdir()?;
|
||||||
|
// Make current dir's name deterministic.
|
||||||
|
let current_dir = temp_dir.path().join(project_dir);
|
||||||
|
create_dir_all(¤t_dir)?;
|
||||||
|
let project_path = ¤t_dir;
|
||||||
|
assert!(project_path.exists());
|
||||||
|
|
||||||
|
assert!(subcommand_init()
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(project_path);
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_1_dir_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "dir";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_init()
|
||||||
|
.arg(project_dir)
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subcommand_init_with_2_dir_path_and_custom_name() -> Result<()> {
|
||||||
|
let project_dir = "a/b";
|
||||||
|
let project_name = "project";
|
||||||
|
|
||||||
|
let current_dir = tempdir()?;
|
||||||
|
|
||||||
|
assert!(subcommand_init()
|
||||||
|
.arg(project_dir)
|
||||||
|
.arg("--name")
|
||||||
|
.arg(project_name)
|
||||||
|
.current_dir(¤t_dir)
|
||||||
|
.status()
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
|
let project_path = current_dir.path().join(project_dir);
|
||||||
|
let cargo_toml_path = get_cargo_toml_path(&project_path);
|
||||||
|
assert!(project_path.exists());
|
||||||
|
assert!(cargo_toml_path.exists());
|
||||||
|
assert_eq!(get_project_name(&cargo_toml_path)?, project_name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ pub(crate) enum Commands {
|
|||||||
#[clap(name = "new")]
|
#[clap(name = "new")]
|
||||||
New(create::Create),
|
New(create::Create),
|
||||||
|
|
||||||
/// Init a new project for Dioxus in an existing directory.
|
/// Init a new project for Dioxus in the current directory (by default).
|
||||||
/// Will attempt to keep your project in a good state.
|
/// Will attempt to keep your project in a good state.
|
||||||
#[clap(name = "init")]
|
#[clap(name = "init")]
|
||||||
Init(init::Init),
|
Init(init::Init),
|
||||||
|
|||||||
Reference in new issue
Block a user