Skip to content

Commit

Permalink
Merge pull request #37 from pwnxpl0it/config_option
Browse files Browse the repository at this point in the history
feat: Added option to change default config path
  • Loading branch information
pwnxpl0it authored Jun 28, 2024
2 parents 8510dba + 37e9dab commit 85fd7f1
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 45 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ path="src/cli/main.rs"
chrono = "0.4.34"
clap = { version = "3.2.17", features = ["derive"] }
colored = "2.0.0"
dirs = "5.0.1"
indexmap = "2.2.6"
promptly = "0.3.1"
regex = "1.7.1"
serde = { version = "1.0.152", features = ["serde_derive"] }
shellexpand = "3.1.0"
toml = "0.5.9"
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ note that the template `info` section can be totally ignored, straight to the po
-->
Default templates path is `~/.config/idkmng/templates`<br>

> [!NOTE]
> You can use -c option to override the config path if you needed to.
The template structure is like the following:
```toml
[info]
Expand Down Expand Up @@ -236,7 +239,8 @@ Also there is one more time saving way! if you have some files in `/foo/bar/` yo

## Special Keywords 🔧
You can have your own Keywords for idkmng to replace with desired values!
Idkmng finds them stored in $HOME/.config/idkmng/config.toml
Idkmng finds them stored in $HOME/.config/idkmng/config.toml Or the config path you specified using -c/--config option 🦀

```toml
[Keywords]
AUTHOR = "Mohamed Tarek"
Expand Down
8 changes: 8 additions & 0 deletions src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ impl Cli {
.short('q')
.requires("template"),
)
.arg(
Arg::with_name("config")
.long("config")
.short('c')
.help("Config path")
.default_value("~/.config/idkmng/config.toml")
.requires("template")
)
.subcommand(Command::new("init").about("Creates a template for the current directory"))
.get_matches()
}
Expand Down
7 changes: 5 additions & 2 deletions src/cli/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use idkmng::config::Config;
use idkmng::types::Template;
mod args;
use args::Cli;
Expand All @@ -6,6 +7,8 @@ use colored::*;
fn main() {
let args = Cli::parse();

let config = Config::new(args.value_of("config").unwrap());

if args.subcommand_matches("init").is_some() {
let dest = format!(
"{}.toml",
Expand All @@ -19,13 +22,13 @@ fn main() {
println!("{}: {}", "Creating Template".bold().green(), &dest.yellow());
Template::generate(&dest);
} else if let Some(filename) = args.value_of("template") {
let template = Template::validate(filename.to_string());
let template = Template::validate(filename.to_string(), config.templates_path.clone());
println!("\n{}: {}", "Using Template".blue(), &template.magenta());
if !args.is_present("quiet") {
Template::show_info(&Template::parse(&template, true));
}

Template::extract(template, true);
Template::extract(template, true, config);
} else {
println!(
"{} {}",
Expand Down
28 changes: 19 additions & 9 deletions src/core/config.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
use crate::keywords::Keywords;
use crate::types::Template;
use crate::utils::gethome;
use std::collections::HashMap;
use std::fs;
use toml::Value;

pub const CONFIG_PATH: &str = "{{$HOME}}/.config/idkmng/config.toml";
pub const TEMPLATES_PATH: &str = "{{$HOME}}/.config/idkmng/templates/";
pub const KEYWORDS_FORMAT: &str = "{{$%s:f}}";
pub const KEYWORDS_REGEX: &str = r"\{\{\$[^\s}]+(:[^\s}]+)?\}\}";

pub struct Config {
pub path: String,
pub templates_path: String,
}

impl Config {
pub fn new(path: &str) -> Self {
let config_path = shellexpand::tilde(path).to_string();
let mut config_dir: Vec<&str> = path.split("/").collect();

config_dir.pop();

//NOTE: maybe templates path should be parsed from config.toml itself??
let templates = config_dir.join("/") + "/templates/";

Config {
path: config_path,
templates_path: shellexpand::tilde(&templates).to_string(),
}
}

pub fn init(self) {
// this sample is just a template that create config.toml and the new.toml template for the
// first time, Now something maybe confusing is the "initPJNAME" wtf is it ?
Expand All @@ -29,7 +42,7 @@ description = "A Template for making a template"
author = "Mohamed Tarek @pwnxpl0it"
[[files]]
path="~/.config/idkmng/templates/initPJNAME.toml"
path="TEMPLATES_PATH/initPJNAME.toml"
content="""
[info]
name = "initPJNAME"
Expand All @@ -51,12 +64,9 @@ content = '''
'''
"#
.replace("CONFIGPATH", &self.path)
.replace(
"TEMPLATES_PATH",
&TEMPLATES_PATH.replace("{{$HOME}}", &gethome()),
);
.replace("TEMPLATES_PATH", &self.templates_path);

Template::extract(sample, false);
Template::extract(sample, false, self);
}

pub fn get_keywords(self) -> HashMap<String, String> {
Expand Down
10 changes: 3 additions & 7 deletions src/core/keywords.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::config::{Config, CONFIG_PATH, KEYWORDS_FORMAT};
use crate::utils::gethome;
use crate::config::{Config, KEYWORDS_FORMAT};
use chrono::Datelike;
use std::{collections::HashMap, env};

Expand All @@ -20,7 +19,7 @@ impl Keywords {
}
}

pub fn init() -> HashMap<String, String> {
pub fn init(config: Config) -> HashMap<String, String> {
let mut keywords = HashMap::new();
keywords.insert(
Self::new(String::from("HOME"), "".to_string()),
Expand Down Expand Up @@ -71,10 +70,7 @@ impl Keywords {
chrono::Local::now().day().to_string(),
);

let other_keywords = Config {
path: CONFIG_PATH.replace("{{$HOME}}", &gethome()),
}
.get_keywords();
let other_keywords = config.get_keywords();

keywords.extend(other_keywords);
keywords
Expand Down
29 changes: 13 additions & 16 deletions src/core/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ impl Template {
}

/// This method "extracts" a template, means it takes a template and starts initializing files based that template
pub fn extract(template: String, is_file: bool) {
pub fn extract(template: String, is_file: bool, config: Config) {
let mut keywords: HashMap<String, String>;
let re = Regex::new(KEYWORDS_REGEX).unwrap();

keywords = Keywords::init();
keywords = Keywords::init(config);

let sample = Self::parse(&template, is_file);

Expand All @@ -77,17 +77,14 @@ impl Template {
let path = Keywords::replace_keywords(keywords.to_owned(), file.path.to_owned());

if dir.len() > 1 {
create_dirs(
&Keywords::replace_keywords(
keywords.to_owned(),
file.path.to_owned().replace(dir[dir.len() - 1], ""),
)
.replace('~', &gethome()),
)
create_dirs(&shellexpand::tilde(&Keywords::replace_keywords(
keywords.to_owned(),
file.path.to_owned().replace(dir[dir.len() - 1], ""),
)))
}

write_content(
&path.replace('~', &gethome()),
&shellexpand::tilde(&path),
Keywords::replace_keywords(keywords.to_owned(), file.content),
)
});
Expand All @@ -108,9 +105,9 @@ impl Template {
toml::from_str(&content).unwrap()
}

/// This method validates Template path, in other words it just checks if the template is in
/// the current working Directory,if not it uses the default templates directory, also automatically adds .toml
pub fn validate(mut template: String) -> String {
/// This method validates template path, in other words it just checks if the template is in
/// the current working directory,if not it uses the default templates directory, also automatically adds .toml
pub fn validate(mut template: String, template_path: String) -> String {
if template.contains(".toml") {
//IGNORE
} else {
Expand All @@ -120,14 +117,14 @@ impl Template {
if fs::read_to_string(&template).is_ok() {
//IGNORE
} else {
template = TEMPLATES_PATH.replace("{{$HOME}}", &gethome()) + &template
template = template_path + &template
}

template
}

/// This method shows information about current Template, basically Reads them from Information
/// section in the Template TOML file
/// This method shows information about current template, basically Reads them from Information
/// section in the template TOML file
pub fn show_info(template: &Self) {
match &template.info {
Some(information) => println!(
Expand Down
9 changes: 0 additions & 9 deletions src/core/utils.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
use crate::types::Fns;
use colored::*;
use dirs;
use regex::Regex;
use std::{collections::HashMap, fs, path::Path};

pub fn gethome() -> String {
dirs::home_dir()
.expect("Failed to know home directory")
.to_str()
.unwrap()
.to_string()
}

pub fn create_dirs(dir: &str) {
match fs::create_dir_all(dir) {
Ok(_) => println!("{}: {}", "creating directory".blue(), dir.bold().green()),
Expand Down

0 comments on commit 85fd7f1

Please sign in to comment.