##// END OF EJS Templates
Show More
Commit message Age Author Refs
r63:79fd940a7856
Add minimum Gradle compatibility functional test
cin
0
r62:c7861b56e1d8
Upgrade Gradle to 9.4.1 and fix functional tests
cin
0
r61:9b11838beca6
Keep contribution-based assemblies on managed Sync tasks, register direct producers through ArtifactAssemblyRegistry, wire builtBy on outgoing artifacts, and cover the behavior with functional tests.
cin
0
r60:e376d0cab00e
Set the project version to 0.1.0, add publication descriptions/license metadata, and keep module-level docs as compatibility pointers to the root documentation.
cin
0
r59:780370baa54c
variants: move source set layout conventions out of model Keep GenericSourceSet convention-free and apply layout defaults from SourcesPlugin and VariantSourcesPlugin. Add compile unit layout convention and cover standalone and variant source set layouts in functional tests.
cin
0
r58:a4138749793f
variants: expose compile unit source set specs Route variantSources selectors through CompileUnitSourceSetSpec so source set materialization keeps compile unit identity available. Add configureEach hooks and keep GenericSourceSet as a plain source set model.
cin
0
r57:1abf7dba60ee
variants: validate source context identities
cin
0
r56:c41a563716ec
variants: refine public API boundary
cin
0
r55:a06b08ec0a7f
variants: stabilize artifact slot materialization
cin
0
r54:3469331e3c4b
variants: enforce source configuration policies
cin
0
< 1 2 3 4 5 6 7 >

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.

Local Build

./gradlew clean check javadoc jar sourcesJar javadocJar --rerun-tasks

Configuration cache smoke check:

./gradlew check --configuration-cache

Local Ivy Publication

The current publication target is:

${user.home}/ivy-repo

Publish both modules locally:

./gradlew :common:publishIvyPublicationToIvyRepository \
          :variants:publishIvyPublicationToIvyRepository

or:

./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:

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.

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.

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/<sourceSet>
  • outputsDir = build/out/<sourceSet>

The base GenericSourceSet model itself is convention-free.

Variant Sources DSL

variantSources derives compile units from finalized variants.

A compile unit is:

(variant, layer)

Selectors configure materialized compile-unit source sets:

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:

configureEach -> variant -> layer -> unit

Late selector registration is controlled by:

variantSources {
    lateConfigurationPolicy {
        failOnLateConfiguration()
    }
}

Compile-unit source set names are generated by default as:

<variant> + capitalize(<layer>)

Name collisions fail by default and may be resolved deterministically:

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.
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}"
    }
}

Slot bodies have two assembly modes:

  • contribution-based assembly with from(...), fromVariant(...), fromRole(...), or fromLayer(...); the plugin copies selected inputs into a managed directory and publishes that directory;
  • task-produced assembly with producedBy(task) { outputFile }; the mapped task output file or directory is published directly.

These modes are mutually exclusive for one slot.

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.