History

[hours-demo] clap

Sebastian Thiel committed 5 years ago

Commit b0e4f041 parent 17258cc3 files · +61 −34Browse files

Unified · Split

3 files
  1. Cargo.lock +13 −1
  2. examples/hours/Cargo.toml +1 −1
  3. examples/hours/src/main.rs +47 −32
Cargo.lock+13−1
@@ -272,6 +272,7 @@ dependencies = [ · 271 unmodified lines
272272 "os_str_bytes",
273273 "strsim",
274274 "termcolor",
275+ "terminal_size",
275276 "textwrap 0.12.1",
276277 "unicode-width",
277278 "vec_map",
@@ -1067,7 +1068,7 @@ name = "hours" · 789 unmodified lines
10671068 version = "0.1.0"
10681069 dependencies = [
10691070 "anyhow",
1070− "dashmap",
1071+ "clap 3.0.0-beta.2",
10711072 "git-hash",
10721073 "git-object",
10731074 "git-odb",
@@ -2024,6 +2025,16 @@ dependencies = [ · 950 unmodified lines
20242025 "winapi-util",
20252026 ]
20262027
2028+[[package]]
2029+name = "terminal_size"
2030+version = "0.1.16"
2031+source = "registry+https://github.com/rust-lang/crates.io-index"
2032+checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
2033+dependencies = [
2034+ "libc",
2035+ "winapi",
2036+]
2037+
20272038 [[package]]
20282039 name = "termion"
20292040 version = "1.5.6"
@@ -2051,6 +2062,7 @@ version = "0.12.1" · 21 unmodified lines
20512062 source = "registry+https://github.com/rust-lang/crates.io-index"
20522063 checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
20532064 dependencies = [
2065+ "terminal_size",
20542066 "unicode-width",
20552067 ]
20562068
examples/hours/Cargo.toml+1−1
@@ -14,5 +14,5 @@ git-traverse = { version = "0.1", path = "../../git-traverse" } · 13 unmodified lines
1414 git-hash = { version = "^0.3", path = "../../git-hash" }
1515 git-object = { version = "^0.8", path = "../../git-object" }
1616 rayon = "1.5.0"
17−dashmap = "4.0.2"
1817 itertools = "0.10.0"
18+clap = { version = "=3.0.0-beta.2", default-features = true, features = ["wrap_help"] }
examples/hours/src/main.rs+47−32
@@ -1,44 +1,59 @@
11 use anyhow::{anyhow, bail};
2+use clap::Clap;
23 use git_hash::{bstr::ByteSlice, ObjectId};
34 use git_object::bstr::BString;
45 use git_odb::find::FindExt;
56 use git_traverse::commit;
67 use itertools::Itertools;
78 use rayon::prelude::*;
8−use std::{path::PathBuf, time::Instant};
9+use std::{
10+ ffi::{OsStr, OsString},
11+ path::PathBuf,
12+ time::Instant,
13+};
14+
15+fn is_repo_inner(dir: &OsStr) -> anyhow::Result<()> {
16+ let p = PathBuf::from(dir).join(".git").canonicalize()?;
17+ if p.extension().unwrap_or_default() == "git"
18+ || p.file_name().unwrap_or_default() == ".git"
19+ || p.join("HEAD").is_file()
20+ {
21+ Ok(())
22+ } else {
23+ Err(anyhow!(
24+ "Path '{}' needs to be a directory containing '.git/'",
25+ p.display()
26+ ))
27+ }
28+}
29+
30+fn is_repo(dir: &OsStr) -> Result<(), String> {
31+ is_repo_inner(dir).map_err(|err| err.to_string())
32+}
33+
34+#[derive(Clap)]
35+#[clap(name = "git-hours", about = "Estimate hours worked basted on a commit history", version = clap::crate_version!())]
36+struct Opts {
37+ /// The directory containing a '.git/' folder.
38+ #[clap(parse(from_os_str))]
39+ #[clap(validator_os = is_repo)]
40+ working_dir: PathBuf,
41+ /// The name of the ref like 'main' or 'master' at which to start iterating the commit graph.
42+ refname: OsString,
43+ /// Omit personally identifyable information, leaving only the summary.
44+ #[clap(short = 'p' long)]
45+ omit_pii: bool,
46+}
947
1048 fn main() -> anyhow::Result<()> {
11− let mut args = std::env::args();
12− let repo_git_dir = args
13− .nth(1)
14− .ok_or_else(|| anyhow!("First argument is the .git directory to work in"))
15− .and_then(|p| {
16− let p = PathBuf::from(p).join(".git").canonicalize()?;
17− if p.extension().unwrap_or_default() == "git"
18− || p.file_name().unwrap_or_default() == ".git"
19− || p.join("HEAD").is_file()
20− {
21− Ok(p)
22− } else {
23− Err(anyhow!(
24− "Path '{}' needs to be a directory containing '.git/'",
25− p.display()
26− ))
27− }
28− })?;
29− let commit_id = args
30− .next()
31− .ok_or_else(|| {
32− anyhow!("Second argument is the name of the branch from which to start iteration, like 'main' or 'master'")
33− })
34− .and_then(|name| {
35− ObjectId::from_hex(
36− &std::fs::read(repo_git_dir.join("refs").join("heads").join(name))?
37− .as_bstr()
38− .trim(),
39− )
40− .map_err(Into::into)
41− })?;
49+ let opts: Opts = Opts::parse();
50+ let repo_git_dir = opts.working_dir.join(".git");
51+ let commit_id = ObjectId::from_hex(
52+ &std::fs::read(repo_git_dir.join("refs").join("heads").join(opts.refname))?
53+ .as_bstr()
54+ .trim(),
55+ )?;
56+
4257 let repo_objects_dir = {
4358 let mut d = repo_git_dir;
4459 d.push("objects");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t