Skip to content

Commit

Permalink
Merge pull request #503 from diffplug/feat/gradle-6
Browse files Browse the repository at this point in the history
Fix Gradle 6+
  • Loading branch information
nedtwigg committed Jan 1, 2020
2 parents 20e7a7c + 7535906 commit d776768
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .ci/ci.sh
@@ -1,7 +1,7 @@
#!/bin/bash

# Do the Gradle build
./gradlew --scan build --build-cache || exit 1
./gradlew build --build-cache || exit 1
./gradlew npmTest --build-cache || exit 1

if [ "$TRAVIS_REPO_SLUG" == "diffplug/spotless" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
Expand Down
6 changes: 5 additions & 1 deletion CONTRIBUTING.md
Expand Up @@ -145,6 +145,7 @@ pluginManagement {

In Gradle 6.0+, you can use the following snippet in your `settings.gradle`.


```gradle
pluginManagement {
repositories {
Expand All @@ -159,12 +160,15 @@ pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'com.diffplug.gradle.spotless') {
useModule('com.github.{{user-or-org}}.spotless:spotless-plugin-gradle:SHA_OF_COMMIT_YOU_WANT')
useModule('com.github.{{USER_OR_ORG}}.spotless:spotless-plugin-gradle:{{SHA_OF_COMMIT_YOU_WANT}}')
}
}
}
}
```

If it doesn't work, you can check the JitPack log at `https://jitpack.io/com/github/{{USER_OR_ORG}}/spotless/{{SHA_OF_COMMIT_YOU_WANT}}/build.log`.

### Maven

Run `./gradlew publishToMavenLocal` to publish this to your local repository. The maven plugin is not published to JitPack due to [jitpack/jitpack.io#4112](https://github.com/jitpack/jitpack.io/issues/4112).
Expand Down
7 changes: 0 additions & 7 deletions build.gradle
Expand Up @@ -5,8 +5,6 @@ plugins {
id 'com.diffplug.gradle.eclipse.resourcefilters' version '3.18.1'
// https://plugins.gradle.org/plugin/com.gradle.plugin-publish
id 'com.gradle.plugin-publish' version '0.10.1' apply false
// https://plugins.gradle.org/plugin/com.gradle.build-scan
id 'com.gradle.build-scan' version '2.4'
// https://github.com/bintray/gradle-bintray-plugin/releases
id 'com.jfrog.bintray' version '1.8.4' apply false
// https://github.com/mnlipp/jdrupes-mdoclet/releases
Expand All @@ -17,11 +15,6 @@ plugins {
id "com.github.spotbugs" version "2.0.0" apply false
}

buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
apply from: 'gradle/build-scans.gradle'
}

// root eclipse project
apply plugin: 'com.diffplug.gradle.eclipse.resourcefilters'
eclipseResourceFilters {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
22 changes: 19 additions & 3 deletions gradlew
@@ -1,5 +1,21 @@
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
## Gradle start up script for UN*X
Expand Down Expand Up @@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
Expand Down Expand Up @@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
Expand Down
18 changes: 17 additions & 1 deletion gradlew.bat
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
Expand All @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
Expand Down
4 changes: 3 additions & 1 deletion plugin-gradle/CHANGES.md
Expand Up @@ -3,7 +3,9 @@
### Version 3.27.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-gradle/))

* Added method `FormatExtension.createIndependentTask(String taskName)` which allows creating a Spotless task outside of the `check`/`apply` lifecycle. See [javadoc](https://github.com/diffplug/spotless/blob/91ed7203994e52058ea6c2e0f88d023ed290e433/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java#L613-L639) for details. ([#500](https://github.com/diffplug/spotless/pull/500))
* Running clean and spotlessCheck during a parallel build could cause exceptions, fixed by ([#501](https://github.com/diffplug/spotless/pull/501)).
* Running `clean` and `spotlessCheck` during a parallel build could cause exceptions, fixed by ([#501](https://github.com/diffplug/spotless/pull/501)).
* Fixed Gradle 7 deprecation warnings that started being emitted in Gradle 6. ([#503](https://github.com/diffplug/spotless/pull/503))
* Even if you're using a pre-6.0 version of Gradle, you will probably see small performance and stability improvements. The PR above finally fixed the root problems of ([#372](https://github.com/diffplug/spotless/issues/372)).

### Version 3.26.1 - November 27th 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.26.1/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.26.1))

Expand Down
Expand Up @@ -603,6 +603,9 @@ protected void setupTask(SpotlessTask task) {
}
task.setSteps(steps);
task.setLineEndingsPolicy(getLineEndings().createPolicy(getProject().getProjectDir(), () -> task.target));
if (root.project != root.project.getRootProject()) {
root.registerDependenciesTask.hookSubprojectTask(task);
}
}

/** Returns the project that this extension is attached to. */
Expand Down
Expand Up @@ -15,45 +15,73 @@
*/
package com.diffplug.gradle.spotless;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.Dependency;

import com.diffplug.common.base.StringPrinter;
import com.diffplug.common.base.Preconditions;
import com.diffplug.common.collect.ImmutableList;
import com.diffplug.spotless.Provisioner;

/** Gradle integration for Provisioner. */
public class GradleProvisioner {
private GradleProvisioner() {}

public static Provisioner fromProject(Project project) {
// TODO: this method is not necessary - we could remove it entirely for a small speedup
return project.getPlugins().apply(SpotlessPlugin.class).getExtension().registerDependenciesTask.rootProvisioner;
}

/** The provisioner used for the root project. */
static class RootProvisioner implements Provisioner {
private final Project rootProject;
private final Map<Request, Set<File>> cache = new HashMap<>();

RootProvisioner(Project rootProject) {
Preconditions.checkArgument(rootProject == rootProject.getRootProject());
this.rootProject = rootProject;
}

@Override
public Set<File> provisionWithTransitives(boolean withTransitives, Collection<String> mavenCoordinates) {
Request req = new Request(withTransitives, mavenCoordinates);
Set<File> result = cache.get(req);
if (result != null) {
return result;
} else {
result = GradleProvisioner.fromRootBuildscript(rootProject).provisionWithTransitives(req.withTransitives, req.mavenCoords);
cache.put(req, result);
return result;
}
}
}

static Provisioner fromRootBuildscript(Project project) {
Objects.requireNonNull(project);
return (withTransitives, mavenCoords) -> {
try {
Dependency[] deps = mavenCoords.stream()
.map(project.getBuildscript().getDependencies()::create)
.toArray(Dependency[]::new);

// #372 workaround: Accessing rootProject.configurations from multiple projects is not thread-safe
ConfigurationContainer configContainer;
synchronized (project.getRootProject()) {
configContainer = project.getRootProject().getBuildscript().getConfigurations();
}
Configuration config = configContainer.detachedConfiguration(deps);
Configuration config = project.getRootProject().getBuildscript().getConfigurations().detachedConfiguration(deps);
config.setDescription(mavenCoords.toString());
config.setTransitive(withTransitives);
return config.resolve();
} catch (Exception e) {
logger.log(Level.SEVERE,
StringPrinter.buildStringFromLines("You probably need to add a repository containing the '" + mavenCoords + "' artifact in the 'build.gradle' of your root project.",
logger.log(
Level.SEVERE,
"You probably need to add a repository containing the '" + mavenCoords + "' artifact in the 'build.gradle' of your root project.\n" +
"E.g.: 'buildscript { repositories { mavenCentral() }}'",
"Note that included buildscripts (using 'apply from') do not share their buildscript repositories with the underlying project.",
"You have to specify the missing repository explicitly in the buildscript of the root project."),
e);
throw e;
}
Expand All @@ -62,4 +90,44 @@ public static Provisioner fromProject(Project project) {

private static final Logger logger = Logger.getLogger(GradleProvisioner.class.getName());

/** Models a request to the provisioner. */
private static class Request {
final boolean withTransitives;
final ImmutableList<String> mavenCoords;

public Request(boolean withTransitives, Collection<String> mavenCoords) {
this.withTransitives = withTransitives;
this.mavenCoords = ImmutableList.copyOf(mavenCoords);
}

@Override
public int hashCode() {
return withTransitives ? mavenCoords.hashCode() : ~mavenCoords.hashCode();
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof Request) {
Request o = (Request) obj;
return o.withTransitives == withTransitives && o.mavenCoords.equals(mavenCoords);
} else {
return false;
}
}

@Override
public String toString() {
String coords = mavenCoords.toString();
StringBuilder builder = new StringBuilder();
builder.append(coords.substring(1, coords.length() - 1)); // strip off []
if (withTransitives) {
builder.append(" with transitives");
} else {
builder.append(" no transitives");
}
return builder.toString();
}
}
}
Expand Up @@ -178,7 +178,7 @@ protected void setupTask(SpotlessTask task) {
if (target == null) {
JavaPluginConvention javaPlugin = getProject().getConvention().findPlugin(JavaPluginConvention.class);
if (javaPlugin == null) {
throw new GradleException("You must apply the java plugin before the spotless plugin if you are using the java extension.");
throw new GradleException("You must either specify 'target' manually or apply the 'java' plugin.");
}
FileCollection union = getProject().files();
for (SourceSet sourceSet : javaPlugin.getSourceSets()) {
Expand Down
@@ -0,0 +1,97 @@
/*
* Copyright 2016 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.diffplug.gradle.spotless;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import org.gradle.api.DefaultTask;
import org.gradle.api.execution.TaskExecutionGraph;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

import com.diffplug.common.base.Preconditions;
import com.diffplug.common.io.Files;
import com.diffplug.spotless.FormatterStep;

/**
* NOT AN END-USER TASK, DO NOT USE FOR ANYTHING!
*
* - When a user asks for a formatter, we need to download the jars for that formatter
* - Gradle wants us to resolve all our dependencies in the root project - no new dependencies in subprojects
* - So, whenever a SpotlessTask in a subproject gets configured, we call {@link #hookSubprojectTask(SpotlessTask)},
* which makes this task a dependency of the SpotlessTask
* - When this "registerDependencies" task does its up-to-date check, it queries the task execution graph to see which
* SpotlessTasks are at risk of being executed, and causes them all to be evaluated safely in the root buildscript.
*/
public class RegisterDependenciesTask extends DefaultTask {
static final String TASK_NAME = "spotlessInternalRegisterDependencies";

@Input
public List<FormatterStep> getSteps() {
List<FormatterStep> allSteps = new ArrayList<>();
TaskExecutionGraph taskGraph = getProject().getGradle().getTaskGraph();
for (SpotlessTask task : tasks) {
if (taskGraph.hasTask(task)) {
allSteps.addAll(task.getSteps());
}
}
return allSteps;
}

private List<SpotlessTask> tasks = new ArrayList<>();

@Internal
public List<SpotlessTask> getTasks() {
return tasks;
}

void hookSubprojectTask(SpotlessTask task) {
tasks.add(task);
task.dependsOn(this);
}

File unitOutput;

@OutputFile
public File getUnitOutput() {
return unitOutput;
}

GradleProvisioner.RootProvisioner rootProvisioner;

@Internal
public GradleProvisioner.RootProvisioner getRootProvisioner() {
return rootProvisioner;
}

void setup() {
Preconditions.checkArgument(getProject().getRootProject() == getProject(), "Can only be used on the root project");
unitOutput = new File(getProject().getBuildDir(), "tmp/spotless-register-dependencies");
rootProvisioner = new GradleProvisioner.RootProvisioner(getProject());
}

@TaskAction
public void trivialFunction() throws IOException {
Files.createParentDirs(unitOutput);
Files.write(Integer.toString(getSteps().size()), unitOutput, StandardCharsets.UTF_8);
}
}

0 comments on commit d776768

Please sign in to comment.