2828import org .gradle .api .attributes .java .TargetJvmEnvironment ;
2929import org .gradle .api .model .ObjectFactory ;
3030import org .gradle .api .provider .ListProperty ;
31+ import org .gradle .api .provider .Property ;
3132
3233import io .quarkus .gradle .tooling .dependency .DependencyUtils ;
3334import io .quarkus .gradle .tooling .dependency .ExtensionDependency ;
@@ -169,22 +170,26 @@ public static void setCommonAttributes(AttributeContainer attrs, ObjectFactory o
169170 * @param project project
170171 * @param mode launch mode
171172 */
172- public static void addVariants (Project project , LaunchMode mode ) {
173- new QuarkusComponentVariants (project , mode ).configureAndAddVariants ();
173+ public static void addVariants (Project project , LaunchMode mode ,
174+ Property <ManualPlatformSpec > manualPlatformConfig ) {
175+ new QuarkusComponentVariants (project , mode , manualPlatformConfig ).configureAndAddVariants ();
174176 }
175177
176178 private final Attribute <String > quarkusDepAttr ;
177179 private final Project project ;
180+ private final Property <ManualPlatformSpec > manualPlatformConfig ;
178181 private final Map <ArtifactKey , ProcessedDependency > processedDeps = new HashMap <>();
179182 private final Map <ArtifactKey , ConditionalDependency > allConditionalDeps = new HashMap <>();
180183 private final List <ConditionalDependencyVariant > dependencyVariantQueue = new ArrayList <>();
181184 private final Map <String , SatisfiedExtensionDeps > satisfiedExtensionDeps = new HashMap <>();
182185 private final LaunchMode mode ;
183186 private final AtomicInteger configCopyCounter = new AtomicInteger ();
184187
185- private QuarkusComponentVariants (Project project , LaunchMode mode ) {
188+ private QuarkusComponentVariants (Project project , LaunchMode mode ,
189+ Property <ManualPlatformSpec > manualPlatformConfig ) {
186190 this .project = project ;
187191 this .mode = mode ;
192+ this .manualPlatformConfig = manualPlatformConfig ;
188193 this .quarkusDepAttr = getConditionalDependencyAttribute (project .getName (), mode );
189194 project .getDependencies ().getAttributesSchema ().attribute (quarkusDepAttr );
190195 project .getDependencies ().getAttributesSchema ().attribute (getDeploymentDependencyAttribute (project .getName (), mode ));
@@ -407,7 +412,10 @@ private void processDependency(ProcessedDependency parent,
407412 }
408413
409414 private void queueConditionalDependency (ProcessedDependency parent , Dependency dep ) {
410- dependencyVariantQueue .add (new ConditionalDependencyVariant (parent .extension , getOrCreateConditionalDep (dep )));
415+ var conditionalDep = getOrCreateConditionalDep (dep );
416+ if (conditionalDep != null ) {
417+ dependencyVariantQueue .add (new ConditionalDependencyVariant (parent .extension , conditionalDep ));
418+ }
411419 }
412420
413421 private ConditionalDependency getOrCreateConditionalDep (Dependency dep ) {
@@ -417,7 +425,7 @@ private ConditionalDependency getOrCreateConditionalDep(Dependency dep) {
417425 }
418426
419427 private ResolvedArtifact tryResolvingRelocationArtifact (Dependency dep ) {
420- final Configuration configForRelocated = project . getConfigurations (). detachedConfiguration (dep ).setTransitive (true );
428+ final Configuration configForRelocated = getDetachedWithExclusions (dep ).setTransitive (true );
421429 setConditionalAttributes (configForRelocated , project , mode );
422430
423431 var firstLevelDeps = configForRelocated .getResolvedConfiguration ().getFirstLevelModuleDependencies ();
@@ -447,8 +455,11 @@ private ResolvedArtifact tryResolvingRelocationArtifact(Dependency dep) {
447455 return artifact ;
448456 }
449457
450- private ConditionalDependency newConditionalDep (Dependency dep ) {
451- final Configuration config = project .getConfigurations ().detachedConfiguration (dep ).setTransitive (false );
458+ private ConditionalDependency newConditionalDep (Dependency originalDep ) {
459+ var manualConfig = manualPlatformConfig .get ();
460+ var dep = getConstrainedDep (originalDep , manualConfig .getConstraints ());
461+ final Configuration config = getDetachedWithExclusions (dep ).setTransitive (false );
462+
452463 setConditionalAttributes (config , project , mode );
453464 ResolvedArtifact resolvedArtifact = null ;
454465
@@ -464,6 +475,11 @@ private ConditionalDependency newConditionalDep(Dependency dep) {
464475 }
465476
466477 if (resolvedArtifact == null ) {
478+ // check if that's due to exclude rules, and if yes, ignore
479+ if (isExplicitlyExcluded (dep )) {
480+ project .getLogger ().info ("Conditional dependency {} ignored due to exclusion rule" , dep );
481+ return null ;
482+ }
467483 throw new RuntimeException (dep + " did not resolve to any artifacts" );
468484 }
469485
@@ -474,6 +490,48 @@ private ConditionalDependency newConditionalDep(Dependency dep) {
474490
475491 }
476492
493+ private boolean isExplicitlyExcluded (Dependency dep ) {
494+ return manualPlatformConfig .get ().getExclusions ().stream ().anyMatch (rule -> {
495+ rule .getGroup ();
496+ if (!rule .getGroup ().equals (dep .getGroup ())) {
497+ return false ;
498+ }
499+ rule .getModule ();
500+ return rule .getModule ().equals (dep .getName ());
501+ });
502+ }
503+
504+ private Configuration getDetachedWithExclusions (Dependency dep ) {
505+ var c = project .getConfigurations ().detachedConfiguration (dep );
506+ manualPlatformConfig .get ().getExclusions ().forEach (rule -> {
507+ Map <String , String > excludeProperties = new HashMap <>();
508+ excludeProperties .put ("group" , rule .getGroup ());
509+ excludeProperties .put ("module" , rule .getModule ());
510+ c .exclude (excludeProperties );
511+ });
512+ return c ;
513+ }
514+
515+ private Dependency getConstrainedDep (Dependency dep , Set <ManualPlatformSpec .Constraint > constraints ) {
516+ if (constraints == null || constraints .isEmpty ()) {
517+ return dep ;
518+ }
519+
520+ var matchingConstraints = constraints .stream ().filter (c -> c .matches (dep )).toList ();
521+
522+ if (matchingConstraints .isEmpty ()) {
523+ return dep ;
524+ }
525+
526+ if (matchingConstraints .size () > 1 ) {
527+ throw new RuntimeException ("Multiple matching constraints for " + dep + ": " + matchingConstraints );
528+ }
529+
530+ var c = matchingConstraints .get (0 );
531+ return project .getDependencies ().create (
532+ dep .getGroup () + ":" + dep .getName () + ":" + c .getVersion ());
533+ }
534+
477535 private class ProcessedDependency {
478536 private final ResolvedArtifact artifact ;
479537 private final ExtensionDependency <?> extension ;
0 commit comments