mirror of
https://github.com/archtechx/todo-system.git
synced 2025-12-12 00:54:03 +00:00
CLI arg parsing
This commit is contained in:
parent
15c2c7d3f0
commit
574cee8895
4 changed files with 318 additions and 27 deletions
216
Cargo.lock
generated
216
Cargo.lock
generated
|
|
@ -2,6 +2,222 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "todo-system"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
name = "todo-system"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Samuel Štancl <samuel@archte.ch>"]
|
||||
description = "An intuitive system for organizing TODOs in code"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.4.8", features = ["derive"] }
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ That said, this repo includes a simple CLI tool written in Rust for getting an e
|
|||
|
||||
Usage:
|
||||
```
|
||||
todos src/
|
||||
todos --exclude node_modules src/
|
||||
```
|
||||
|
||||
Output:
|
||||
|
|
@ -131,3 +131,8 @@ Output:
|
|||
```
|
||||
|
||||
(without the HTML comments).
|
||||
|
||||
Notes:
|
||||
- `node_modules/` (for npm) and `vendor/` (for composer) are ignored by default
|
||||
- paths starting with `.` are **always** ignored
|
||||
- `--exclude`s are relative to the current working directory, not passed paths (including default excludes mentioned above). If you're running the script for another folder and want to exclude folders there, type out the path in `--exclude`
|
||||
|
|
|
|||
119
src/main.rs
119
src/main.rs
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{io, fs};
|
||||
use std::path::{Path, PathBuf};
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
struct Location {
|
||||
|
|
@ -32,6 +33,25 @@ impl Entry {
|
|||
}
|
||||
}
|
||||
|
||||
struct Stats {
|
||||
visited_folders: usize,
|
||||
visited_files: usize,
|
||||
}
|
||||
|
||||
impl Stats {
|
||||
fn new() -> Stats {
|
||||
Stats {
|
||||
visited_folders: 0,
|
||||
visited_files: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn print(&self) {
|
||||
eprintln!("[INFO] Visited folders: {}", self.visited_folders);
|
||||
eprintln!("[INFO] Visited files: {}", self.visited_files);
|
||||
}
|
||||
}
|
||||
|
||||
fn scan_string(str: String, filename: PathBuf, entries: &mut Vec<Entry>) {
|
||||
for (line_num, line) in str.lines().enumerate() {
|
||||
if ! line.to_lowercase().contains("todo") {
|
||||
|
|
@ -44,7 +64,7 @@ fn scan_string(str: String, filename: PathBuf, entries: &mut Vec<Entry>) {
|
|||
}
|
||||
|
||||
// Handles: `todo`, `TODO`, `todo:`, `TODO:`
|
||||
// todo `replace` isnt ideal, it should only replace *after* the todo, to avoid merging eg `to:do`
|
||||
// todo@real `replace` isnt ideal, it should only replace *after* the todo, to avoid merging eg `to:do`
|
||||
if word.to_lowercase().replace(':', "") == "todo" {
|
||||
let text_dirty = line.split_once(word).unwrap().1.replace("*/", "");
|
||||
let text = text_dirty.trim();
|
||||
|
|
@ -113,7 +133,6 @@ fn scan_string(str: String, filename: PathBuf, entries: &mut Vec<Entry>) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo test this using sample.ts
|
||||
fn scan_file(path: &Path, entries: &mut Vec<Entry>) -> io::Result<()> {
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(str) => scan_string(str, path.to_path_buf(), entries),
|
||||
|
|
@ -123,27 +142,27 @@ fn scan_file(path: &Path, entries: &mut Vec<Entry>) -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn scan_dir(path: &Path, entries: &mut Vec<Entry>) -> io::Result<()> {
|
||||
for entry in fs::read_dir(path)? {
|
||||
fn scan_dir(path: &Path, entries: &mut Vec<Entry>, excludes: &Vec<PathBuf>, stats: &mut Stats) -> io::Result<()> {
|
||||
stats.visited_folders += 1;
|
||||
|
||||
'entry: for entry in fs::read_dir(path)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
|
||||
if path.components().last().unwrap().as_os_str().to_string_lossy().starts_with('.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if path.is_dir() {
|
||||
// todo make these configurable
|
||||
if path.ends_with("node_modules") {
|
||||
continue;
|
||||
for exclude in excludes {
|
||||
if path == *exclude {
|
||||
continue 'entry;
|
||||
}
|
||||
}
|
||||
|
||||
if path.ends_with("vendor") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if path.ends_with(".git") {
|
||||
continue;
|
||||
}
|
||||
|
||||
scan_dir(path.as_path(), entries)?
|
||||
scan_dir(path.as_path(), entries, excludes, stats)?
|
||||
} else {
|
||||
stats.visited_files += 1;
|
||||
scan_file(path.as_path(), entries)?
|
||||
}
|
||||
}
|
||||
|
|
@ -233,21 +252,66 @@ fn render(entries: Vec<Entry>) {
|
|||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = std::env::args();
|
||||
let mut root_dir: PathBuf = std::env::current_dir().unwrap();
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Path to your README.md file
|
||||
#[arg(short, long, default_value = "")]
|
||||
readme: String,
|
||||
|
||||
if args.len() > 1 {
|
||||
for arg in args.skip(1) {
|
||||
root_dir.push(arg);
|
||||
}
|
||||
// Path to your todo.md file
|
||||
#[arg(short, long, default_value = "")]
|
||||
todos: String,
|
||||
|
||||
// Paths to search
|
||||
#[arg(default_values_t = Vec::from([".".to_string()]))]
|
||||
paths: Vec<String>,
|
||||
|
||||
// Paths to exclude
|
||||
#[arg(short, long, default_values_t = Vec::from([
|
||||
"node_modules".to_string(),
|
||||
"vendor".to_string(),
|
||||
]))]
|
||||
exclude: Vec<String>,
|
||||
|
||||
#[arg(short, long, default_value_t = false)]
|
||||
verbose: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let root_dir: PathBuf = std::env::current_dir().unwrap();
|
||||
let mut paths: Vec<PathBuf> = vec![];
|
||||
let mut excludes: Vec<PathBuf> = vec![];
|
||||
|
||||
for p in args.paths {
|
||||
let mut path = root_dir.clone();
|
||||
path.push(p);
|
||||
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
let mut entries: Vec<Entry> = vec![];
|
||||
for exclude in args.exclude {
|
||||
let mut path = root_dir.clone();
|
||||
path.push(exclude);
|
||||
|
||||
scan_dir(root_dir.as_path(), &mut entries).unwrap();
|
||||
excludes.push(path);
|
||||
}
|
||||
|
||||
// todo@real logic for readme.md and todos.md
|
||||
|
||||
let mut entries: Vec<Entry> = vec![];
|
||||
let mut stats = Stats::new();
|
||||
|
||||
scan_dir(root_dir.as_path(), &mut entries, &excludes, &mut stats).unwrap();
|
||||
|
||||
render(entries);
|
||||
|
||||
if args.verbose {
|
||||
eprint!("\n\n");
|
||||
stats.print();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -515,7 +579,10 @@ fn sample_test_ts() {
|
|||
let mut filepath = path.clone();
|
||||
filepath.push("1.ts");
|
||||
|
||||
scan_dir(path.as_path(), &mut entries).unwrap();
|
||||
let excludes: Vec<PathBuf> = vec![];
|
||||
let mut stats = Stats::new();
|
||||
|
||||
scan_dir(path.as_path(), &mut entries, &excludes, &mut stats).unwrap();
|
||||
|
||||
assert_eq!(10, entries.len());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue