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