diff --git a/.phil-project b/.phil-project index c411e96..a77f874 100644 --- a/.phil-project +++ b/.phil-project @@ -1,4 +1,4 @@ logo:assets/logo.png logo_small:assets/logo.png description_translate:de -version:0.2.2 +version:0.3.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index cc868b9..8ad6f08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ --- +## [v0.3.0](https://github.com/cophilot/templify/tree/0.3.0) (2024-2-6) + +- Bug fixes +- Added `command` argument for the `help` command to display help for a specific command +- Command `generate` uses pattern matching to determine the type of template to generate +- Added `-strict` flag for `generate` command to disable pattern matching + +--- + ## [v0.2.2](https://github.com/cophilot/templify/tree/0.2.2) (2024-2-5) - Added `-force` flag for `load` command diff --git a/Cargo.lock b/Cargo.lock index 0256dda..e7ef38e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -784,7 +784,7 @@ dependencies = [ [[package]] name = "templify" -version = "0.2.2" +version = "0.3.0" dependencies = [ "reqwest", "self-replace", diff --git a/Cargo.toml b/Cargo.toml index 2e63298..4417172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "templify" -version = "0.2.2" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 8669ab0..67e9331 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ last commit + + docs + stars @@ -25,6 +28,10 @@ --- +For a more detailed documentation visit the [templify-docs](https://templify.philipp-bonin.com/). + +--- + - [Concept](#concept) - [Installation](#installation) - [Linux](#linux) @@ -206,10 +213,12 @@ tpy load https://github.com/cophilot/templify-vault/tree/main/React-ts ## [Release Notes](https://github.com/cophilot/templify/blob/master/CHANGELOG.md) -### [v0.2.2](https://github.com/cophilot/templify/tree/0.2.2) +### [v0.3.0](https://github.com/cophilot/templify/tree/0.3.0) -- Added `-force` flag for `load` command -- Added `-version` flag for `update` command +- Bug fixes +- Added `command` argument for the `help` command to display help for a specific command +- Command `generate` uses pattern matching to determine the type of template to generate +- Added `-strict` flag for `generate` command to disable pattern matching --- diff --git a/install b/install index 77131c1..fd0ecfd 100755 --- a/install +++ b/install @@ -18,6 +18,10 @@ do esac done +if [[ $version == v* ]]; then + version=${version:1} +fi + echo "Installing templify..." echo "This will install a binary to $homePath and add it to your PATH." if [ "$yesFlag" = false ]; then diff --git a/src/command_storage.rs b/src/command_storage.rs index 0b60ece..5431a75 100644 --- a/src/command_storage.rs +++ b/src/command_storage.rs @@ -6,12 +6,19 @@ pub fn get_all_commands() -> Vec { // *** help *** - let help_com = Command::new( + let mut help_com = Command::new( vec!["help".to_string(), "h".to_string()], commands::help, "Show this help message.".to_string(), ); + help_com.add_argument(Argument::new( + "command".to_string(), + 0, + false, + "The command to show help for.".to_string(), + )); + commands.push(help_com); // *** version *** @@ -138,6 +145,11 @@ pub fn get_all_commands() -> Vec { "The name of the new file.".to_string(), )); + generate_com.add_flag(Flag::new_bool_flag( + vec!["strict".to_string()], + "If enabled the template name must match exactly.".to_string(), + )); + commands.push(generate_com); return commands; diff --git a/src/commands.rs b/src/commands.rs index f14ec1a..4fdd65c 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -69,17 +69,41 @@ pub fn generate(command: &Command) -> Status { return st; } - let template_name = command.get_argument("template-name").value.clone(); + let strict = command.get_bool_flag("strict"); + + let mut template_name = command.get_argument("template-name").value.clone(); + let parsed_template_name = template_name.clone().to_lowercase().to_string(); + let template_name_raw = template_name.clone().to_string(); + let given_name = command.get_argument("new-name").value.clone(); let paths = std::fs::read_dir(".templates").unwrap(); let mut found = false; for path in paths { let path = path.unwrap().path(); - if path.is_dir() && path.file_name().unwrap().to_str().unwrap() == template_name.to_string() - { - found = true; + let path_name = path + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string() + .clone(); + + let parsed_path_name = path_name.clone().to_lowercase().to_string(); + + if path.is_dir() && parsed_path_name.starts_with(parsed_template_name.as_str()) && !strict { + if found { + return Status::error(format!( + "Template {} is not unique. Please use a more specific name.", + template_name_raw + )); + } + template_name = path_name.clone(); + found = true; + } else if path.is_dir() && path_name == template_name && strict { + template_name = path_name.clone(); + found = true; break; } } @@ -202,15 +226,39 @@ pub fn init(command: &Command) -> Status { return Status::ok(); } -pub fn help(_command: &Command) -> Status { - let command_name = unsafe { crate::env::BASE_COMMAND_NAME.clone() }; +pub fn help(command: &Command) -> Status { + let base_command_name = unsafe { crate::env::BASE_COMMAND_NAME.clone() }; + + if command.get_argument("command").is_set { + let mut command_name = command.get_argument("command").value.clone(); + let all_commands = crate::command_storage::get_all_commands(); + for c in all_commands { + if c.names.contains(&command_name) { + command_name = c.names[0].clone(); + println!("templify help center"); + println!(""); + println!("<...> - required"); + println!("[...] - optional"); + println!(""); + println!("Usage: {} {}", base_command_name, command_name); + println!(""); + println!("{}", c.to_help_string()); + println!( + "To get more information please visit: https://templify.philipp-bonin.com/#/command/{}", command_name + ); + + return Status::ok(); + } + } + return Status::error(format!("Command {} not found.", command_name)); + } println!("templify help center"); println!(""); println!("<...> - required"); println!("[...] - optional"); println!(""); - println!("Usage: {} ", command_name); + println!("Usage: {} ", base_command_name); println!(""); println!("Commands:"); diff --git a/src/executer.rs b/src/executer.rs index b26ff9f..b71ee9a 100644 --- a/src/executer.rs +++ b/src/executer.rs @@ -3,13 +3,22 @@ use crate::command_storage; pub fn execute(args: Vec) -> bool { let mut command = command_storage::get_command(&args); let parse_status = command.parse(&args); + let base_command_name = unsafe { crate::env::BASE_COMMAND_NAME.clone() }; + if !parse_status.is_ok { println!("Command parse error: {}", parse_status.message); + println!("Run `{} help` for more information.", base_command_name); + return false; } let execute_status = command.execute(); if !execute_status.is_ok { println!("Command execution error: {}", execute_status.message); + println!( + "Run `{} help {}` for more information.", + base_command_name, command.names[0] + ); + return false; } return true; diff --git a/src/main.rs b/src/main.rs index 01c61b0..3d08777 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,29 +30,7 @@ fn main() { return; } - // match command - /* match args[1].to_lowercase().as_str() { - "help" => commands::help(), - "-h" => commands::help(), - "version" => commands::version(), - "-v" => commands::version(), - "init" => commands::init(), - "i" => commands::init(), - "new" => commands::new(args), - "n" => commands::new(args), - "list" => commands::list(), - "ls" => commands::list(), - "load" => commands::load(args), - "l" => commands::load(args), - "generate" => commands::generate(args), - "g" => commands::generate(args), - "update" => commands::update(), - _ => println!("Unknown command: {}", args[1]), - } */ - if !executer::execute(args) { - let command_name = unsafe { crate::env::BASE_COMMAND_NAME.clone() }; - println!("Run `{} help` for more information.", command_name); std::process::exit(1); } diff --git a/src/utils.rs b/src/utils.rs index 4bd562e..eecc027 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -93,6 +93,11 @@ pub fn load_remote_template_file(path: &str, url: &str, force: bool) { text = text.replace("\\n", "\n"); + // create all subdirs if they don't exist + let path_dir = path.split("/").collect::>(); + let path_dir = path_dir[..path_dir.len() - 1].join("/"); + std::fs::create_dir_all(path_dir.clone()).unwrap(); + let mut new_file = std::fs::File::create(path).unwrap(); new_file.write_all(text.as_bytes()).unwrap();