diary_cli/
cli.rs

1use clap::*;
2use crate::archive::Archive;
3use crate::*;
4use soulog::*;
5
6pub static mut VERBOSE: bool = false;
7
8#[derive(Parser)]
9#[command(author, version, about)]
10pub struct Cli {
11    #[arg(short, long, help="Specifies if you want it to log everything it does")]
12    pub verbose: bool,
13    #[command(subcommand)]
14    pub command: Commands,
15}
16
17#[derive(Subcommand)]
18pub enum Commands {
19    #[command(about="A mere test command")]
20    Test,
21    #[command(about="Initialises a new archive")]
22    Init,
23    #[command(about="Wipes the archive")]
24    Wipe,
25    #[command(about="Commit an entry into the archive")]
26    Commit {
27        #[arg(index=1, required=true, help="The path to the entry config toml file to commit.")]
28        file_path: String,
29    },
30    #[command(about="Backs up the archive")]
31    Backup {
32        #[arg(index=1, required=false, help="Specifies the path that you want the backup file to be generated.")]
33        out_path: Option<String>,
34    },
35    #[command(about="Loads a backed up archive")]
36    Load {
37        #[arg(short, long, help="Force loads a backup even if you may lose archive data.")]
38        force: bool,
39        #[arg(index=1, required=true, help="The path of the backup file you want to load.")]
40        file_path: String,
41    },
42    #[command(about="Rolls back to the last backed up archive")]
43    Rollback {
44        #[arg(short, long, help="Force loads a backup even if you may lose archive data.")]
45        force: bool,
46    },
47    #[command(about="Returns the days since 2020 from a specified date")]
48    Since {
49        #[arg(short, long, number_of_values=3, value_names=&["year", "month", "day"])]
50        date: Option<Vec<u16>>,
51        #[arg(short, long)]
52        today: bool,
53    },
54    #[command(about="Pulls a entry or moc from the archive as toml in case you need to change something")]
55    Pull {
56        #[arg(short='m', long, help="Specifies if it is a moc or not (otherwise it is an entry).")]
57        is_moc: bool,
58        #[arg(index=1, required=true, help="The uid of the entry or moc.")]
59        uid: String,
60        #[arg(short='1', long, help="Specifies if you want it all in one file.")]
61        one_file: bool,
62        #[arg(short, long, default_value=".", help="Specfies path of the containing folder of the config file.")]
63        path: String,
64        #[arg(short, long, default_value="config.toml", help="Specifies the name of the output config file.")]
65        file_name: String,
66    },
67    #[command(about="Searches the archive with specified tags.")]
68    List {
69        #[arg(short='f', long="filter", num_args=1.., help="Filters out the list accordding to specified tags")]
70        tags: Option<Vec<String>>,
71        #[arg(short, long, requires="tags", help="Sets if the search is strict or not (if the item must implement all tags)")]
72        strict: bool,
73        #[arg(short='e', long, help="Sets if you want to show entries")]
74        show_entries: bool,
75        #[arg(short='m', long, help="Sets if you want to show mocs")]
76        show_mocs: bool,
77    },
78    #[command(about="Sorts the unsorted, committed, entries.")]
79    Sort,
80    #[command(about="Exports the archive as an `Obsidian.md` vault.")]
81    Export {
82        #[arg(short, long, num_args=1.., help="Filters out entries and mocs that don't have all these tags")]
83        tags: Option<Vec<String>>,
84        #[arg(short, long, requires="tags", help="Determines if the tags filter strictly or not")]
85        strict: bool,
86        #[arg(index=1, required=true, help="The path the `Obsidian.md` vault is going to be placed")]
87        path: String,
88    },
89    #[command(about="Lists the attributes about an entry or moc.")]
90    About {
91        #[arg(short='m', long, help="Determines if it is a moc or not")]
92        is_moc: bool,
93        #[arg(index=1, required=true, help="The uid of the entry or moc")]
94        uid: String,
95    },
96    #[command(about="Removes an entry or moc from the archive.")]
97    Remove {
98        #[arg(short='m', long, help="Determines if it is a moc or not")]
99        is_moc: bool,
100        #[arg(index=1)]
101        uid: String,
102    },
103}
104
105impl Commands {
106    pub fn execute(self) {
107        use Commands::*;
108        let logger = DynamicLogger::new();
109        match self {
110            Test => println!("Hello, world!"),
111            Init => {Archive::init(logger);},
112            Wipe => Archive::load(logger.hollow()).wipe(logger),
113            Commit { file_path } => Archive::load(logger.hollow()).commit(file_path, logger),
114            Load { file_path, force } => Archive::load_backup(file_path, force, logger),
115            Rollback { force } => Archive::rollback(force, logger),
116            Backup { out_path } => {
117                match out_path {
118                    Some(path) => Archive::backup(path, logger),
119                    None => Archive::backup(home_dir().join("backup.ldb"), logger),
120                }
121            },
122            Since { date, today: _ } => since::since_2023(date, logger),
123            Pull { is_moc, one_file, uid, path, file_name } => pull::pull(std::path::PathBuf::from(path), file_name, is_moc, uid, one_file, logger),
124            List { strict, tags, show_entries, show_mocs } => search::list_command(strict, show_mocs, show_entries, tags, logger),
125            Sort => sort::sort(logger),
126            Export { strict, tags, path } => export::export_md(strict, tags, path, logger.hollow()),
127            About { is_moc, uid } => about::about(is_moc, uid, logger),
128            Remove { is_moc, uid } => uncommit::uncommmit(uid, is_moc, logger),
129        }
130    }
131}
132
133pub fn run() {
134    let args = Cli::parse();
135    unsafe { VERBOSE = args.verbose };
136    args.command.execute();
137}