Skip to content

Commit a9d6947

Browse files
committed
Auto merge of #8707 - dtolnay:plain, r=ehuss
Add plain message format for locate-project Supersedes #8683, as recommended in #8683 (comment). This PR adds a flag `--message-format` to `cargo locate-project` with possible values `json` (default) and `plain`. ```console $ cargo locate-project --message-format json {"root":"/git/cargo/Cargo.toml"} $ cargo locate-project --message-format plain /git/cargo/Cargo.toml ``` Closes #8009.
2 parents c369b8c + 9ecf5e9 commit a9d6947

File tree

8 files changed

+96
-8
lines changed

8 files changed

+96
-8
lines changed

src/bin/cargo/commands/locate_project.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
use crate::command_prelude::*;
2+
use anyhow::bail;
3+
use cargo::{drop_println, CargoResult};
24
use serde::Serialize;
35

46
pub fn cli() -> App {
57
subcommand("locate-project")
68
.about("Print a JSON representation of a Cargo.toml file's location")
79
.arg(opt("quiet", "No output printed to stdout").short("q"))
810
.arg_manifest_path()
11+
.arg(
12+
opt(
13+
"message-format",
14+
"Output representation [possible values: json, plain]",
15+
)
16+
.value_name("FMT"),
17+
)
918
.after_help("Run `cargo help locate-project` for more detailed information.\n")
1019
}
1120

@@ -29,6 +38,29 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
2938

3039
let location = ProjectLocation { root };
3140

32-
config.shell().print_json(&location);
41+
match MessageFormat::parse(args)? {
42+
MessageFormat::Json => config.shell().print_json(&location),
43+
MessageFormat::Plain => drop_println!(config, "{}", location.root),
44+
}
45+
3346
Ok(())
3447
}
48+
49+
enum MessageFormat {
50+
Json,
51+
Plain,
52+
}
53+
54+
impl MessageFormat {
55+
fn parse(args: &ArgMatches<'_>) -> CargoResult<Self> {
56+
let fmt = match args.value_of("message-format") {
57+
Some(fmt) => fmt,
58+
None => return Ok(MessageFormat::Json),
59+
};
60+
match fmt.to_ascii_lowercase().as_str() {
61+
"json" => Ok(MessageFormat::Json),
62+
"plain" => Ok(MessageFormat::Plain),
63+
s => bail!("invalid message format specifier: `{}`", s),
64+
}
65+
}
66+
}

src/doc/man/cargo-locate-project.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ workspace root.
2121
### Display Options
2222

