Skip to content

Commit

Permalink
Add plain message format for locate-project
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Sep 17, 2020
1 parent e4b65bd commit 9ecf5e9
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 8 deletions.
34 changes: 33 additions & 1 deletion src/bin/cargo/commands/locate_project.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
use crate::command_prelude::*;
use anyhow::bail;
use cargo::{drop_println, CargoResult};
use serde::Serialize;

pub fn cli() -> App {
subcommand("locate-project")
.about("Print a JSON representation of a Cargo.toml file's location")
.arg(opt("quiet", "No output printed to stdout").short("q"))
.arg_manifest_path()
.arg(
opt(
"message-format",
"Output representation [possible values: json, plain]",
)
.value_name("FMT"),
)
.after_help("Run `cargo help locate-project` for more detailed information.\n")
}

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

let location = ProjectLocation { root };

config.shell().print_json(&location);
match MessageFormat::parse(args)? {
MessageFormat::Json => config.shell().print_json(&location),
MessageFormat::Plain => drop_println!(config, "{}", location.root),
}

Ok(())
}

enum MessageFormat {
Json,
Plain,
}

impl MessageFormat {
fn parse(args: &ArgMatches<'_>) -> CargoResult<Self> {
let fmt = match args.value_of("message-format") {
Some(fmt) => fmt,
None => return Ok(MessageFormat::Json),
};
match fmt.to_ascii_lowercase().as_str() {
"json" => Ok(MessageFormat::Json),
"plain" => Ok(MessageFormat::Plain),
s => bail!("invalid message format specifier: `{}`", s),
}
}
}
8 changes: 8 additions & 0 deletions src/doc/man/cargo-locate-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ workspace root.
### Display Options

{{#options}}

{{#option "`--message-format` _fmt_" }}
The representation in which to print the project location. Valid values:

- `json` (default): JSON object with the path under the key "root".
- `plain`: Just the path.
{{/option}}

{{> options-display }}
{{/options}}

Expand Down
8 changes: 8 additions & 0 deletions src/doc/man/generated_txt/cargo-locate-project.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ DESCRIPTION

OPTIONS
Display Options
--message-format fmt
The representation in which to print the project location. Valid
values:

o json (default): JSON object with the path under the key "root".

o plain: Just the path.

-v, --verbose
Use verbose output. May be specified twice for "very verbose" output
which includes extra output such as dependency warnings and build
Expand Down
9 changes: 9 additions & 0 deletions src/doc/src/commands/cargo-locate-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ workspace root.
### Display Options

<dl>

<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>
<dd class="option-desc">The representation in which to print the project location. Valid values:</p>
<ul>
<li><code>json</code> (default): JSON object with the path under the key &quot;root&quot;.</li>
<li><code>plain</code>: Just the path.</li>
</ul></dd>


<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>
<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>
<dd class="option-desc">Use verbose output. May be specified twice for &quot;very verbose&quot; output which
Expand Down
6 changes: 3 additions & 3 deletions src/etc/_cargo
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ _cargo() {
;;

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

login)
Expand Down Expand Up @@ -367,8 +368,7 @@ _cargo_package_names() {
# Extracts the values of "name" from the array given in $1 and shows them as
# command line options for completion
_cargo_names_from_array() {
# strip json from the path
local manifest=${${${"$(cargo locate-project)"}%\"\}}##*\"}
local manifest=$(cargo locate-project --message-format plain)
if [[ -z $manifest ]]; then
return 0
fi
Expand Down
6 changes: 2 additions & 4 deletions src/etc/cargo.bashcomp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ _cargo()
local opt__help="$opt_help"
local opt__init="$opt_common $opt_lock --bin --lib --name --vcs --edition --registry"
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"
local opt__locate_project="$opt_common $opt_mani $opt_lock"
local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format"
local opt__login="$opt_common $opt_lock --registry"
local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version=1 --no-deps --filter-platform"
local opt__new="$opt_common $opt_lock --vcs --bin --lib --name --edition --registry"
Expand Down Expand Up @@ -155,9 +155,7 @@ complete -F _cargo cargo
__cargo_commands=$(cargo --list 2>/dev/null | awk 'NR>1 {print $1}')

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

# Extracts the values of "name" from the array given in $1 and shows them as
Expand Down
13 changes: 13 additions & 0 deletions src/etc/man/cargo-locate-project.1
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ workspace root.
.SH "OPTIONS"
.SS "Display Options"
.sp
\fB\-\-message\-format\fR \fIfmt\fR
.RS 4
The representation in which to print the project location. Valid values:
.sp
.RS 4
\h'-04'\(bu\h'+02'\fBjson\fR (default): JSON object with the path under the key "root".
.RE
.sp
.RS 4
\h'-04'\(bu\h'+02'\fBplain\fR: Just the path.
.RE
.RE
.sp
\fB\-v\fR,
\fB\-\-verbose\fR
.RS 4
Expand Down
20 changes: 20 additions & 0 deletions tests/testsuite/locate_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,23 @@ fn simple() {
))
.run();
}

#[cargo_test]
fn message_format() {
let p = project().build();
let root_manifest_path = p.root().join("Cargo.toml");
let root_str = root_manifest_path.to_str().unwrap();

p.cargo("locate-project --message-format plain")
.with_stdout(root_str)
.run();

p.cargo("locate-project --message-format json")
.with_stdout(format!(r#"{{"root":"{}"}}"#, root_str))
.run();

p.cargo("locate-project --message-format cryptic")
.with_stderr("error: invalid message format specifier: `cryptic`")
.with_status(101)
.run();
}

0 comments on commit 9ecf5e9

Please sign in to comment.