@@ -173,7 +173,7 @@ class RustManifestSyncer : Callable<Unit> {
173173 .map { TargetProperties .fromPropertiesFile(it, workspaceRefs) }
174174 .groupBy { Pair (it.name, it.path) }.values
175175 .map { TargetProperties .mergeList(it) }
176- .apply { attachTestAndBuildProperties(this ) }
176+ .run { attachTestAndBuildProperties(this ) }
177177 }
178178
179179 private fun findSyncPropertiesFiles (bazelBin : File ): List <File > {
@@ -183,7 +183,7 @@ class RustManifestSyncer : Callable<Unit> {
183183 return filesToCheck.filter { it.name.endsWith(MANIFEST_PROPERTIES_SUFFIX ) }
184184 }
185185
186- private fun attachTestAndBuildProperties (properties : Collection <TargetProperties >) {
186+ private fun attachTestAndBuildProperties (properties : Collection <TargetProperties >): List < TargetProperties > {
187187 val TESTS_DIR = " tests"
188188 val BENCHES_DIR = " benches" // we translate Bazel Tests in 'benches' into Cargo benchmarks
189189 val (testProperties, nonTestProperties) = properties.partition { it.type == TargetProperties .Type .TEST }
@@ -220,11 +220,18 @@ class RustManifestSyncer : Callable<Unit> {
220220 parent[0 ].benches + = tp
221221 }
222222 }
223+
223224 val (buildProperties, nonBuildProperties) = properties.partition { it.type == TargetProperties .Type .BUILD }
224225 .let { it.first.associateBy { properties -> properties.name } to it.second }
225226 nonBuildProperties.forEach { nbp ->
226227 nbp.buildDeps.forEach { buildProperties[" ${it} _" ]?.let { buildProperties -> nbp.buildScripts + = buildProperties } }
227228 }
229+
230+ val packages = properties.filter { it.type == TargetProperties .Type .LIB || it.type == TargetProperties .Type .BIN }
231+ .groupBy { it.cratePath }.values
232+ .map { TargetProperties .mergePackage(it) }
233+
234+ return packages;
228235 }
229236
230237 private fun shouldGenerateManifest (properties : TargetProperties ): Boolean {
@@ -267,6 +274,7 @@ class RustManifestSyncer : Callable<Unit> {
267274 }
268275
269276 cargoToml.addDevAndBuildDependencies()
277+ cargoToml.addBins()
270278 cargoToml.addBenches()
271279 cargoToml.addTests()
272280
@@ -343,6 +351,23 @@ class RustManifestSyncer : Callable<Unit> {
343351 }
344352 }
345353
354+ private fun Config.addBins () {
355+ if (properties.bins.isNotEmpty()) {
356+ val mapped = properties.bins.map {
357+ if (it.entryPointPath != null ) {
358+ val path = Path (properties.cratePath).relativize(Path (it.cratePath)).resolve(it.entryPointPath)
359+ createSubConfig().apply {
360+ this .set<String >(" name" , it.name);
361+ this .set<String >(" path" , path.toString());
362+ }
363+ } else {
364+ null
365+ }
366+ }.filterNotNull()
367+ this .set<List <Config >>(" bin" , mapped)
368+ }
369+ }
370+
346371 private fun Config.addBenches () {
347372 if (properties.benches.isNotEmpty()) {
348373 val mapped = properties.benches.map {
@@ -385,6 +410,7 @@ class RustManifestSyncer : Callable<Unit> {
385410 val entryPointPath : Path ? ,
386411 val buildDeps : Collection <String >,
387412 val deps : Collection <Dependency >,
413+ val bins : MutableCollection <TargetProperties >,
388414 val tests : MutableCollection <TargetProperties >,
389415 val benches : MutableCollection <TargetProperties >,
390416 val buildScripts : MutableCollection <TargetProperties >,
@@ -523,6 +549,7 @@ class RustManifestSyncer : Callable<Unit> {
523549 buildDeps = props.getProperty(BUILD_DEPS , " " ).split(" ," ).filter { it.isNotBlank() },
524550 entryPointPath = props.getProperty(ENTRY_POINT_PATH )?.let { Path (it) },
525551 cratePath = props.getProperty(PATH ),
552+ bins = mutableListOf (),
526553 tests = mutableListOf (),
527554 benches = mutableListOf (),
528555 buildScripts = mutableListOf (),
@@ -547,6 +574,7 @@ class RustManifestSyncer : Callable<Unit> {
547574 buildDeps = base.buildDeps,
548575 entryPointPath = base.entryPointPath,
549576 cratePath = base.cratePath,
577+ bins = base.bins,
550578 tests = base.tests,
551579 benches = base.benches,
552580 buildScripts = base.buildScripts,
@@ -555,6 +583,55 @@ class RustManifestSyncer : Callable<Unit> {
555583 return base;
556584 }
557585
586+ fun mergePackage (package_properties : List <TargetProperties >): TargetProperties {
587+ if (package_properties.size == 1 ) {
588+ return package_properties.get(0 );
589+ }
590+ var lib = package_properties.firstOrNull { it.type == TargetProperties .Type .LIB }
591+ if (lib == null ) {
592+ val first = package_properties.get(0 );
593+ return TargetProperties (
594+ path = first.path,
595+ name = first.cratePath.replace(' /' , ' -' ),
596+ targetName = first.targetName,
597+ type = first.type,
598+ features = first.features,
599+ version = first.version,
600+ edition = first.edition,
601+ deps = package_properties.flatMap { it.deps }.distinct(),
602+ buildDeps = first.buildDeps,
603+ entryPointPath = first.entryPointPath,
604+ cratePath = first.cratePath,
605+ bins = package_properties.toMutableList(),
606+ tests = first.tests,
607+ benches = first.benches,
608+ buildScripts = first.buildScripts,
609+ )
610+ } else {
611+ val (libs, bins) = package_properties.partition { it.type == TargetProperties .Type .LIB }
612+ if (libs.size > 1 ) {
613+ throw IllegalStateException (" Found too many distinct libs post-merge at $lib .cratePath: ${libs.map { it.name }} " )
614+ }
615+ return TargetProperties (
616+ path = lib.path,
617+ name = lib.name,
618+ targetName = lib.targetName,
619+ type = lib.type,
620+ features = lib.features,
621+ version = lib.version,
622+ edition = lib.edition,
623+ deps = package_properties.flatMap { it.deps }.distinct(),
624+ buildDeps = lib.buildDeps,
625+ entryPointPath = lib.entryPointPath,
626+ cratePath = lib.cratePath,
627+ bins = bins.toMutableList(),
628+ tests = lib.tests,
629+ benches = lib.benches,
630+ buildScripts = lib.buildScripts,
631+ )
632+ }
633+ }
634+
558635 private fun extractDependencyEntries (props : Properties ): Map <String , String > {
559636 return props.entries
560637 .map { it.key.toString() to it.value.toString() }
0 commit comments