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 = |
|
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