Skip to content

Commit 97a2e17

Browse files
committed
Add version requirement format option to cargo tree
Also update unit tests with test cases for normal and inverted output. Signed-off-by: Alexandre Barone <abalexandrebarone@gmail.com>
1 parent 2e3adce commit 97a2e17

File tree

3 files changed

+36
-12
lines changed

3 files changed

+36
-12
lines changed

src/cargo/ops/tree/format/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ enum Chunk {
1414
Repository,
1515
Features,
1616
LibName,
17+
VersionRequirement,
1718
}
1819

1920
pub struct Pattern(Vec<Chunk>);
@@ -30,6 +31,7 @@ impl Pattern {
3031
RawChunk::Argument("r") => Chunk::Repository,
3132
RawChunk::Argument("f") => Chunk::Features,
3233
RawChunk::Argument("lib") => Chunk::LibName,
34+
RawChunk::Argument("ver-req") => Chunk::VersionRequirement,
3335
RawChunk::Argument(a) => {
3436
bail!("unsupported pattern `{}`", a);
3537
}
@@ -111,6 +113,13 @@ impl<'a> fmt::Display for Display<'a> {
111113
write!(fmt, "{}", target.crate_name())?;
112114
}
113115
}
116+
Chunk::VersionRequirement => {
117+
if let Some(version_req) =
118+
self.graph.version_req_for_id(package.package_id())
119+
{
120+
write!(fmt, "{}", version_req)?;
121+
}
122+
}
114123
}
115124
}
116125
}

src/cargo/ops/tree/graph.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::core::dependency::DepKind;
66
use crate::core::resolver::Resolve;
77
use crate::core::resolver::features::{CliFeatures, FeaturesFor, ResolvedFeatures};
88
use crate::core::{FeatureMap, FeatureValue, Package, PackageId, PackageIdSpec, Workspace};
9-
use crate::util::CargoResult;
109
use crate::util::interning::{INTERNED_DEFAULT, InternedString};
10+
use crate::util::{CargoResult, OptVersionReq};
1111
use std::collections::{HashMap, HashSet};
1212

1313
#[derive(Debug, Copy, Clone)]
@@ -161,6 +161,8 @@ pub struct Graph<'a> {
161161
/// Key is the index of a package node, value is a map of `dep_name` to a
162162
/// set of `(pkg_node_index, is_optional)`.
163163
dep_name_map: HashMap<NodeId, HashMap<InternedString, HashSet<(NodeId, bool)>>>,
164+
/// Map for looking up version requirements for dependency packages.
165+
version_req_map: HashMap<PackageId, OptVersionReq>,
164166
}
165167

166168
impl<'a> Graph<'a> {
@@ -172,6 +174,7 @@ impl<'a> Graph<'a> {
172174
package_map,
173175
cli_features: HashSet::new(),
174176
dep_name_map: HashMap::new(),
177+
version_req_map: HashMap::new(),
175178
}
176179
}
177180

@@ -240,6 +243,12 @@ impl<'a> Graph<'a> {
240243
}
241244
}
242245

246+
/// Returns the version requirement for the given package ID. Returns `None`
247+
/// if no version requirement is recorded (e.g., root packages).
248+
pub fn version_req_for_id(&self, package_id: PackageId) -> Option<&OptVersionReq> {
249+
self.version_req_map.get(&package_id)
250+
}
251+
243252
/// Returns `true` if the given feature node index is a feature enabled
244253
/// via the command-line.
245254
pub fn is_cli_feature(&self, index: NodeId) -> bool {
@@ -523,6 +532,12 @@ fn add_pkg(
523532
requested_kind,
524533
opts,
525534
);
535+
// Store the version requirement for this dependency for
536+
// later use in formatting.
537+
graph.version_req_map.insert(
538+
graph.package_id_for_index(dep_index),
539+
dep.version_req().clone(),
540+
);
526541
let new_edge = Edge {
527542
kind: EdgeKind::Dep(dep.kind()),
528543
node: dep_index,

tests/testsuite/cargo_tree/deps.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,25 +1248,25 @@ foo v0.1.0 ([ROOT]/foo) [bar,default,dep_that_is_awesome,foo,other-dep]
12481248
.run();
12491249

12501250
p.cargo("tree --all-features")
1251-
.arg("--format={p}")
1251+
.arg("--format={p} satisfies {ver-req}")
12521252
.with_stdout_data(str![[r#"
1253-
foo v0.1.0 ([ROOT]/foo)
1254-
├── dep v1.0.0
1255-
├── dep_that_is_awesome v1.0.0
1256-
└── other-dep v1.0.0
1257-
└── dep v1.0.0
1253+
foo v0.1.0 ([ROOT]/foo) satisfies
1254+
├── dep v1.0.0 satisfies ^1.0
1255+
├── dep_that_is_awesome v1.0.0 satisfies >=1.0, <2
1256+
└── other-dep v1.0.0 satisfies ^1.0
1257+
└── dep v1.0.0 satisfies ^1.0
12581258
12591259
"#]])
12601260
.run();
12611261

12621262
p.cargo("tree --all-features")
1263-
.arg("--format={p}")
1263+
.arg("--format={p} satisfies {ver-req}")
12641264
.arg("--invert=dep")
12651265
.with_stdout_data(str![[r#"
1266-
dep v1.0.0
1267-
├── foo v0.1.0 ([ROOT]/foo)
1268-
└── other-dep v1.0.0
1269-
└── foo v0.1.0 ([ROOT]/foo)
1266+
dep v1.0.0 satisfies ^1.0
1267+
├── foo v0.1.0 ([ROOT]/foo) satisfies
1268+
└── other-dep v1.0.0 satisfies ^1.0
1269+
└── foo v0.1.0 ([ROOT]/foo) satisfies
12701270
12711271
"#]])
12721272
.run();

0 commit comments

Comments
 (0)