Skip to content

Commit

Permalink
Auto merge of #8712 - dtolnay:workspace, r=ehuss
Browse files Browse the repository at this point in the history
--workspace flag for locate-project to find the workspace root

<pre>
<i>/git/serde/serde_derive</i>$ <b>cargo locate-project</b>
{"root":"<a href="https://github.com/serde-rs/serde/blob/master/serde_derive/Cargo.toml">/git/serde/serde_derive/Cargo.toml</a>"}

<i>/git/serde/serde_derive</i>$ <b>cargo locate-project --workspace</b>
{"root":"<a href="https://github.com/serde-rs/serde/blob/master/Cargo.toml">/git/serde/Cargo.toml</a>"}
</pre>
  • Loading branch information
bors committed Sep 23, 2020
2 parents 4e6fa34 + 17053fc commit 05c611a
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 25 deletions.
29 changes: 28 additions & 1 deletion src/bin/cargo/commands/locate_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn cli() -> App {
)
.value_name("FMT"),
)
.arg(opt("workspace", "Locate Cargo.toml of the workspace root"))
.after_help("Run `cargo help locate-project` for more detailed information.\n")
}

Expand All @@ -24,7 +25,18 @@ pub struct ProjectLocation<'a> {
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let root = args.root_manifest(config)?;
let root_manifest;
let workspace;
let root = match WhatToFind::parse(args) {
WhatToFind::CurrentManifest => {
root_manifest = args.root_manifest(config)?;
&root_manifest
}
WhatToFind::Workspace => {
workspace = args.workspace(config)?;
workspace.root_manifest()
}
};

let root = root
.to_str()
Expand All @@ -46,6 +58,21 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
Ok(())
}

enum WhatToFind {
CurrentManifest,
Workspace,
}

impl WhatToFind {
fn parse(args: &ArgMatches<'_>) -> Self {
if args.is_present("workspace") {
WhatToFind::Workspace
} else {
WhatToFind::CurrentManifest
}
}
}

enum MessageFormat {
Json,
Plain,
Expand Down
21 changes: 10 additions & 11 deletions src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,21 +315,20 @@ impl<'cfg> Workspace<'cfg> {
/// That is, this returns the path of the directory containing the
/// `Cargo.toml` which is the root of this workspace.
pub fn root(&self) -> &Path {
match self.root_manifest {
Some(ref p) => p,
None => &self.current_manifest,
}
.parent()
.unwrap()
self.root_manifest().parent().unwrap()
}

/// Returns the path of the `Cargo.toml` which is the root of this
/// workspace.
pub fn root_manifest(&self) -> &Path {
self.root_manifest
.as_ref()
.unwrap_or(&self.current_manifest)
}

/// Returns the root Package or VirtualManifest.
fn root_maybe(&self) -> &MaybePackage {
let root = self
.root_manifest
.as_ref()
.unwrap_or(&self.current_manifest);
self.packages.get(root)
self.packages.get(self.root_manifest())
}

pub fn target_dir(&self) -> Filesystem {
Expand Down
12 changes: 9 additions & 3 deletions src/doc/man/cargo-locate-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ cargo-locate-project - Print a JSON representation of a Cargo.toml file's locati
This command will print a JSON object to stdout with the full path to the
`Cargo.toml` manifest.

See also {{man "cargo-metadata" 1}} which is capable of returning the path to a
workspace root.

## OPTIONS

{{#options}}

{{#option "`--workspace`" }}
Locate the `Cargo.toml` at the root of the workspace, as opposed to the current
workspace member.
{{/option}}

{{/options}}

### Display Options

{{#options}}
Expand Down
7 changes: 4 additions & 3 deletions src/doc/man/generated_txt/cargo-locate-project.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ DESCRIPTION
This command will print a JSON object to stdout with the full path to
the Cargo.toml manifest.

See also cargo-metadata(1) which is capable of returning the path to a
workspace root.

OPTIONS
--workspace
Locate the Cargo.toml at the root of the workspace, as opposed to
the current workspace member.

Display Options
--message-format fmt
The representation in which to print the project location. Valid
Expand Down
12 changes: 9 additions & 3 deletions src/doc/src/commands/cargo-locate-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ cargo-locate-project - Print a JSON representation of a Cargo.toml file's locati
This command will print a JSON object to stdout with the full path to the
`Cargo.toml` manifest.

See also [cargo-metadata(1)](cargo-metadata.md) which is capable of returning the path to a
workspace root.

## OPTIONS

<dl>

<dt class="option-term" id="option-cargo-locate-project---workspace"><a class="option-anchor" href="#option-cargo-locate-project---workspace"></a><code>--workspace</code></dt>
<dd class="option-desc">Locate the <code>Cargo.toml</code> at the root of the workspace, as opposed to the current
workspace member.</dd>


</dl>

### Display Options

<dl>
Expand Down
1 change: 1 addition & 0 deletions src/etc/_cargo
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ _cargo() {
locate-project)
_arguments -s -S $common $manifest \
'--message-format=[specify output representation]:output representation [json]:(json plain)'
'--workspace[locate Cargo.toml of the workspace root]'
;;

login)
Expand Down
2 changes: 1 addition & 1 deletion 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 --message-format"
local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format --workspace"
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
9 changes: 6 additions & 3 deletions src/etc/man/cargo-locate-project.1
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ cargo\-locate\-project \- Print a JSON representation of a Cargo.toml file's loc
.SH "DESCRIPTION"
This command will print a JSON object to stdout with the full path to the
\fBCargo.toml\fR manifest.
.sp
See also \fBcargo\-metadata\fR(1) which is capable of returning the path to a
workspace root.
.SH "OPTIONS"
.sp
\fB\-\-workspace\fR
.RS 4
Locate the \fBCargo.toml\fR at the root of the workspace, as opposed to the current
workspace member.
.RE
.SS "Display Options"
.sp
\fB\-\-message\-format\fR \fIfmt\fR
Expand Down
52 changes: 52 additions & 0 deletions tests/testsuite/locate_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,55 @@ fn message_format() {
.with_status(101)
.run();
}

#[cargo_test]
fn workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "outer"
version = "0.0.0"
[workspace]
members = ["inner"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"inner/Cargo.toml",
r#"
[package]
name = "inner"
version = "0.0.0"
"#,
)
.file("inner/src/lib.rs", "")
.build();

let outer_manifest = format!(
r#"{{"root":"{}"}}"#,
p.root().join("Cargo.toml").to_str().unwrap(),
);
let inner_manifest = format!(
r#"{{"root":"{}"}}"#,
p.root().join("inner").join("Cargo.toml").to_str().unwrap(),
);

p.cargo("locate-project").with_stdout(&outer_manifest).run();

p.cargo("locate-project")
.cwd("inner")
.with_stdout(&inner_manifest)
.run();

p.cargo("locate-project --workspace")
.with_stdout(&outer_manifest)
.run();

p.cargo("locate-project --workspace")
.cwd("inner")
.with_stdout(&outer_manifest)
.run();
}

0 comments on commit 05c611a

Please sign in to comment.