Show More
@@ -53,6 +53,14 b' fn main_with_result(' | |||||
53 | // Not ok: `--config section.key1=val section.key2=val2` |
|
53 | // Not ok: `--config section.key1=val section.key2=val2` | |
54 | .number_of_values(1), |
|
54 | .number_of_values(1), | |
55 | ) |
|
55 | ) | |
|
56 | .arg( | |||
|
57 | Arg::with_name("cwd") | |||
|
58 | .help("change working directory") | |||
|
59 | .long("--cwd") | |||
|
60 | .value_name("DIR") | |||
|
61 | .takes_value(true) | |||
|
62 | .global(true), | |||
|
63 | ) | |||
56 | .version("0.0.1"); |
|
64 | .version("0.0.1"); | |
57 | let app = add_subcommand_args(app); |
|
65 | let app = add_subcommand_args(app); | |
58 |
|
66 | |||
@@ -87,6 +95,28 b' fn main() {' | |||||
87 | let ui = ui::Ui::new(); |
|
95 | let ui = ui::Ui::new(); | |
88 |
|
96 | |||
89 | let early_args = EarlyArgs::parse(std::env::args_os()); |
|
97 | let early_args = EarlyArgs::parse(std::env::args_os()); | |
|
98 | ||||
|
99 | let initial_current_dir = early_args.cwd.map(|cwd| { | |||
|
100 | let cwd = get_path_from_bytes(&cwd); | |||
|
101 | std::env::current_dir() | |||
|
102 | .and_then(|initial| { | |||
|
103 | std::env::set_current_dir(cwd)?; | |||
|
104 | Ok(initial) | |||
|
105 | }) | |||
|
106 | .unwrap_or_else(|error| { | |||
|
107 | exit( | |||
|
108 | &None, | |||
|
109 | &ui, | |||
|
110 | OnUnsupported::Abort, | |||
|
111 | Err(CommandError::abort(format!( | |||
|
112 | "abort: {}: '{}'", | |||
|
113 | error, | |||
|
114 | cwd.display() | |||
|
115 | ))), | |||
|
116 | ) | |||
|
117 | }) | |||
|
118 | }); | |||
|
119 | ||||
90 | let non_repo_config = |
|
120 | let non_repo_config = | |
91 | Config::load(early_args.config).unwrap_or_else(|error| { |
|
121 | Config::load(early_args.config).unwrap_or_else(|error| { | |
92 | // Normally this is decided based on config, but we donβt have that |
|
122 | // Normally this is decided based on config, but we donβt have that | |
@@ -94,7 +124,7 b' fn main() {' | |||||
94 | // "unsupported" error but that is not enforced by the type system. |
|
124 | // "unsupported" error but that is not enforced by the type system. | |
95 | let on_unsupported = OnUnsupported::Abort; |
|
125 | let on_unsupported = OnUnsupported::Abort; | |
96 |
|
126 | |||
97 | exit(&ui, on_unsupported, Err(error.into())) |
|
127 | exit(&initial_current_dir, &ui, on_unsupported, Err(error.into())) | |
98 | }); |
|
128 | }); | |
99 |
|
129 | |||
100 | if let Some(repo_path_bytes) = &early_args.repo { |
|
130 | if let Some(repo_path_bytes) = &early_args.repo { | |
@@ -105,6 +135,7 b' fn main() {' | |||||
105 | } |
|
135 | } | |
106 | if SCHEME_RE.is_match(&repo_path_bytes) { |
|
136 | if SCHEME_RE.is_match(&repo_path_bytes) { | |
107 | exit( |
|
137 | exit( | |
|
138 | &initial_current_dir, | |||
108 | &ui, |
|
139 | &ui, | |
109 | OnUnsupported::from_config(&non_repo_config), |
|
140 | OnUnsupported::from_config(&non_repo_config), | |
110 | Err(CommandError::UnsupportedFeature { |
|
141 | Err(CommandError::UnsupportedFeature { | |
@@ -124,6 +155,7 b' fn main() {' | |||||
124 | Err(NoRepoInCwdError { cwd: at }) |
|
155 | Err(NoRepoInCwdError { cwd: at }) | |
125 | } |
|
156 | } | |
126 | Err(error) => exit( |
|
157 | Err(error) => exit( | |
|
158 | &initial_current_dir, | |||
127 | &ui, |
|
159 | &ui, | |
128 | OnUnsupported::from_config(&non_repo_config), |
|
160 | OnUnsupported::from_config(&non_repo_config), | |
129 | Err(error.into()), |
|
161 | Err(error.into()), | |
@@ -142,7 +174,12 b' fn main() {' | |||||
142 | repo_result.as_ref(), |
|
174 | repo_result.as_ref(), | |
143 | config, |
|
175 | config, | |
144 | ); |
|
176 | ); | |
145 | exit(&ui, OnUnsupported::from_config(config), result) |
|
177 | exit( | |
|
178 | &initial_current_dir, | |||
|
179 | &ui, | |||
|
180 | OnUnsupported::from_config(config), | |||
|
181 | result, | |||
|
182 | ) | |||
146 | } |
|
183 | } | |
147 |
|
184 | |||
148 | fn exit_code(result: &Result<(), CommandError>) -> i32 { |
|
185 | fn exit_code(result: &Result<(), CommandError>) -> i32 { | |
@@ -159,6 +196,7 b' fn exit_code(result: &Result<(), Command' | |||||
159 | } |
|
196 | } | |
160 |
|
197 | |||
161 | fn exit( |
|
198 | fn exit( | |
|
199 | initial_current_dir: &Option<PathBuf>, | |||
162 | ui: &Ui, |
|
200 | ui: &Ui, | |
163 | mut on_unsupported: OnUnsupported, |
|
201 | mut on_unsupported: OnUnsupported, | |
164 | result: Result<(), CommandError>, |
|
202 | result: Result<(), CommandError>, | |
@@ -182,7 +220,12 b' fn exit(' | |||||
182 | on_unsupported = OnUnsupported::Abort |
|
220 | on_unsupported = OnUnsupported::Abort | |
183 | } else { |
|
221 | } else { | |
184 | // `args` is now `argv[1..]` since weβve already consumed `argv[0]` |
|
222 | // `args` is now `argv[1..]` since weβve already consumed `argv[0]` | |
185 |
let |
|
223 | let mut command = Command::new(executable_path); | |
|
224 | command.args(args); | |||
|
225 | if let Some(initial) = initial_current_dir { | |||
|
226 | command.current_dir(initial); | |||
|
227 | } | |||
|
228 | let result = command.status(); | |||
186 | match result { |
|
229 | match result { | |
187 | Ok(status) => std::process::exit( |
|
230 | Ok(status) => std::process::exit( | |
188 | status.code().unwrap_or(exitcode::ABORT), |
|
231 | status.code().unwrap_or(exitcode::ABORT), | |
@@ -283,6 +326,8 b' struct EarlyArgs {' | |||||
283 | config: Vec<Vec<u8>>, |
|
326 | config: Vec<Vec<u8>>, | |
284 | /// Value of the `-R` or `--repository` argument, if any. |
|
327 | /// Value of the `-R` or `--repository` argument, if any. | |
285 | repo: Option<Vec<u8>>, |
|
328 | repo: Option<Vec<u8>>, | |
|
329 | /// Value of the `--cwd` argument, if any. | |||
|
330 | cwd: Option<Vec<u8>>, | |||
286 | } |
|
331 | } | |
287 |
|
332 | |||
288 | impl EarlyArgs { |
|
333 | impl EarlyArgs { | |
@@ -290,6 +335,7 b' impl EarlyArgs {' | |||||
290 | let mut args = args.into_iter().map(get_bytes_from_os_str); |
|
335 | let mut args = args.into_iter().map(get_bytes_from_os_str); | |
291 | let mut config = Vec::new(); |
|
336 | let mut config = Vec::new(); | |
292 | let mut repo = None; |
|
337 | let mut repo = None; | |
|
338 | let mut cwd = None; | |||
293 | // Use `while let` instead of `for` so that we can also call |
|
339 | // Use `while let` instead of `for` so that we can also call | |
294 | // `args.next()` inside the loop. |
|
340 | // `args.next()` inside the loop. | |
295 | while let Some(arg) = args.next() { |
|
341 | while let Some(arg) = args.next() { | |
@@ -301,6 +347,14 b' impl EarlyArgs {' | |||||
301 | config.push(value.to_owned()) |
|
347 | config.push(value.to_owned()) | |
302 | } |
|
348 | } | |
303 |
|
349 | |||
|
350 | if arg == b"--cwd" { | |||
|
351 | if let Some(value) = args.next() { | |||
|
352 | cwd = Some(value) | |||
|
353 | } | |||
|
354 | } else if let Some(value) = arg.drop_prefix(b"--cwd=") { | |||
|
355 | cwd = Some(value.to_owned()) | |||
|
356 | } | |||
|
357 | ||||
304 | if arg == b"--repository" || arg == b"-R" { |
|
358 | if arg == b"--repository" || arg == b"-R" { | |
305 | if let Some(value) = args.next() { |
|
359 | if let Some(value) = args.next() { | |
306 | repo = Some(value) |
|
360 | repo = Some(value) | |
@@ -311,7 +365,7 b' impl EarlyArgs {' | |||||
311 | repo = Some(value.to_owned()) |
|
365 | repo = Some(value.to_owned()) | |
312 | } |
|
366 | } | |
313 | } |
|
367 | } | |
314 | Self { config, repo } |
|
368 | Self { config, repo, cwd } | |
315 | } |
|
369 | } | |
316 | } |
|
370 | } | |
317 |
|
371 |
General Comments 0
You need to be logged in to leave comments.
Login now