Skip to content

Commit 05c611a

Browse files
committed
Auto merge of #8712 - dtolnay:workspace, r=ehuss
--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>
2 parents 4e6fa34 + 17053fc commit 05c611a

File tree

9 files changed

+120
-25
lines changed

9 files changed

+120
-25
lines changed

src/bin/cargo/commands/locate_project.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub fn cli() -> App {
1515
)
1616
.value_name("FMT"),
1717
)
18+
.arg(opt("workspace", "Locate Cargo.toml of the workspace root"))
1819
.after_help("Run `cargo help locate-project` for more detailed information.\n")
1920
}
2021

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

2627
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
27-
let root = args.root_manifest(config)?;
28+
let root_manifest;
29+
let workspace;
30+
let root = match WhatToFind::parse(args) {
31+
WhatToFind::CurrentManifest => {
32+
root_manifest = args.root_manifest(config)?;
33+
&root_manifest
34+
}
35+
WhatToFind::Workspace => {
36+
workspace = args.workspace(config)?;
37+
workspace.root_manifest()
38+
}
39+
};
2840

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

61+
enum WhatToFind {
62+
CurrentManifest,
63+
Workspace,
64+
}
65+
66+
impl WhatToFind {
67+
fn parse(args: &ArgMatches<'_>) -> Self {
68+
if args.is_present("workspace") {
69+
WhatToFind::Workspace
70+
} else {
71+
WhatToFind::CurrentManifest
72+
}
73+
}
74+
}
75+
4976
enum MessageFormat {
5077
Json,
5178
Plain,

src/cargo/core/workspace.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,21 +315,20 @@ impl<'cfg> Workspace<'cfg> {
315315
/// That is, this returns the path of the directory containing the
316316
/// `Cargo.toml` which is the root of this workspace.
317317
pub fn root(&self) -> &Path {
318-
match self.root_manifest {
319-
Some(ref p) => p,
320-
None => &self.current_manifest,
321-
}
322-
.parent()
323-
.unwrap()
318+
self.root_manifest().parent().unwrap()
319+
}
320+
321+
/// Returns the path of the `Cargo.toml` which is the root of this
322+
/// workspace.
323+
pub fn root_manifest(&self) -> &Path {
324+
self.root_manifest
325+
.as_ref()
326+
.unwrap_or(&self.current_manifest)
324327
}
325328

326329
/// Returns the root Package or VirtualManifest.
327330
fn root_maybe(&self) -> &MaybePackage {
328-
let root = self
329-
.root_manifest
330-
.as_ref()
331-
.unwrap_or(&self.current_manifest);
332-
self.packages.get(root)
331+
self.packages.get(self.root_manifest())
333332
}
334333

335334
pub fn target_dir(&self) -> Filesystem {

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@ cargo-locate-project - Print a JSON representation of a Cargo.toml file's locati
1313
This command will print a JSON object to stdout with the full path to the
1414
`Cargo.toml` manifest.
1515

16-
See also {{man "cargo-metadata" 1}} which is capable of returning the path to a
17-
workspace root.
18-
1916
## OPTIONS
2017

18+
{{#options}}
19+
20+
{{#option "`--workspace`" }}
21+
Locate the `Cargo.toml` at the root of the workspace, as opposed to the current
22+
workspace member.
23+
{{/option}}
24+
25+
{{/options}}
26+
2127
### Display Options
2228

2329
{{#options}}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ DESCRIPTION
1111
This command will print a JSON object to stdout with the full path to
1212
the Cargo.toml manifest.
1313

14-
See also cargo-metadata(1) which is capable of returning the path to a
15-
workspace root.
16-
1714
OPTIONS
15+
--workspace
16+
Locate the Cargo.toml at the root of the workspace, as opposed to
17+
the current workspace member.
18+
1819
Display Options
1920
--message-format fmt
2021
The representation in which to print the project location. Valid

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@ cargo-locate-project - Print a JSON representation of a Cargo.toml file's locati
1313
This command will print a JSON object to stdout with the full path to the
1414
`Cargo.toml` manifest.
1515

16-
See also [cargo-metadata(1)](cargo-metadata.md) which is capable of returning the path to a
17-
workspace root.
18-
1916
## OPTIONS
2017

18+
<dl>
19+
20+
<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>
21+
<dd class="option-desc">Locate the <code>Cargo.toml</code> at the root of the workspace, as opposed to the current
22+
workspace member.</dd>
23+
24+
25+
</dl>
26+
2127
### Display Options
2228

2329
<dl>

src/etc/_cargo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ _cargo() {
162162
locate-project)
163163
_arguments -s -S $common $manifest \
164164
'--message-format=[specify output representation]:output representation [json]:(json plain)'
165+
'--workspace[locate Cargo.toml of the workspace root]'
165166
;;
166167

167168
login)

src/etc/cargo.bashcomp.sh

Lines changed: 1 addition & 1 deletion
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 --message-format"
62+
local opt__locate_project="$opt_common $opt_mani $opt_lock --message-format --workspace"
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"

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ cargo\-locate\-project \- Print a JSON representation of a Cargo.toml file's loc
1010
.SH "DESCRIPTION"
1111
This command will print a JSON object to stdout with the full path to the
1212
\fBCargo.toml\fR manifest.
13-
.sp
14-
See also \fBcargo\-metadata\fR(1) which is capable of returning the path to a
15-
workspace root.
1613
.SH "OPTIONS"
14+
.sp
15+
\fB\-\-workspace\fR
16+
.RS 4
17+
Locate the \fBCargo.toml\fR at the root of the workspace, as opposed to the current
18+
workspace member.
19+
.RE
1720
.SS "Display Options"
1821
.sp
1922
\fB\-\-message\-format\fR \fIfmt\fR

tests/testsuite/locate_project.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,55 @@ fn message_format() {
3434
.with_status(101)
3535
.run();
3636
}
37+
38+
#[cargo_test]
39+
fn workspace() {
40+
let p = project()
41+
.file(
42+
"Cargo.toml",
43+
r#"
44+
[package]
45+
name = "outer"
46+
version = "0.0.0"
47+
48+
[workspace]
49+
members = ["inner"]
50+
"#,
51+
)
52+
.file("src/main.rs", "fn main() {}")
53+
.file(
54+
"inner/Cargo.toml",
55+
r#"
56+
[package]
57+
name = "inner"
58+
version = "0.0.0"
59+
"#,
60+
)
61+
.file("inner/src/lib.rs", "")
62+
.build();
63+
64+
let outer_manifest = format!(
65+
r#"{{"root":"{}"}}"#,
66+
p.root().join("Cargo.toml").to_str().unwrap(),
67+
);
68+
let inner_manifest = format!(
69+
r#"{{"root":"{}"}}"#,
70+
p.root().join("inner").join("Cargo.toml").to_str().unwrap(),
71+
);
72+
73+
p.cargo("locate-project").with_stdout(&outer_manifest).run();
74+
75+
p.cargo("locate-project")
76+
.cwd("inner")
77+
.with_stdout(&inner_manifest)
78+
.run();
79+
80+
p.cargo("locate-project --workspace")
81+
.with_stdout(&outer_manifest)
82+
.run();
83+
84+
p.cargo("locate-project --workspace")
85+
.cwd("inner")
86+
.with_stdout(&outer_manifest)
87+
.run();
88+
}

0 commit comments

Comments
 (0)