# gradle-common Java 21 multi-project build with shared Gradle utilities and experimental variant-oriented Gradle plugins. The repository currently publishes to a local Ivy repository only. Maven Central and Gradle Plugin Portal publication are intentionally not configured yet. ## Modules - `common` - shared Gradle utilities, JSON helpers, shell execution helpers, and small core value/util classes. - `variants` - Gradle plugins for variant topology, source-set materialization, and outgoing artifact slots. ## Requirements - JDK 21. - Gradle Wrapper from this repository, currently Gradle 8.10.2. The produced bytecode targets Java 21. ## License This project is licensed under the BSD 2-Clause "Simplified" License (`BSD-2-Clause`). See [LICENSE](LICENSE). ## Local Build ```bash ./gradlew clean check javadoc jar sourcesJar javadocJar --rerun-tasks ``` Configuration cache smoke check: ```bash ./gradlew check --configuration-cache ``` ## Local Ivy Publication The current publication target is: ```text ${user.home}/ivy-repo ``` Publish both modules locally: ```bash ./gradlew :common:publishIvyPublicationToIvyRepository \ :variants:publishIvyPublicationToIvyRepository ``` or: ```bash ./gradlew publish ``` The publication includes: - main jar - sources jar - javadoc jar - Ivy descriptor - Gradle module metadata ## Local Consumption Current plugin ids are packaged as classic Gradle plugin marker resources inside the `variants` jar: - `org.implab.gradle-variants` - `org.implab.gradle-sources` - `org.implab.gradle-variants-sources` - `org.implab.gradle-variants-artifacts` Until Gradle Plugin Portal marker artifacts are configured, consume the plugin through `buildscript` classpath: ```groovy buildscript { repositories { ivy { url "${System.properties['user.home']}/ivy-repo" } mavenCentral() } dependencies { classpath 'org.implab.gradle:variants:0.1.0' } } apply plugin: 'org.implab.gradle-variants' apply plugin: 'org.implab.gradle-variants-sources' ``` The `plugins { id(...) version(...) }` DSL is not part of the current local Ivy contract. ## Variants DSL `variants` defines the finalized build topology. It does not create compile tasks, source directories, or outgoing publications by itself. ```groovy apply plugin: 'org.implab.gradle-variants' variants.layers.create('main') variants.layers.create('test') variants.roles.create('main') variants.roles.create('test') variants.variant('browser') { role('main') { layers('main') } role('test') { layers('main', 'test') } } variants.whenFinalized { view -> println view.entries.collect { "${it.variant().name}:${it.role().name}:${it.layer().name}" }.sort() } ``` The finalized model exposes cheap identity objects: `Variant`, `Role`, `Layer`, and the normalized relation `(variant, role, layer)`. ## Sources DSL `sources` creates standalone `GenericSourceSet` objects. This is useful for fallback workflows that do not need variant topology. ```groovy apply plugin: 'org.implab.gradle-sources' sources.create('main') { declareOutputs('js') registerOutput('js', layout.projectDirectory.file('inputs/main.js')) sets.create('ts') { srcDir 'src/main/ts' } } ``` `SourcesPlugin` applies layout conventions: - `sourceSetDir = src/` - `outputsDir = build/out/` The base `GenericSourceSet` model itself is convention-free. ## Variant Sources DSL `variantSources` derives compile units from finalized `variants`. A compile unit is: ```text (variant, layer) ``` Selectors configure materialized compile-unit source sets: ```groovy apply plugin: 'org.implab.gradle-variants-sources' variants.layers.create('main') variants.roles.create('main') variants.variant('browser') { role('main') { layers('main') } } variantSources { layer('main') { sourceSet { declareOutputs('js') registerOutput('js', layout.projectDirectory.file('inputs/browser.js')) } } configureEach { println "sourceSet=${sourceSet.name}, variant=${variant.name}, layer=${layer.name}" } } ``` Selector order for future materialization is: ```text configureEach -> variant -> layer -> unit ``` Late selector registration is controlled by: ```groovy variantSources { lateConfigurationPolicy { failOnLateConfiguration() } } ``` Compile-unit source set names are generated by default as: ```text + capitalize() ``` Name collisions fail by default and may be resolved deterministically: ```groovy variantSources { namingPolicy { resolveNameCollision() } } ``` ## Variant Artifacts DSL `variantArtifacts` is an experimental outgoing artifact layer over `variants` and `variantSources`. The current model maps: - `Variant` to a variant-level consumable outgoing configuration. - `Slot` to a Gradle outgoing artifact variant inside that configuration. - `primarySlot` to the primary artifact set of the outgoing configuration. ```groovy apply plugin: 'org.implab.gradle-variants-artifacts' variants.layers.create('main') variants.roles.create('main') variants.variant('browser') { role('main') { layers('main') } } variantSources.layer('main') { sourceSet { declareOutputs('types', 'js') registerOutput('types', layout.projectDirectory.file('inputs/index.d.ts')) registerOutput('js', layout.projectDirectory.file('inputs/index.js')) } } variantArtifacts { variant('browser') { primarySlot('typesPackage') { fromVariant { output('types') } } slot('js') { fromVariant { output('js') } } } whenOutgoingConfiguration { publication -> publication.configuration { description = "Outgoing contract for ${publication.variant.name}" } } whenOutgoingSlot { publication -> println "slot=${publication.artifactSlot.slot.name}, primary=${publication.primary}" } } ``` The artifact API is still considered pre-1.0 and may change. ## Publication Status Current status: - local Ivy publication only - no Maven Central publication metadata - no signing - no Gradle Plugin Portal marker artifacts - BSD-2-Clause license committed Before external publication, see [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md).