-
Notifications
You must be signed in to change notification settings - Fork 455
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
Refactored Eclipse formatter configuration and step creation #253
Changes from 1 commit
3890fbd
5057d35
1626f1b
5ae1ce9
c456b92
266ba0d
59782cb
9003a0d
ca0deb9
b4be00c
064409e
4affb5d
96f01ea
53e8cbe
cfb3e44
c475288
cb303ad
7bdd7a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,257 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* 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.spotless.extra.config; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.io.File; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.io.IOException; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.io.Serializable; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.net.MalformedURLException; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.net.URL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.nio.file.Path; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.nio.file.Paths; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.Objects; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.Properties; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.TreeSet; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.stream.Collectors; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import com.diffplug.spotless.FileSignature; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import com.diffplug.spotless.FormatterProperties; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import com.diffplug.spotless.JarState; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import com.diffplug.spotless.Provisioner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import com.diffplug.spotless.ThrowingEx; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Eclipse formatter generic configuration validates the user arguments and creates on request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* a {@link State} of the current values. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public class EclipseConfiguration implements ThrowingEx.Supplier<EclipseConfiguration.State> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Resource location of Spotless Eclipse Formatter Maven coordinate lists. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* <p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Spotless Eclipse Formatter dependencies have fixed transitive versions, since Spotless Eclipse Formatter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* implementations access internal methods of the Eclipse plugins, which may change with every | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* version change, including minor and patch version changes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* At the resource location for each supported Spotless Eclipse Formatter, a text file is provided, containing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* the fixed versions for the formatter and its transitive dependencies. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Each line in the text file corresponds to the {@link MavenCoordinates.Coordinate#FORMAT}. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* </p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private static final String ECLIPSE_FORMATTER_RESOURCES = EclipseConfiguration.class.getPackage().getName().replace('.', '/'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final TreeSet<SemanticVersion> supportedEclipseVersions; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final URL eclipseConfigContext; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final Provisioner jarProvisioner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private URL defaultCoordinatesUrl; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private MavenCoordinates coordinateAdaptations; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private SemanticVersion version; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private Iterable<File> settingsFiles; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private EclipseConfiguration.State state; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Initialize valid default configuration, taking latest version */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public EclipseConfiguration(String formatterName, Provisioner jarProvisioner, String... supportedEclipseVersions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Objects.requireNonNull(formatterName, "formatterName"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Objects.requireNonNull(jarProvisioner, "jarProvisioner"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Objects.requireNonNull(supportedEclipseVersions, "supportedEclipseVersions"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (supportedEclipseVersions.length < 1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new IllegalArgumentException("At lease one version must be allowed."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Path relativeFormatterResourcePath = Paths.get(ECLIPSE_FORMATTER_RESOURCES, formatterName.replace(' ', '_')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
eclipseConfigContext = getClass().getClassLoader().getResource(relativeFormatterResourcePath.toString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (null == eclipseConfigContext) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new IllegalArgumentException(String.format("Eclipse configuration context resource path '%s' not found.", relativeFormatterResourcePath)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.supportedEclipseVersions = new TreeSet<SemanticVersion>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (String allowedVersion : supportedEclipseVersions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.supportedEclipseVersions.add(new SemanticVersion(allowedVersion)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
version = this.supportedEclipseVersions.last(); //Use latest version per default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defaultCoordinatesUrl = getDefaultCoordinatesUrl(eclipseConfigContext, version); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.jarProvisioner = jarProvisioner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coordinateAdaptations = new MavenCoordinates(); //Use default coordinates configured for version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
settingsFiles = new ArrayList<File>(); //Use default preferences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state = null; //Create state only on demand too speed up initialization | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Set Eclipse version */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void setVersion(String versionOrUrl) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// For development purpose and patch delivery it is allowed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// to specify directly the URL of a M2 coordinates file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defaultCoordinatesUrl = new URL(versionOrUrl); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The default version is not changed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (MalformedURLException ignored) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SemanticVersion newVersion = new SemanticVersion(versionOrUrl); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (supportedEclipseVersions.contains(newVersion)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defaultCoordinatesUrl = getDefaultCoordinatesUrl(eclipseConfigContext, newVersion); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
version = newVersion; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new UserArgumentException(versionOrUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
String.format("Version is not part of the supported versions '%s'.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
supportedEclipseVersions.stream().map(v -> v.toString()).collect(Collectors.joining(", ")))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
invalidateState(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private static URL getDefaultCoordinatesUrl(URL eclipseConfigContext, SemanticVersion version) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Path filePath = Paths.get(eclipseConfigContext.getPath(), String.format("v%s.txt", version.toString())); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return new URL(eclipseConfigContext.getProtocol(), eclipseConfigContext.getHost(), filePath.toString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (MalformedURLException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* This exception must be prevented by the strict syntax checking of | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* SemanticVersion and unit-tests of all allowed versions. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new RuntimeException(e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Modify default Maven dependencies configured for the formatter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* The default dependencies are located in {@link #ECLIPSE_FORMATTER_RESOURCES}. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void setDepenencies(String... coordinates) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/setDepenencies/setDependencies :) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coordinateAdaptations = new MavenCoordinates(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coordinateAdaptations.update(coordinates); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
invalidateState(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Set settings files containing Eclipse preferences */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void setPreferences(Iterable<File> settingsFiles) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.settingsFiles = settingsFiles; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
invalidateState(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** The current state becomes invalid in case a configuration item has successfully changed */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private void invalidateState() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Creates the state of the configuration */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public EclipseConfiguration.State get() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (null == state) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state = new State( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
jarProvisioner, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
createMavenCoordinates(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
version, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
settingsFiles); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return state; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see an upside to caching the state. I would create a new state for every call to get(). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't know who and how often There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
:-P I think the safe thing is to avoid caching until it's absolutely necessary. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private MavenCoordinates createMavenCoordinates() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MavenCoordinates coordinates = new MavenCoordinates(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coordinates.add(defaultCoordinatesUrl); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coordinates.update(coordinateAdaptations); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return coordinates; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* State of Eclipse configuration items, providing functionality to derived information | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* based on the state. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public static class State implements Serializable { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Not used, only the serialization output is required to determine whether the object has changed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private static final long serialVersionUID = 1L; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final FileSignature settingsFiles; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final MavenCoordinates coordinates; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final SemanticVersion version; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Fields are transient because not needed to uniquely identify a Eclipse configuration state, and also because | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Gradle only needs this class to be serializable so it can compare its members for incremental builds. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private transient ClassLoader lazyClassLoader; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private final transient Provisioner jarProvisioner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally, JarState is part of the serialized state:
This allows you to remove
JarState captures this, because it hashes the content of the jars. The current approach would miss this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the resolution of the jars take time, I wanted to be sure that it's only done when necessary. So what I basically want to avoid is a download in the following scenario:
The download should not be triggered before it is assured that the Formatter will be executed. When I work on code I want to see quickly whether it works. I am not sure when Gradle requests the state. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spotless (gradle or maven) requests the state at the last possible moment - not until someone actually calls |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** State constructor expects that all passed items are not modified afterwards */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected State(Provisioner jarProvisioner, MavenCoordinates coordinates, SemanticVersion version, Iterable<File> settingsFiles) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.jarProvisioner = jarProvisioner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.coordinates = coordinates; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.version = version; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lazyClassLoader = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.settingsFiles = FileSignature.signAsList(settingsFiles); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (NullPointerException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new UserArgumentException(null, "Configuration file settings", e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (IOException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new RuntimeException(e); //Canonical path problems are not user argument problems | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the .equals() and .hashCode() methods don't matter, only the serialization is used to determine up-to-date-ness. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I admit that I just added the functionality because it is demanded by the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beside the convenience / checks for user data, the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This won't work as you intend for up-to-date checking. Up-to-date checking is based solely on the serialized representation, it doesn't care about
SerializableEqualityTester is only meant to be used on either steps or the entire step state. Not the components of step state. Up-to-date checking works like this:
Provisioner only takes a List. So I don't see how we will pass this detailed semantic information to the step's implementation. We can always do feature testing a-la: spotless/lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java Lines 98 to 115 in c6c32e3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what your goal is. I can reduce the LOC by integrating the functionality back into EclipseConfiguration, though I would still prefer to have it a separated inner class, to keep the code readable. class EclipseJdtFormatterStep .... {
...
private static String INITV = "4.7.2"; //Highest version compatible to initial interface
private static VERSIONS[] = {"4.6.1", "4.6.3", "4.7.0", "4.7.1", INITV, "4.7.3"};
private final String implClassPath;
public static FormatterStep createStep(EclipseConfiguration config) {
String classPath = config.versionHigher(INITV)? "com.diffplug.spotless.extra.java.eclipse.EclipseJdtFormatterStepImpl" : ""com.diffplug.gradle.spotless.java.eclipse.EclipseFormatterStepImpl"
return FormatterStep.createLazy(NAME, config, new EclipseJdtFormatterStep(classPath));
}
} The EclipseConfiguration and maybe later on some other XyzConfgiuration shall be the front end. The other package scope classes are just generic tools. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tools have three goals:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My goal is to minimize LOC. You've convinced me of Version, I'm not convinced about MavenCoordinates and Coordinate. I trust you, so we can leave them in if they help :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One remaining question about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the compiler check is good enough. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public boolean equals(Object obj) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (obj instanceof EclipseConfiguration.State) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
EclipseConfiguration.State other = (EclipseConfiguration.State) obj; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this.hashCode() == other.hashCode(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public int hashCode() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//Omit transient/derived information when providing the hash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Objects.hash(settingsFiles, coordinates, version); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Comparison of configured Eclipse version with another version. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Return one of -1, 0, or 1 according to whether the other version is higher, equal or lower. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public int compareVersionTo(String otherVersion) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return version.compareTo(new SemanticVersion(otherVersion)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Get formatter preferences */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public Properties getPreferences() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//Keep the IllegalArgumentException since it contains detailed information | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FormatterProperties preferences = FormatterProperties.from(settingsFiles.files()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return preferences.getProperties(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Load class based on the given configuration of JAR provider and Maven coordinates. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public Class<?> loadClass(String name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return getClassLoader().loadClass(name); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (ClassNotFoundException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new UserArgumentException(coordinates, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
String.format("Could not find class '%s' in Maven coordinates.", name), e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private ClassLoader getClassLoader() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (null == lazyClassLoader) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
String[] mavenCoordinates = coordinates.get(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
JarState jarState = JarState.from(jarProvisioner, mavenCoordinates); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lazyClassLoader = jarState.getClassLoader(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (IOException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new UserArgumentException(mavenCoordinates, "Not all dependencies have been resolved successfully.", e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return lazyClassLoader; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know @nedtwigg's stance on throwing plain
RuntimeException
s, but if it were me, I'd elect to throw a more specific exception:IllegalArgumentException
if the user passed in an invalid URL or some other illegal argument, orIllegalStateException
if it's either not the user's fault or is due to unexpected state inthis
. :)