-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.rs
More file actions
116 lines (98 loc) · 3.11 KB
/
Copy pathmain.rs
File metadata and controls
116 lines (98 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use anyhow::{Result, anyhow};
use good_git::{hash_object, repo::Repo};
use std::{fs, path::Path, path::PathBuf};
use clap::{Args, Parser, Subcommand};
use std::io;
#[derive(Parser)]
#[command(version)]
#[command(about = "A good git client", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Initialize a new empty repo.
Init(InitArgs),
/// Calculates the hash of an object.
HashObject(HashObjectArgs),
/// Prints contents of an object.
CatFile(CatFileArgs),
/// Show a log of the history.
Log(LogArgs),
/// Show a list of references
ShowRef(ShowRefArgs),
}
#[derive(Args)]
struct InitArgs {
#[arg(default_value = ".")]
path: PathBuf,
#[arg(default_value = "master")]
branch: String,
}
#[derive(Args)]
struct HashObjectArgs {
/// Write the object into the object database.
#[arg(short)]
write: bool,
/// Read the object from stdin instead of from a file.
#[arg(long)]
stdin: bool,
#[arg(required_unless_present("stdin"))]
file: Option<PathBuf>,
}
#[derive(Args)]
struct CatFileArgs {
object: String,
}
#[derive(Args)]
struct LogArgs {
object: String,
}
#[derive(Args)]
struct ShowRefArgs {}
fn main() -> Result<()> {
let cli = Cli::parse();
match &cli.command {
Commands::Init(init_args) => {
good_git::init_repo(&Repo::new(&init_args.path), &init_args.branch)?;
}
Commands::HashObject(hash_object_args) => {
let repo = Repo::from_dir(Path::new("."));
let mode = if hash_object_args.write {
good_git::HashObjectMode::Write(
repo.as_ref()
.ok_or_else(|| anyhow!("Could not find a valid git repository"))?,
)
} else {
good_git::HashObjectMode::HashOnly
};
if hash_object_args.stdin {
hash_object(mode, &mut io::stdin(), &mut io::stdout())?;
} else {
let f = hash_object_args
.file
.clone()
.expect("<file> is required when --stdin isn't set");
let f = fs::File::open(f)?;
hash_object(mode, &mut io::BufReader::new(f), &mut io::stdout())?;
}
}
Commands::CatFile(cat_file_args) => {
let repo = Repo::from_dir(Path::new("."))
.ok_or_else(|| anyhow!("Could not find a valid git repository"))?;
good_git::cat_file(&repo, &cat_file_args.object, &mut io::stdout())?;
}
Commands::Log(log_args) => {
let repo = Repo::from_dir(Path::new("."))
.ok_or_else(|| anyhow!("Could not find a valid git repository"))?;
good_git::log(&repo, &log_args.object, &mut io::stdout())?;
}
Commands::ShowRef(_show_ref_args) => {
let repo = Repo::from_dir(Path::new("."))
.ok_or_else(|| anyhow!("Could not find a valid git repository"))?;
good_git::show_ref(&repo, &mut io::stdout())?;
}
}
Ok(())
}