##// END OF EJS Templates
rhg: Group values passed to every sub-command into a struct...
Simon Sapin -
r47334:80840b65 default
parent child Browse files
Show More
@@ -1,14 +1,10 b''
1 1 use crate::error::CommandError;
2 use crate::ui::Ui;
3 2 use clap::Arg;
4 use clap::ArgMatches;
5 use hg::config::Config;
6 3 use hg::operations::cat;
7 4 use hg::repo::Repo;
8 5 use hg::utils::hg_path::HgPathBuf;
9 6 use micro_timer::timed;
10 7 use std::convert::TryFrom;
11 use std::path::Path;
12 8
13 9 pub const HELP_TEXT: &str = "
14 10 Output the current or given revision of files
@@ -36,19 +32,14 b" pub fn args() -> clap::App<'static, 'sta"
36 32 }
37 33
38 34 #[timed]
39 pub fn run(
40 ui: &Ui,
41 config: &Config,
42 repo_path: Option<&Path>,
43 args: &ArgMatches,
44 ) -> Result<(), CommandError> {
45 let rev = args.value_of("rev");
46 let file_args = match args.values_of("files") {
35 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
36 let rev = invocation.subcommand_args.value_of("rev");
37 let file_args = match invocation.subcommand_args.values_of("files") {
47 38 Some(files) => files.collect(),
48 39 None => vec![],
49 40 };
50 41
51 let repo = Repo::find(config, repo_path)?;
42 let repo = Repo::find(invocation.non_repo_config, invocation.repo_path)?;
52 43 let cwd = hg::utils::current_dir()?;
53 44
54 45 let mut files = vec![];
@@ -67,7 +58,7 b' pub fn run('
67 58 match rev {
68 59 Some(rev) => {
69 60 let data = cat(&repo, rev, &files).map_err(|e| (e, rev))?;
70 ui.write_stdout(&data)?;
61 invocation.ui.write_stdout(&data)?;
71 62 Ok(())
72 63 }
73 64 None => Err(CommandError::Unimplemented.into()),
@@ -1,13 +1,9 b''
1 1 use crate::error::CommandError;
2 use crate::ui::Ui;
3 2 use clap::Arg;
4 use clap::ArgMatches;
5 3 use format_bytes::format_bytes;
6 use hg::config::Config;
7 4 use hg::errors::HgError;
8 5 use hg::repo::Repo;
9 6 use hg::utils::SliceExt;
10 use std::path::Path;
11 7
12 8 pub const HELP_TEXT: &str = "
13 9 With one argument of the form section.name, print just the value of that config item.
@@ -25,20 +21,16 b" pub fn args() -> clap::App<'static, 'sta"
25 21 .about(HELP_TEXT)
26 22 }
27 23
28 pub fn run(
29 ui: &Ui,
30 config: &Config,
31 repo_path: Option<&Path>,
32 args: &ArgMatches,
33 ) -> Result<(), CommandError> {
34 let opt_repo = Repo::find_optional(config, repo_path)?;
24 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
25 let opt_repo =
26 Repo::find_optional(invocation.non_repo_config, invocation.repo_path)?;
35 27 let config = if let Some(repo) = &opt_repo {
36 28 repo.config()
37 29 } else {
38 config
30 invocation.non_repo_config
39 31 };
40
41 let (section, name) = args
32 let (section, name) = invocation
33 .subcommand_args
42 34 .value_of("name")
43 35 .expect("missing required CLI argument")
44 36 .as_bytes()
@@ -47,6 +39,6 b' pub fn run('
47 39
48 40 let value = config.get(section, name).unwrap_or(b"");
49 41
50 ui.write_stdout(&format_bytes!(b"{}\n", value))?;
42 invocation.ui.write_stdout(&format_bytes!(b"{}\n", value))?;
51 43 Ok(())
52 44 }
@@ -1,13 +1,9 b''
1 1 use crate::error::CommandError;
2 use crate::ui::Ui;
3 2 use clap::Arg;
4 3 use clap::ArgGroup;
5 use clap::ArgMatches;
6 use hg::config::Config;
7 4 use hg::operations::{debug_data, DebugDataKind};
8 5 use hg::repo::Repo;
9 6 use micro_timer::timed;
10 use std::path::Path;
11 7
12 8 pub const HELP_TEXT: &str = "
13 9 Dump the contents of a data file revision
@@ -42,12 +38,8 b" pub fn args() -> clap::App<'static, 'sta"
42 38 }
43 39
44 40 #[timed]
45 pub fn run(
46 ui: &Ui,
47 config: &Config,
48 repo_path: Option<&Path>,
49 args: &ArgMatches,
50 ) -> Result<(), CommandError> {
41 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
42 let args = invocation.subcommand_args;
51 43 let rev = args
52 44 .value_of("rev")
53 45 .expect("rev should be a required argument");
@@ -63,10 +55,10 b' pub fn run('
63 55 }
64 56 };
65 57
66 let repo = Repo::find(config, repo_path)?;
58 let repo = Repo::find(invocation.non_repo_config, invocation.repo_path)?;
67 59 let data = debug_data(&repo, rev, kind).map_err(|e| (e, rev))?;
68 60
69 let mut stdout = ui.stdout_buffer();
61 let mut stdout = invocation.ui.stdout_buffer();
70 62 stdout.write_all(&data)?;
71 63 stdout.flush()?;
72 64
@@ -1,9 +1,5 b''
1 1 use crate::error::CommandError;
2 use crate::ui::Ui;
3 use clap::ArgMatches;
4 use hg::config::Config;
5 2 use hg::repo::Repo;
6 use std::path::Path;
7 3
8 4 pub const HELP_TEXT: &str = "
9 5 Print the current repo requirements.
@@ -13,13 +9,8 b" pub fn args() -> clap::App<'static, 'sta"
13 9 clap::SubCommand::with_name("debugrequirements").about(HELP_TEXT)
14 10 }
15 11
16 pub fn run(
17 ui: &Ui,
18 config: &Config,
19 repo_path: Option<&Path>,
20 _args: &ArgMatches,
21 ) -> Result<(), CommandError> {
22 let repo = Repo::find(config, repo_path)?;
12 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
13 let repo = Repo::find(invocation.non_repo_config, invocation.repo_path)?;
23 14 let mut output = String::new();
24 15 let mut requirements: Vec<_> = repo.requirements().iter().collect();
25 16 requirements.sort();
@@ -27,6 +18,6 b' pub fn run('
27 18 output.push_str(req);
28 19 output.push('\n');
29 20 }
30 ui.write_stdout(output.as_bytes())?;
21 invocation.ui.write_stdout(output.as_bytes())?;
31 22 Ok(())
32 23 }
@@ -1,14 +1,11 b''
1 1 use crate::error::CommandError;
2 2 use crate::ui::Ui;
3 3 use clap::Arg;
4 use clap::ArgMatches;
5 use hg::config::Config;
6 4 use hg::operations::list_rev_tracked_files;
7 5 use hg::operations::Dirstate;
8 6 use hg::repo::Repo;
9 7 use hg::utils::files::{get_bytes_from_path, relativize_path};
10 8 use hg::utils::hg_path::{HgPath, HgPathBuf};
11 use std::path::Path;
12 9
13 10 pub const HELP_TEXT: &str = "
14 11 List tracked files.
@@ -29,23 +26,18 b" pub fn args() -> clap::App<'static, 'sta"
29 26 .about(HELP_TEXT)
30 27 }
31 28
32 pub fn run(
33 ui: &Ui,
34 config: &Config,
35 repo_path: Option<&Path>,
36 args: &ArgMatches,
37 ) -> Result<(), CommandError> {
38 let rev = args.value_of("rev");
29 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
30 let rev = invocation.subcommand_args.value_of("rev");
39 31
40 let repo = Repo::find(config, repo_path)?;
32 let repo = Repo::find(invocation.non_repo_config, invocation.repo_path)?;
41 33 if let Some(rev) = rev {
42 34 let files =
43 35 list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?;
44 display_files(ui, &repo, files.iter())
36 display_files(invocation.ui, &repo, files.iter())
45 37 } else {
46 38 let distate = Dirstate::new(&repo)?;
47 39 let files = distate.tracked_files()?;
48 display_files(ui, &repo, files)
40 display_files(invocation.ui, &repo, files)
49 41 }
50 42 }
51 43
@@ -1,11 +1,7 b''
1 1 use crate::error::CommandError;
2 use crate::ui::Ui;
3 use clap::ArgMatches;
4 2 use format_bytes::format_bytes;
5 use hg::config::Config;
6 3 use hg::repo::Repo;
7 4 use hg::utils::files::get_bytes_from_path;
8 use std::path::Path;
9 5
10 6 pub const HELP_TEXT: &str = "
11 7 Print the root directory of the current repository.
@@ -17,14 +13,11 b" pub fn args() -> clap::App<'static, 'sta"
17 13 clap::SubCommand::with_name("root").about(HELP_TEXT)
18 14 }
19 15
20 pub fn run(
21 ui: &Ui,
22 config: &Config,
23 repo_path: Option<&Path>,
24 _args: &ArgMatches,
25 ) -> Result<(), CommandError> {
26 let repo = Repo::find(config, repo_path)?;
16 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
17 let repo = Repo::find(invocation.non_repo_config, invocation.repo_path)?;
27 18 let bytes = get_bytes_from_path(repo.working_directory_path());
28 ui.write_stdout(&format_bytes!(b"{}\n", bytes.as_slice()))?;
19 invocation
20 .ui
21 .write_stdout(&format_bytes!(b"{}\n", bytes.as_slice()))?;
29 22 Ok(())
30 23 }
@@ -1,9 +1,11 b''
1 1 extern crate log;
2 use crate::ui::Ui;
2 3 use clap::App;
3 4 use clap::AppSettings;
4 5 use clap::Arg;
5 6 use clap::ArgMatches;
6 7 use format_bytes::format_bytes;
8 use hg::config::Config;
7 9 use std::path::Path;
8 10
9 11 mod error;
@@ -48,31 +50,41 b' fn main_with_result(ui: &ui::Ui) -> Resu'
48 50 let (subcommand_name, subcommand_matches) = matches.subcommand();
49 51 let run = subcommand_run_fn(subcommand_name)
50 52 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
51 let args = subcommand_matches
53 let subcommand_args = subcommand_matches
52 54 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
53 55
54 56 // Global arguments can be in either based on e.g. `hg -R ./foo log` v.s.
55 57 // `hg log -R ./foo`
56 let value_of_global_arg =
57 |name| args.value_of_os(name).or_else(|| matches.value_of_os(name));
58 let value_of_global_arg = |name| {
59 subcommand_args
60 .value_of_os(name)
61 .or_else(|| matches.value_of_os(name))
62 };
58 63 // For arguments where multiple occurences are allowed, return a
59 64 // possibly-iterator of all values.
60 65 let values_of_global_arg = |name: &str| {
61 66 let a = matches.values_of_os(name).into_iter().flatten();
62 let b = args.values_of_os(name).into_iter().flatten();
67 let b = subcommand_args.values_of_os(name).into_iter().flatten();
63 68 a.chain(b)
64 69 };
65 70
66 let repo_path = value_of_global_arg("repository").map(Path::new);
67 71 let config_args = values_of_global_arg("config")
68 72 // `get_bytes_from_path` works for OsStr the same as for Path
69 73 .map(hg::utils::files::get_bytes_from_path);
70 let config = hg::config::Config::load(config_args)?;
71 run(&ui, &config, repo_path, args)
74 let non_repo_config = &hg::config::Config::load(config_args)?;
75
76 let repo_path = value_of_global_arg("repository").map(Path::new);
77
78 run(&CliInvocation {
79 ui,
80 subcommand_args,
81 non_repo_config,
82 repo_path,
83 })
72 84 }
73 85
74 86 fn main() {
75 let ui = ui::Ui::new();
87 let ui = Ui::new();
76 88
77 89 let exit_code = match main_with_result(&ui) {
78 90 Ok(()) => exitcode::OK,
@@ -109,12 +121,9 b' macro_rules! subcommands {'
109 121 )+
110 122 }
111 123
112 fn subcommand_run_fn(name: &str) -> Option<fn(
113 &ui::Ui,
114 &hg::config::Config,
115 Option<&Path>,
116 &ArgMatches,
117 ) -> Result<(), CommandError>> {
124 pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
125
126 fn subcommand_run_fn(name: &str) -> Option<RunFn> {
118 127 match name {
119 128 $(
120 129 stringify!($command) => Some(commands::$command::run),
@@ -133,3 +142,9 b' subcommands! {'
133 142 root
134 143 config
135 144 }
145 pub struct CliInvocation<'a> {
146 ui: &'a Ui,
147 subcommand_args: &'a ArgMatches<'a>,
148 non_repo_config: &'a Config,
149 repo_path: Option<&'a Path>,
150 }
General Comments 0
You need to be logged in to leave comments. Login now