Skip to content

Commit

Permalink
v0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cophilot committed Feb 20, 2024
1 parent f6c58a4 commit 95ad370
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .phil-project
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
logo:assets/logo.png
logo_small:assets/logo.png
description_translate:de
version:0.5.0
version:0.6.0
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

---

## [v0.6.0](https://github.com/cophilot/templify/tree/0.6.0) (2024-2-20)

- Refactoring
- Added placeholder `$$month-name$$`
- Added case conversion support for the `name` placeholder

---

## [v0.5.0](https://github.com/cophilot/templify/tree/0.5.0) (2024-2-17)

- Refactoring
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "templify"
version = "0.5.0"
version = "0.6.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
34 changes: 26 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ For a more detailed documentation visit the [templify-docs](https://templify.phi
- [list](#list)
- [generate](#generate)
- [Placeholders](#placeholders)
- [Case conversion](#case-conversion)
- [templify-vault](#templify-vault)
- [Bugs](#bugs)
- [Release Notes](#release-notes)
Expand Down Expand Up @@ -185,9 +186,29 @@ Generates a file from the given template.

## Placeholders

Placeholders are used to replace parts of the template with the given values. They are defined by surrounding a word with two dollar signs (`$$`):
- `$$name$$`: The name of the new file (This placeholder supports case conversion).
- `$$year$$`: The current year.
- `$$month$$`: The current month as a number.
- `$$month-name$$`: The current month as a name.
- `$$day$$`: The current day.
- `$$git-name$$`: The name of the git user.

- `$$name$$` will be replaced with the given name
### Case conversion

Case conversion is used to convert placeholders to different case styles. You can use them by adding a `.` and the case style to a placeholder that supports case conversion.

_Example: `$$name.kebab$$`_

You can use the following case conversion:

- `$$<placeholder>.lower$$`: Lower case (e.g. `mycomponent`)
- `$$<placeholder>.upper$$`: Upper case (e.g. `MYCOMPONENT`)
- `$$<placeholder>.camel$$`: Camel case (e.g. `myComponent`)
- `$$<placeholder>.snake$$`: Snake case (e.g. `my_component`)
- `$$<placeholder>.kebab$$`: Kebab case (e.g. `my-component`)
- `$$<placeholder>.pascal$$`: Pascal case (e.g. `MyComponent`)
- `$$<placeholder>.macro$$`: Macro case (e.g. `MY_COMPONENT`)
- `$$<placeholder>.train$$`: Train case (e.g. `My-Component`)

---

Expand All @@ -213,14 +234,11 @@ tpy load https://github.com/cophilot/templify-vault/tree/main/React-ts

## [Release Notes](https://github.com/cophilot/templify/blob/master/CHANGELOG.md)

### [v0.5.0](https://github.com/cophilot/templify/tree/0.5.0)
### [v0.6.0](https://github.com/cophilot/templify/tree/0.6.0)

- Refactoring
- Added `reload` command
- Added `-name` flag for the `list` command
- Added `-path` flag for the `list` command
- Added `-template` flag for the `load` command
- Support for `.tpykeep` file to prevent a directory from being deleted
- Added placeholder `$$month-name$$`
- Added case conversion support for the `name` placeholder

---

Expand Down
6 changes: 6 additions & 0 deletions src/command_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ pub fn get_all_commands() -> Vec<Command> {
"If enabled the file will not be created and the output will be printed.".to_string(),
));

/* generate_com.add_flag(Flag::new_bool_flag(
vec!["force".to_string(), "f".to_string()],
"If enabled files will be overwritten if they already exist.".to_string(),
));
*/

commands.push(generate_com);

return commands;
Expand Down
9 changes: 2 additions & 7 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
formater,
types::{self, Command, Status},
utils, version_control,
};
use chrono::{self, Datelike};
use std::fs::read_dir;

pub fn list(command: &Command) -> Status {
Expand Down Expand Up @@ -179,12 +179,7 @@ pub fn generate(command: &Command) -> Status {
);
let meta = types::TemplateMeta::parse(template_name.clone().to_string());
let mut new_path = meta.get_path();

new_path = new_path.replace("$$name$$", given_name.as_str());
new_path = new_path.replace("$$year$$", chrono::Local::now().year().to_string().as_str());
new_path = new_path.replace("$$month$$", &chrono::Local::now().month().to_string());
new_path = new_path.replace("$$day$$", &chrono::Local::now().day().to_string());
new_path = new_path.replace("$$git-name$$", &utils::get_git_name());
new_path = formater::handle_placeholders(&new_path, &given_name);

// create dir and all subdirs if they don't exist
if !dry_run {
Expand Down
30 changes: 29 additions & 1 deletion src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn get_init_readme_content() -> String {
# Welcome to templify (v{})
This is a README file generated by templify.
_This is a README file generated by templify._
---
Expand Down Expand Up @@ -75,6 +75,34 @@ This will create a new file from the given template in the current project folde
---
## Placeholders
- `$$name$$`: The name of the new file (This placeholder supports case conversion).
- `$$year$$`: The current year.
- `$$month$$`: The current month as a number.
- `$$month-name$$`: The current month as a name.
- `$$day$$`: The current day.
- `$$git-name$$`: The name of the git user.
### Case conversion
Case conversion is used to convert placeholders to different case styles. You can use them by adding a `.` and the case style to a placeholder that supports case conversion.
_Example: `$$name.kebab$$`_
You can use the following case conversion:
- `$$<placeholder>.lower$$`: Lower case (e.g. `mycomponent`)
- `$$<placeholder>.upper$$`: Upper case (e.g. `MYCOMPONENT`)
- `$$<placeholder>.camel$$`: Camel case (e.g. `myComponent`)
- `$$<placeholder>.snake$$`: Snake case (e.g. `my_component`)
- `$$<placeholder>.kebab$$`: Kebab case (e.g. `my-component`)
- `$$<placeholder>.pascal$$`: Pascal case (e.g. `MyComponent`)
- `$$<placeholder>.macro$$`: Macro case (e.g. `MY_COMPONENT`)
- `$$<placeholder>.train$$`: Train case (e.g. `My-Component`)
---
by [Philipp B.](https://github.com/cophilot)
", env!("CARGO_PKG_VERSION"));

Expand Down
110 changes: 110 additions & 0 deletions src/formater.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use chrono::Datelike;

pub fn handle_placeholders(s: &str, name: &str) -> String {
let mut s = s.to_string();

s = s.replace("$$name$$", name);
s = s.replace("$$name.lower$$", name.to_lowercase().as_str());
s = s.replace("$$name.upper$$", name.to_uppercase().as_str());

let tokens = tokenize_string(name);
s = s.replace("$$name.camel$$", &to_camel_case(tokens.clone()));
s = s.replace("$$name.snake$$", &to_snake_case(tokens.clone()));
s = s.replace("$$name.kebab$$", &to_kebab_case(tokens.clone()));
s = s.replace("$$name.pascal$$", &to_pascal_case(tokens.clone()));
s = s.replace("$$name.macro$$", &to_macro_case(tokens.clone()));
s = s.replace("$$name.train$$", &to_train_case(tokens.clone()));

s = s.replace("$$year$$", chrono::Local::now().year().to_string().as_str());
s = s.replace("$$month$$", &chrono::Local::now().month().to_string());
let month_str = match chrono::Local::now().month() {
1 => "Jan",
2 => "Feb",
3 => "Mar",
4 => "Apr",
5 => "May",
6 => "Jun",
7 => "Jul",
8 => "Aug",
9 => "Sep",
10 => "Oct",
11 => "Nov",
12 => "Dec",
_ => "Unknown",
};
s = s.replace("$$month-name$$", month_str);
s = s.replace("$$day$$", &chrono::Local::now().day().to_string());
s = s.replace("$$git-name$$", &crate::utils::get_git_name());
return s;
}

fn to_train_case(tokens: Vec<String>) -> String {
let mut result = String::new();
for (i, token) in tokens.iter().enumerate() {
let newtoken = format!("{}{}", &token[0..1].to_uppercase(), &token[1..]);
if i == 0 {
result.push_str(&newtoken);
} else {
result.push_str(&format!("-{}", newtoken));
}
}
return result;
}

fn to_macro_case(tokens: Vec<String>) -> String {
return tokens.join("_").to_uppercase();
}

fn to_pascal_case(tokens: Vec<String>) -> String {
let mut result = String::new();
for token in tokens {
let newtoken = format!("{}{}", &token[0..1].to_uppercase(), &token[1..]);
result.push_str(&newtoken);
}
return result;
}

fn to_kebab_case(tokens: Vec<String>) -> String {
return tokens.join("-");
}

fn to_snake_case(tokens: Vec<String>) -> String {
return tokens.join("_");
}

fn to_camel_case(tokens: Vec<String>) -> String {
let mut result = String::new();
for (i, token) in tokens.iter().enumerate() {
if i == 0 {
result.push_str(&token);
} else {
let newtoken = format!("{}{}", &token[0..1].to_uppercase(), &token[1..]);
result.push_str(&newtoken);
}
}
return result;
}

fn tokenize_string(input: &str) -> Vec<String> {
let mut result = input.replace('-', " ").replace('_', " ").to_string();
result = result.replace("_", " ");

// replace all uppercase letters with lowercase and a space before
result = result
.chars()
.enumerate()
.map(|(i, c)| {
if c.is_uppercase() && i > 0 {
format!(" {}", c.to_lowercase().to_string())
} else {
c.to_string()
}
})
.collect::<Vec<String>>()
.join("");
return result
.to_lowercase()
.split_whitespace()
.map(|s| s.to_string())
.collect();
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod commands;
mod data;
mod env;
mod executer;
mod formater;
mod types;
mod utils;
mod version_control;
Expand Down
18 changes: 3 additions & 15 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use chrono::{self, Datelike};
use std::{io::Write, path::Path};

use crate::types::Status;
use crate::{formater, types::Status};

pub fn parse_template_name(name: &mut String, strict: bool) -> Status {
let template_name_raw = name.clone().to_string();
Expand Down Expand Up @@ -264,13 +263,7 @@ pub fn generate_template_dir(path: &str, new_path: &str, given_name: &str, dry_r
continue;
}

let mut new_file_name = file_name.replace("$$name$$", given_name);
new_file_name =
new_file_name.replace("$$year$$", chrono::Local::now().year().to_string().as_str());
new_file_name =
new_file_name.replace("$$month$$", &chrono::Local::now().month().to_string());
new_file_name = new_file_name.replace("$$day$$", &chrono::Local::now().day().to_string());
new_file_name = new_file_name.replace("$$git-name$$", &crate::utils::get_git_name());
let new_file_name = formater::handle_placeholders(file_name, given_name);
let new_path = format!("{}/{}", new_path, new_file_name);

// check if new_path already exists
Expand All @@ -295,12 +288,7 @@ pub fn generate_template_dir(path: &str, new_path: &str, given_name: &str, dry_r

pub fn generate_template_file(path: &str, new_path: &str, given_name: &str, dry_run: bool) -> bool {
let file_content = std::fs::read_to_string(path).unwrap();
let mut file_content = file_content.replace("$$name$$", given_name);
file_content =
file_content.replace("$$year$$", chrono::Local::now().year().to_string().as_str());
file_content = file_content.replace("$$month$$", &chrono::Local::now().month().to_string());
file_content = file_content.replace("$$day$$", &chrono::Local::now().day().to_string());
file_content = file_content.replace("$$git-name$$", &crate::utils::get_git_name());
let file_content = formater::handle_placeholders(&file_content, given_name);

if Path::new(new_path).exists() {
println!("File {} already exists.", new_path);
Expand Down

0 comments on commit 95ad370

Please sign in to comment.