Skip to content

Modernize the maven build #1496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jan 17, 2023
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -30,8 +30,7 @@ jobs:
- name: spotlessCheck
run: ./gradlew spotlessCheck --build-cache
- name: assemble testClasses
run: ./gradlew assemble testClasses --build-cache -PSPOTLESS_EXCLUDE_MAVEN=true
# If this gets resolved, remove the EXCLUDE_MAVEN https://github.com/diffplug/spotless/issues/554
run: ./gradlew assemble testClasses --build-cache
build:
needs: sanityCheck
strategy:
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]
### Added
* `ProcessRunner` has added some convenience methods so it can be used for maven testing. ([#1496](https://github.com/diffplug/spotless/pull/1496))
### Fixed
* The default list of type annotations used by `formatAnnotations` has had 8 more annotations from the Checker Framework added [#1494](https://github.com/diffplug/spotless/pull/1494)
### Changes
8 changes: 1 addition & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -28,10 +28,4 @@ VER_DURIAN=1.2.0
VER_JGIT=5.13.1.202206130422-r
VER_JUNIT=5.9.2
VER_ASSERTJ=3.24.2
VER_MOCKITO=4.11.0

# Used for Maven Plugin
VER_MAVEN_API=3.0
VER_ECLIPSE_AETHER=1.1.0
VER_MUSTACHE=0.9.10
VER_PLEXUS_RESOURCES=1.2.0
VER_MOCKITO=4.11.0
4 changes: 2 additions & 2 deletions lib-extra/build.gradle
Original file line number Diff line number Diff line change
@@ -25,8 +25,8 @@ dependencies {
// we'll hold the core lib to a high standard
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)

test {
useJUnitPlatform()
apply from: rootProject.file('gradle/special-tests.gradle')
tasks.named('test') {
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16)) {
// needed for EclipseCdtFormatterStepTest
jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
5 changes: 1 addition & 4 deletions lib/build.gradle
Original file line number Diff line number Diff line change
@@ -112,10 +112,7 @@ dependencies {
// we'll hold the core lib to a high standard
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)

tasks.withType(Test).configureEach {
useJUnitPlatform()
}

apply from: rootProject.file('gradle/special-tests.gradle')
jar {
for (glue in NEEDS_GLUE) {
from sourceSets.getByName(glue).output.classesDirs
41 changes: 36 additions & 5 deletions lib/src/main/java/com/diffplug/spotless/ProcessRunner.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 DiffPlug
* Copyright 2020-2023 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,18 +16,22 @@
package com.diffplug.spotless;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;

import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
@@ -55,13 +59,18 @@ public Result shell(String cmd) throws IOException, InterruptedException {

/** Executes the given shell command (using {@code cmd} on windows and {@code sh} on unix). */
public Result shellWinUnix(String cmdWin, String cmdUnix) throws IOException, InterruptedException {
return shellWinUnix(null, null, cmdWin, cmdUnix);
}

/** Executes the given shell command (using {@code cmd} on windows and {@code sh} on unix). */
public Result shellWinUnix(@Nullable File cwd, @Nullable Map<String, String> environment, String cmdWin, String cmdUnix) throws IOException, InterruptedException {
List<String> args;
if (FileSignature.machineIsWin()) {
args = Arrays.asList("cmd", "/c", cmdWin);
} else {
args = Arrays.asList("sh", "-c", cmdUnix);
}
return exec(args);
return exec(cwd, environment, null, args);
}

/** Creates a process with the given arguments. */
@@ -70,18 +79,32 @@ public Result exec(String... args) throws IOException, InterruptedException {
}

/** Creates a process with the given arguments, the given byte array is written to stdin immediately. */
public Result exec(byte[] stdin, String... args) throws IOException, InterruptedException {
public Result exec(@Nullable byte[] stdin, String... args) throws IOException, InterruptedException {
return exec(stdin, Arrays.asList(args));
}

/** Creates a process with the given arguments. */
public Result exec(List<String> args) throws IOException, InterruptedException {
return exec(new byte[0], args);
return exec(null, args);
}

/** Creates a process with the given arguments, the given byte array is written to stdin immediately. */
public Result exec(byte[] stdin, List<String> args) throws IOException, InterruptedException {
public Result exec(@Nullable byte[] stdin, List<String> args) throws IOException, InterruptedException {
return exec(null, null, stdin, args);
}

/** Creates a process with the given arguments, the given byte array is written to stdin immediately. */
public Result exec(@Nullable File cwd, @Nullable Map<String, String> environment, @Nullable byte[] stdin, List<String> args) throws IOException, InterruptedException {
ProcessBuilder builder = new ProcessBuilder(args);
if (cwd != null) {
builder.directory(cwd);
}
if (environment != null) {
builder.environment().putAll(environment);
}
if (stdin == null) {
stdin = new byte[0];
}
Process process = builder.start();
Future<byte[]> outputFut = threadStdOut.submit(() -> drainToBytes(process.getInputStream(), bufStdOut));
Future<byte[]> errorFut = threadStdErr.submit(() -> drainToBytes(process.getErrorStream(), bufStdErr));
@@ -147,6 +170,14 @@ public byte[] stdErr() {
return stdErr;
}

public String stdOutUtf8() {
return new String(stdOut, StandardCharsets.UTF_8);
}

public String stdErrUtf8() {
return new String(stdErr, StandardCharsets.UTF_8);
}

/** Returns true if the exit code was not zero. */
public boolean exitNotZero() {
return exitCode != 0;
6 changes: 2 additions & 4 deletions plugin-gradle/build.gradle
Original file line number Diff line number Diff line change
@@ -27,13 +27,11 @@ dependencies {
testImplementation "com.diffplug.durian:durian-testlib:${VER_DURIAN}"
}

test {
useJUnitPlatform()
apply from: rootProject.file('gradle/special-tests.gradle')
tasks.named('test') {
testLogging.showStandardStreams = true
}

apply from: rootProject.file('gradle/special-tests.gradle')

//////////////////////////
// GRADLE PLUGIN PORTAL //
//////////////////////////
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
### Fixed
* The default list of type annotations used by `formatAnnotations` has had 8 more annotations from the Checker Framework added [#1494](https://github.com/diffplug/spotless/pull/1494)
### Changes
* Spotless' custom build was replaced by [`maven-plugin-development`](https://github.com/britter/maven-plugin-development). ([#1496](https://github.com/diffplug/spotless/pull/1496) fixes [#554](https://github.com/diffplug/spotless/issues/554))

## [2.30.0] - 2023-01-13
### Added
188 changes: 23 additions & 165 deletions plugin-maven/build.gradle
Original file line number Diff line number Diff line change
@@ -1,71 +1,29 @@
buildscript {
repositories { mavenCentral() }
dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" }
}
plugins {
id 'cz.malohlava.visteg' version '1.0.5' // https://github.com/mmalohlava/gradle-visteg
// https://www.benediktritter.de/maven-plugin-development/#release-history
id 'de.benediktritter.maven-plugin-development' version '0.4.0'
}

repositories { mavenCentral() }
apply from: rootProject.file('gradle/changelog.gradle')
apply from: rootProject.file('gradle/spotless-freshmark.gradle')

// to generate taskGraph.pdf
// - set enabled (below) to true
// - run: ./gradlew :plugin-maven:test
// - run: rm plugin-maven/output.pdf
// - run: dot -Tpdf plugin-maven/build/reports/visteg.dot > plugin-maven/taskGraph.pdf
visteg {
enabled = false
nodeShape = 'box'
startNodeShape = 'box'
endNodeShape = 'box'
colorscheme = 'pastel24' // https://www.graphviz.org/doc/info/colors.html
}

import com.github.mustachejava.DefaultMustacheFactory

import java.nio.file.Files

import static java.nio.charset.StandardCharsets.UTF_8
import static java.nio.file.StandardOpenOption.CREATE
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING

ext.artifactId = project.artifactIdMaven
version = spotlessChangelog.versionNext
apply from: rootProject.file("gradle/java-setup.gradle")
apply from: rootProject.file("gradle/java-publish.gradle")

final MAVEN_PROJECT_DIR = project.layout.buildDirectory.dir("mavenProject").get()
final LOCAL_MAVEN_REPO_DIR = project.layout.buildDirectory.dir("localMavenRepository").get()
apply from: rootProject.file("gradle/java-setup.gradle")
apply from: rootProject.file('gradle/spotless-freshmark.gradle')

def mvnw(String args) {
boolean isWin = System.getProperty('os.name').toLowerCase().contains('win')
if (isWin) {
return [
'cmd',
'/c',
'mvnw.cmd -e ' + args
]
} else {
return [
'/bin/sh',
'-c',
'./mvnw -e ' + args
]
}
apply plugin: 'de.benediktritter.maven-plugin-development'
mavenPlugin {
name = 'Spotless Maven Plugin'
artifactId = project.artifactIdMaven
description = project.description
}

String libVersion = version.endsWith('-SNAPSHOT') ?
rootProject.spotlessChangelog.versionNext :
rootProject.spotlessChangelog.versionLast
String VER_MAVEN_API = '3.0'
String VER_ECLIPSE_AETHER = '1.1.0'
String VER_PLEXUS_RESOURCES = '1.2.0'
dependencies {
if (version.endsWith('-SNAPSHOT') || (rootProject.spotlessChangelog.versionNext == rootProject.spotlessChangelog.versionLast)) {
implementation project(':lib')
implementation project(':lib-extra')
} else {
implementation "com.diffplug.spotless:spotless-lib:${libVersion}"
implementation "com.diffplug.spotless:spotless-lib-extra:${libVersion}"
}
implementation project(':lib')
implementation project(':lib-extra')

compileOnly "org.apache.maven:maven-plugin-api:${VER_MAVEN_API}"
compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:${VER_MAVEN_API}"
@@ -83,119 +41,19 @@ dependencies {
testImplementation "org.assertj:assertj-core:${VER_ASSERTJ}"
testImplementation "org.mockito:mockito-core:${VER_MOCKITO}"
testImplementation "com.diffplug.durian:durian-io:${VER_DURIAN}"
testImplementation "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}"
testImplementation 'com.github.spullara.mustache.java:compiler:0.9.10'
testImplementation "org.apache.maven:maven-plugin-api:${VER_MAVEN_API}"
testImplementation "org.eclipse.aether:aether-api:${VER_ECLIPSE_AETHER}"
testImplementation "org.codehaus.plexus:plexus-resources:${VER_PLEXUS_RESOURCES}"
testImplementation "org.apache.maven:maven-core:${VER_MAVEN_API}"
}

task copySourceFiles(type: Sync) {
from "src/main/java"
into MAVEN_PROJECT_DIR.dir("src/main/java")
}

task copyMvnw(type: Copy, dependsOn: copySourceFiles) {
from 'src/test/resources'
include 'mvnw'
include 'mvnw.cmd'
include '.mvn/**'
into MAVEN_PROJECT_DIR
}

task installLocalDependencies
def libs = [
'lib',
'lib-extra',
'testlib'
]
libs.each {
def groupId = 'com.diffplug.spotless'
def artifactId = "spotless-${it}"
def jarTask = tasks.getByPath(":${it}:jar")
def file = jarTask.archivePath

def installDependency = task "install_${artifactId}"(type: Exec) {
workingDir MAVEN_PROJECT_DIR

inputs.file(file)
outputs.dir(LOCAL_MAVEN_REPO_DIR.file(groupId.replace('.', '/') + "/" + artifactId + "/" + version))
commandLine mvnw("org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file " +
"-Dfile=${file} " +
"-DgroupId=${groupId} " +
"-DartifactId=${artifactId} " +
"-Dversion=${libVersion} " +
"-Dpackaging=jar " +
"-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}")
}
installDependency.dependsOn(jarTask)

installLocalDependencies.dependsOn installDependency
}

task createPomXml(dependsOn: installLocalDependencies) {
def newPomXml = MAVEN_PROJECT_DIR.file("pom.xml").asFile.toPath()

outputs.file(newPomXml)
doLast {
def additionalDependencies = project.configurations.runtimeClasspath.resolvedConfiguration.resolvedArtifacts.findAll {
return !libs.contains(it.moduleVersion.id.name)
}.collect {
return " <dependency>\n" +
" <groupId>${it.moduleVersion.id.group}</groupId>\n" +
" <artifactId>${it.moduleVersion.id.name}</artifactId>\n" +
" <version>${it.moduleVersion.id.version}</version>\n" +
" </dependency>\n"
}.join()

def versions = [
spotlessMavenPluginVersion: version,
mavenApiVersion : VER_MAVEN_API,
eclipseAetherVersion : VER_ECLIPSE_AETHER,
spotlessLibVersion : libVersion,
jsr305Version : VER_JSR_305,
additionalDependencies : additionalDependencies
]

def pomXmlTemplate = project.layout.projectDirectory.file("src/test/resources/pom-build.xml.mustache").asFile.toPath()

Files.newBufferedReader(pomXmlTemplate).withCloseable { reader ->
Files.newBufferedWriter(newPomXml, UTF_8, CREATE, TRUNCATE_EXISTING).withCloseable { writer ->
def mustache = new DefaultMustacheFactory().compile(reader, "pom")
mustache.execute(writer, versions)
}
}
}
}

task runMavenBuild(type: Exec, dependsOn: [
copySourceFiles,
copyMvnw,
createPomXml
]) {
outputs.dir(LOCAL_MAVEN_REPO_DIR)

workingDir MAVEN_PROJECT_DIR
// -B batch mode to make dependency download logging less verbose
commandLine mvnw("clean install -B -Dmaven.repo.local=${LOCAL_MAVEN_REPO_DIR}")
}

jar.setActions Arrays.asList()
jar.dependsOn(runMavenBuild)
File jarIn = MAVEN_PROJECT_DIR.file("target/spotless-maven-plugin-${version}.jar").asFile
File jarOut = jar.archivePath
jar.inputs.file(jarIn)
jar.outputs.file(jarOut)
jar.doLast {
Files.copy(jarIn.toPath(), jarOut.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING)
}

test { useJUnitPlatform() }

apply from: rootProject.file('gradle/special-tests.gradle')

tasks.withType(Test) {
systemProperty "localMavenRepositoryDir", LOCAL_MAVEN_REPO_DIR.asFile
systemProperty "spotlessMavenPluginVersion", project.version
dependsOn(jar)
tasks.withType(Test).configureEach {
systemProperty 'spotlessMavenPluginVersion', project.version
dependsOn 'publishToMavenLocal'
dependsOn ':lib:publishToMavenLocal'
dependsOn ':lib-extra:publishToMavenLocal'
}

apply from: rootProject.file("gradle/java-publish.gradle")
Loading