diff --git a/Cargo.lock b/Cargo.lock index 8cc3fbb..819b246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -28,24 +28,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -67,9 +66,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys", @@ -87,12 +86,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" - [[package]] name = "block-buffer" version = "0.10.4" @@ -120,9 +113,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "cc" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -169,20 +162,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.19" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", @@ -192,9 +184,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", @@ -204,9 +196,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -255,27 +247,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fnv" version = "1.0.7" @@ -322,7 +293,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" dependencies = [ - "bitflags 1.3.2", + "bitflags", "ignore", "walkdir", ] @@ -333,12 +304,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - [[package]] name = "humansize" version = "2.1.3" @@ -388,17 +353,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] - [[package]] name = "itoa" version = "1.0.9" @@ -422,9 +376,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libm" @@ -432,12 +386,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" -[[package]] -name = "linux-raw-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" - [[package]] name = "log" version = "0.4.20" @@ -571,9 +519,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -647,16 +595,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] -name = "rustix" -version = "0.38.6" +name = "rust-embed" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" +checksum = "b1e7d90385b59f0a6bf3d3b757f3ca4ece2048265d70db20a2016043d4509a40" dependencies = [ - "bitflags 2.3.3", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3d8c6fd84090ae348e63a84336b112b5c3918b3bf0493a581f7bd8ee623c29" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada" +dependencies = [ + "globset", + "sha2", + "walkdir", ] [[package]] @@ -743,16 +713,16 @@ version = "0.1.0" dependencies = [ "clap", "regex", + "rust-embed", "serde", "tera", - "walkdir", ] [[package]] name = "syn" -version = "2.0.31" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -875,9 +845,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" @@ -979,9 +949,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -1012,9 +982,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1027,42 +997,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 6e25c34..4d0d257 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ edition = "2021" [dependencies] clap = { version = "4.3.19", features = ["derive"] } regex = "1.9.1" -walkdir = "2.3.3" tera = "1.19.0" -serde = { version = "1.0", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } +rust-embed = { version = "8.0.0", features = ["include-exclude"] } \ No newline at end of file diff --git a/Readme.md b/Readme.md index d8dd2fa..a758b68 100644 --- a/Readme.md +++ b/Readme.md @@ -3,4 +3,10 @@ Install *nix: ``` sudo wget -c https://github.com/nstreamio/swim-create/releases/latest/download/swim-create-x86_64-unknown-linux-gnu.tar.gz | sudo tar -xz -C /usr/local/bin +``` + +Releasing a new version: +``` +git tag VERSION (e.g. v0.1.0) +git push origin VERSION ``` \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index 197aa16..62adc04 100644 --- a/src/error.rs +++ b/src/error.rs @@ -7,6 +7,7 @@ use std::fmt::Display; pub(crate) enum CliError { CreateDir { dir: String, description: String }, CreateFile { file: String, description: String }, + MissingFile { file: String }, ProjectName, } @@ -19,6 +20,10 @@ impl CliError { CreateFile { file, description } } + pub(crate) fn missing_file_err(file: String) -> Self { + CliError::MissingFile { file } + } + pub(crate) fn project_name_err() -> Self { CliError::ProjectName } @@ -29,12 +34,19 @@ impl Error for CliError {} impl Display for CliError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - CliError::CreateDir { dir, description } => { + CreateDir { dir, description } => { write!(f, "Unable to create directory '{}': {}!", dir, description) } - CliError::CreateFile { file, description } => { + CreateFile { file, description } => { write!(f, "Unable to write file '{}': {}!", file, description) } + CliError::MissingFile { file } => { + write!( + f, + "Unable to write file '{}': Source file is missing!", + file + ) + } CliError::ProjectName => { write!(f, "The project name must start with a letter and contain only alphanumeric characters and underscores!") } diff --git a/src/main.rs b/src/main.rs index 8f55479..5977ee0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,12 @@ mod utils; use crate::utils::*; use clap::Parser; +use rust_embed::RustEmbed; use serde::Serialize; use std::fmt::Debug; -use walkdir::WalkDir; +use std::path::Path; -const PROJECT_TEMPLATE_FOLDER: &str = "templates/swim-template"; +const PROJECT_TEMPLATE_FOLDER: &str = "swim-template"; #[derive(Parser, Debug, Serialize)] #[command(author, version, about, long_about = None)] @@ -24,26 +25,23 @@ struct Args { swim_version: String, } +#[derive(RustEmbed)] +#[folder = "templates"] +#[exclude = "swim-template/.git/*"] +struct Templates; + fn main() { let args = Args::parse(); - for path in WalkDir::new(PROJECT_TEMPLATE_FOLDER) - .into_iter() - .filter_entry(|e| !is_hidden(e)) - .filter_map(|e| e.ok()) - .map(|entry| entry.into_path()) - { - // Creates the directories and files recursively - if path.is_dir() { - if let Err(err) = create_dir(&path, &args) { - println!("{}", err); - std::process::exit(1) - } - } else if path.is_file() { - if let Err(err) = create_file(&path, &args) { - println!("{}", err); - std::process::exit(1) - } + if let Err(err) = create_dir(args.name.clone()) { + println!("{}", err); + std::process::exit(1) + } + + for path in Templates::iter() { + if let Err(err) = create_file(Path::new(&path.to_string()), &args) { + println!("{}", err); + std::process::exit(1) } } diff --git a/src/utils.rs b/src/utils.rs index 3961227..bc81a6a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,12 +1,11 @@ use crate::error::CliError; -use crate::{Args, PROJECT_TEMPLATE_FOLDER}; +use crate::{Args, Templates, PROJECT_TEMPLATE_FOLDER}; use regex::Regex; use serde::Serialize; use std::error::Error; use std::fs; use std::path::Path; use tera::Tera; -use walkdir::DirEntry; pub(crate) fn validate_name(name: &str) -> Result { let name = name.trim().to_lowercase(); @@ -21,20 +20,17 @@ pub(crate) fn validate_name(name: &str) -> Result { } } -pub(crate) fn is_hidden(entry: &DirEntry) -> bool { - entry - .file_name() - .to_str() - .map(|s| s.starts_with('.')) - .unwrap_or(false) +pub(crate) fn create_dir(dir: String) -> Result<(), CliError> { + fs::create_dir(&dir).map_err(|err| CliError::create_dir_err(dir, err.kind().to_string()))?; + Ok(()) } -pub(crate) fn create_dir(input_dir: &Path, args: &Args) -> Result<(), CliError> { - let output_dir = get_output_dir(input_dir, args).map_err(|err| { - CliError::create_dir_err(input_dir.display().to_string(), err.to_string()) - })?; - fs::create_dir(&output_dir) - .map_err(|err| CliError::create_dir_err(output_dir, err.kind().to_string()))?; +pub(crate) fn create_parent_dirs(file: &str) -> Result<(), CliError> { + if let Some(parent_dirs) = Path::new(file).parent() { + fs::create_dir_all(parent_dirs).map_err(|err| { + CliError::create_dir_err(parent_dirs.display().to_string(), err.kind().to_string()) + })?; + } Ok(()) } @@ -42,10 +38,18 @@ pub(crate) fn create_file(input_file: &Path, args: &Args) -> Result<(), CliError let output_file = get_output_dir(input_file, args).map_err(|err| { CliError::create_file_err(input_file.display().to_string(), err.to_string()) })?; - let input_text = fs::read_to_string(input_file) - .map_err(|err| CliError::create_file_err(output_file.clone(), err.kind().to_string()))?; + + create_parent_dirs(&output_file)?; + + let input_file = Templates::get(&input_file.display().to_string()) + .ok_or(CliError::missing_file_err(output_file.clone()))?; + + let input_text = String::from_utf8(input_file.data.to_vec()) + .map_err(|err| CliError::create_file_err(output_file.clone(), err.to_string()))?; + let output_text = replace_text(&input_text, args) .map_err(|err| CliError::create_file_err(output_file.clone(), err.to_string()))?; + fs::write(&output_file, output_text) .map_err(|err| CliError::create_file_err(output_file, err.kind().to_string()))?;