Skip to content

Commit fa5e5b6

Browse files
authored
bug: Add lib targets as deps for bin/test targets in same crate (#39)
Fixes a bug where public items from lib targets were not accessible to bin/test targets in the same crate. This is accomplished by including any lib targets in a given crate as dependencies of bin/test targets in the same crate. Fixes #28
1 parent 99b69ec commit fa5e5b6

1 file changed

Lines changed: 71 additions & 57 deletions

File tree

src/rust_project.rs

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -483,20 +483,25 @@ impl PackageGraph {
483483
proc_macro_dylibs: HashMap<PackageId, FilePathBuf>,
484484
build_scripts: HashMap<PackageId, BuildScript>,
485485
) -> Result<Vec<Crate>> {
486-
let iter = self.graph.into_iter().flat_map(|(id, package)| {
487-
// TODO: clones
488-
package
489-
.clone()
490-
.targets
491-
.into_iter()
492-
.map(move |target| (id.clone(), package.clone(), target))
493-
});
494-
495486
let mut crates = Vec::new();
496487
let mut deps = Vec::new();
497488
let mut indexes: HashMap<PackageId, usize> = HashMap::new();
498489

499-
for (id, package, target) in iter {
490+
for (id, package) in self.graph.into_iter() {
491+
// Represents the indices of the `crates` array corresponding to lib targets for this
492+
// package
493+
let lib_indices: Vec<_> = package
494+
.targets
495+
.iter()
496+
.enumerate()
497+
.filter(|(_, target)| matches!(TargetKind::new(&target.kind), TargetKind::Lib))
498+
.map(|(i, target)| {
499+
// I *think* this is the right way to handle target names in this
500+
// context...
501+
(crates.len() + i, target.name.clone().replace('-', "_"))
502+
})
503+
.collect();
504+
500505
let mut env = HashMap::new();
501506
let mut include_dirs = vec![package.manifest_path.parent().unwrap().to_string()];
502507
if let Some(script) = build_scripts.get(&id) {
@@ -508,57 +513,66 @@ impl PackageGraph {
508513
}
509514
}
510515

511-
let target_kind = TargetKind::new(&target.kind);
512-
if matches!(target_kind, TargetKind::Lib) {
513-
indexes.insert(id.clone(), crates.len());
514-
}
516+
for target in package.targets {
517+
let target_kind = TargetKind::new(&target.kind);
518+
if matches!(target_kind, TargetKind::Lib) {
519+
indexes.insert(id.clone(), crates.len());
520+
}
515521

516-
deps.push(package.dependencies);
517-
518-
crates.push(Crate {
519-
display_name: Some(package.name.to_string().replace('-', "_")),
520-
root_module: target.root_module.clone(),
521-
edition: target.edition,
522-
version: Some(package.version.to_string()),
523-
deps: vec![],
524-
is_workspace_member: package.is_workspace_member,
525-
is_proc_macro: target.is_proc_macro(),
526-
repository: package.repository.clone(),
527-
build: Some(BuildInfo {
528-
label: target.name.clone(),
529-
build_file: package.manifest_path.to_string(),
530-
target_kind,
531-
}),
532-
proc_macro_dylib_path: proc_macro_dylibs.get(&id).cloned(),
533-
source: Some(CrateSource {
534-
include_dirs,
535-
exclude_dirs: vec![".git".into(), "target".into()],
536-
}),
537-
// cfg_groups: None,
538-
cfg: package
539-
.features
540-
.clone()
541-
.into_iter()
542-
.map(|feature| format!("feature=\"{feature}\""))
543-
.collect(),
544-
target: None,
545-
env,
546-
proc_macro_cwd: package
547-
.manifest_path
548-
.as_file_path()
549-
.parent()
550-
.map(|a| a.into()),
551-
});
522+
// If the target is a bin or a test, we want to include all the lib targets of the
523+
// package in the dependencies for this target. This is what gives bin/test targets
524+
// access to the public items defined in lib targets in the same crate
525+
let mut this_deps = vec![];
526+
if !matches!(target_kind, TargetKind::Lib) {
527+
for (crate_index, name) in lib_indices.clone().into_iter() {
528+
this_deps.push(Dep { crate_index, name });
529+
}
530+
}
531+
532+
deps.push(package.dependencies.clone());
533+
534+
crates.push(Crate {
535+
display_name: Some(package.name.to_string().replace('-', "_")),
536+
root_module: target.root_module.clone(),
537+
edition: target.edition,
538+
version: Some(package.version.to_string()),
539+
deps: this_deps,
540+
is_workspace_member: package.is_workspace_member,
541+
is_proc_macro: target.is_proc_macro(),
542+
repository: package.repository.clone(),
543+
build: Some(BuildInfo {
544+
label: target.name.clone(),
545+
build_file: package.manifest_path.to_string(),
546+
target_kind,
547+
}),
548+
proc_macro_dylib_path: proc_macro_dylibs.get(&id).cloned(),
549+
source: Some(CrateSource {
550+
include_dirs: include_dirs.clone(),
551+
exclude_dirs: vec![".git".into(), "target".into()],
552+
}),
553+
// cfg_groups: None,
554+
cfg: package
555+
.features
556+
.clone()
557+
.into_iter()
558+
.map(|feature| format!("feature=\"{feature}\""))
559+
.collect(),
560+
target: None,
561+
env: env.clone(),
562+
proc_macro_cwd: package
563+
.manifest_path
564+
.as_file_path()
565+
.parent()
566+
.map(|a| a.into()),
567+
});
568+
}
552569
}
553570

554571
for (c, deps) in crates.iter_mut().zip(deps.into_iter()) {
555-
c.deps = deps
556-
.into_iter()
557-
.map(|dep| Dep {
558-
name: dep.name,
559-
crate_index: indexes.get(&dep.id).copied().unwrap(),
560-
})
561-
.collect();
572+
c.deps.extend(deps.into_iter().map(|dep| Dep {
573+
name: dep.name,
574+
crate_index: indexes.get(&dep.id).copied().unwrap(),
575+
}));
562576

563577
// *shrug* buck does this, not sure if it's necessary
564578
c.deps.sort_by_key(|dep| dep.crate_index);

0 commit comments

Comments
 (0)