Skip to content

Commit

Permalink
add a command-line options to initialize configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
VladimirMarkelov committed Nov 25, 2024
1 parent 3f422f8 commit 1bd9186
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
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 = "ttdl"
version = "4.6.0"
version = "4.6.1"
authors = ["Vladimir Markelov <[email protected]>"]
edition = "2021"
keywords = ["todotxt", "terminal", "cli", "todo", "tasks"]
Expand Down
44 changes: 42 additions & 2 deletions src/conf.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{stdout, BufReader, IsTerminal, Read};
use std::fs::{self, File};
use std::io::{stdout, BufReader, IsTerminal, Read, Write};
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
Expand All @@ -24,6 +24,7 @@ const CONF_FILE: &str = "ttdl.toml";
const TODO_FILE: &str = "todo.txt";
const DONE_FILE: &str = "done.txt";
const EDITOR: &str = "EDITOR";
const DEFAULT_CONFIG: &str = include_str!("../ttdl.toml");

struct RangeEnds {
l: usize,
Expand Down Expand Up @@ -153,6 +154,7 @@ fn print_usage(program: &str, opts: &Options) {

let extras = r#"Extra options:
--dry-run, --sort | -s, --sort-rev, --wrap, --short, --width, --local, --no-colors, --syntax, --no-syntax, --clean-subject, --auto-hide-cols, --auto-show-cols, --always-hide-cols
--interactive | -i, --init, --init-local
"#;
let commands = r#"Available commands:
list | l - list todos
Expand Down Expand Up @@ -1029,6 +1031,33 @@ fn detect_conf_file_path() -> PathBuf {
}
}

fn init_config_file(local: bool) -> Result<()> {
let conf_dir = if local {
PathBuf::from("")
} else {
let mut cfg = match dirs::config_dir() {
None => return Err(anyhow!("Failed to get user's directory for configuration files")),
Some(dir) => dir,
};
cfg.push(APP_DIR);
cfg
};
let mut conf_path = conf_dir.clone();
conf_path.push(CONF_FILE);
if conf_path.exists() {
println!("Configuration file '{0}' already exists.", conf_path.display());
} else {
if !local && !conf_dir.exists() {
fs::create_dir_all(conf_dir.clone())?;
println!("Created directory '{0}'", conf_dir.display());
}
let mut file = File::create(conf_path.clone())?;
file.write_all(DEFAULT_CONFIG.as_bytes())?;
println!("Configuration initialized: '{0}'", conf_path.display());
}
Ok(())
}

fn load_from_config(conf: &mut Conf, conf_path: Option<PathBuf>) -> Result<()> {
let path: PathBuf = match conf_path {
Some(p) => p,
Expand Down Expand Up @@ -1254,6 +1283,8 @@ pub fn parse_args(args: &[String]) -> Result<Conf> {
);
opts.optflag("k", "keep-tags", "in edit mode a new subject replaces regular text of the todo, everything else(tags, priority etc) is taken from the old and appended to the new subject. A convenient way to replace just text and keep all the tags without typing the tags again");
opts.optflag("i", "interactive", "Open an external edit to modify all filtered tasks. If the task list is modified inside an editor, the old tasks will be removed and new ones will be added to the end of the task list. If you do not change anything or save an empty file, the edit operation will be canceled. To set editor, change config.global.editor option or set EDITOR environment variable.");
opts.optflag("", "init", "create a default configuration file in user's configuration directory if the configuration file does not exist yet");
opts.optflag("", "init-local", "create a default configuration file in the current working directory if the configuration file does not exist yet");

let matches: Matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Expand All @@ -1273,6 +1304,15 @@ pub fn parse_args(args: &[String]) -> Result<Conf> {
print_usage(&program, &opts);
exit(0);
}
if matches.opt_present("init") || matches.opt_present("init-local") {
match init_config_file(matches.opt_present("init-local")) {
Ok(()) => exit(0),
Err(e) => {
println!("{e}");
exit(1);
}
}
}
let conf_file = if matches.opt_present("config") { matches.opt_str("config").map(PathBuf::from) } else { None };

load_from_config(&mut conf, conf_file)?;
Expand Down

0 comments on commit 1bd9186

Please sign in to comment.