2323
{{#options}}
24+
25+
{{#option "`--message-format` _fmt_" }}
26+
The representation in which to print the project location. Valid values:
27+
28+
- `json` (default): JSON object with the path under the key "root".
29+
- `plain`: Just the path.
30+
{{/option}}
31+
2432
{{> options-display }}
2533
{{/options}}
2634

src/doc/man/generated_txt/cargo-locate-project.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ DESCRIPTION
1616

1717
OPTIONS
1818
Display Options
19+
--message-format fmt
20+
The representation in which to print the project location. Valid
21+
values:
22+
23+
o json (default): JSON object with the path under the key "root".
24+
25+
o plain: Just the path.
26+
1927
-v, --verbose
2028
Use verbose output. May be specified twice for "very verbose" output
2129
which includes extra output such as dependency warnings and build

src/doc/src/commands/cargo-locate-project.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ workspace root.
2121
### Display Options
2222

2323
<dl>
24+
25+
<dt class="option-term" id="option-cargo-locate-project---message-format"><a class="option-anchor" href="#option-cargo-locate-project---message-format"></a><code>--message-format</code> <em>fmt</em></dt>
26+
<dd class="option-desc">The representation in which to print the project location. Valid values:</p>
27+
<ul>
28+
<li><code>json</code> (default): JSON object with the path under the key &quot;root&quot;.</li>
29+
<li><code>plain</code>: Just the path.</li>
30+
</ul></dd>
31+
32+
2433
<dt class="option-term" id="option-cargo-locate-project--v"><a class="option-anchor" href="#option-cargo-locate-project--v"></a><code>-v</code></dt>
2534
<dt class="option-term" id="option-cargo-locate-project---verbose"><a class="option-anchor" href="#option-cargo-locate-project---verbose"></a><code>--verbose</code></dt>
2635
<dd class="option-desc">Use verbose output. May be specified twice for &quot;very verbose&quot; output which

src/etc/_cargo

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ _cargo() {
160160
;;
161161

162162
locate-project)
163-
_arguments -s -S $common $manifest
163+
_arguments -s -S $common $manifest \
164+
'--message-format=[specify output representation]:output representation [json]:(json plain)'
164165
;;
165166

166167
login)
@@ -367,8 +368,7 @@ _cargo_package_names() {
367368
# Extracts the values of "name" from the array given in $1 and shows them as
368369
# command line options for completion
369370
_cargo_names_from_array() {
370-
# strip json from the path
371-
local manifest=${${${"$(cargo locate-project)"}%\"\}}##*\"}
371+
local manifest=$(cargo locate-project --message-format plain)
372372
if [[ -z $manifest ]]; then
373373
return 0
374374
fi

src/etc/cargo.bashcomp.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ _cargo()
5959
local opt__help="$opt_help"
6060
local opt__init="$opt_common $opt_lock --bin --lib --name --vcs --edition --registry"
6161
local opt__install="$opt_common $opt_feat $opt_jobs $opt_lock $opt_force --bin --bins --branch --debug --example --examples --git --list --path --rev --root --tag --version --registry --target --profile --no-track"
62-
local opt__locate_project="$opt_common $opt_mani $opt_lock"
62+
local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format"
6363
local opt__login="$opt_common $opt_lock --registry"
6464
local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version=1 --no-deps --filter-platform"
6565
local opt__new="$opt_common $opt_lock --vcs --bin --lib --name --edition --registry"
@@ -155,9 +155,7 @@ complete -F _cargo cargo
155155
__cargo_commands=$(cargo --list 2>/dev/null | awk 'NR>1 {print $1}')
156156

157157
_locate_manifest(){
158-
local manifest=`cargo locate-project 2>/dev/null`
159-
# regexp-replace manifest '\{"root":"|"\}' ''
160-
echo ${manifest:9:${#manifest}-11}
158+
cargo locate-project --message-format plain 2>/dev/null
161159
}
162160

163161
# Extracts the values of "name" from the array given in $1 and shows them as

src/etc/man/cargo-locate-project.1

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ workspace root.
1616
.SH "OPTIONS"
1717
.SS "Display Options"
1818
.sp
19+
\fB\-\-message\-format\fR \fIfmt\fR
20+
.RS 4
21+
The representation in which to print the project location. Valid values:
22+
.sp
23+
.RS 4
24+
\h'-04'\(bu\h'+02'\fBjson\fR (default): JSON object with the path under the key "root".
25+
.RE
26+
.sp
27+
.RS 4
28+
\h'-04'\(bu\h'+02'\fBplain\fR: Just the path.
29+
.RE
30+
.RE
31+
.sp
1932
\fB\-v\fR,
2033
\fB\-\-verbose\fR
2134
.RS 4

tests/testsuite/locate_project.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,23 @@ fn simple() {
1414
))
1515
.run();
1616
}
17+
18+
#[cargo_test]
19+
fn message_format() {
20+
let p = project().build();
21+
let root_manifest_path = p.root().join("Cargo.toml");
22+
let root_str = root_manifest_path.to_str().unwrap();
23+
24+
p.cargo("locate-project --message-format plain")
25+
.with_stdout(root_str)
26+
.run();
27+
28+
p.cargo("locate-project --message-format json")
29+
.with_stdout(format!(r#"{{"root":"{}"}}"#, root_str))
30+
.run();
31+
32+
p.cargo("locate-project --message-format cryptic")
33+
.with_stderr("error: invalid message format specifier: `cryptic`")
34+
.with_status(101)
35+
.run();
36+
}

0 commit comments

Comments
 (0)