Skip to content

Commit 27c1030

Browse files
committed
Use batch warnings and only warn about used dependency packages
Signed-off-by: hi-rustin <[email protected]>
1 parent cc891a0 commit 27c1030

File tree

3 files changed

+149
-36
lines changed

3 files changed

+149
-36
lines changed

src/cargo/core/package.rs

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -516,27 +516,14 @@ impl<'cfg> PackageSet<'cfg> {
516516
if !used.insert(pkg_id) {
517517
return Ok(());
518518
}
519-
let filtered_deps = resolve.deps(pkg_id).filter(|&(_id, deps)| {
520-
deps.iter().any(|dep| {
521-
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
522-
return false;
523-
}
524-
// This is overly broad, since not all target-specific
525-
// dependencies are used both for target and host. To tighten this
526-
// up, this function would need to track "for_host" similar to how
527-
// unit dependencies handles it.
528-
if force_all_targets == ForceAllTargets::No {
529-
let activated = requested_kinds
530-
.iter()
531-
.chain(Some(&CompileKind::Host))
532-
.any(|kind| target_data.dep_platform_activated(dep, *kind));
533-
if !activated {
534-
return false;
535-
}
536-
}
537-
true
538-
})
539-
});
519+
let filtered_deps = PackageSet::filter_deps(
520+
pkg_id,
521+
resolve,
522+
has_dev_units,
523+
requested_kinds,
524+
target_data,
525+
force_all_targets,
526+
);
540527
for (dep_id, _deps) in filtered_deps {
541528
collect_used_deps(
542529
used,
@@ -571,6 +558,66 @@ impl<'cfg> PackageSet<'cfg> {
571558
Ok(())
572559
}
573560

561+
/// Check if there are any dependency packages that do not have any libs.
562+
pub(crate) fn no_lib_pkgs(
563+
&self,
564+
resolve: &Resolve,
565+
root_ids: &[PackageId],
566+
has_dev_units: HasDevUnits,
567+
requested_kinds: &[CompileKind],
568+
target_data: &RustcTargetData<'_>,
569+
force_all_targets: ForceAllTargets,
570+
) -> CargoResult<Vec<&Package>> {
571+
let mut ret = vec![];
572+
573+
root_ids.iter().for_each(|pkg_id| {
574+
PackageSet::filter_deps(
575+
*pkg_id,
576+
resolve,
577+
has_dev_units,
578+
requested_kinds,
579+
target_data,
580+
force_all_targets,
581+
)
582+
.for_each(|(package_id, _)| {
583+
if let Ok(dep_pkg) = self.get_one(package_id) {
584+
if !dep_pkg.targets().iter().any(|t| t.is_lib()) {
585+
ret.push(dep_pkg);
586+
}
587+
}
588+
});
589+
});
590+
591+
Ok(ret)
592+
}
593+
594+
fn filter_deps<'a>(
595+
pkg_id: PackageId,
596+
resolve: &'a Resolve,
597+
has_dev_units: HasDevUnits,
598+
requested_kinds: &'a [CompileKind],
599+
target_data: &'a RustcTargetData<'_>,
600+
force_all_targets: ForceAllTargets,
601+
) -> impl Iterator<Item = (PackageId, &'a HashSet<Dependency>)> {
602+
resolve.deps(pkg_id).filter(move |&(_id, deps)| {
603+
deps.iter().any(|dep| {
604+
if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No {
605+
return false;
606+
}
607+
if force_all_targets == ForceAllTargets::No {
608+
let activated = requested_kinds
609+
.iter()
610+
.chain(Some(&CompileKind::Host))
611+
.any(|kind| target_data.dep_platform_activated(dep, *kind));
612+
if !activated {
613+
return false;
614+
}
615+
}
616+
true
617+
})
618+
})
619+
}
620+
574621
pub fn sources(&self) -> Ref<'_, SourceMap<'cfg>> {
575622
self.sources.borrow()
576623
}

src/cargo/ops/resolve.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,24 @@ pub fn resolve_ws_with_opts<'cfg>(
171171
feature_opts,
172172
)?;
173173

174-
// Check if there are any dependency packages that do not have any libs.
175-
if let Some(r) = resolve.as_ref() {
176-
for id in member_ids.iter() {
177-
for (package_id, _) in r.deps(*id) {
178-
if let Ok(dep_pkg) = pkg_set.get_one(package_id) {
179-
if !dep_pkg.targets().iter().any(|t| t.is_lib()) {
180-
ws.config().shell().warn(format!(
181-
"No library were found in package `{}`",
182-
dep_pkg.name()
183-
))?
184-
}
185-
}
186-
}
187-
}
174+
let no_lib_warnings: Vec<String> = pkg_set
175+
.no_lib_pkgs(
176+
&resolved_with_overrides,
177+
&member_ids,
178+
has_dev_units,
179+
requested_targets,
180+
target_data,
181+
force_all_targets,
182+
)?
183+
.iter()
184+
.map(|pkg| format!("No lib found in package `{}`.", pkg.name()))
185+
.collect();
186+
if !no_lib_warnings.is_empty() {
187+
ws.config().shell().warn(format!(
188+
"{} The dependent package should have a lib, \
189+
otherwise it is an invalid dependency.",
190+
no_lib_warnings.join("\n")
191+
))?;
188192
}
189193

190194
Ok(WorkspaceResolve {

tests/testsuite/run.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,69 @@ fn run_with_bin_dep() {
756756
p.cargo("run")
757757
.with_stderr(
758758
"\
759-
[WARNING] No library were found in package `bar`
759+
[WARNING] No lib found in package `bar`. \
760+
The dependent package should have a lib, \
761+
otherwise it is an invalid dependency.
762+
[COMPILING] foo v0.0.1 ([CWD])
763+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
764+
[RUNNING] `target/debug/foo[EXE]`",
765+
)
766+
.with_stdout("hello")
767+
.run();
768+
}
769+
770+
#[cargo_test]
771+
fn run_with_bin_deps() {
772+
let p = project()
773+
.file(
774+
"Cargo.toml",
775+
r#"
776+
[package]
777+
name = "foo"
778+
version = "0.0.1"
779+
780+
[dependencies.bar1]
781+
path = "bar1"
782+
[dependencies.bar2]
783+
path = "bar2"
784+
"#,
785+
)
786+
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
787+
.file(
788+
"bar1/Cargo.toml",
789+
r#"
790+
[package]
791+
name = "bar1"
792+
version = "0.0.1"
793+
authors = []
794+
795+
[[bin]]
796+
name = "bar1"
797+
"#,
798+
)
799+
.file("bar1/src/main.rs", r#"fn main() { println!("bar"); }"#)
800+
.file(
801+
"bar2/Cargo.toml",
802+
r#"
803+
[package]
804+
name = "bar2"
805+
version = "0.0.1"
806+
authors = []
807+
808+
[[bin]]
809+
name = "bar2"
810+
"#,
811+
)
812+
.file("bar2/src/main.rs", r#"fn main() { println!("bar"); }"#)
813+
.build();
814+
815+
p.cargo("run")
816+
.with_stderr(
817+
"\
818+
[WARNING] No lib found in package `bar1`.
819+
No lib found in package `bar2`. \
820+
The dependent package should have a lib, \
821+
otherwise it is an invalid dependency.
760822
[COMPILING] foo v0.0.1 ([CWD])
761823
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
762824
[RUNNING] `target/debug/foo[EXE]`",

0 commit comments

Comments
 (0)