Skip to content

Commit

Permalink
Modernize the maven build (#1496)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Jan 17, 2023
2 parents 9f24a34 + b256bd4 commit bba3ea1
Show file tree
Hide file tree
Showing 23 changed files with 235 additions and 526 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 1 addition & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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'
Expand Down
5 changes: 1 addition & 4 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
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.
Expand All @@ -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;

/**
Expand Down Expand Up @@ -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. */
Expand All @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions plugin-gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
//////////////////////////
Expand Down
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
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}"
Expand All @@ -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

0 comments on commit bba3ea1

Please sign in to comment.