diff --git a/.circleci/config.yml b/.circleci/config.yml index 2da87c90e0..67e9313838 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -283,6 +283,8 @@ workflows: - do_release_all: requires: - release_all + context: + - SonatypeDeploy - release_plugin_gradle: type: approval requires: @@ -290,6 +292,8 @@ workflows: - do_release_plugin_gradle: requires: - release_plugin_gradle + context: + - SonatypeDeploy - release_plugin_maven: type: approval requires: @@ -297,6 +301,8 @@ workflows: - do_release_plugin_maven: requires: - release_plugin_maven + context: + - SonatypeDeploy - release_lib: type: approval requires: @@ -304,6 +310,8 @@ workflows: - do_release_lib: requires: - release_lib + context: + - SonatypeDeploy ext_deploy: jobs: - ext_changelog_print: @@ -317,6 +325,8 @@ workflows: - ext_do_release_base: requires: - ext_release_base + context: + - SonatypeDeploy - ext_release_jdt: type: approval requires: @@ -324,6 +334,8 @@ workflows: - ext_do_release_jdt: requires: - ext_release_jdt + context: + - SonatypeDeploy - ext_release_cdt: type: approval requires: @@ -334,6 +346,8 @@ workflows: only: main requires: - ext_release_cdt + context: + - SonatypeDeploy - ext_release_groovy: type: approval requires: @@ -344,6 +358,8 @@ workflows: only: main requires: - ext_release_groovy + context: + - SonatypeDeploy - ext_release_wtp: type: approval requires: @@ -354,3 +370,5 @@ workflows: only: main requires: - ext_release_wtp + context: + - SonatypeDeploy diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..10ef831183 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/CHANGES.md b/CHANGES.md index 6aea102237..a42c3d57c1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,113 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +## [2.15.3] - 2021-08-20 +### Changed +* Added support for [scalafmt 3.0.0](https://github.com/scalameta/scalafmt/releases/tag/v3.0.0) and bump default scalafmt version to `3.0.0` ([#913](https://github.com/diffplug/spotless/pull/913)). +* Bump default versions ([#915](https://github.com/diffplug/spotless/pull/915)) + * `ktfmt` from `0.24` to `0.27` + * `ktlint` from `0.35.0` to `0.42.1` + * `google-java-format` from `1.10.0` to `1.11.0` +* Fix javadoc publishing ([#916](https://github.com/diffplug/spotless/pull/916) fixes [#775](https://github.com/diffplug/spotless/issues/775)). + +## [2.15.2] - 2021-07-20 +### Fixed + * Improved [SQL formatting](https://github.com/diffplug/spotless/pull/897) with respect to comments + +## [2.15.1] - 2021-07-06 +### Changed +* Improved exception messages for [JSON formatting](https://github.com/diffplug/spotless/pull/885) failures + +## [2.15.0] - 2021-06-17 + +### Added +* Added formatter for [JVM-based JSON formatting](https://github.com/diffplug/spotless/issues/850) +* Added Gradle configuration JVM-based JSON formatting + +## [2.14.0] - 2021-06-10 +### Added +* Added support for `eclipse-cdt` at `4.19.0`. Note that version requires Java 11 or higher. +* Added support for `eclipse-groovy` at `4.18.0` and `4.19.0`. +* Added support for `eclipse-wtp` at `4.19.0`. Note that version requires Java 11 or higher. +### Changed +* Bump `eclipse-groovy` default version from `4.17.0` to `4.19.0`. + +## [2.13.5] - 2021-05-13 +### Changed +* Update ktfmt from 0.21 to 0.24 +### Fixed +* The `` field in the maven POM is now set correctly ([#798](https://github.com/diffplug/spotless/issues/798)) +* Node is re-installed if some other build step removed it ([#863](https://github.com/diffplug/spotless/issues/863)) + +## [2.13.4] - 2021-04-21 +### Fixed +* Explicitly separate target file from git arguments when parsing year for license header to prevent command from failing on argument-like paths ([#847](https://github.com/diffplug/spotless/pull/847)) + +## [2.13.3] - 2021-04-20 +### Fixed +* LicenseHeaderStep treats address as copyright year ([#716](https://github.com/diffplug/spotless/issues/716)) + +## [2.13.2] - 2021-04-12 +### Fixed +* Fix license header bug for years in range ([#840](https://github.com/diffplug/spotless/pull/840)). + +## [2.13.1] - 2021-04-10 +### Changed +* Update default google-java-format from 1.9 to 1.10.0 +* Expose configuration exceptions from scalafmt ([#837](https://github.com/diffplug/spotless/issues/837)) + +## [2.13.0] - 2021-03-05 +### Added +* Bump ktfmt to 0.21 and add support to Google and Kotlinlang formats ([#812](https://github.com/diffplug/spotless/pull/812)) + +## [2.12.1] - 2021-02-16 +### Fixed +* Allow licence headers to be blank ([#801](https://github.com/diffplug/spotless/pull/801)). + +## [2.12.0] - 2021-02-09 +### Added +* Support for diktat ([#789](https://github.com/diffplug/spotless/pull/789)) + +## [2.11.0] - 2021-01-04 +### Added +* Added support for `eclipse-cdt`, `eclipse-jdt`, and `eclipse-wtp` at `4.18.0`. +### Changed +* Bump `eclipse-jdt` default version from `4.17.0` to `4.18.0`. +* Bump `eclipse-wtp` default version from `4.17.0` to `4.18.0`. +* Bump `ktfmt` default version from `0.16` to `0.19` ([#748](https://github.com/diffplug/spotless/issues/748) and [#773](https://github.com/diffplug/spotless/issues/773)). +* Bump `jgit` from `5.9` to `5.10` ([#773](https://github.com/diffplug/spotless/issues/773)). +### Fixed +* Fixed `ratchetFrom` support for git-submodule ([#746](https://github.com/diffplug/spotless/issues/746)). +* Fixed `ratchetFrom` excess memory consumption ([#735](https://github.com/diffplug/spotless/issues/735)). +* `ktfmt` v0.19+ with dropbox-style works again ([#765](https://github.com/diffplug/spotless/pull/765)). +* `prettier` no longer throws errors on empty files ([#751](https://github.com/diffplug/spotless/pull/751)). +* Fixed error when running on root of windows mountpoint ([#760](https://github.com/diffplug/spotless/pull/760)). +* Fixed typo in javadoc comment for SQL\_FORMATTER\_INDENT\_TYPE ([#753](https://github.com/diffplug/spotless/pull/753)). + +## [2.10.2] - 2020-11-16 +### Fixed +* Fixed a bug which occurred if the root directory of the project was also the filesystem root ([#732](https://github.com/diffplug/spotless/pull/732)) + +## [2.10.1] - 2020-11-13 +### Fixed +* Bump JGit from `5.8.0` to `5.9.0` to improve performance ([#726](https://github.com/diffplug/spotless/issues/726)) + +## [2.10.0] - 2020-11-02 +### Added +* Added support to npm-based steps for picking up `.npmrc` files ([#727](https://github.com/diffplug/spotless/pull/727)) + +## [2.9.0] - 2020-10-20 +### Added +* Added support for eclipse-cdt 4.14.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-groovy 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-jdt 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-wtp 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +### Changed +* Updated default eclipse-cdt from 4.13.0 to 4.16.0 ([#722](https://github.com/diffplug/spotless/pull/722)). Note that version 4.17.0 is supported, but requires Java 11 or higher. +* Updated default eclipse-groovy from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-jdt from 4.16.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-wtp from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). + ## [2.8.0] - 2020-10-05 ### Added * Exposed new methods in `GitRatchet` to support faster ratcheting in the maven plugin ([#706](https://github.com/diffplug/spotless/pull/706)). diff --git a/README.md b/README.md index bac3e7458e..7a1ac5171d 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} extra('java.EclipseJdtFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtfmtStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', +lib('kotlin.DiktatStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |', lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', @@ -95,6 +96,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | [`java.EclipseJdtFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: | | [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :+1: | :white_large_square: | | [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | +| [`kotlin.DiktatStep`](lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | @@ -126,7 +128,7 @@ Once someone has filled in one square of the formatter/build system matrix, it's - Thanks to [Matthias Andreas Benkard](https://github.com/benkard) for adding support for google-java-format 1.8+ ([#563](https://github.com/diffplug/spotless/pull/563)) - Thanks to [Ranadeep Polavarapu](https://github.com/RanadeepPolavarapu) for adding support for ktfmt ([#569](https://github.com/diffplug/spotless/pull/569)) - Thanks to [Simon Gamma](https://github.com/simschla) for [adding support for npm-based formatters](https://github.com/diffplug/spotless/pull/283), [twice](https://github.com/diffplug/spotless/pull/606) including `prettier` and `tsfmt`. -- Thanks to [Kevin Brooks](https://github.com/k-brooks) for [updating all eclipse-based formatters to 4.13](https://github.com/diffplug/spotless/pull/482). +- Thanks to [Kevin Brooks](https://github.com/k-brooks) for [updating all eclipse-based formatters to 4.13](https://github.com/diffplug/spotless/pull/482) and [fixing Groovy for multiproject](https://github.com/diffplug/spotless/issues/877). - Thanks to [Thomas Glaeser](https://github.com/tglaeser) for [finding](https://github.com/diffplug/spotless/issues/654) and [fixing](https://github.com/diffplug/spotless/pull/656) a file-permissions-clobbering bug. - Thanks to [Joan Goyeau](https://github.com/joan38) for [fixing scalafmt integration](https://github.com/diffplug/spotless/pull/260). - Thanks to [Nick Sutcliffe](https://github.com/nsutcliffe) for [fixing scalafmt post-2.0](https://github.com/diffplug/spotless/pull/416). @@ -151,6 +153,7 @@ Once someone has filled in one square of the formatter/build system matrix, it's - Thanks to [Oliver Szymanski](https://github.com/source-knights) for porting [tsfmt](https://github.com/diffplug/spotless/pull/553) and [prettier](https://github.com/diffplug/spotless/pull/555) to maven. - Thanks to Andrew Oberstar for improvements to formatting java source in non-java source sets. [PR #60](https://github.com/diffplug/spotless/pull/60). - Thanks to [Sameer Balasubrahmanyam](https://github.com/sameer-b) for [adding support for IntelliJ-style year placeholders](https://github.com/diffplug/spotless/pull/542). +- Thanks to [Jamie Tanna](https://github.com/jamietanna) for [adding a simple JSON formatter](https://github.com/diffplug/spotless/pull/853). - Thanks to [Adib Saikali](https://github.com/asaikali) and [Paul Merlin](https://github.com/eskatos) for tracking down the tricky cause of [#506](https://github.com/diffplug/spotless/issues/506). - Import ordering from [EclipseCodeFormatter](https://github.com/krasa/EclipseCodeFormatter). - Built by [gradle](https://gradle.org/). diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index eebde40c34..8eb126f4c7 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -1,4 +1,6 @@ -# Release checklist +# Manual Release checklist + +We now do this automatically in CI. - [ ] Revise [`CHANGES.md`](CHANGES.md), [`plugin-gradle/CHANGES.md`](plugin-gradle/CHANGES.md), and [`plugin-maven/CHANGES.md`](plugin-maven/CHANGES.md) - [ ] If necessary, release lib `./gradlew :changelogPush` diff --git a/_ext/eclipse-base/CHANGES.md b/_ext/eclipse-base/CHANGES.md index 815333a897..67d18662a4 100644 --- a/_ext/eclipse-base/CHANGES.md +++ b/_ext/eclipse-base/CHANGES.md @@ -4,6 +4,15 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +## [3.5.0] - 2021-06-20 +### Added +* Support of `org.eclipse.core.resources` version `3.15.0` required by Eclipse `4.20`. +* Minimum required Java version changed from 8 to 11. + +## [3.4.2] - 2020-12-26 +### Fixed +* `org.eclipse.osgi` version `3.16.100` does not allow `null` as Debug service for `CloseableBundleFile`. + ## [3.4.1] - 2020-09-24 ### Fixed * Restored scope of transitive dependencies to 'compile'. diff --git a/_ext/eclipse-base/build.gradle b/_ext/eclipse-base/build.gradle index ae1f893a4d..88255b57b3 100644 --- a/_ext/eclipse-base/build.gradle +++ b/_ext/eclipse-base/build.gradle @@ -11,7 +11,6 @@ dependencies { api("org.eclipse.platform:org.eclipse.core.resources:${VER_ECLIPSE_CORE_RESOURCES}") { exclude group: 'org.eclipse.platform', module: 'org.eclipse.ant.core' exclude group: 'org.eclipse.platform', module: 'org.eclipse.core.expressions' - exclude group: 'org.eclipse.platform', module: 'org.eclipse.core.filesystem' } api("org.slf4j:slf4j-api:${VER_SLF4J}") diff --git a/_ext/eclipse-base/gradle.properties b/_ext/eclipse-base/gradle.properties index a511dbb1ff..9f8774a417 100644 --- a/_ext/eclipse-base/gradle.properties +++ b/_ext/eclipse-base/gradle.properties @@ -1,5 +1,8 @@ artifactId=spotless-eclipse-base description=Eclipse bundle controller and services for Spotless +# Build requirements +VER_JAVA=11 + # Compile dependencies -VER_ECLIPSE_CORE_RESOURCES=[3.13.800,4.0.0[ +VER_ECLIPSE_CORE_RESOURCES=[3.15.0,4.0.0[ diff --git a/_ext/eclipse-base/src/main/java/com/diffplug/spotless/extra/eclipse/base/osgi/ResourceAccessor.java b/_ext/eclipse-base/src/main/java/com/diffplug/spotless/extra/eclipse/base/osgi/ResourceAccessor.java index 139d818158..b75a2835ac 100644 --- a/_ext/eclipse-base/src/main/java/com/diffplug/spotless/extra/eclipse/base/osgi/ResourceAccessor.java +++ b/_ext/eclipse-base/src/main/java/com/diffplug/spotless/extra/eclipse/base/osgi/ResourceAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; +import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.storage.bundlefile.BundleEntry; import org.eclipse.osgi.storage.bundlefile.BundleFile; import org.eclipse.osgi.storage.bundlefile.DirBundleFile; @@ -32,6 +33,8 @@ import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import com.diffplug.spotless.extra.eclipse.base.service.NoDebugging; + /** * Helper to access resources. *

@@ -48,8 +51,7 @@ *

*/ class ResourceAccessor { - /** - */ + private static final Debug NO_DEBUGGING = new Debug(new NoDebugging()); private final String fatJarResourcePath; private final BundleFile bundleFile; @@ -77,7 +79,7 @@ private static BundleFile getBundlFile(Class clazz) throws BundleException { throw new BundleException(String.format("Path '%s' for '%s' is not accessible exist on local file system.", objUri, clazz.getName()), BundleException.READ_ERROR); } try { - return jarOrDirectory.isDirectory() ? new DirBundleFile(jarOrDirectory, false) : new ZipBundleFile(jarOrDirectory, null, null, null); + return jarOrDirectory.isDirectory() ? new DirBundleFile(jarOrDirectory, false) : new ZipBundleFile(jarOrDirectory, null, null, NO_DEBUGGING, false); } catch (IOException e) { throw new BundleException(String.format("Cannot access bundle at '%s'.", jarOrDirectory), BundleException.READ_ERROR, e); } diff --git a/_ext/eclipse-cdt/CHANGES.md b/_ext/eclipse-cdt/CHANGES.md index 5b7923b8b9..0dc9014bbb 100644 --- a/_ext/eclipse-cdt/CHANGES.md +++ b/_ext/eclipse-cdt/CHANGES.md @@ -3,16 +3,30 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `9.9.0`). ## [Unreleased] -### Changed + +## [10.3.0] - 2021-06-27 +### Added +* Switch to Eclipse CDT release 10.3 for Eclipse 4.20. + +## [10.2.0] - 2021-06-07 +### Added +* Switch to Eclipse CDT release 10.2 for Eclipse 4.19. + +## [10.1.0] - 2020-12-26 +### Added +* Switch to Eclipse CDT release 10.1 for Eclipse 4.18. + +## [10.0.0] - 2020-10-17 +### Added * Switch to Eclipse CDT release 10.0 for Eclipse 4.17. -* Minimum required Java version changed from 8 to 11. +* **BREAKING** Minimum required Java version changed from 8 to 11. ## [9.11.0] - 2020-10-03 -### Changed +### Added * Switch to Eclipse CDT release 9.11.1 for Eclipse 4.16. ## [9.10.0] - 2020-09-25 -### Changed +### Added * Switch to Eclipse CDT release 9.10 for Eclipse 4.14. ## [9.9.0] - 2019-11-01 diff --git a/_ext/eclipse-cdt/gradle.properties b/_ext/eclipse-cdt/gradle.properties index 0ca88bca41..4e10db22ef 100644 --- a/_ext/eclipse-cdt/gradle.properties +++ b/_ext/eclipse-cdt/gradle.properties @@ -5,8 +5,8 @@ description=Eclipse's CDT C/C++ formatter bundled for Spotless VER_JAVA=11 # Compile dependencies -VER_ECLIPSE_CDT=10.0 -VER_SPOTLESS_ECLISPE_BASE=[3.3.0,4.0.0[ -VER_ECLISPE_JFACE=[3.15.300,4.0.0[ -VER_ECLISPE_EFS=[3.6.700,4.0.0[ -VER_IBM_ICU=[61,65[ +VER_ECLIPSE_CDT=10.3 +VER_SPOTLESS_ECLISPE_BASE=[3.5.0,4.0.0[ +VER_ECLISPE_JFACE=[3.18.0,4.0.0[ +VER_ECLISPE_EFS=[3.7.0,4.0.0[ +VER_IBM_ICU=[67.1,68[ diff --git a/_ext/eclipse-cdt/src/main/java/com/diffplug/spotless/extra/eclipse/cdt/EclipseCdtFormatterStepImpl.java b/_ext/eclipse-cdt/src/main/java/com/diffplug/spotless/extra/eclipse/cdt/EclipseCdtFormatterStepImpl.java index fd9c7310e5..4482f3e752 100644 --- a/_ext/eclipse-cdt/src/main/java/com/diffplug/spotless/extra/eclipse/cdt/EclipseCdtFormatterStepImpl.java +++ b/_ext/eclipse-cdt/src/main/java/com/diffplug/spotless/extra/eclipse/cdt/EclipseCdtFormatterStepImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.formatter.CodeFormatter; -import org.eclipse.core.internal.filebuffers.FileBuffersPlugin; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.TextEdit; @@ -56,7 +55,6 @@ public void registerServices(SpotlessEclipseServiceConfig config) { @Override public void activatePlugins(SpotlessEclipsePluginConfig config) { config.applyDefault(); - config.add(new FileBuffersPlugin()); config.add(new CCorePlugin()); } } diff --git a/_ext/eclipse-groovy/CHANGES.md b/_ext/eclipse-groovy/CHANGES.md index e98e35c237..823cd6eea7 100644 --- a/_ext/eclipse-groovy/CHANGES.md +++ b/_ext/eclipse-groovy/CHANGES.md @@ -4,6 +4,26 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +### Fixed +* Fixed IndexOutOfBoundsException in parallel execution of `eclipse-groovy` formatter ([#877](https://github.com/diffplug/spotless/issues/877)) + +## [4.1.0] - 2021-06-05 +### Added +* Switch to Groovy-Eclipse release 4.1.0 for Eclipse 4.19 using Groovy 4.0.0 Alpha 2. + +## [4.0.0] - 2021-04-10 +### Added +* Switch to Groovy-Eclipse release 4.0.0 for Eclipse 4.18 using Groovy 4.0.0 Alpha 2. +* **BREAKING** Keep spotless-eclipse-groovy major version in sync with Groovy-Eclipse version. + +## [3.9.0] - 2020-10-17 +### Added +* Fixed version number determined by change log. + +## [3.8.1] - 2020-10-17 +### Added +* Switch to Groovy-Eclipse release 3.9.0 for Eclipse 4.17 using Groovy-Indy 3.0.6. + ## [3.8.0] - 2020-10-04 ### Added * Switch to Groovy-Eclipse release 3.8.0 for Eclipse 4.16 using Groovy-Indy 3.0.4. diff --git a/_ext/eclipse-groovy/build.gradle b/_ext/eclipse-groovy/build.gradle index 83b61b4db9..e1382acd76 100644 --- a/_ext/eclipse-groovy/build.gradle +++ b/_ext/eclipse-groovy/build.gradle @@ -12,7 +12,7 @@ ext { // the once used during code formatting 'org.codehaus.groovy':'+', // Groovy compiler patches supporting use within GrEclipse and Groovy itself 'org.codehaus.groovy.eclipse.core':'+', // Groovy core classes (provides central logging used by formatter) - 'org.eclipse.jdt.core':'3.22.0.v202006301451-e2006-RELEASE', // Patches org.eclipse.jdt.core classes supporting use within GrEclipse (provides AST generator) + 'org.eclipse.jdt.core':"${VAR_GRECLIPSE_JDT_PATCH}", // Patches org.eclipse.jdt.core classes supporting use within GrEclipse (provides AST generator) 'org.eclipse.jdt.groovy.core':'+' // Extends org.eclipse.jdt.core for Groovy ] @@ -20,7 +20,8 @@ ext { //Jars included by org.codehaus.groovy ////////////////////////////////////////////////////////////////////////// // Use Groovy compiler compatible with GrEclipse instead of localGroovy - "**/groovy-${VER_GROOVY}-indy", + "**/groovy-${VER_GROOVY}", + "**/groovy-parser2", // Patches/Overrides some of the Groovy compiler classes '**/groovy-eclipse', // Provides logging capabilities for groovy-eclipse diff --git a/_ext/eclipse-groovy/gradle.properties b/_ext/eclipse-groovy/gradle.properties index acc8e853e3..2f2fd30968 100644 --- a/_ext/eclipse-groovy/gradle.properties +++ b/_ext/eclipse-groovy/gradle.properties @@ -2,10 +2,10 @@ artifactId=spotless-eclipse-groovy description=Groovy Eclipse's formatter bundled for Spotless # Compile -VER_ECLIPSE=4.16 -VER_SPOTLESS_ECLISPE_BASE=[3.3.0,4.0.0[ +VER_ECLIPSE=4.19 +VER_SPOTLESS_ECLISPE_BASE=[3.4.2,4.0.0[ VER_ECLISPE_JFACE=[3.15.300,4.0.0[ -VER_GRECLIPSE=3.8.0 -VER_GROOVY=3.0.4 +VER_GRECLIPSE=4.1.0 +VER_GROOVY=4.0.0 # Use org.eclipse.jdt.core patched for Groovy-Eclipse -VAR_GRECLIPSE_JDT_PATCH=3.22.0.v202006301451-e2006-RELEASE +VAR_GRECLIPSE_JDT_PATCH=3.25.0.v202103311613-e2103-RELEASE diff --git a/_ext/eclipse-groovy/src/main/java/com/diffplug/spotless/extra/eclipse/groovy/GrEclipseFormatterStepImpl.java b/_ext/eclipse-groovy/src/main/java/com/diffplug/spotless/extra/eclipse/groovy/GrEclipseFormatterStepImpl.java index 2d1208c0e5..1d2b71c69f 100644 --- a/_ext/eclipse-groovy/src/main/java/com/diffplug/spotless/extra/eclipse/groovy/GrEclipseFormatterStepImpl.java +++ b/_ext/eclipse-groovy/src/main/java/com/diffplug/spotless/extra/eclipse/groovy/GrEclipseFormatterStepImpl.java @@ -106,7 +106,9 @@ public GroovyErrorListener() { errors = Collections.synchronizedList(new ArrayList()); ILog groovyLogger = GroovyCoreActivator.getDefault().getLog(); groovyLogger.addLogListener(this); - GroovyLogManager.manager.addLogger(this); + synchronized(GroovyLogManager.manager) { + GroovyLogManager.manager.addLogger(this); + } } @Override @@ -117,7 +119,9 @@ public void logging(final IStatus status, final String plugin) { public boolean errorsDetected() { ILog groovyLogger = GroovyCoreActivator.getDefault().getLog(); groovyLogger.removeLogListener(this); - GroovyLogManager.manager.removeLogger(this); + synchronized(GroovyLogManager.manager) { + GroovyLogManager.manager.removeLogger(this); + } return 0 != errors.size(); } diff --git a/_ext/eclipse-jdt/gradle.properties b/_ext/eclipse-jdt/gradle.properties index 74734a8bf3..ec4094639d 100644 --- a/_ext/eclipse-jdt/gradle.properties +++ b/_ext/eclipse-jdt/gradle.properties @@ -1,8 +1,9 @@ -# Mayor/Minor versions correspond to the minimum Eclipse version supported/tested. -# Patch version is incremented for backward compatible patches of this library. artifactId=spotless-eclipse-jdt description=Eclipse's JDT formatter bundled for Spotless +# Build requirements +VER_JAVA=11 + # Compile VER_ECLIPSE_JDT_CORE=[3.12.0,4.0.0[ -VER_SPOTLESS_ECLISPE_BASE=[3.3.0,4.0.0[ +VER_SPOTLESS_ECLISPE_BASE=[3.5.0,4.0.0[ diff --git a/_ext/eclipse-wtp/CHANGES.md b/_ext/eclipse-wtp/CHANGES.md index 18e6d454cb..b0c64771ee 100644 --- a/_ext/eclipse-wtp/CHANGES.md +++ b/_ext/eclipse-wtp/CHANGES.md @@ -4,6 +4,26 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +## [3.22.0] - 2021-06-27 +### Added +* Switch to Web Tools Platform release 3.22.0 for Eclipse 4.20. + +## [3.21.0] - 2021-06-07 +### Added +* Switch to Web Tools Platform release 3.21.0 for Eclipse 4.19. Minimum required Java version changed from 8 to 11. + +## [3.20.0] - 2020-12-26 +### Added +* Switch to Web Tools Platform release 3.20.0 for Eclipse 4.18. + +## [3.19.0] - 2020-10-17 +### Added +* Fixed version number determined by change log. + +## [3.18.1] - 2020-10-17 +### Added +* Switch to Web Tools Platform release 3.19.0 for Eclipse 4.17. + ## [3.18.0] - 2020-10-03 ### Added * Switch to Web Tools Platform release 3.18.0 for Eclipse 4.16. diff --git a/_ext/eclipse-wtp/gradle.properties b/_ext/eclipse-wtp/gradle.properties index e9ee563886..fe7ee1327b 100644 --- a/_ext/eclipse-wtp/gradle.properties +++ b/_ext/eclipse-wtp/gradle.properties @@ -1,13 +1,16 @@ artifactId=spotless-eclipse-wtp description=Eclipse's WTP formatters bundled for Spotless +# Build requirements +VER_JAVA=11 + # Compile -VER_ECLIPSE_WTP=2020-06 -VER_SPOTLESS_ECLISPE_BASE=[3.3.0,4.0.0[ -VER_IBM_ICU=[61,65[ -VER_ECLISPE_EMF=[2.16.0,3.0.0[ -VER_ECLIPSE_OSGI_SERVICES=[3.8.0,4.0.0[ -VER_ECLIPSE_FILE_BUFFERS=[3.6.700,4.0.0[ -VER_ECLISPE_JFACE=[3.15.300,4.0.0[ -VER_ECLISPE_EFS=[1.7.600,2.0.0[ -VER_ECLISPE_XSD=[2.15.0,3.0.0[ +VER_ECLIPSE_WTP=2021-06 +VER_SPOTLESS_ECLISPE_BASE=[3.5.0,4.0.0[ +VER_IBM_ICU=[67.1,68[ +VER_ECLISPE_EMF=[2.22.0,3.0.0[ +VER_ECLIPSE_OSGI_SERVICES=[3.10.0,4.0.0[ +VER_ECLIPSE_FILE_BUFFERS=[3.7.0,4.0.0[ +VER_ECLISPE_JFACE=[3.18.0,4.0.0[ +VER_ECLISPE_EFS=[1.9.0,2.0.0[ +VER_ECLISPE_XSD=[2.18.0,3.0.0[ diff --git a/build.gradle b/build.gradle index 54d9c12ae7..cd12283961 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,9 @@ -plugins { - // https://github.com/diffplug/goomph/blob/main/CHANGES.md - id 'com.diffplug.eclipse.resourcefilters' version '3.22.0' - // https://plugins.gradle.org/plugin/com.gradle.plugin-publish - id 'com.gradle.plugin-publish' version '0.12.0' apply false - // https://github.com/bintray/gradle-bintray-plugin/releases - id 'com.jfrog.bintray' version '1.8.5' apply false - // https://github.com/mnlipp/jdrupes-mdoclet/releases - id 'org.jdrupes.mdoclet' version '1.0.10' apply false - // https://github.com/spotbugs/spotbugs-gradle-plugin/releases - id "com.github.spotbugs" version "4.3.0" apply false - //https://github.com/diffplug/goomph - id "com.diffplug.p2.asmaven" version "3.22.0" apply false - // https://github.com/diffplug/spotless-changelog - id "com.diffplug.spotless-changelog" version "2.0.0" apply false +buildscript { + repositories { + mavenCentral() + } } - +apply from: rootProject.file('gradle/java-publish.gradle') apply from: rootProject.file('gradle/changelog.gradle') allprojects { apply from: rootProject.file('gradle/spotless.gradle') diff --git a/gradle.properties b/gradle.properties index 9770f4eeb6..7e9453896f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ VER_SLF4J=[1.6,2.0[ # Used in multiple places VER_DURIAN=1.2.0 -VER_JGIT=5.8.0.202006091008-r +VER_JGIT=5.10.0.202012080955-r VER_JUNIT=4.13 VER_ASSERTJ=3.15.0 VER_MOCKITO=3.3.3 diff --git a/gradle/java-publish.gradle b/gradle/java-publish.gradle index 15e9562633..2c070e7ae8 100644 --- a/gradle/java-publish.gradle +++ b/gradle/java-publish.gradle @@ -1,14 +1,40 @@ + +if (project.parent == null) { + group = 'com.diffplug.spotless' + // it's the root project + apply plugin: 'io.github.gradle-nexus.publish-plugin' + nexusPublishing { + repositories { + sonatype { + username = System.env['nexus_user'] + password = System.env['nexus_pass'] + } + } + } + def initTask = tasks.named('initializeSonatypeStagingRepository') + allprojects { + initTask.configure { + shouldRunAfter(tasks.withType(Sign)) + } + } + return +} + /////////// // MAVEN // /////////// -apply plugin: 'maven-publish' -apply plugin: 'com.jfrog.bintray' +java { + withJavadocJar() + withSourcesJar() +} -task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allJava +tasks.named('sourcesJar') { + dependsOn 'jar' } +apply plugin: 'maven-publish' +apply plugin: 'signing' + // Where it's possible to name parameters and methods clearly enough // that javadoc is not necessary, why make the code bigger? // @@ -16,7 +42,6 @@ task sourcesJar(type: Jar) { javadoc { options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('Xwerror', '-quiet') - enabled = org.gradle.api.JavaVersion.current() == org.gradle.api.JavaVersion.VERSION_1_8 } // make sure bad javadoc breaks the build tasks.named('check') { @@ -29,7 +54,6 @@ def javadocInfo = '

' + makeLink("https://github.com/${org}/${name}", "${grou ' by ' + makeLink('https://www.diffplug.com', 'DiffPlug') + '

' String dotdotGradle = project.name.startsWith('eclipse-') ? '../../gradle' : '../gradle' -apply plugin: 'org.jdrupes.mdoclet' javadoc { options.encoding = 'UTF-8' // Where it's possible to name parameters and methods clearly enough @@ -37,6 +61,7 @@ javadoc { // // Thus, no javadoc warnings. options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('source', '8') // setup the header options.header javadocInfo options.footer javadocInfo @@ -49,11 +74,6 @@ javadoc { options.linksOffline("https://javadoc.io/static/com.diffplug.spotless/spotless-lib-extra/${rootProject.spotlessChangelog.versionLast}", "${dotdotGradle}/javadoc/spotless-lib-extra") } -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - //////////////// // PUBLISHING // //////////////// @@ -68,8 +88,6 @@ model { if (project.ext.artifactId != 'spotless-plugin-gradle') { from components.java } - artifact sourcesJar - artifact javadocJar groupId project.group artifactId project.ext.artifactId @@ -138,36 +156,12 @@ model { } if (!version.endsWith('-SNAPSHOT')) { - // upload releases to bintray and then mavenCentral - bintray { - user = System.env['bintray_user'] - key = System.env['bintray_pass'] - publications = [ - 'pluginMaven' - ] - publish = true - pkg { - repo = 'opensource' - name = project.ext.artifactId - userOrg = project.org - version { - name = project.version - mavenCentralSync { - user = System.env['nexus_user'] - password = System.env['nexus_pass'] - } - } - } + signing { + String gpg_key = new String(System.env['gpg_key64'].decodeBase64()) + useInMemoryPgpKeys(gpg_key, System.env['gpg_passphrase']) + sign(publishing.publications) } - publish.dependsOn(bintrayUpload) - bintrayUpload.dependsOn([ - 'generatePomFileForPluginMavenPublication', - jar, - sourcesJar, - javadocJar - ]) - // find the project with the changelog (this project for plugins, root project for libs) def changelogTasks = (tasks.names.contains('changelogBump') ? project : rootProject).tasks @@ -176,14 +170,15 @@ if (!version.endsWith('-SNAPSHOT')) { dependsOn changelogTasks.named('changelogCheck') } // ensures that changelog bump and push only happens if the publish was successful - changelogTasks.named('changelogBump').configure { - dependsOn tasks.named('bintrayUpload') - // only the root project has bintrayPublish, and it finalizes all bintrayUpload tasks - // https://github.com/bintray/gradle-bintray-plugin/blob/3fe02dfdae3e807afba57e0140a0d4c2424674e1/src/main/groovy/com/jfrog/bintray/gradle/ProjectsEvaluatedBuildListener.groovy#L37-L41 - dependsOn rootProject.tasks.named('bintrayPublish') - // if we have a gradle plugin, we need to push it up to the plugin portal too - if (tasks.names.contains('publishPlugins')) { - dependsOn tasks.named('publishPlugins') + def thisProj = project + afterEvaluate { + changelogTasks.named('changelogBump').configure { + dependsOn thisProj.tasks.named('publishPluginMavenPublicationToSonatypeRepository') + dependsOn rootProject.tasks.named('closeAndReleaseSonatypeStagingRepository') + // if we have a gradle plugin, we need to push it up to the plugin portal too + if (thisProj.tasks.names.contains('publishPlugins')) { + dependsOn thisProj.tasks.named('publishPlugins') + } } } } diff --git a/gradle/java-setup.gradle b/gradle/java-setup.gradle index b4a13d81ff..f723a80826 100644 --- a/gradle/java-setup.gradle +++ b/gradle/java-setup.gradle @@ -1,7 +1,7 @@ ////////// // JAVA // ////////// -repositories { jcenter() } +repositories { mavenCentral() } // setup java apply plugin: 'java' diff --git a/gradle/spotless-freshmark.gradle b/gradle/spotless-freshmark.gradle index dc7888adc4..d444740a33 100644 --- a/gradle/spotless-freshmark.gradle +++ b/gradle/spotless-freshmark.gradle @@ -1,4 +1,30 @@ +import java.util.regex.Matcher +import java.util.regex.Pattern + + +def thisVm() { + String jre = System.getProperty("java.version") + if (jre.startsWith("1.8")) { + return 8 + } else { + Matcher matcher = Pattern.compile("(\\d+)").matcher(jre) + if (!matcher.find()) { + throw new IllegalArgumentException("Expected " + jre + " to start with an integer") + } + int version = Integer.parseInt(matcher.group(1)) + if (version <= 8) { + throw new IllegalArgumentException("Expected " + jre + " to start with an integer greater than 8") + } + return version + } +} + +if (thisVm() >= 15) { + // freshmark doesn't run on JRE 15+ + return +} + apply plugin: 'com.diffplug.spotless' import com.diffplug.gradle.spotless.FreshMarkExtension diff --git a/lib-extra/build.gradle b/lib-extra/build.gradle index 781a12a6d9..a1fc0c7e0f 100644 --- a/lib-extra/build.gradle +++ b/lib-extra/build.gradle @@ -15,7 +15,7 @@ dependencies { implementation "org.eclipse.jgit:org.eclipse.jgit:${VER_JGIT}" implementation "com.googlecode.concurrent-trees:concurrent-trees:2.6.1" // used for xml parsing in EclipseFormatter - implementation "org.codehaus.groovy:groovy-xml:3.0.3" + implementation "org.codehaus.groovy:groovy-xml:3.0.8" // testing testImplementation project(':testlib') diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitAttributesLineEndings.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitAttributesLineEndings.java index bd7cbd992c..bceb0630fa 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitAttributesLineEndings.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitAttributesLineEndings.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,8 +55,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** - * Uses [.gitattributes](https://git-scm.com/docs/gitattributes) to determine - * the appropriate line ending. Falls back to the `core.eol` property in the + * Uses .gitattributes to determine + * the appropriate line ending. Falls back to the {@code core.eol} property in the * git config if there are no applicable git attributes, then finally falls * back to the platform native. */ @@ -108,7 +108,8 @@ static class CachedEndings implements Serializable { final ConcurrentRadixTree hasNonDefaultEnding = new ConcurrentRadixTree<>(new DefaultCharSequenceNodeFactory()); CachedEndings(File projectDir, Runtime runtime, Iterable toFormat) { - rootDir = FileSignature.pathNativeToUnix(projectDir.getAbsolutePath()) + "/"; + String rootPath = FileSignature.pathNativeToUnix(projectDir.getAbsolutePath()); + rootDir = rootPath.equals("/") ? rootPath : rootPath + "/"; defaultEnding = runtime.defaultEnding; for (File file : toFormat) { String ending = runtime.getEndingFor(file); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java index 5130760091..a8797c2e86 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -51,7 +53,7 @@ /** * How to use: * - For best performance, you should have one instance of GitRatchet, shared by all projects. - * - Use {@link #rootTreeShaOf(Object, String)} to turn `origin/master` into the SHA of the tree object at that reference + * - Use {@link #rootTreeShaOf(Object, String)} to turn {@code origin/master} into the SHA of the tree object at that reference * - Use {@link #isClean(Object, ObjectId, File)} to see if the given file is "git clean" relative to that tree * - If you have up-to-date checking and want the best possible performance, use {@link #subtreeShaOf(Object, ObjectId)} to optimize up-to-date checks on a per-project basis. */ @@ -139,7 +141,7 @@ private static boolean worktreeIsCleanCheckout(TreeWalk treeWalk) { /** * The first part of making this fast is finding the appropriate git repository quickly. Because of composite * builds and submodules, it's quite possible that a single Gradle project will span across multiple git repositories. - * We cache the Repository for every Project in `gitRoots`, and use dynamic programming to populate it. + * We cache the Repository for every Project in {@code gitRoots}, and use dynamic programming to populate it. */ protected Repository repositoryFor(Project project) throws IOException { Repository repo = gitRoots.get(project); @@ -170,26 +172,47 @@ protected Repository repositoryFor(Project project) throws IOException { protected abstract @Nullable Project getParent(Project project); private static @Nullable Repository traverseParentsUntil(File startWith, File file) throws IOException { - while (startWith != null) { + while (startWith != null && !Objects.equals(startWith, file)) { if (isGitRoot(startWith)) { return createRepo(startWith); } else { startWith = startWith.getParentFile(); - if (Objects.equals(startWith, file)) { - return null; - } } } return null; } + /** + * When populating a new submodule directory with "git submodule init", the $GIT_DIR meta-information directory + * for submodules is created inside $GIT_DIR/modules// directory of the super-project + * and referenced via the git-file mechanism. + */ + private static @Nullable File getDotGitDir(File dir, String dotGit) { + File dotGitPath = new File(dir, dotGit); + + if (dotGitPath.isDirectory()) { + return dotGitPath; + } else if (dotGitPath.isFile()) { + try { + String relativePath = new String(Files.readAllBytes(dotGitPath.toPath()), StandardCharsets.UTF_8) + .split(":")[1].trim(); + return getDotGitDir(dir, relativePath); + } catch (IOException e) { + System.err.println("failed to parse git meta: " + e.getMessage()); + return null; + } + } else { + return null; + } + } + private static boolean isGitRoot(File dir) { - File dotGit = new File(dir, Constants.DOT_GIT); - return dotGit.isDirectory() && RepositoryCache.FileKey.isGitRepository(dotGit, FS.DETECTED); + File dotGit = getDotGitDir(dir, Constants.DOT_GIT); + return dotGit != null && RepositoryCache.FileKey.isGitRepository(dotGit, FS.DETECTED); } static Repository createRepo(File dir) throws IOException { - return FileRepositoryBuilder.create(new File(dir, Constants.DOT_GIT)); + return FileRepositoryBuilder.create(getDotGitDir(dir, Constants.DOT_GIT)); } /** diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStep.java index 6806a21f47..f9c11ca2d0 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStep.java @@ -36,7 +36,7 @@ private EclipseCdtFormatterStep() {} private static final String NAME = "eclipse cdt formatter"; private static final String FORMATTER_CLASS = "com.diffplug.spotless.extra.eclipse.cdt.EclipseCdtFormatterStepImpl"; - private static final String DEFAULT_VERSION = "4.13.0"; + private static final String DEFAULT_VERSION = "4.16.0"; private static final String FORMATTER_METHOD = "format"; public static String defaultVersion() { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java index 96664e6475..f6ad4a8c00 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ private GrEclipseFormatterStep() {} private static final String FORMATTER_CLASS = "com.diffplug.spotless.extra.eclipse.groovy.GrEclipseFormatterStepImpl"; private static final String FORMATTER_CLASS_OLD = "com.diffplug.gradle.spotless.groovy.eclipse.GrEclipseFormatterStepImpl"; private static final String MAVEN_GROUP_ARTIFACT = "com.diffplug.spotless:spotless-eclipse-groovy"; - private static final String DEFAULT_VERSION = "4.13.0"; + private static final String DEFAULT_VERSION = "4.19.0"; private static final String FORMATTER_METHOD = "format"; public static String defaultVersion() { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java index ebc8c037f3..5faa4cb2c1 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ private EclipseJdtFormatterStep() {} private static final String FORMATTER_CLASS_OLD = "com.diffplug.gradle.spotless.java.eclipse.EclipseFormatterStepImpl"; private static final String FORMATTER_CLASS = "com.diffplug.spotless.extra.eclipse.java.EclipseJdtFormatterStepImpl"; private static final String MAVEN_GROUP_ARTIFACT = "com.diffplug.spotless:spotless-eclipse-jdt"; - private static final String DEFAULT_VERSION = "4.16.0"; + private static final String DEFAULT_VERSION = "4.19.0"; private static final String FORMATTER_METHOD = "format"; public static String defaultVersion() { diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java index 63e8673774..6b12a375e8 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStep.java @@ -36,7 +36,7 @@ public enum EclipseWtpFormatterStep { private static final String NAME = "eclipse wtp formatters"; private static final String FORMATTER_PACKAGE = "com.diffplug.spotless.extra.eclipse.wtp."; - private static final String DEFAULT_VERSION = "4.13.0"; + private static final String DEFAULT_VERSION = "4.18.0"; private static final String FORMATTER_METHOD = "format"; private final String implementationClassName; diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.14.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.14.0.lockfile new file mode 100644 index 0000000000..43cb98774d --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.14.0.lockfile @@ -0,0 +1,22 @@ +# Spotless formatter based on CDT version 9.10.0 (see https://www.eclipse.org/cdt/) +com.diffplug.spotless:spotless-eclipse-cdt:9.10.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.600 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.500 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.800 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.600 +org.eclipse.platform:org.eclipse.core.jobs:3.10.600 +org.eclipse.platform:org.eclipse.core.resources:3.13.600 +org.eclipse.platform:org.eclipse.core.runtime:3.17.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.300 +org.eclipse.platform:org.eclipse.equinox.common:3.10.600 +org.eclipse.platform:org.eclipse.equinox.preferences:3.7.600 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.600 +org.eclipse.platform:org.eclipse.jface.text:3.16.100 +org.eclipse.platform:org.eclipse.jface:3.18.0 +org.eclipse.platform:org.eclipse.osgi:3.15.100 +org.eclipse.platform:org.eclipse.text:3.10.0 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.16.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.16.0.lockfile new file mode 100644 index 0000000000..3bf6b1ca01 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.16.0.lockfile @@ -0,0 +1,22 @@ +# Spotless formatter based on CDT version 9.11.1 (see https://www.eclipse.org/cdt/) +com.diffplug.spotless:spotless-eclipse-cdt:9.11.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.google.j2objc:j2objc-annotations:1.3 +com.ibm.icu:icu4j:64.2 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.700 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1000 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.700 +org.eclipse.platform:org.eclipse.core.runtime:3.18.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.500 +org.eclipse.platform:org.eclipse.equinox.common:3.12.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.800 +org.eclipse.platform:org.eclipse.jface.text:3.16.300 +org.eclipse.platform:org.eclipse.jface:3.20.0 +org.eclipse.platform:org.eclipse.osgi:3.15.300 +org.eclipse.platform:org.eclipse.text:3.10.200 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.17.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.17.0.lockfile new file mode 100644 index 0000000000..78a6db147f --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.17.0.lockfile @@ -0,0 +1,22 @@ +# Spotless formatter based on CDT version 10.0 (see https://www.eclipse.org/cdt/) +com.diffplug.spotless:spotless-eclipse-cdt:10.0.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.1 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1000 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.800 +org.eclipse.platform:org.eclipse.core.runtime:3.19.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.13.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.9.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.400 +org.eclipse.platform:org.eclipse.jface:3.21.0 +org.eclipse.platform:org.eclipse.osgi:3.16.0 +org.eclipse.platform:org.eclipse.text:3.10.300 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.18.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.18.0.lockfile new file mode 100644 index 0000000000..7135a6826d --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.18.0.lockfile @@ -0,0 +1,22 @@ +# Spotless formatter based on CDT version 10.1 (see https://www.eclipse.org/cdt/) +com.diffplug.spotless:spotless-eclipse-cdt:10.1.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1100 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1000 +org.eclipse.platform:org.eclipse.core.resources:3.13.900 +org.eclipse.platform:org.eclipse.core.runtime:3.20.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.14.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.100 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.500 +org.eclipse.platform:org.eclipse.jface:3.22.0 +org.eclipse.platform:org.eclipse.osgi:3.16.100 +org.eclipse.platform:org.eclipse.text:3.10.400 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.19.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.19.0.lockfile new file mode 100644 index 0000000000..7c508e64bd --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_cdt_formatter/v4.19.0.lockfile @@ -0,0 +1,22 @@ +# Spotless formatter based on CDT version 10.2 (see https://www.eclipse.org/cdt/) +com.diffplug.spotless:spotless-eclipse-cdt:10.2.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:67.1 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.900 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1100 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1100 +org.eclipse.platform:org.eclipse.core.resources:3.14.0 +org.eclipse.platform:org.eclipse.core.runtime:3.20.100 +org.eclipse.platform:org.eclipse.equinox.app:1.5.100 +org.eclipse.platform:org.eclipse.equinox.common:3.14.100 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.200 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.100 +org.eclipse.platform:org.eclipse.jface.text:3.17.0 +org.eclipse.platform:org.eclipse.jface:3.22.100 +org.eclipse.platform:org.eclipse.osgi:3.16.200 +org.eclipse.platform:org.eclipse.text:3.11.0 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.17.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.17.0.lockfile new file mode 100644 index 0000000000..47cb5f10dd --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.17.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on JDT version 4.17.0 (see https://projects.eclipse.org/projects/eclipse.jdt) +# Compare tag in M2 pom with https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R4_17 to determine core version. +com.diffplug.spotless:spotless-eclipse-jdt:4.8.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.1 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.jdt:org.eclipse.jdt.core:3.23.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.800 +org.eclipse.platform:org.eclipse.core.runtime:3.19.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.13.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.9.0 +org.eclipse.platform:org.eclipse.osgi:3.16.0 +org.eclipse.platform:org.eclipse.text:3.10.300 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.18.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.18.0.lockfile new file mode 100644 index 0000000000..c5b2799c11 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.18.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on JDT version 4.18.0 (see https://projects.eclipse.org/projects/eclipse.jdt) +# Compare tag in M2 pom with https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R4_18 to determine core version. +com.diffplug.spotless:spotless-eclipse-jdt:4.8.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.jdt:org.eclipse.jdt.core:3.24.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1000 +org.eclipse.platform:org.eclipse.core.resources:3.13.900 +org.eclipse.platform:org.eclipse.core.runtime:3.20.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.14.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.100 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.0 +org.eclipse.platform:org.eclipse.osgi:3.16.100 +org.eclipse.platform:org.eclipse.text:3.10.400 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.19.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.19.0.lockfile new file mode 100644 index 0000000000..fcc96b8520 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_jdt_formatter/v4.19.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on JDT version 4.19.0 (see https://projects.eclipse.org/projects/eclipse.jdt) +# Compare tag in M2 pom with https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R4_19 to determine core version. +com.diffplug.spotless:spotless-eclipse-jdt:4.8.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.jdt:org.eclipse.jdt.core:3.25.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.900 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1100 +org.eclipse.platform:org.eclipse.core.resources:3.14.0 +org.eclipse.platform:org.eclipse.core.runtime:3.20.100 +org.eclipse.platform:org.eclipse.equinox.app:1.5.100 +org.eclipse.platform:org.eclipse.equinox.common:3.14.100 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.200 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.100 +org.eclipse.platform:org.eclipse.osgi:3.16.200 +org.eclipse.platform:org.eclipse.text:3.11.0 \ No newline at end of file diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.14.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.14.0.lockfile new file mode 100644 index 0000000000..102f42489f --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.14.0.lockfile @@ -0,0 +1,25 @@ +# Spotless formatter based on Eclipse-WTP version 3.16 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.16.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +org.eclipse.emf:org.eclipse.emf.common:2.17.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.20.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.600 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.500 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.800 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.600 +org.eclipse.platform:org.eclipse.core.jobs:3.10.600 +org.eclipse.platform:org.eclipse.core.resources:3.13.600 +org.eclipse.platform:org.eclipse.core.runtime:3.17.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.300 +org.eclipse.platform:org.eclipse.equinox.common:3.10.600 +org.eclipse.platform:org.eclipse.equinox.preferences:3.7.600 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.600 +org.eclipse.platform:org.eclipse.jface.text:3.16.100 +org.eclipse.platform:org.eclipse.jface:3.18.0 +org.eclipse.platform:org.eclipse.osgi.services:3.8.0 +org.eclipse.platform:org.eclipse.osgi:3.15.100 +org.eclipse.platform:org.eclipse.text:3.10.0 +org.eclipse.xsd:org.eclipse.xsd:2.12.0 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.15.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.15.0.lockfile new file mode 100644 index 0000000000..80f47d328b --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.15.0.lockfile @@ -0,0 +1,25 @@ +# Spotless formatter based on Eclipse-WTP version 3.17 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.17.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +org.eclipse.emf:org.eclipse.emf.common:2.18.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.21.0 +org.eclipse.emf:org.eclipse.xsd:2.17.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.600 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.900 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.700 +org.eclipse.platform:org.eclipse.core.resources:3.13.700 +org.eclipse.platform:org.eclipse.core.runtime:3.17.100 +org.eclipse.platform:org.eclipse.equinox.app:1.4.400 +org.eclipse.platform:org.eclipse.equinox.common:3.11.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.7.700 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.700 +org.eclipse.platform:org.eclipse.jface.text:3.16.200 +org.eclipse.platform:org.eclipse.jface:3.19.0 +org.eclipse.platform:org.eclipse.osgi.services:3.8.0 +org.eclipse.platform:org.eclipse.osgi:3.15.200 +org.eclipse.platform:org.eclipse.text:3.10.100 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.16.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.16.0.lockfile new file mode 100644 index 0000000000..efb3a2cdb1 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.16.0.lockfile @@ -0,0 +1,25 @@ +# Spotless formatter based on Eclipse-WTP version 3.18 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.18.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +org.eclipse.emf:org.eclipse.emf.common:2.19.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.22.0 +org.eclipse.emf:org.eclipse.xsd:2.17.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.700 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1000 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.700 +org.eclipse.platform:org.eclipse.core.runtime:3.18.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.500 +org.eclipse.platform:org.eclipse.equinox.common:3.12.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.800 +org.eclipse.platform:org.eclipse.jface.text:3.16.300 +org.eclipse.platform:org.eclipse.jface:3.20.0 +org.eclipse.platform:org.eclipse.osgi.services:3.8.0 +org.eclipse.platform:org.eclipse.osgi:3.15.300 +org.eclipse.platform:org.eclipse.text:3.10.200 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.17.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.17.0.lockfile new file mode 100644 index 0000000000..6960ea01b3 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.17.0.lockfile @@ -0,0 +1,26 @@ +# Spotless formatter based on Eclipse-WTP version 3.19 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.19.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.1 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.emf:org.eclipse.emf.common:2.20.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.23.0 +org.eclipse.emf:org.eclipse.xsd:2.18.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1000 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.800 +org.eclipse.platform:org.eclipse.core.runtime:3.19.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.13.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.9.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.400 +org.eclipse.platform:org.eclipse.jface:3.21.0 +org.eclipse.platform:org.eclipse.osgi.services:3.9.0 +org.eclipse.platform:org.eclipse.osgi:3.16.0 +org.eclipse.platform:org.eclipse.text:3.10.300 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.18.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.18.0.lockfile new file mode 100644 index 0000000000..3112a78912 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.18.0.lockfile @@ -0,0 +1,26 @@ +# Spotless formatter based on Eclipse-WTP version 3.20 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.20.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:64.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.emf:org.eclipse.emf.common:2.21.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.23.0 +org.eclipse.emf:org.eclipse.xsd:2.18.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1100 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1000 +org.eclipse.platform:org.eclipse.core.resources:3.13.900 +org.eclipse.platform:org.eclipse.core.runtime:3.20.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.14.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.100 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.500 +org.eclipse.platform:org.eclipse.jface:3.22.0 +org.eclipse.platform:org.eclipse.osgi.services:3.9.0 +org.eclipse.platform:org.eclipse.osgi:3.16.100 +org.eclipse.platform:org.eclipse.text:3.10.400 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.19.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.19.0.lockfile new file mode 100644 index 0000000000..424b1fb920 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.19.0.lockfile @@ -0,0 +1,26 @@ +# Spotless formatter based on Eclipse-WTP version 3.20 (see https://www.eclipse.org/webtools/) +com.diffplug.spotless:spotless-eclipse-wtp:3.21.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +com.ibm.icu:icu4j:67.1 +net.jcip:jcip-annotations:1.0 +org.eclipse.emf:org.eclipse.emf.common:2.22.0 +org.eclipse.emf:org.eclipse.emf.ecore:2.24.0 +org.eclipse.emf:org.eclipse.xsd:2.18.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.900 +org.eclipse.platform:org.eclipse.core.filebuffers:3.6.1100 +org.eclipse.platform:org.eclipse.core.filesystem:1.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1100 +org.eclipse.platform:org.eclipse.core.resources:3.14.0 +org.eclipse.platform:org.eclipse.core.runtime:3.20.100 +org.eclipse.platform:org.eclipse.equinox.app:1.5.100 +org.eclipse.platform:org.eclipse.equinox.common:3.14.100 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.200 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.100 +org.eclipse.platform:org.eclipse.jface.text:3.17.0 +org.eclipse.platform:org.eclipse.jface:3.22.100 +org.eclipse.platform:org.eclipse.osgi.services:3.10.0 +org.eclipse.platform:org.eclipse.osgi:3.16.200 +org.eclipse.platform:org.eclipse.text:3.11.0 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.14.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.14.0.lockfile new file mode 100644 index 0000000000..bca432c337 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.14.0.lockfile @@ -0,0 +1,18 @@ +# Spotless formatter based on Groovy-Eclipse version 3.6.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:3.6.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +org.eclipse.platform:org.eclipse.core.commands:3.9.600 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.500 +org.eclipse.platform:org.eclipse.core.jobs:3.10.600 +org.eclipse.platform:org.eclipse.core.resources:3.13.600 +org.eclipse.platform:org.eclipse.core.runtime:3.17.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.300 +org.eclipse.platform:org.eclipse.equinox.common:3.10.600 +org.eclipse.platform:org.eclipse.equinox.preferences:3.7.600 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.600 +org.eclipse.platform:org.eclipse.jface.text:3.16.100 +org.eclipse.platform:org.eclipse.jface:3.18.0 +org.eclipse.platform:org.eclipse.osgi:3.15.100 +org.eclipse.platform:org.eclipse.text:3.10.0 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.15.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.15.0.lockfile new file mode 100644 index 0000000000..fc91fae066 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.15.0.lockfile @@ -0,0 +1,18 @@ +# Spotless formatter based on Groovy-Eclipse version 3.7.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:3.7.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.600 +org.eclipse.platform:org.eclipse.core.jobs:3.10.700 +org.eclipse.platform:org.eclipse.core.resources:3.13.700 +org.eclipse.platform:org.eclipse.core.runtime:3.17.100 +org.eclipse.platform:org.eclipse.equinox.app:1.4.400 +org.eclipse.platform:org.eclipse.equinox.common:3.11.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.7.700 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.700 +org.eclipse.platform:org.eclipse.jface.text:3.16.200 +org.eclipse.platform:org.eclipse.jface:3.19.0 +org.eclipse.platform:org.eclipse.osgi:3.15.200 +org.eclipse.platform:org.eclipse.text:3.10.100 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.16.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.16.0.lockfile new file mode 100644 index 0000000000..2c5f4ccd03 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.16.0.lockfile @@ -0,0 +1,18 @@ +# Spotless formatter based on Groovy-Eclipse version 3.8.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:3.8.0 +com.diffplug.spotless:spotless-eclipse-base:3.3.0 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.700 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.700 +org.eclipse.platform:org.eclipse.core.runtime:3.18.0 +org.eclipse.platform:org.eclipse.equinox.app:1.4.500 +org.eclipse.platform:org.eclipse.equinox.common:3.12.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.8.800 +org.eclipse.platform:org.eclipse.jface.text:3.16.300 +org.eclipse.platform:org.eclipse.jface:3.20.0 +org.eclipse.platform:org.eclipse.osgi:3.15.300 +org.eclipse.platform:org.eclipse.text:3.10.200 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.17.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.17.0.lockfile new file mode 100644 index 0000000000..5242d0da8c --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.17.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on Groovy-Eclipse version 3.9.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:3.9.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.1 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.700 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.jobs:3.10.800 +org.eclipse.platform:org.eclipse.core.resources:3.13.800 +org.eclipse.platform:org.eclipse.core.runtime:3.19.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.13.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.0 +org.eclipse.platform:org.eclipse.equinox.registry:3.9.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.400 +org.eclipse.platform:org.eclipse.jface:3.21.0 +org.eclipse.platform:org.eclipse.osgi:3.16.0 +org.eclipse.platform:org.eclipse.text:3.10.300 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.18.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.18.0.lockfile new file mode 100644 index 0000000000..6bfec53756 --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.18.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on Groovy-Eclipse version 4.0.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:4.0.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.800 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1000 +org.eclipse.platform:org.eclipse.core.resources:3.13.900 +org.eclipse.platform:org.eclipse.core.runtime:3.20.0 +org.eclipse.platform:org.eclipse.equinox.app:1.5.0 +org.eclipse.platform:org.eclipse.equinox.common:3.14.0 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.100 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.0 +org.eclipse.platform:org.eclipse.jface.text:3.16.500 +org.eclipse.platform:org.eclipse.jface:3.22.0 +org.eclipse.platform:org.eclipse.osgi:3.16.100 +org.eclipse.platform:org.eclipse.text:3.10.400 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.19.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.19.0.lockfile new file mode 100644 index 0000000000..880d55ac8d --- /dev/null +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.19.0.lockfile @@ -0,0 +1,19 @@ +# Spotless formatter based on Groovy-Eclipse version 4.1.0 (see https://github.com/groovy/groovy-eclipse/releases) +com.diffplug.spotless:spotless-eclipse-groovy:4.1.0 +com.diffplug.spotless:spotless-eclipse-base:3.4.2 +com.github.spotbugs:spotbugs-annotations:4.0.2 +com.google.code.findbugs:jsr305:3.0.2 +net.jcip:jcip-annotations:1.0 +org.eclipse.platform:org.eclipse.core.commands:3.9.800 +org.eclipse.platform:org.eclipse.core.contenttype:3.7.900 +org.eclipse.platform:org.eclipse.core.jobs:3.10.1100 +org.eclipse.platform:org.eclipse.core.resources:3.14.0 +org.eclipse.platform:org.eclipse.core.runtime:3.20.100 +org.eclipse.platform:org.eclipse.equinox.app:1.5.100 +org.eclipse.platform:org.eclipse.equinox.common:3.14.100 +org.eclipse.platform:org.eclipse.equinox.preferences:3.8.200 +org.eclipse.platform:org.eclipse.equinox.registry:3.10.100 +org.eclipse.platform:org.eclipse.jface.text:3.17.0 +org.eclipse.platform:org.eclipse.jface:3.22.100 +org.eclipse.platform:org.eclipse.osgi:3.16.200 +org.eclipse.platform:org.eclipse.text:3.11.0 diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepOldTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepOldTest.java new file mode 100644 index 0000000000..85ea2ea365 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepOldTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2016-2020 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.cpp; + +/** Older versions of CDT support Java 8 or higher */ +public class EclipseCdtFormatterStepOldTest extends EclipseCdtFormatterStepTest { + + @Override + protected String[] getSupportedVersions() { + return new String[]{"4.7.3a", "4.11.0", "4.12.0", "4.13.0", "4.14.0", "4.16.0"}; + } + + @Override + protected void makeAssumptions() {} + +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepTest.java index 079f255f93..7ed9653c60 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/cpp/EclipseCdtFormatterStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.diffplug.spotless.extra.cpp; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.JreVersion; import com.diffplug.spotless.TestProvisioner; import com.diffplug.spotless.extra.EclipseBasedStepBuilder; import com.diffplug.spotless.extra.eclipse.EclipseCommonTests; @@ -24,7 +25,12 @@ public class EclipseCdtFormatterStepTest extends EclipseCommonTests { @Override protected String[] getSupportedVersions() { - return new String[]{"4.7.3a", "4.11.0", "4.12.0", "4.13.0"}; + return new String[]{"4.17.0", "4.18.0", "4.19.0"}; + } + + @Override + protected void makeAssumptions() { + JreVersion.assume11OrGreater(); } @Override diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepOldTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepOldTest.java new file mode 100644 index 0000000000..9060b64fb1 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepOldTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016-2020 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.groovy; + +import com.diffplug.spotless.JreVersion; + +/** Older versions only support Java version 11 or lower */ +public class GrEclipseFormatterStepOldTest extends GrEclipseFormatterStepTest { + @Override + protected String[] getSupportedVersions() { + return new String[]{"2.3.0", "4.6.3", "4.8.0", "4.8.1", "4.10.0", "4.12.0", "4.13.0", "4.14.0", "4.15.0", "4.16.0"}; + } + + @Override + protected void makeAssumptions() { + // JRE 11 warns like this: + // WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations + // WARNING: All illegal access operations will be denied in a future release + // And after that it fails like this: + // Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7 + // at org.codehaus.groovy.vmplugin.VMPluginFactory.(VMPluginFactory.java:39) + // at org.codehaus.groovy.ast.ClassHelper.makeCached(ClassHelper.java:133) + // at org.codehaus.groovy.ast.ClassHelper.(ClassHelper.java:67) + // at org.codehaus.groovy.classgen.Verifier.(Verifier.java:113) + // at org.codehaus.groovy.control.CompilationUnit.(CompilationUnit.java:158) + // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.makeCompilationUnit(GroovyParser.java:467) + // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.(GroovyParser.java:247) + // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.(GroovyParser.java:216) + // at org.codehaus.groovy.eclipse.core.compiler.GroovySnippetParser.dietParse(GroovySnippetParser.java:105) + // at org.codehaus.groovy.eclipse.core.compiler.GroovySnippetParser.parse(GroovySnippetParser.java:69) + // at org.codehaus.groovy.eclipse.refactoring.core.utils.ASTTools.getASTNodeFromSource(ASTTools.java:204) + // at org.codehaus.groovy.eclipse.refactoring.formatter.DefaultGroovyFormatter.initCodebase(DefaultGroovyFormatter.java:109) + // at org.codehaus.groovy.eclipse.refactoring.formatter.DefaultGroovyFormatter.format(DefaultGroovyFormatter.java:121) + // at com.diffplug.spotless.extra.eclipse.groovy.GrEclipseFormatterStepImpl.format(GrEclipseFormatterStepImpl.java:81) + JreVersion.assume11OrLess(); + } + +} diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java index 74a6627fd8..f6ed0032da 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.diffplug.spotless.extra.groovy; import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.JreVersion; import com.diffplug.spotless.TestProvisioner; import com.diffplug.spotless.extra.EclipseBasedStepBuilder; import com.diffplug.spotless.extra.eclipse.EclipseCommonTests; @@ -24,7 +23,7 @@ public class GrEclipseFormatterStepTest extends EclipseCommonTests { @Override protected String[] getSupportedVersions() { - return new String[]{"2.3.0", "4.6.3", "4.8.0", "4.8.1", "4.10.0", "4.12.0", "4.13.0"}; + return new String[]{"4.17.0", "4.18.0", "4.19.0"}; } @Override @@ -37,30 +36,6 @@ protected String getTestExpectation(String version) { return "class F{\n\tdef m(){}\n}"; } - @Override - protected void makeAssumptions() { - // JRE 11 warns like this: - // WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations - // WARNING: All illegal access operations will be denied in a future release - // And after that it fails like this: - // Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7 - // at org.codehaus.groovy.vmplugin.VMPluginFactory.(VMPluginFactory.java:39) - // at org.codehaus.groovy.ast.ClassHelper.makeCached(ClassHelper.java:133) - // at org.codehaus.groovy.ast.ClassHelper.(ClassHelper.java:67) - // at org.codehaus.groovy.classgen.Verifier.(Verifier.java:113) - // at org.codehaus.groovy.control.CompilationUnit.(CompilationUnit.java:158) - // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.makeCompilationUnit(GroovyParser.java:467) - // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.(GroovyParser.java:247) - // at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.(GroovyParser.java:216) - // at org.codehaus.groovy.eclipse.core.compiler.GroovySnippetParser.dietParse(GroovySnippetParser.java:105) - // at org.codehaus.groovy.eclipse.core.compiler.GroovySnippetParser.parse(GroovySnippetParser.java:69) - // at org.codehaus.groovy.eclipse.refactoring.core.utils.ASTTools.getASTNodeFromSource(ASTTools.java:204) - // at org.codehaus.groovy.eclipse.refactoring.formatter.DefaultGroovyFormatter.initCodebase(DefaultGroovyFormatter.java:109) - // at org.codehaus.groovy.eclipse.refactoring.formatter.DefaultGroovyFormatter.format(DefaultGroovyFormatter.java:121) - // at com.diffplug.spotless.extra.eclipse.groovy.GrEclipseFormatterStepImpl.format(GrEclipseFormatterStepImpl.java:81) - JreVersion.assume11OrLess(); - } - @Override protected FormatterStep createStep(String version) { EclipseBasedStepBuilder builder = GrEclipseFormatterStep.createBuilder(TestProvisioner.mavenCentral()); diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStepTest.java index a0001423dc..876f91a030 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/java/EclipseJdtFormatterStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ public class EclipseJdtFormatterStepTest extends EclipseCommonTests { @Override protected String[] getSupportedVersions() { return new String[]{"4.6.1", "4.6.2", "4.6.3", "4.7.0", "4.7.1", "4.7.2", "4.7.3a", "4.8.0", "4.9.0", "4.10.0", - "4.11.0", "4.12.0", "4.13.0", "4.14.0", "4.15.0", "4.16.0"}; + "4.11.0", "4.12.0", "4.13.0", "4.14.0", "4.15.0", "4.16.0", "4.17.0", "4.18.0", "4.19.0"}; } @Override diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTest.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTest.java index 90b2e81258..2cc5a520b6 100644 --- a/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTest.java +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.junit.runners.Parameterized.Parameters; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.JreVersion; import com.diffplug.spotless.TestProvisioner; import com.diffplug.spotless.extra.EclipseBasedStepBuilder; import com.diffplug.spotless.extra.eclipse.EclipseCommonTests; @@ -66,6 +67,11 @@ public EclipseBasedStepBuilder createBuilder() { } } + @Override + protected void makeAssumptions() { + JreVersion.assume11OrGreater(); + } + @Parameters(name = "{0}") public static Iterable data() { return Arrays.asList(WTP.values()); @@ -76,7 +82,7 @@ public static Iterable data() { @Override protected String[] getSupportedVersions() { - return new String[]{"4.7.3a", "4.7.3b", "4.8.0", "4.12.0", "4.13.0"}; + return new String[]{"4.19.0"}; } @Override diff --git a/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTestOld.java b/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTestOld.java new file mode 100644 index 0000000000..0208bcd4b5 --- /dev/null +++ b/lib-extra/src/test/java/com/diffplug/spotless/extra/wtp/EclipseWtpFormatterStepTestOld.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016-2021 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.wtp; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(value = Parameterized.class) +public class EclipseWtpFormatterStepTestOld extends EclipseWtpFormatterStepTest { + + @Override + protected String[] getSupportedVersions() { + return new String[]{"4.7.3a", "4.7.3b", "4.8.0", "4.12.0", "4.13.0", "4.14.0", "4.15.0", "4.16.0", "4.17.0", "4.18.0"}; + } + + @Override + protected void makeAssumptions() {} +} diff --git a/lib/src/main/java/com/diffplug/spotless/FileSignature.java b/lib/src/main/java/com/diffplug/spotless/FileSignature.java index d0a8c2881c..59893f26e6 100644 --- a/lib/src/main/java/com/diffplug/spotless/FileSignature.java +++ b/lib/src/main/java/com/diffplug/spotless/FileSignature.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -200,6 +200,9 @@ public static String subpath(String root, String child) { if (child.startsWith(root)) { return child.substring(root.length()); } else { + if (machineIsWin() && root.endsWith("://") && child.startsWith(root.substring(0, root.length() - 1))) { + return child.substring(root.length() - 1); + } throw new IllegalArgumentException("Expected '" + child + "' to start with '" + root + "'"); } } diff --git a/lib/src/main/java/com/diffplug/spotless/ForeignExe.java b/lib/src/main/java/com/diffplug/spotless/ForeignExe.java index 1f707fcbb8..d1f8abd3ee 100644 --- a/lib/src/main/java/com/diffplug/spotless/ForeignExe.java +++ b/lib/src/main/java/com/diffplug/spotless/ForeignExe.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ * If either part of that fails, it shows you why * and helps you fix it. * - * Usage: `ForeignExe.nameAndVersion("grep", "2.5.7").confirmVersionAndGetAbsolutePath()` + * Usage: {@code ForeignExe.nameAndVersion("grep", "2.5.7").confirmVersionAndGetAbsolutePath()} * will find grep, confirm that it is version 2.5.7, and then return. */ public class ForeignExe { @@ -55,7 +55,7 @@ public ForeignExe versionFlag(String versionFlag) { return this; } - /** A regex which can parse the version out of the output of the {@link #versionFlag(String)} command (defaults to `version (\\S*)`) */ + /** A regex which can parse the version out of the output of the {@link #versionFlag(String)} command (defaults to {@code version (\\S*)}) */ public ForeignExe versionRegex(Pattern versionRegex) { this.versionRegex = Objects.requireNonNull(versionRegex); return this; diff --git a/lib/src/main/java/com/diffplug/spotless/FormatExceptionPolicy.java b/lib/src/main/java/com/diffplug/spotless/FormatExceptionPolicy.java index a3ace84bce..da23f74432 100644 --- a/lib/src/main/java/com/diffplug/spotless/FormatExceptionPolicy.java +++ b/lib/src/main/java/com/diffplug/spotless/FormatExceptionPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ public interface FormatExceptionPolicy extends Serializable, NoLambda { public void handleError(Throwable e, FormatterStep step, String relativePath); /** - * Returns a byte array representation of everything inside this `FormatExceptionPolicy`. + * Returns a byte array representation of everything inside this {@code FormatExceptionPolicy}. * * The main purpose of this method is to ensure one can't instantiate this class with lambda * expressions, which are notoriously difficult to serialize and deserialize properly. @@ -31,7 +31,7 @@ public interface FormatExceptionPolicy extends Serializable, NoLambda { public byte[] toBytes(); /** - * A policy which rethrows subclasses of `Error` and logs other kinds of Exception. + * A policy which rethrows subclasses of {@code Error} and logs other kinds of Exception. */ public static FormatExceptionPolicy failOnlyOnError() { return new FormatExceptionPolicyLegacy(); diff --git a/lib/src/main/java/com/diffplug/spotless/FormatterFunc.java b/lib/src/main/java/com/diffplug/spotless/FormatterFunc.java index bd17e7fc8f..48a8e810ee 100644 --- a/lib/src/main/java/com/diffplug/spotless/FormatterFunc.java +++ b/lib/src/main/java/com/diffplug/spotless/FormatterFunc.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ import java.util.Objects; /** - * A `Function` which can throw an exception. Technically, there - * is also a `File` argument which gets passed around as well, but that is invisible + * A {@code Function} which can throw an exception. Technically, there + * is also a {@code File} argument which gets passed around as well, but that is invisible * to formatters. If you need the File, see {@link NeedsFile}. */ @FunctionalInterface @@ -33,7 +33,7 @@ default String apply(String unix, File file) throws Exception { } /** - * `Function` and `BiFunction` whose implementation + * {@code Function} and {@code BiFunction} whose implementation * requires a resource which should be released when the function is no longer needed. */ interface Closeable extends FormatterFunc, AutoCloseable { @@ -45,10 +45,10 @@ interface Closeable extends FormatterFunc, AutoCloseable { * * It's important for FormatterStep's to allocate their resources as lazily as possible. * It's easy to create a resource inside the state, and not realize that it may not be - * released. It's far better to use one of the non-deprecated `of()` methods below. + * released. It's far better to use one of the non-deprecated {@code of()} methods below. * * The bug (and its fix) which is easy to write using this method: https://github.com/diffplug/spotless/commit/7f16ecca031810b5e6e6f647e1f10a6d2152d9f4 - * How the `of()` methods below make the correct thing easier to write and safer: https://github.com/diffplug/spotless/commit/18c10f9c93d6f18f753233d0b5f028d5f0961916 + * How the {@code of()} methods below make the correct thing easier to write and safer: https://github.com/diffplug/spotless/commit/18c10f9c93d6f18f753233d0b5f028d5f0961916 */ public static Closeable ofDangerous(AutoCloseable closeable, FormatterFunc function) { Objects.requireNonNull(closeable, "closeable"); @@ -135,7 +135,7 @@ public String apply(String unix) throws Exception { /** * Ideally, formatters don't need the underlying file. But in case they do, they should only use it's path, - * and should never read the content inside the file, because that breaks the `Function` composition + * and should never read the content inside the file, because that breaks the {@code Function} composition * that Spotless is based on. For the rare case that you need access to the file, use this method * or {@link NeedsFile} to create a {@link FormatterFunc} which needs the File. */ diff --git a/lib/src/main/java/com/diffplug/spotless/FormatterStep.java b/lib/src/main/java/com/diffplug/spotless/FormatterStep.java index 93e747aa40..6675d09128 100644 --- a/lib/src/main/java/com/diffplug/spotless/FormatterStep.java +++ b/lib/src/main/java/com/diffplug/spotless/FormatterStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,8 +37,8 @@ public interface FormatterStep extends Serializable { * @param rawUnix * the content to format, guaranteed to have unix-style newlines ('\n'); never null * @param file - * the file which `rawUnix` was obtained from; never null. Pass an empty file using - * `new File("")` if and only if no file is actually associated with `rawUnix` + * the file which {@code rawUnix} was obtained from; never null. Pass an empty file using + * {@code new File("")} if and only if no file is actually associated with {@code rawUnix} * @return the formatted content, guaranteed to only have unix-style newlines; may return null * if the formatter step doesn't have any changes to make * @throws Exception if the formatter step experiences a problem diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index 1a60c6fbc1..abe595e608 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,7 +79,7 @@ URL[] jarUrls() { /** * Returns a classloader containing the only jars in this JarState. - * Look-up of classes in the `org.slf4j` package + * Look-up of classes in the {@code org.slf4j} package * are not taken from the JarState, but instead redirected to the class loader of this class to enable * passthrough logging. *
@@ -91,7 +91,7 @@ public ClassLoader getClassLoader() { /** * Returns a classloader containing the only jars in this JarState. - * Look-up of classes in the `org.slf4j` package + * Look-up of classes in the {@code org.slf4j} package * are not taken from the JarState, but instead redirected to the class loader of this class to enable * passthrough logging. *
diff --git a/lib/src/main/java/com/diffplug/spotless/LineEnding.java b/lib/src/main/java/com/diffplug/spotless/LineEnding.java index c4af47d3f3..6ea5372807 100644 --- a/lib/src/main/java/com/diffplug/spotless/LineEnding.java +++ b/lib/src/main/java/com/diffplug/spotless/LineEnding.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ */ public enum LineEnding { // @formatter:off - /** Uses the same line endings as Git, using `.gitattributes` and the `core.eol` property. */ + /** Uses the same line endings as Git, using {@code .gitattributes} and the {@code core.eol} property. */ GIT_ATTRIBUTES { /** .gitattributes is path-specific, so you must use {@link LineEnding#createPolicy(File, Supplier)}. */ @Override @Deprecated @@ -37,11 +37,11 @@ public Policy createPolicy() { return super.createPolicy(); } }, - /** `\n` on unix systems, `\r\n` on windows systems. */ + /** {@code \n} on unix systems, {@code \r\n} on windows systems. */ PLATFORM_NATIVE, - /** `\r\n` */ + /** {@code \r\n} */ WINDOWS, - /** `\n` */ + /** {@code \n} */ UNIX; // @formatter:on diff --git a/lib/src/main/java/com/diffplug/spotless/NoLambda.java b/lib/src/main/java/com/diffplug/spotless/NoLambda.java index 6ce14d914d..ce326a6ceb 100644 --- a/lib/src/main/java/com/diffplug/spotless/NoLambda.java +++ b/lib/src/main/java/com/diffplug/spotless/NoLambda.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,11 +33,11 @@ */ public interface NoLambda extends Serializable { /** - * Returns a byte array representation of everything inside this `SerializableFileFilter`. + * Returns a byte array representation of everything inside this {@code SerializableFileFilter}. * * The main purpose of this method is to ensure one can't instantiate this class with lambda * expressions, which are notoriously difficult to serialize and deserialize properly. (See - * `SerializableFileFilterImpl.SkipFilesNamed` for an example of how to make a serializable + * {@code SerializableFileFilterImpl.SkipFilesNamed} for an example of how to make a serializable * subclass.) */ public byte[] toBytes(); diff --git a/lib/src/main/java/com/diffplug/spotless/PaddedCell.java b/lib/src/main/java/com/diffplug/spotless/PaddedCell.java index e209400caf..5204e23953 100644 --- a/lib/src/main/java/com/diffplug/spotless/PaddedCell.java +++ b/lib/src/main/java/com/diffplug/spotless/PaddedCell.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -256,7 +256,7 @@ public boolean didNotConverge() { private byte[] canonicalBytes() { if (canonicalBytes == null) { - throw new IllegalStateException("First make sure that `!isClean()` and `!didNotConverge()`"); + throw new IllegalStateException("First make sure that {@code !isClean()} and {@code !didNotConverge()}"); } return canonicalBytes; } @@ -270,7 +270,7 @@ public void writeCanonicalTo(OutputStream out) throws IOException { } } - /** Returns the DirtyState which corresponds to `isClean()`. */ + /** Returns the DirtyState which corresponds to {@code isClean()}. */ public static DirtyState isClean() { return isClean; } diff --git a/lib/src/main/java/com/diffplug/spotless/ProcessRunner.java b/lib/src/main/java/com/diffplug/spotless/ProcessRunner.java index 7361a583a0..c798ed6c07 100644 --- a/lib/src/main/java/com/diffplug/spotless/ProcessRunner.java +++ b/lib/src/main/java/com/diffplug/spotless/ProcessRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,12 +48,12 @@ public class ProcessRunner implements AutoCloseable { public ProcessRunner() {} - /** Executes the given shell command (using `cmd` on windows and `sh` on unix). */ + /** Executes the given shell command (using {@code cmd} on windows and {@code sh} on unix). */ public Result shell(String cmd) throws IOException, InterruptedException { return shellWinUnix(cmd, cmd); } - /** Executes the given shell command (using `cmd` on windows and `sh` on unix). */ + /** 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 { List args; if (FileSignature.machineIsWin()) { diff --git a/lib/src/main/java/com/diffplug/spotless/SpotlessCache.java b/lib/src/main/java/com/diffplug/spotless/SpotlessCache.java index 30b0ccae14..b90682f1b6 100644 --- a/lib/src/main/java/com/diffplug/spotless/SpotlessCache.java +++ b/lib/src/main/java/com/diffplug/spotless/SpotlessCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,8 +96,8 @@ private static void clear() { private static volatile Object lastClear; /** - * Closes all cached classloaders iff `key` is not `.equals()` to the last call to `clearOnce()`. - * If `key` is null, the clear will always happen (as though null != null). + * Closes all cached classloaders iff {@code key} is not {@code .equals()} to the last call to {@code clearOnce()}. + * If {@code key} is null, the clear will always happen (as though null != null). */ public static boolean clearOnce(@Nullable Object key) { synchronized (instance) { diff --git a/lib/src/main/java/com/diffplug/spotless/ThrowingEx.java b/lib/src/main/java/com/diffplug/spotless/ThrowingEx.java index d0d69c5661..f664c62bf3 100644 --- a/lib/src/main/java/com/diffplug/spotless/ThrowingEx.java +++ b/lib/src/main/java/com/diffplug/spotless/ThrowingEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,13 +96,13 @@ public static RuntimeException asRuntime(Exception e) { /** * Utility method for rethrowing an exception's cause with as few wrappers as possible. * - * ```java + *
{@code
 	 * try {
 	 *     doSomething();
 	 * } catch (Throwable e) {
 	 *     throw unwrapCause(e);
 	 * }
-	 * ```
+	 * }
*/ public static RuntimeException unwrapCause(Throwable e) { Throwable cause = e.getCause(); @@ -116,14 +116,14 @@ public static RuntimeException unwrapCause(Throwable e) { /** * Rethrows errors, wraps and returns everything else as a runtime exception. * + *
{@code
 	 * try {
 	 *     doSomething();
 	 * } catch (Throwable e) {
 	 *     throw asRuntimeRethrowError(e);
 	 * }
-	 * ```
-	 *
-	 * */
+	 * }
+ */ static RuntimeException asRuntimeRethrowError(Throwable e) { if (e instanceof Error) { throw (Error) e; diff --git a/lib/src/main/java/com/diffplug/spotless/annotations/Internal.java b/lib/src/main/java/com/diffplug/spotless/annotations/Internal.java index 6d81f178b9..77a318f268 100644 --- a/lib/src/main/java/com/diffplug/spotless/annotations/Internal.java +++ b/lib/src/main/java/com/diffplug/spotless/annotations/Internal.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ import java.lang.annotation.Target; /** - * Signifies that a `public` API is actually an implementation detail, and should be treated as if it - * were `private`. + * Signifies that a {@code public} API is actually an implementation detail, and should be treated as if it + * were {@code private}. * * The user of the API should be warned that it may unexpectedly disappear in future versions of * Spotless. Usually the best place to put this warning is in the API's class JavaDoc. diff --git a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java index ade6978359..5256739004 100644 --- a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ public FormatterStep create() { private State createState() throws IOException, InterruptedException { String howToInstall = "" + "You can download clang-format from https://releases.llvm.org and " + - "then point Spotless to it with `pathToExe('/path/to/clang-format')` " + + "then point Spotless to it with {@code pathToExe('/path/to/clang-format')} " + "or you can use your platform's package manager:" + "\n win: choco install llvm --version {version} (try dropping version if it fails)" + "\n mac: brew install clang-format (TODO: how to specify version?)" + @@ -79,7 +79,7 @@ private State createState() throws IOException, InterruptedException { .pathToExe(pathToExe) .fixCantFind(howToInstall) .fixWrongVersion( - "You can tell Spotless to use the version you already have with `clangFormat('{versionFound}')`" + + "You can tell Spotless to use the version you already have with {@code clangFormat('{versionFound}')}" + "or you can download the currently specified version, {version}.\n" + howToInstall) .confirmVersionAndGetAbsolutePath(); return new State(this, exeAbsPath); diff --git a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java index 40eee8a6f4..1e93acce31 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -151,6 +151,7 @@ private static class Runtime implements Serializable { private final @Nullable String beforeYear; private final @Nullable String afterYear; private final boolean updateYearWithLatest; + private final boolean licenseHeaderWithRange; /** The license that we'd like enforced. */ private Runtime(String licenseHeader, String delimiter, String yearSeparator, boolean updateYearWithLatest) { @@ -159,25 +160,35 @@ private Runtime(String licenseHeader, String delimiter, String yearSeparator, bo } // sanitize the input license licenseHeader = LineEnding.toUnix(licenseHeader); - if (!licenseHeader.endsWith("\n")) { + if (!licenseHeader.isEmpty() && !licenseHeader.endsWith("\n")) { licenseHeader = licenseHeader + "\n"; } this.delimiterPattern = Pattern.compile('^' + delimiter, Pattern.UNIX_LINES | Pattern.MULTILINE); Optional yearToken = getYearToken(licenseHeader); if (yearToken.isPresent()) { - yearToday = String.valueOf(YearMonth.now().getYear()); + this.yearToday = String.valueOf(YearMonth.now().getYear()); int yearTokenIndex = licenseHeader.indexOf(yearToken.get()); - beforeYear = licenseHeader.substring(0, yearTokenIndex); - afterYear = licenseHeader.substring(yearTokenIndex + yearToken.get().length()); - yearSepOrFull = yearSeparator; + this.beforeYear = licenseHeader.substring(0, yearTokenIndex); + this.afterYear = licenseHeader.substring(yearTokenIndex + yearToken.get().length()); + this.yearSepOrFull = yearSeparator; this.updateYearWithLatest = updateYearWithLatest; + + boolean hasHeaderWithRange = false; + int yearPlusSep = 4 + yearSeparator.length(); + if (beforeYear.endsWith(yearSeparator) && yearTokenIndex > yearPlusSep) { + // year from in range + String yearFrom = licenseHeader.substring(yearTokenIndex - yearPlusSep, yearTokenIndex).substring(0, 4); + hasHeaderWithRange = YYYY.matcher(yearFrom).matches(); + } + this.licenseHeaderWithRange = hasHeaderWithRange; } else { - yearToday = null; - beforeYear = null; - afterYear = null; + this.yearToday = null; + this.beforeYear = null; + this.afterYear = null; this.yearSepOrFull = licenseHeader; this.updateYearWithLatest = false; + this.licenseHeaderWithRange = false; } } @@ -243,7 +254,11 @@ private String calculateYearExact(String parsedYear) { return parsedYear; } else if (YYYY.matcher(parsedYear).matches()) { if (updateYearWithLatest) { - return parsedYear + yearSepOrFull + yearToday; + if (licenseHeaderWithRange) { + return yearToday; + } else { + return parsedYear + yearSepOrFull + yearToday; + } } else { // it's already good as a single year return parsedYear; @@ -258,15 +273,31 @@ private String calculateYearBySearching(String content) { Matcher yearMatcher = YYYY.matcher(content); if (yearMatcher.find()) { String firstYear = yearMatcher.group(); - String secondYear; + + String secondYear = null; if (updateYearWithLatest) { secondYear = firstYear.equals(yearToday) ? null : yearToday; - } else if (yearMatcher.find(yearMatcher.end() + 1)) { - secondYear = yearMatcher.group(); } else { - secondYear = null; + String contentWithSecondYear = content.substring(yearMatcher.end() + 1); + int endOfLine = contentWithSecondYear.indexOf('\n'); + if (endOfLine != -1) { + contentWithSecondYear = contentWithSecondYear.substring(0, endOfLine); + } + Matcher secondYearMatcher = YYYY.matcher(contentWithSecondYear); + if (secondYearMatcher.find()) { + secondYear = secondYearMatcher.group(); + } + } + + if (secondYear == null) { + return firstYear; + } else { + if (licenseHeaderWithRange) { + return secondYear; + } else { + return firstYear + yearSepOrFull + secondYear; + } } - return secondYear == null ? firstYear : firstYear + yearSepOrFull + secondYear; } else { System.err.println("Can't parse copyright year '" + content + "', defaulting to " + yearToday); // couldn't recognize the year format @@ -304,7 +335,7 @@ private String setLicenseHeaderYearsFromGitHistory(String raw, File file) throws } private static String parseYear(String cmd, File file) throws IOException { - String fullCmd = cmd + " " + file.getAbsolutePath(); + String fullCmd = cmd + " -- " + file.getAbsolutePath(); ProcessBuilder builder = new ProcessBuilder().directory(file.getParentFile()); if (FileSignature.machineIsWin()) { builder.command("cmd", "/c", fullCmd); diff --git a/lib/src/main/java/com/diffplug/spotless/generic/PipeStepPair.java b/lib/src/main/java/com/diffplug/spotless/generic/PipeStepPair.java index 7c54359bca..38373fec59 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/PipeStepPair.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/PipeStepPair.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; public class PipeStepPair { - /** The two steps will be named `In` and `Out`. */ + /** The two steps will be named {@code In} and {@code Out}. */ public static Builder named(String name) { return new Builder(name); } diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java index 6d506e28ed..fe5fa18358 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ThrowingEx.Function; -/** Wraps up [google-java-format](https://github.com/google/google-java-format) as a FormatterStep. */ +/** Wraps up google-java-format as a FormatterStep. */ public class GoogleJavaFormatStep { // prevent direct instantiation private GoogleJavaFormatStep() {} @@ -94,13 +94,13 @@ public static FormatterStep create(String version, String style, Provisioner pro } } - /** On JRE 11+, returns `1.9`. On earlier JREs, returns `1.7`. */ + /** On JRE 11+, returns {@code 1.9}. On earlier JREs, returns {@code 1.7}. */ public static String defaultVersion() { return JRE_VERSION >= 11 ? LATEST_VERSION_JRE_11 : LATEST_VERSION_JRE_8; } private static final String LATEST_VERSION_JRE_8 = "1.7"; - private static final String LATEST_VERSION_JRE_11 = "1.9"; + private static final String LATEST_VERSION_JRE_11 = "1.11.0"; public static String defaultStyle() { return DEFAULT_STYLE; diff --git a/lib/src/main/java/com/diffplug/spotless/json/JsonSimpleStep.java b/lib/src/main/java/com/diffplug/spotless/json/JsonSimpleStep.java new file mode 100644 index 0000000000..a970149133 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/json/JsonSimpleStep.java @@ -0,0 +1,101 @@ +/* + * Copyright 2021 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.json; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.JarState; +import com.diffplug.spotless.Provisioner; + +/** + * Simple JSON formatter which reformats the file according to the org.json library's default pretty-printing, but has no ability to customise more than the indentation size. + */ +public final class JsonSimpleStep { + private static final String MAVEN_COORDINATE = "org.json:json:"; + private static final String DEFAULT_VERSION = "20210307"; + + public static FormatterStep create(int indent, Provisioner provisioner) { + Objects.requireNonNull(provisioner, "provisioner cannot be null"); + return FormatterStep.createLazy("json", () -> new State(indent, provisioner), State::toFormatter); + } + + private static final class State implements Serializable { + private static final long serialVersionUID = 1L; + + private final int indentSpaces; + private final JarState jarState; + + private State(int indent, Provisioner provisioner) throws IOException { + this.indentSpaces = indent; + this.jarState = JarState.from(MAVEN_COORDINATE + DEFAULT_VERSION, provisioner); + } + + FormatterFunc toFormatter() { + Method objectToString; + Method arrayToString; + Constructor objectConstructor; + Constructor arrayConstructor; + try { + ClassLoader classLoader = jarState.getClassLoader(); + Class jsonObject = classLoader.loadClass("org.json.JSONObject"); + Class[] constructorArguments = new Class[]{String.class}; + objectConstructor = jsonObject.getConstructor(constructorArguments); + objectToString = jsonObject.getMethod("toString", int.class); + + Class jsonArray = classLoader.loadClass("org.json.JSONArray"); + arrayConstructor = jsonArray.getConstructor(constructorArguments); + arrayToString = jsonArray.getMethod("toString", int.class); + } catch (ClassNotFoundException | NoSuchMethodException e) { + throw new IllegalStateException("There was a problem preparing org.json dependencies", e); + } + + return s -> { + if (s.isEmpty()) { + return s; + } + char first = s.charAt(0); + if (first == '{') { + return format(objectConstructor, objectToString, s); + } + if (first == '[') { + return format(arrayConstructor, arrayToString, s); + } + + throw new AssertionError(String.format("Unable to determine JSON type, expected a '{' or '[' but found '%s'", first)); + }; + } + + private String format(Constructor constructor, Method toString, String input) throws Exception { + try { + Object parsed = constructor.newInstance(input); + return toString.invoke(parsed, indentSpaces) + "\n"; + } catch (InvocationTargetException ex) { + throw new AssertionError("Unable to format JSON", ex.getCause()); + } + } + } + + private JsonSimpleStep() { + // cannot be directly instantiated + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/json/package-info.java b/lib/src/main/java/com/diffplug/spotless/json/package-info.java new file mode 100644 index 0000000000..0d62356d77 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/json/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@ReturnValuesAreNonnullByDefault +package com.diffplug.spotless.extra.json.java; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.diffplug.spotless.annotations.ReturnValuesAreNonnullByDefault; diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/BadSemver.java b/lib/src/main/java/com/diffplug/spotless/kotlin/BadSemver.java new file mode 100644 index 0000000000..ae500e55b4 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/BadSemver.java @@ -0,0 +1,38 @@ +/* + * Copyright 2021 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.kotlin; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class BadSemver { + protected static int version(String input) { + Matcher matcher = BAD_SEMVER.matcher(input); + if (!matcher.find() || matcher.start() != 0) { + throw new IllegalArgumentException("Version must start with " + BAD_SEMVER.pattern()); + } + String major = matcher.group(1); + String minor = matcher.group(2); + return version(Integer.parseInt(major), Integer.parseInt(minor)); + } + + /** Ambiguous after 2147.483647.blah-blah */ + protected static int version(int major, int minor) { + return major * 1_000_000 + minor; + } + + private static final Pattern BAD_SEMVER = Pattern.compile("(\\d+)\\.(\\d+)"); +} diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java new file mode 100644 index 0000000000..4af23f5559 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java @@ -0,0 +1,188 @@ +/* + * Copyright 2021 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.kotlin; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.*; + +import javax.annotation.Nullable; + +import com.diffplug.spotless.*; + +/** Wraps up diktat as a FormatterStep. */ +public class DiktatStep { + + // prevent direct instantiation + private DiktatStep() {} + + private static final String DEFAULT_VERSION = "0.4.0"; + static final String NAME = "diktat"; + static final String PACKAGE_DIKTAT = "org.cqfn.diktat"; + static final String PACKAGE_KTLINT = "com.pinterest.ktlint"; + static final String MAVEN_COORDINATE = PACKAGE_DIKTAT + ":diktat-rules:"; + + public static String defaultVersionDiktat() { + return DEFAULT_VERSION; + } + + public static FormatterStep create(Provisioner provisioner) { + return create(defaultVersionDiktat(), provisioner); + } + + public static FormatterStep create(String versionDiktat, Provisioner provisioner) { + return create(versionDiktat, provisioner, Collections.emptyMap(), null); + } + + public static FormatterStep create(String versionDiktat, Provisioner provisioner, @Nullable FileSignature config) { + return create(versionDiktat, provisioner, Collections.emptyMap(), config); + } + + public static FormatterStep create(String versionDiktat, Provisioner provisioner, Map userData, @Nullable FileSignature config) { + return create(versionDiktat, provisioner, false, userData, config); + } + + public static FormatterStep createForScript(String versionDiktat, Provisioner provisioner, @Nullable FileSignature config) { + return createForScript(versionDiktat, provisioner, Collections.emptyMap(), config); + } + + public static FormatterStep createForScript(String versionDiktat, Provisioner provisioner, Map userData, @Nullable FileSignature config) { + return create(versionDiktat, provisioner, true, userData, config); + } + + public static FormatterStep create(String versionDiktat, Provisioner provisioner, boolean isScript, Map userData, @Nullable FileSignature config) { + Objects.requireNonNull(versionDiktat, "versionDiktat"); + Objects.requireNonNull(provisioner, "provisioner"); + return FormatterStep.createLazy(NAME, + () -> new DiktatStep.State(versionDiktat, provisioner, isScript, userData, config), + DiktatStep.State::createFormat); + } + + static final class State implements Serializable { + + private static final long serialVersionUID = 1L; + + /** Are the files being linted Kotlin script files. */ + private final boolean isScript; + private final @Nullable FileSignature config; + private final String pkg; + private final String pkgKtlint; + final JarState jar; + private final TreeMap userData; + + State(String versionDiktat, Provisioner provisioner, boolean isScript, Map userData, @Nullable FileSignature config) throws IOException { + + HashSet pkgSet = new HashSet<>(); + pkgSet.add(MAVEN_COORDINATE + versionDiktat); + + this.userData = new TreeMap<>(userData); + this.pkg = PACKAGE_DIKTAT; + this.pkgKtlint = PACKAGE_KTLINT; + this.jar = JarState.from(pkgSet, provisioner); + this.isScript = isScript; + this.config = config; + } + + FormatterFunc createFormat() throws Exception { + + ClassLoader classLoader = jar.getClassLoader(); + + // first, we get the diktat rules + if (config != null) { + System.setProperty("diktat.config.path", config.getOnlyFile().getAbsolutePath()); + } + + Class ruleSetProviderClass = classLoader.loadClass(pkg + ".ruleset.rules.DiktatRuleSetProvider"); + Object diktatRuleSet = ruleSetProviderClass.getMethod("get").invoke(ruleSetProviderClass.newInstance()); + Iterable ruleSets = Collections.singletonList(diktatRuleSet); + + // next, we create an error callback which throws an assertion error when the format is bad + Class function2Interface = classLoader.loadClass("kotlin.jvm.functions.Function2"); + Class lintErrorClass = classLoader.loadClass(pkgKtlint + ".core.LintError"); + Method detailGetter = lintErrorClass.getMethod("getDetail"); + Method lineGetter = lintErrorClass.getMethod("getLine"); + Method colGetter = lintErrorClass.getMethod("getCol"); + + // grab the KtLint singleton + Class ktlintClass = classLoader.loadClass(pkgKtlint + ".core.KtLint"); + Object ktlint = ktlintClass.getDeclaredField("INSTANCE").get(null); + + Class paramsClass = classLoader.loadClass(pkgKtlint + ".core.KtLint$Params"); + // and its constructor + Constructor constructor = paramsClass.getConstructor( + /* fileName, nullable */ String.class, + /* text */ String.class, + /* ruleSets */ Iterable.class, + /* userData */ Map.class, + /* callback */ function2Interface, + /* script */ boolean.class, + /* editorConfigPath, nullable */ String.class, + /* debug */ boolean.class); + Method formatterMethod = ktlintClass.getMethod("format", paramsClass); + FormatterFunc.NeedsFile formatterFunc = (input, file) -> { + ArrayList errors = new ArrayList<>(); + + Object formatterCallback = Proxy.newProxyInstance(classLoader, new Class[]{function2Interface}, + (proxy, method, args) -> { + Object lintError = args[0]; //ktlint.core.LintError + boolean corrected = (Boolean) args[1]; + if (!corrected) { + errors.add(lintError); + } + return null; + }); + + userData.put("file_path", file.getAbsolutePath()); + try { + Object params = constructor.newInstance( + /* fileName, nullable */ file.getName(), + /* text */ input, + /* ruleSets */ ruleSets, + /* userData */ userData, + /* callback */ formatterCallback, + /* script */ isScript, + /* editorConfigPath, nullable */ null, + /* debug */ false); + String result = (String) formatterMethod.invoke(ktlint, params); + if (!errors.isEmpty()) { + StringBuilder error = new StringBuilder(""); + error.append("There are ").append(errors.size()).append(" unfixed errors:"); + for (Object er : errors) { + String detail = (String) detailGetter.invoke(er); + int line = (Integer) lineGetter.invoke(er); + int col = (Integer) colGetter.invoke(er); + + error.append(System.lineSeparator()).append("Error on line: ").append(line).append(", column: ").append(col).append(" cannot be fixed automatically") + .append(System.lineSeparator()).append(detail); + } + throw new AssertionError(error); + } + return result; + } catch (InvocationTargetException e) { + throw ThrowingEx.unwrapCause(e); + } + }; + + return formatterFunc; + } + + } + +} diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java index 843afdbf29..6c21fac890 100644 --- a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ import java.util.Map; import java.util.Objects; import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; @@ -34,29 +32,12 @@ import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ThrowingEx; -/** Wraps up [ktlint](https://github.com/pinterest/ktlint) as a FormatterStep. */ +/** Wraps up ktlint as a FormatterStep. */ public class KtLintStep { // prevent direct instantiation private KtLintStep() {} - private static int badSemver(String input) { - Matcher matcher = BAD_SEMVER.matcher(input); - if (!matcher.find() || matcher.start() != 0) { - throw new IllegalArgumentException("Version must start with " + BAD_SEMVER.pattern()); - } - String major = matcher.group(1); - String minor = matcher.group(2); - return badSemver(Integer.parseInt(major), Integer.parseInt(minor)); - } - - /** Ambiguous after 2147.483647.blah-blah */ - private static int badSemver(int major, int minor) { - return major * 1_000_000 + minor; - } - - private static final Pattern BAD_SEMVER = Pattern.compile("(\\d+)\\.(\\d+)\\."); - - private static final String DEFAULT_VERSION = "0.35.0"; + private static final String DEFAULT_VERSION = "0.42.1"; static final String NAME = "ktlint"; static final String PACKAGE_PRE_0_32 = "com.github.shyiko"; static final String PACKAGE = "com.pinterest"; @@ -109,14 +90,14 @@ static final class State implements Serializable { State(String version, Provisioner provisioner, boolean isScript, Map userData) throws IOException { this.userData = new TreeMap<>(userData); String coordinate; - if (badSemver(version) < badSemver(0, 32)) { + if (BadSemver.version(version) < BadSemver.version(0, 32)) { coordinate = MAVEN_COORDINATE_PRE_0_32; this.pkg = PACKAGE_PRE_0_32; } else { coordinate = MAVEN_COORDINATE; this.pkg = PACKAGE; } - this.useParams = badSemver(version) >= badSemver(0, 34); + this.useParams = BadSemver.version(version) >= BadSemver.version(0, 34); this.jarState = JarState.from(coordinate + version, provisioner); this.isScript = isScript; } diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java index 59d034f4f5..21c70be5aa 100644 --- a/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.diffplug.spotless.kotlin; import static com.diffplug.spotless.kotlin.KtfmtStep.Style.DEFAULT; -import static com.diffplug.spotless.kotlin.KtfmtStep.Style.DROPBOX; import java.io.IOException; import java.io.Serializable; @@ -27,24 +26,40 @@ import com.diffplug.spotless.*; /** - * Wraps up [ktfmt](https://github.com/facebookincubator/ktfmt) as a FormatterStep. + * Wraps up ktfmt as a FormatterStep. */ public class KtfmtStep { // prevent direct instantiation private KtfmtStep() {} - private static final String DEFAULT_VERSION = "0.16"; + private static final String DEFAULT_VERSION = "0.27"; static final String NAME = "ktfmt"; static final String PACKAGE = "com.facebook"; static final String MAVEN_COORDINATE = PACKAGE + ":ktfmt:"; /** - * Used to allow dropbox style option through formatting options. + * Used to allow multiple style option through formatting options and since when is each of them available. * * @see ktfmt source */ public enum Style { - DEFAULT, DROPBOX + DEFAULT("DEFAULT_FORMAT", "0.0"), DROPBOX("DROPBOX_FORMAT", "0.11"), GOOGLE("GOOGLE_FORMAT", "0.21"), KOTLINLANG("KOTLINLANG_FORMAT", "0.21"); + + final private String format; + final private String since; + + Style(String format, String since) { + this.format = format; + this.since = since; + } + + String getFormat() { + return format; + } + + String getSince() { + return since; + } } private static final String DROPBOX_STYLE_METHOD = "dropboxStyle"; @@ -79,9 +94,15 @@ public static String defaultVersion() { return DEFAULT_VERSION; } + public static String defaultStyle() { + return Style.DEFAULT.name(); + } + static final class State implements Serializable { private static final long serialVersionUID = 1L; + private final String version; + private final String pkg; /** * Option that allows to apply formatting options to perform a 4 spaces block and continuation indent. @@ -91,6 +112,7 @@ static final class State implements Serializable { final JarState jarState; State(String version, Provisioner provisioner, Style style) throws IOException { + this.version = version; this.pkg = PACKAGE; this.style = style; this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner); @@ -101,15 +123,15 @@ FormatterFunc createFormat() throws Exception { Class formatterClazz = classLoader.loadClass(pkg + ".ktfmt.FormatterKt"); return input -> { try { - if (style == DROPBOX) { + if (style == DEFAULT) { + Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class); + return (String) formatterMethod.invoke(formatterClazz, input); + } else { Class formattingOptionsClazz = classLoader.loadClass(pkg + ".ktfmt.FormattingOptions"); Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, formattingOptionsClazz, String.class); - Object formattingOptions = getDropboxStyleFormattingOptions(classLoader); + Object formattingOptions = getCustomFormattingOptions(classLoader, style); return (String) formatterMethod.invoke(formatterClazz, formattingOptions, input); - } else { - Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class); - return (String) formatterMethod.invoke(formatterClazz, input); } } catch (InvocationTargetException e) { throw ThrowingEx.unwrapCause(e); @@ -117,11 +139,25 @@ FormatterFunc createFormat() throws Exception { }; } - private Object getDropboxStyleFormattingOptions(ClassLoader classLoader) throws Exception { - Class formattingOptionsCompanionClazz = classLoader.loadClass(pkg + ".ktfmt.FormattingOptions$Companion"); - Object companion = formattingOptionsCompanionClazz.getConstructors()[0].newInstance((Object) null); - Method formattingOptionsMethod = formattingOptionsCompanionClazz.getDeclaredMethod(DROPBOX_STYLE_METHOD); - return formattingOptionsMethod.invoke(companion); + private Object getCustomFormattingOptions(ClassLoader classLoader, Style style) throws Exception { + if (BadSemver.version(version) < BadSemver.version(style.since)) { + throw new IllegalStateException(String.format("The style %s is available from version %s (current version: %s)", style.name(), style.since, version)); + } + + try { + // ktfmt v0.19 and later + return classLoader.loadClass(pkg + ".ktfmt.FormatterKt").getField(style.getFormat()).get(null); + } catch (NoSuchFieldException ignored) {} + + // fallback to old, pre-0.19 ktfmt interface. + if (style == Style.DEFAULT || style == Style.DROPBOX) { + Class formattingOptionsCompanionClazz = classLoader.loadClass(pkg + ".ktfmt.FormattingOptions$Companion"); + Object companion = formattingOptionsCompanionClazz.getConstructors()[0].newInstance((Object) null); + Method formattingOptionsMethod = formattingOptionsCompanionClazz.getDeclaredMethod(DROPBOX_STYLE_METHOD); + return formattingOptionsMethod.invoke(companion); + } else { + throw new IllegalStateException("Versions pre-0.19 can only use Default and Dropbox styles"); + } } } } diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java index e2566f3f0b..11f10bebd5 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ThrowingEx.Supplier; -/** A step for [FreshMark](https://github.com/diffplug/freshmark). */ +/** A step for FreshMark. */ public class FreshMarkStep { // prevent direct instantiation private FreshMarkStep() {} diff --git a/lib/src/main/java/com/diffplug/spotless/npm/FileFinder.java b/lib/src/main/java/com/diffplug/spotless/npm/FileFinder.java new file mode 100644 index 0000000000..76016d68db --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/npm/FileFinder.java @@ -0,0 +1,215 @@ +/* + * Copyright 2020 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.npm; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +class FileFinder { + + private final List>> fileCandidateFinders; + + private FileFinder(Builder builder) { + this.fileCandidateFinders = Collections.unmodifiableList(new ArrayList<>(builder.candidateFinders)); + } + + static Builder finderForFilename(String fileName) { + return new Builder(fileName, null); + } + + static Builder finderForExecutableFilename(String fileName) { + return new Builder(fileName, true); + } + + Optional tryFind() { + return fileCandidateFinders + .stream() + .map(Supplier::get) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); + } + + static class Builder { + + private final String fileName; + + private final Boolean executable; + + private final List>> candidateFinders = new ArrayList<>(); + + Builder(String fileName, Boolean executable) { + this.fileName = requireNonNull(fileName); + this.executable = executable; + } + + public Builder candidateEnvironmentPath(String environmentVar) { + candidateFinders.add(new CandidateOnSinglePathEnvironmentVar(environmentVar, fileName, FileIsExecutableFilter.executable(this.executable))); + return this; + } + + public Builder candidateEnvironmentPathList(String environmentVar, Function fileTransformer) { + candidateFinders.add(new CandidateOnPathListEnvironmentVar(environmentVar, fileName, fileTransformer, FileIsExecutableFilter.executable(this.executable))); + return this; + } + + public Builder candidateSystemProperty(String systemProperty) { + candidateFinders.add(new CandidateOnSystemPropertyVar(systemProperty, FileIsExecutableFilter.executable(this.executable))); + return this; + } + + public Builder candidateFileInFolder(File folder) { + candidateFinders.add(new CandidateInFolder(folder, fileName, FileIsExecutableFilter.executable(this.executable))); + return this; + } + + public FileFinder build() { + return new FileFinder(this); + } + } + + private static class FileIsExecutableFilter implements Predicate { + @Override + public boolean test(File file) { + return file.canExecute(); + } + + static Predicate executable() { + return new FileIsExecutableFilter(); + } + + static Predicate executable(Boolean executable) { + if (executable == null) { + return AnyFileFilter.any(); + } + if (executable) { + return executable(); + } + // !executable + return executable().negate(); + } + } + + private static class AnyFileFilter implements Predicate { + + @Override + public boolean test(File file) { + return true; + } + + static AnyFileFilter any() { + return new AnyFileFilter(); + } + } + + private static class CandidateOnSinglePathEnvironmentVar implements Supplier> { + private final String environmentVar; + private final String fileName; + private final Predicate additionalFilters; + + public CandidateOnSinglePathEnvironmentVar(String environmentVar, String fileName, Predicate additionalFilter) { + this.environmentVar = environmentVar; + this.fileName = fileName; + this.additionalFilters = additionalFilter == null ? AnyFileFilter.any() : additionalFilter; + } + + @Override + public Optional get() { + return Optional.ofNullable(environmentVar) + .map(File::new) + .map(file -> new File(file, fileName)) + .filter(File::exists) + .filter(additionalFilters); + } + } + + private static class CandidateOnPathListEnvironmentVar implements Supplier> { + private final String environmentVar; + private final String fileName; + private final Function fileTransformer; + private final Predicate additionalFilter; + + public CandidateOnPathListEnvironmentVar(String environmentVar, String fileName, Function fileTransformer, Predicate additionalFilter) { + this.environmentVar = environmentVar; + this.fileName = fileName; + this.fileTransformer = fileTransformer; + this.additionalFilter = additionalFilter; + } + + @Override + public Optional get() { + String pathList = System.getenv(environmentVar); + if (pathList != null) { + return Arrays.stream(pathList.split(System.getProperty("path.separator", ":"))) + .map(File::new) + .filter(File::exists) + .map(fileTransformer) + .map(dir -> new File(dir, fileName)) + .filter(File::exists) + .filter(additionalFilter) + .findFirst(); + } + return Optional.empty(); + } + } + + private static class CandidateOnSystemPropertyVar implements Supplier> { + private final String systemProperty; + private final Predicate additionalFilter; + + public CandidateOnSystemPropertyVar(String systemProperty, Predicate additionalFilter) { + this.systemProperty = systemProperty; + this.additionalFilter = additionalFilter == null ? AnyFileFilter.any() : additionalFilter; + + } + + @Override + public Optional get() { + return Optional.ofNullable(System.getProperty(this.systemProperty)) + .map(File::new) + .filter(File::exists) + .filter(additionalFilter); + } + } + + private static class CandidateInFolder implements Supplier> { + + private final File folder; + private final String fileName; + private final Predicate additionalFilter; + + public CandidateInFolder(File folder, String fileName, Predicate additionalFilter) { + this.folder = folder; + this.fileName = fileName; + this.additionalFilter = additionalFilter == null ? AnyFileFilter.any() : additionalFilter; + } + + @Override + public Optional get() { + return Optional.of(folder) + .filter(File::exists) + .filter(File::isDirectory) + .map(folder -> new File(folder, fileName)) + .filter(File::exists) + .filter(additionalFilter); + } + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NodeServerLayout.java b/lib/src/main/java/com/diffplug/spotless/npm/NodeServerLayout.java index ef873ed2af..a175080517 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NodeServerLayout.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NodeServerLayout.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +22,13 @@ class NodeServerLayout { private final File nodeModulesDir; private final File packageJsonFile; private final File serveJsFile; + private final File npmrcFile; NodeServerLayout(File buildDir, String stepName) { this.nodeModulesDir = new File(buildDir, "spotless-node-modules-" + stepName); this.packageJsonFile = new File(nodeModulesDir, "package.json"); this.serveJsFile = new File(nodeModulesDir, "serve.js"); + this.npmrcFile = new File(nodeModulesDir, ".npmrc"); } File nodeModulesDir() { @@ -40,4 +42,12 @@ File packageJsonFile() { File serveJsFile() { return serveJsFile; } + + public File npmrcFile() { + return npmrcFile; + } + + static File getBuildDirFromNodeModulesDir(File nodeModulesDir) { + return nodeModulesDir.getParentFile(); + } } diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java index 7fe3daf0b7..1492fe7a99 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java @@ -21,7 +21,7 @@ class NpmConfig implements Serializable { - private static final long serialVersionUID = -7660089232952131272L; + private static final long serialVersionUID = 684264546497914877L; private final String packageJsonContent; @@ -29,10 +29,13 @@ class NpmConfig implements Serializable { private final String serveScriptContent; - public NpmConfig(String packageJsonContent, String npmModule, String serveScriptContent) { + private final String npmrcContent; + + public NpmConfig(String packageJsonContent, String npmModule, String serveScriptContent, String npmrcContent) { this.packageJsonContent = packageJsonContent; this.npmModule = npmModule; this.serveScriptContent = serveScriptContent; + this.npmrcContent = npmrcContent; } public String getPackageJsonContent() { @@ -47,4 +50,8 @@ public String getNpmModule() { public String getServeScriptContent() { return serveScriptContent; } + + public String getNpmrcContent() { + return npmrcContent; + } } diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java index 5be273621e..8c233abc8c 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java @@ -18,16 +18,14 @@ import static com.diffplug.spotless.npm.PlatformInfo.OS.WINDOWS; import java.io.File; -import java.util.Arrays; import java.util.Optional; -import java.util.function.Supplier; -import java.util.stream.Stream; +import java.util.function.Function; /** * Utility class to resolve an npm binary to be used by npm-based steps. * Tries to find an npm executable in the following order: *
    - *
  1. from System-Property {@code npm.exec} (unverified)
  2. + *
  3. from System-Property {@code npm.exec}
  4. *
  5. from Environment-Properties in the following order:
  6. *
      *
    1. from NVM_BIN environment variable, if available
    2. @@ -39,6 +37,14 @@ */ class NpmExecutableResolver { + private static final FileFinder NPM_EXECUTABLE_FINDER = FileFinder.finderForExecutableFilename(npmExecutableName()) + .candidateSystemProperty("npm.exec") + .candidateEnvironmentPath("NVM_BIN") + .candidateEnvironmentPathList("NVM_SYMLINK", resolveParentOfNodeModulesDir()) + .candidateEnvironmentPathList("NODE_PATH", resolveParentOfNodeModulesDir()) + .candidateEnvironmentPathList("PATH", resolveParentOfNodeModulesDir()) + .build(); + private NpmExecutableResolver() { // no instance } @@ -51,58 +57,23 @@ static String npmExecutableName() { return npmName; } - static Supplier> systemProperty() { - return () -> Optional.ofNullable(System.getProperty("npm.exec")) - .map(File::new); - } - - static Supplier> environmentNvmBin() { - return () -> Optional.ofNullable(System.getenv("NVM_BIN")) - .map(File::new) - .map(binDir -> new File(binDir, npmExecutableName())) - .filter(File::exists) - .filter(File::canExecute); + private static ParentOfNodeModulesDirResolver resolveParentOfNodeModulesDir() { + return new ParentOfNodeModulesDirResolver(); } - static Supplier> environmentNvmSymlink() { - return pathListFromEnvironment("NVM_SYMLINK"); - } - - static Supplier> environmentNodepath() { - return pathListFromEnvironment("NODE_PATH"); - } + static class ParentOfNodeModulesDirResolver implements Function { - static Supplier> environmentPath() { - return pathListFromEnvironment("PATH"); + @Override + public File apply(File file) { + if (file != null && file.isDirectory() && file.getName().equalsIgnoreCase("node_modules")) { + return file.getParentFile(); + } + return file; + } } static Optional tryFind() { - return Stream.of(systemProperty(), - environmentNvmBin(), - environmentNvmSymlink(), - environmentNodepath(), - environmentPath()) - .map(Supplier::get) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); - } - - private static Supplier> pathListFromEnvironment(String environmentPathListName) { - return () -> { - String pathList = System.getenv(environmentPathListName); - if (pathList != null) { - return Arrays.stream(pathList.split(System.getProperty("path.separator", ":"))) - .map(File::new) - .map(dir -> dir.getName().equalsIgnoreCase("node_modules") ? dir.getParentFile() : dir) - .map(dir -> new File(dir, npmExecutableName())) - .filter(File::exists) - .filter(File::canExecute) - .findFirst(); - - } - return Optional.empty(); - }; + return NPM_EXECUTABLE_FINDER.tryFind(); } static String explainMessage() { diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java index 22752aae31..48bec00c8f 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmFormatterStepStateBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,13 +25,10 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Logger; -import javax.annotation.Nullable; - import com.diffplug.spotless.FileSignature; import com.diffplug.spotless.FormatterFunc; @@ -56,11 +53,10 @@ abstract class NpmFormatterStepStateBase implements Serializable { private final String stepName; - protected NpmFormatterStepStateBase(String stepName, NpmConfig npmConfig, File buildDir, - @Nullable File npm) throws IOException { + protected NpmFormatterStepStateBase(String stepName, NpmConfig npmConfig, File buildDir, File npm) throws IOException { this.stepName = requireNonNull(stepName); this.npmConfig = requireNonNull(npmConfig); - this.npmExecutable = resolveNpm(npm); + this.npmExecutable = npm; NodeServerLayout layout = prepareNodeServer(buildDir); this.nodeModulesDir = layout.nodeModulesDir(); @@ -74,6 +70,11 @@ private NodeServerLayout prepareNodeServer(File buildDir) throws IOException { this.npmConfig.getPackageJsonContent()); NpmResourceHelper .writeUtf8StringToFile(layout.serveJsFile(), this.npmConfig.getServeScriptContent()); + if (this.npmConfig.getNpmrcContent() != null) { + NpmResourceHelper.writeUtf8StringToFile(layout.npmrcFile(), this.npmConfig.getNpmrcContent()); + } else { + NpmResourceHelper.deleteFileIfExists(layout.npmrcFile()); + } FormattedPrinter.SYSOUT.print("running npm install"); runNpmInstall(layout.nodeModulesDir()); FormattedPrinter.SYSOUT.print("npm install finished"); @@ -84,7 +85,11 @@ private void runNpmInstall(File npmProjectDir) throws IOException { new NpmProcess(npmProjectDir, this.npmExecutable).install(); } - protected ServerProcessInfo npmRunServer() throws ServerStartException { + protected ServerProcessInfo npmRunServer() throws ServerStartException, IOException { + if (!this.nodeModulesDir.exists()) { + prepareNodeServer(NodeServerLayout.getBuildDirFromNodeModulesDir(this.nodeModulesDir)); + } + try { // The npm process will output the randomly selected port of the http server process to 'server.port' file // so in order to be safe, remove such a file if it exists before starting. @@ -116,12 +121,6 @@ protected ServerProcessInfo npmRunServer() throws ServerStartException { } } - private static File resolveNpm(@Nullable File npm) { - return Optional.ofNullable(npm) - .orElseGet(() -> NpmExecutableResolver.tryFind() - .orElseThrow(() -> new IllegalStateException("Can't automatically determine npm executable and none was specifically supplied!\n\n" + NpmExecutableResolver.explainMessage()))); - } - protected static String replaceDevDependencies(String template, Map devDependencies) { StringBuilder builder = new StringBuilder(); Iterator> entryIter = devDependencies.entrySet().iterator(); diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java new file mode 100644 index 0000000000..a9a15bd49d --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 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.npm; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class NpmPathResolver { + + private final File explicitNpmExecutable; + + private final File explicitNpmrcFile; + + private final List additionalNpmrcLocations; + + public NpmPathResolver(File explicitNpmExecutable, File explicitNpmrcFile, File... additionalNpmrcLocations) { + this.explicitNpmExecutable = explicitNpmExecutable; + this.explicitNpmrcFile = explicitNpmrcFile; + this.additionalNpmrcLocations = Arrays.asList(additionalNpmrcLocations); + } + + public File resolveNpmExecutable() { + return Optional.ofNullable(this.explicitNpmExecutable) + .orElseGet(() -> NpmExecutableResolver.tryFind() + .orElseThrow(() -> new IllegalStateException("Can't automatically determine npm executable and none was specifically supplied!\n\n" + NpmExecutableResolver.explainMessage()))); + } + + public String resolveNpmrcContent() { + File npmrcFile = Optional.ofNullable(this.explicitNpmrcFile) + .orElseGet(() -> new NpmrcResolver(additionalNpmrcLocations).tryFind() + .orElse(null)); + if (npmrcFile != null) { + return NpmResourceHelper.readUtf8StringFromFile(npmrcFile); + } + return null; + } + +} diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmrcResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmrcResolver.java new file mode 100644 index 0000000000..64e2bb7d41 --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmrcResolver.java @@ -0,0 +1,53 @@ +/* + * Copyright 2016-2020 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.npm; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * Utility class to resolve a {@code .npmrc} file to use in our node config. + * Tries to find a {@code .npmrc} config file in the following order: + *
        + *
      1. from System-Property {@code npm.npmrc}
      2. + *
      3. from 0..n projectLocations (specified by arguments)
      4. + *
      5. from the user home directory, resolved via environment variable{@code $HOME}
      6. + *
      + */ +class NpmrcResolver { + + private final FileFinder npmrcFileFinder; + + NpmrcResolver(File... projectLocations) { + this(Arrays.asList(projectLocations)); + } + + NpmrcResolver(List projectLocations) { + // no instance + final FileFinder.Builder finderBuilder = FileFinder.finderForFilename(".npmrc") + .candidateSystemProperty("npm.npmrc"); + projectLocations.forEach(finderBuilder::candidateFileInFolder); + npmrcFileFinder = finderBuilder + .candidateEnvironmentPath("HOME") + .build(); + } + + Optional tryFind() { + return npmrcFileFinder.tryFind(); + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java b/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java index 5613f2e2d9..ceb6d923b6 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import java.util.logging.Logger; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterFunc.Closeable; @@ -49,12 +48,12 @@ public static final Map defaultDevDependenciesWithPrettier(Strin return Collections.singletonMap("prettier", version); } - public static FormatterStep create(Map devDependencies, Provisioner provisioner, File buildDir, @Nullable File npm, PrettierConfig prettierConfig) { + public static FormatterStep create(Map devDependencies, Provisioner provisioner, File buildDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) { requireNonNull(devDependencies); requireNonNull(provisioner); requireNonNull(buildDir); return FormatterStep.createLazy(NAME, - () -> new State(NAME, devDependencies, buildDir, npm, prettierConfig), + () -> new State(NAME, devDependencies, buildDir, npmPathResolver, prettierConfig), State::createFormatterFunc); } @@ -63,16 +62,17 @@ private static class State extends NpmFormatterStepStateBase implements Serializ private static final long serialVersionUID = -539537027004745812L; private final PrettierConfig prettierConfig; - State(String stepName, Map devDependencies, File buildDir, @Nullable File npm, PrettierConfig prettierConfig) throws IOException { + State(String stepName, Map devDependencies, File buildDir, NpmPathResolver npmPathResolver, PrettierConfig prettierConfig) throws IOException { super(stepName, new NpmConfig( replaceDevDependencies( NpmResourceHelper.readUtf8StringFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/prettier-package.json"), new TreeMap<>(devDependencies)), "prettier", - NpmResourceHelper.readUtf8StringFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/prettier-serve.js")), + NpmResourceHelper.readUtf8StringFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/prettier-serve.js"), + npmPathResolver.resolveNpmrcContent()), buildDir, - npm); + npmPathResolver.resolveNpmExecutable()); this.prettierConfig = requireNonNull(prettierConfig); } @@ -113,7 +113,7 @@ public PrettierFilePathPassingFormatterFunc(String prettierConfigOptions, Pretti @Override public String applyWithFile(String unix, File file) throws Exception { - FormattedPrinter.SYSOUT.print("formatting String '" + unix.substring(0, Math.min(50, unix.length() - 1)) + "[...]' in file '" + file + "'"); + FormattedPrinter.SYSOUT.print("formatting String '" + unix.substring(0, Math.min(50, unix.length())) + "[...]' in file '" + file + "'"); final String prettierConfigOptionsWithFilepath = assertFilepathInConfigOptions(file); return restService.format(unix, prettierConfigOptionsWithFilepath); diff --git a/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java index 3d2b1fcbc6..457e4dcaf7 100644 --- a/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java +++ b/lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java @@ -39,11 +39,11 @@ public class TsFmtFormatterStep { public static final String NAME = "tsfmt-format"; - public static FormatterStep create(Map versions, Provisioner provisioner, File buildDir, @Nullable File npm, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) { + public static FormatterStep create(Map versions, Provisioner provisioner, File buildDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) { requireNonNull(provisioner); requireNonNull(buildDir); return FormatterStep.createLazy(NAME, - () -> new State(NAME, versions, buildDir, npm, configFile, inlineTsFmtSettings), + () -> new State(NAME, versions, buildDir, npmPathResolver, configFile, inlineTsFmtSettings), State::createFormatterFunc); } @@ -70,14 +70,15 @@ public static class State extends NpmFormatterStepStateBase implements Serializa @Nullable private final TypedTsFmtConfigFile configFile; - public State(String stepName, Map versions, File buildDir, @Nullable File npm, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) throws IOException { + public State(String stepName, Map versions, File buildDir, NpmPathResolver npmPathResolver, @Nullable TypedTsFmtConfigFile configFile, @Nullable Map inlineTsFmtSettings) throws IOException { super(stepName, new NpmConfig( replaceDevDependencies(NpmResourceHelper.readUtf8StringFromClasspath(TsFmtFormatterStep.class, "/com/diffplug/spotless/npm/tsfmt-package.json"), new TreeMap<>(versions)), "typescript-formatter", - NpmResourceHelper.readUtf8StringFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/tsfmt-serve.js")), + NpmResourceHelper.readUtf8StringFromClasspath(PrettierFormatterStep.class, "/com/diffplug/spotless/npm/tsfmt-serve.js"), + npmPathResolver.resolveNpmrcContent()), buildDir, - npm); + npmPathResolver.resolveNpmExecutable()); this.buildDir = requireNonNull(buildDir); this.configFile = configFile; this.inlineTsFmtSettings = inlineTsFmtSettings == null ? new TreeMap<>() : new TreeMap<>(inlineTsFmtSettings); diff --git a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java index 01369b14ae..c19d023ffc 100644 --- a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java +++ b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 DiffPlug + * Copyright 2020-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,8 +63,8 @@ private State createState() throws IOException, InterruptedException { String trackingIssue = "\n github issue to handle this better: https://github.com/diffplug/spotless/issues/674"; String exeAbsPath = ForeignExe.nameAndVersion("black", version) .pathToExe(pathToExe) - .fixCantFind("Try running `pip install black=={version}`, or else tell Spotless where it is with `black().pathToExe('path/to/executable')`" + trackingIssue) - .fixWrongVersion("Try running `pip install --force-reinstall black=={version}`, or else specify `black('{versionFound}')` to Spotless" + trackingIssue) + .fixCantFind("Try running {@code pip install black=={version}}, or else tell Spotless where it is with {@code black().pathToExe('path/to/executable')}" + trackingIssue) + .fixWrongVersion("Try running {@code pip install --force-reinstall black=={version}}, or else specify {@code black('{versionFound}')} to Spotless" + trackingIssue) .confirmVersionAndGetAbsolutePath(); return new State(this, exeAbsPath); } diff --git a/lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java b/lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java index d2ba714c26..f7922387e4 100644 --- a/lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java +++ b/lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,16 +34,18 @@ import com.diffplug.spotless.JarState; import com.diffplug.spotless.Provisioner; -/** Wraps up [scalafmt](https://github.com/olafurpg/scalafmt) as a FormatterStep. */ +/** Wraps up scalafmt as a FormatterStep. */ public class ScalaFmtStep { // prevent direct instantiation private ScalaFmtStep() {} private static final Pattern VERSION_PRE_2_0 = Pattern.compile("[10]\\.(\\d+)\\.\\d+"); - private static final String DEFAULT_VERSION = "2.0.1"; + private static final Pattern VERSION_PRE_3_0 = Pattern.compile("2\\.(\\d+)\\.\\d+"); + private static final String DEFAULT_VERSION = "3.0.0"; static final String NAME = "scalafmt"; static final String MAVEN_COORDINATE_PRE_2_0 = "com.geirsson:scalafmt-core_2.11:"; - static final String MAVEN_COORDINATE = "org.scalameta:scalafmt-core_2.11:"; + static final String MAVEN_COORDINATE_PRE_3_0 = "org.scalameta:scalafmt-core_2.11:"; + static final String MAVEN_COORDINATE = "org.scalameta:scalafmt-core_2.13:"; public static FormatterStep create(Provisioner provisioner) { return create(defaultVersion(), provisioner, null); @@ -69,9 +71,11 @@ static final class State implements Serializable { State(String version, Provisioner provisioner, @Nullable File configFile) throws IOException { String mavenCoordinate; - Matcher versionMatcher = VERSION_PRE_2_0.matcher(version); - if (versionMatcher.matches()) { + Matcher versionMatcher; + if ((versionMatcher = VERSION_PRE_2_0.matcher(version)).matches()) { mavenCoordinate = MAVEN_COORDINATE_PRE_2_0; + } else if ((versionMatcher = VERSION_PRE_3_0.matcher(version)).matches()) { + mavenCoordinate = MAVEN_COORDINATE_PRE_3_0; } else { mavenCoordinate = MAVEN_COORDINATE; } @@ -106,7 +110,7 @@ FormatterFunc createFormat() throws Exception { Class configCls = classLoader.loadClass("org.scalafmt.config.Config"); Class scalafmtCls = classLoader.loadClass("org.scalafmt.Scalafmt"); - Object either; + Object configured; try { // scalafmt >= 1.6.0 @@ -114,8 +118,7 @@ FormatterFunc createFormat() throws Exception { String configStr = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); - Object configured = parseHoconConfig.invoke(null, configStr); - either = invokeNoArg(configured, "toEither"); + configured = parseHoconConfig.invoke(null, configStr); } catch (NoSuchMethodException e) { // scalafmt >= v0.7.0-RC1 && scalafmt < 1.6.0 Method fromHocon = configCls.getMethod("fromHoconString", String.class, optionCls); @@ -123,11 +126,10 @@ FormatterFunc createFormat() throws Exception { String configStr = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); - Object configured = fromHocon.invoke(null, configStr, fromHoconEmptyPath); - either = invokeNoArg(configured, "toEither"); + configured = fromHocon.invoke(null, configStr, fromHoconEmptyPath); } - config = invokeNoArg(invokeNoArg(either, "right"), "get"); + config = invokeNoArg(configured, "get"); } return input -> { Object resultInsideFormatted = formatMethod.invoke(null, input, config, emptyRange); diff --git a/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java b/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java index edfef041c6..f488bd5a00 100644 --- a/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java +++ b/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/DBeaverSQLFormatterConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ public class DBeaverSQLFormatterConfiguration { */ private static final String SQL_FORMATTER_STATEMENT_DELIMITER = "sql.formatter.statement.delimiter"; /** - * space or tag + * space or tab */ private static final String SQL_FORMATTER_INDENT_TYPE = "sql.formatter.indent.type"; /** diff --git a/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/SQLTokenizedFormatter.java b/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/SQLTokenizedFormatter.java index 4a973ba3b1..28f94de0de 100644 --- a/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/SQLTokenizedFormatter.java +++ b/lib/src/main/java/com/diffplug/spotless/sql/dbeaver/SQLTokenizedFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -263,6 +263,8 @@ private List format(final List argList) { index += insertReturnAndIndent(argList, index, 0); } index += insertReturnAndIndent(argList, index + 1, 0); + } else if (token.getType() == TokenType.NAME && index > 0 && argList.get(index - 1).getType() == TokenType.COMMENT) { + index += insertReturnAndIndent(argList, index, indent); } else { if (statementDelimiters.contains(tokenString)) { indent = 0; @@ -322,6 +324,10 @@ private List format(final List argList) { // Do not add space between symbols continue; } + if (prev.getType() == TokenType.COMMENT) { + // Do not add spaces to comments + continue; + } argList.add(index, new FormatterToken(TokenType.SPACE, " ")); } } @@ -383,17 +389,25 @@ private int insertReturnAndIndent(final List argList, final int if (functionBracket.contains(Boolean.TRUE)) return 0; try { - StringBuilder s = new StringBuilder(getDefaultLineSeparator()); + final String defaultLineSeparator = getDefaultLineSeparator(); + StringBuilder s = new StringBuilder(defaultLineSeparator); + for (int index = 0; index < argIndent; index++) { + s.append(formatterCfg.getIndentString()); + } if (argIndex > 0) { + final FormatterToken token = argList.get(argIndex); final FormatterToken prevToken = argList.get(argIndex - 1); - if (prevToken.getType() == TokenType.COMMENT && - isCommentLine(sqlDialect, prevToken.getString())) { - s = new StringBuilder(); + if (token.getType() == TokenType.COMMENT && + isCommentLine(sqlDialect, token.getString()) && + prevToken.getType() != TokenType.END) { + s.setCharAt(0, ' '); + s.setLength(1); + + final String comment = token.getString(); + final String withoutTrailingWhitespace = comment.replaceFirst("\\s*$", ""); + token.setString(withoutTrailingWhitespace); } } - for (int index = 0; index < argIndent; index++) { - s.append(formatterCfg.getIndentString()); - } FormatterToken token = argList.get(argIndex); if (token.getType() == TokenType.SPACE) { diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 2e4943a02f..5bfb322cde 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -4,6 +4,130 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +## [5.14.3] - 2021-08-20 +### Changed +* Added support for [scalafmt 3.0.0](https://github.com/scalameta/scalafmt/releases/tag/v3.0.0) and bump default scalafmt version to `3.0.0` ([#913](https://github.com/diffplug/spotless/pull/913)). +* Bump default versions ([#915](https://github.com/diffplug/spotless/pull/915)) + * `ktfmt` from `0.24` to `0.27` + * `ktlint` from `0.35.0` to `0.42.1` + * `google-java-format` from `1.10.0` to `1.11.0` + +## [5.14.2] - 2021-07-20 +### Fixed + * Improved [SQL formatting](https://github.com/diffplug/spotless/pull/897) with respect to comments + +## [5.14.1] - 2021-07-06 +### Changed +* Improved exception messages for [JSON formatting](https://github.com/diffplug/spotless/pull/885) failures + +## [5.14.0] - 2021-06-17 + +### Added +* Added Gradle configuration [JVM-based JSON formatting](https://github.com/diffplug/spotless/issues/850) +### Fixed +* Fixed IndexOutOfBoundsException in parallel execution of `eclipse-groovy` formatter ([#877](https://github.com/diffplug/spotless/issues/877)) + +## [5.13.0] - 2021-06-10 +### Added +* Added support for `eclipse-cdt` at `4.19.0`. Note that version requires Java 11 or higher. +* Added support for `eclipse-groovy` at `4.18.0` and `4.19.0`. +* Added support for `eclipse-wtp` at `4.19.0`. Note that version requires Java 11 or higher. +### Changed +* Bump `eclipse-groovy` default version from `4.17.0` to `4.19.0`. + +## [5.12.5] - 2021-05-13 +### Changed +* Update ktfmt from 0.21 to 0.24 +### Fixed +* The `` field in the maven POM is now set correctly ([#798](https://github.com/diffplug/spotless/issues/798)) +* Node is re-installed if some other build step removed it ([#863](https://github.com/diffplug/spotless/issues/863)) + +## [5.12.4] - 2021-04-21 +### Fixed +* Dependency configurations are now named rather than detached, attempt to fix #815. + +## [5.12.3] - 2021-04-21 +### Fixed +* Explicitly separate target file from git arguments when parsing year for license header to prevent command from failing on argument-like paths ([#847](https://github.com/diffplug/spotless/pull/847)) + +## [5.12.2] - 2021-04-20 +### Fixed +* LicenseHeaderStep treats address as copyright year ([#716](https://github.com/diffplug/spotless/issues/716)) + +## [5.12.1] - 2021-04-13 +### Fixed +* Fix license header bug for years in range ([#840](https://github.com/diffplug/spotless/pull/840)). + +## [5.12.0] - 2021-04-10 +### Added +* Added support for `eclipse-jdt` at `4.19.0`. +### Changed +* Bump `eclipse-jdt` default version from `4.18.0` to `4.19.0`. +* Bump `google-java-format` default version from `1.9` to `1.10.0`. +* Expose configuration exceptions from scalafmt ([#837](https://github.com/diffplug/spotless/issues/837)) +### Fixed +* Exclude `.git`, `.gradle` and `build` directories when multiple targets are specified ([#835](https://github.com/diffplug/spotless/issues/835)). + * As part of this fix, `**/blah.txt` is now handled the same as `**/*.txt`, which was always the expected behavior. Very unlikely to cause any user-visible changes in behavior. + +## [5.11.1] - 2021-03-26 +### Fixed +* Ensure consistent ordering of task inputs for `RegisterDependenciesTask`,bso the task is `up-to-date` when the spotless config has not changed. + +## [5.11.0] - 2021-03-05 +### Added +* Bump ktfmt to 0.21 and add support to Google and Kotlinlang formats ([#812](https://github.com/diffplug/spotless/pull/812)) + +## [5.10.2] - 2021-02-16 +### Fixed +* Allow licence headers to be blank ([#801](https://github.com/diffplug/spotless/pull/801)). + +## [5.10.1] - 2021-02-11 +### Fixed +* Fixed the `clean` task when Gradle's configuration cache is enabled ([#796](https://github.com/diffplug/spotless/issues/796)) + +## [5.10.0] - 2021-02-09 +### Added +* Support for diktat in KotlinGradleExtension ([#789](https://github.com/diffplug/spotless/pull/789)) + +## [5.9.0] - 2021-01-04 +### Added +* Added support for `eclipse-cdt`, `eclipse-jdt`, and `eclipse-wtp` at `4.18.0`. +### Changed +* Bump `eclipse-jdt` default version from `4.17.0` to `4.18.0`. +* Bump `eclipse-wtp` default version from `4.17.0` to `4.18.0`. +* Bump `ktfmt` default version from `0.16` to `0.19` ([#748](https://github.com/diffplug/spotless/issues/748) and [#773](https://github.com/diffplug/spotless/issues/773)). +### Fixed +* Fixed `ratchetFrom` support for git-submodule ([#746](https://github.com/diffplug/spotless/issues/746)). +* Fixed `ratchetFrom` excess memory consumption ([#735](https://github.com/diffplug/spotless/issues/735)). +* `ktfmt` v0.19+ with dropbox-style works again ([#765](https://github.com/diffplug/spotless/pull/765)). +* `prettier` no longer throws errors on empty files ([#751](https://github.com/diffplug/spotless/pull/751)). +* Fixed error when running on root of windows mountpoint ([#760](https://github.com/diffplug/spotless/pull/760)). +* No longer declare inputs on `SpotlessCheck` and `SpotlessApply` since they don't have any outputs (worker task still does up-to-date and caching) ([#741](https://github.com/diffplug/spotless/issues/741)). + +## [5.8.2] - 2020-11-16 +### Fixed +* Fixed a bug which occurred if the root directory of the project was also the filesystem root ([#732](https://github.com/diffplug/spotless/pull/732)) + +## [5.8.1] - 2020-11-13 +### Fixed +* Bump JGit from `5.8.0` to `5.9.0` to improve performance ([#726](https://github.com/diffplug/spotless/issues/726)) + +## [5.8.0] - 2020-11-12 +### Added +* Added support to npm-based steps for picking up `.npmrc` files ([#727](https://github.com/diffplug/spotless/pull/727)) + +## [5.7.0] - 2020-10-20 +### Added +* Added support for eclipse-cdt 4.14.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-groovy 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-jdt 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-wtp 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +### Changed +* Updated default eclipse-cdt from 4.13.0 to 4.16.0 ([#722](https://github.com/diffplug/spotless/pull/722)). Note that version 4.17.0 is supported, but requires Java 11 or higher. +* Updated default eclipse-groovy from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-jdt from 4.16.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-wtp from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). + ## [5.6.1] - 2020-09-21 ### Fixed * `5.6.0` introduced a bug where it was no longer possible to configure a single format twice, e.g. to have two `java{}` blocks in a single file. Fixed by [#702](https://github.com/diffplug/spotless/pull/702). @@ -167,7 +291,7 @@ spotless { ## [4.1.0] - 2020-06-01 ### Added -* You can now ratchet a project's style by limiting Spotless only to files which have changed since a given [git reference](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), e.g. `ratchetFrom 'origin/main'`. ([#590](https://github.com/diffplug/spotless/pull/590)) +* You can now ratchet a project's style by limiting Spotless only to files which have changed since a given [git reference](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), e.g. `ratchetFrom 'origin/main'`. ([#590](https://github.com/diffplug/spotless/pull/590)) * Support for ktfmt in KotlinGradleExtension. ([#583](https://github.com/diffplug/spotless/pull/583)) ### Fixed * Users can now run `spotlessCheck` and `spotlessApply` in the same build. ([#584](https://github.com/diffplug/spotless/pull/584)) @@ -449,7 +573,7 @@ spotless { * BREAKING CHANGE: `customReplace` and `customReplaceRegex` renamed to just `replace` and `replaceRegex`. * BREAKING CHANGE: Plugin portal ID is still `com.diffplug.gradle.spotless`, but maven coordinate has changed to `com.diffplug.spotless:spotless-plugin-gradle`. * HUGE SPEEDUP: Now supports incremental build / up-to-date-checking. - + If you are using `custom` or `customLazy`, you might want to take a look at [this javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/3.27.0/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-). + + If you are using `custom` or `customLazy`, you might want to take a look at [this javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/3.27.0/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-). * BREAKING CHANGE: `freshmark` no longer includes all project properties by default. All properties must now be added manually: ```gradle diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 26f2b39163..b47a3f6dd1 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -17,9 +17,9 @@ output = [ --> [![Gradle plugin](https://img.shields.io/badge/plugins.gradle.org-com.diffplug.spotless-blue.svg)](https://plugins.gradle.org/plugin/com.diffplug.spotless) [![Maven central](https://img.shields.io/badge/mavencentral-yes-blue.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-gradle%22) -[![Javadoc](https://img.shields.io/badge/javadoc-yes-blue.svg)](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/index.html) +[![Javadoc](https://img.shields.io/badge/javadoc-yes-blue.svg)](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/index.html) [![License Apache](https://img.shields.io/badge/license-apache-blue.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)) -[![Changelog](https://img.shields.io/badge/changelog-5.6.1-blue.svg)](CHANGES.md) +[![Changelog](https://img.shields.io/badge/changelog-5.14.3-blue.svg)](CHANGES.md) [![Circle CI](https://circleci.com/gh/diffplug/spotless/tree/main.svg?style=shield)](https://circleci.com/gh/diffplug/spotless/tree/main) [![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/spotless) @@ -28,7 +28,7 @@ output = [ Spotless is a general-purpose formatting plugin used by [4,000 projects on GitHub (August 2020)](https://github.com/search?l=gradle&q=spotless&type=Code). It is completely à la carte, but also includes powerful "batteries-included" if you opt-in. @@ -60,7 +60,7 @@ Spotless supports all of Gradle's built-in performance features (incremental bui - **Languages** - [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [clang-format](#clang-format), [prettier](#prettier)) - [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy)) - - [Kotlin](#kotlin) ([ktlint](#ktlint), [ktfmt](#ktfmt), [prettier](#prettier)) + - [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [prettier](#prettier)) - [Scala](#scala) ([scalafmt](#scalafmt)) - [C/C++](#cc) ([clang-format](#clang-format), [eclipse cdt](#eclipse-cdt)) - [Python](#python) ([black](#black)) @@ -68,8 +68,9 @@ Spotless supports all of Gradle's built-in performance features (incremental bui - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter)) - [SQL](#sql) ([dbeaver](#dbeaver), [prettier](#prettier)) - [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier)) + - [JSON](#json) - Multiple languages - - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection)) + - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection)) - javascript, jsx, angular, vue, flow, typescript, css, less, scss, html, json, graphql, markdown, ymaml - [clang-format](#clang-format) - c, c++, c#, objective-c, protobuf, javascript, java @@ -121,10 +122,10 @@ spotless { ``` Spotless consists of a list of formats (in the example above, `misc` and `java`), and each format has: -- a `target` (the files to format), which you set with [`target`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#target-java.lang.Object...-) and [`targetExclude`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#targetExclude-java.lang.Object...-) -- a list of `FormatterStep`, which are just `String -> String` functions, such as [`replace`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`replaceRegex`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#replaceRegex-java.lang.String-java.lang.String-java.lang.String-), [`trimTrailingWhitespace`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`custom`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#custom-java.lang.String-groovy.lang.Closure-), [`prettier`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#prettier--), [`eclipseWtp`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#eclipseWtp-com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep-), [`licenseHeader`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#licenseHeader-java.lang.String-java.lang.String-) etc. +- a `target` (the files to format), which you set with [`target`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#target-java.lang.Object...-) and [`targetExclude`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#targetExclude-java.lang.Object...-) +- a list of `FormatterStep`, which are just `String -> String` functions, such as [`replace`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`replaceRegex`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#replaceRegex-java.lang.String-java.lang.String-java.lang.String-), [`trimTrailingWhitespace`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#replace-java.lang.String-java.lang.CharSequence-java.lang.CharSequence-), [`custom`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#custom-java.lang.String-groovy.lang.Closure-), [`prettier`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#prettier--), [`eclipseWtp`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#eclipseWtp-com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep-), [`licenseHeader`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#licenseHeader-java.lang.String-java.lang.String-) etc. -All the generic steps live in [`FormatExtension`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html), and there are many language-specific steps which live in its language-specific subclasses, which are described below. +All the generic steps live in [`FormatExtension`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html), and there are many language-specific steps which live in its language-specific subclasses, which are described below. ### Requirements @@ -136,7 +137,7 @@ If you're stuck on an older version of Gradle, `id 'com.diffplug.gradle.spotless ## Java -`com.diffplug.gradle.spotless.JavaExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/JavaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java) +`com.diffplug.gradle.spotless.JavaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/JavaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java) ```gradle spotless { @@ -197,8 +198,8 @@ spotless { ## Groovy -- `com.diffplug.gradle.spotless.GroovyExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/GroovyExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java) -- `com.diffplug.gradle.spotless.GroovyGradleExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/GroovyGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyGradleExtension.java) +- `com.diffplug.gradle.spotless.GroovyExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/GroovyExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyExtension.java) +- `com.diffplug.gradle.spotless.GroovyGradleExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/GroovyGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GroovyGradleExtension.java) Configuration for Groovy is similar to [Java](#java), in that it also supports `licenseHeader` and `importOrder`. @@ -243,16 +244,17 @@ Groovy-Eclipse formatting errors/warnings lead per default to a build failure. T ## Kotlin -- `com.diffplug.gradle.spotless.KotlinExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/KotlinExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java) -- `com.diffplug.gradle.spotless.KotlinGradleExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/KotlinGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java) +- `com.diffplug.gradle.spotless.KotlinExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/KotlinExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java) +- `com.diffplug.gradle.spotless.KotlinGradleExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/KotlinGradleExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java) ```gradle spotless { // if you are using build.gradle.kts, instead of 'spotless {' use: // configure { kotlin { // by default the target is every '.kt' and '.kts` file in the java sourcesets - ktlint() // has its own section below ktfmt() // has its own section below + ktlint() // has its own section below + diktat() // has its own section below prettier() // has its own section below licenseHeader '/* (C)$YEAR */' // or licenseHeaderFile } @@ -263,6 +265,16 @@ spotless { // if you are using build.gradle.kts, instead of 'spotless {' use: } ``` +### ktfmt + +[homepage](https://github.com/facebookincubator/ktfmt). [changelog](https://github.com/facebookincubator/ktfmt/releases). + +```kotlin +spotless { + kotlin { + ktfmt('0.15').dropboxStyle() // version and dropbox style are optional +``` + ### ktlint @@ -273,26 +285,25 @@ spotless { // if you are using build.gradle.kts, instead of 'spotless {' use: spotless { kotlin { // version and userData are both optional - ktlint('0.37.2').userData(mapOf('indent_size' to '2', 'continuation_indent_size' to '2']) + ktlint('0.37.2').userData(mapOf('indent_size' to '2', 'continuation_indent_size' to '2')) ``` - +### diktat -### ktfmt - -[homepage](https://github.com/facebookincubator/ktfmt). [changelog](https://github.com/facebookincubator/ktfmt/releases). +[homepage](https://github.com/cqfn/diKTat). [changelog](https://github.com/cqfn/diKTat/releases). You can provide configuration path manually as `configFile`. ```kotlin spotless { kotlin { - ktfmt('0.15').dropboxStyle() // version and dropbox style are optional + // version and configFile are both optional + diktat('0.4.0').configFile("full/path/to/diktat-analysis.yml") ``` ## Scala -`com.diffplug.gradle.spotless.ScalaExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/ScalaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ScalaExtension.java) +`com.diffplug.gradle.spotless.ScalaExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/ScalaExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ScalaExtension.java) ```gradle spotless { @@ -324,7 +335,7 @@ spotless { ## C/C++ -`com.diffplug.gradle.spotless.CppExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/CppExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java) +`com.diffplug.gradle.spotless.CppExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/CppExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java) ```gradle spotless { @@ -356,7 +367,7 @@ spotles { ## Python -`com.diffplug.gradle.spotless.PythonExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/PythonExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PythonExtension.java) +`com.diffplug.gradle.spotless.PythonExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/PythonExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/PythonExtension.java) ```gradle spotless { @@ -390,7 +401,7 @@ black().pathToExe('C:/myuser/.pyenv/versions/3.8.0/scripts/black.exe') ## FreshMark -`com.diffplug.gradle.spotless.FreshMarkExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FreshMarkExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FreshMarkExtension.java) +`com.diffplug.gradle.spotless.FreshMarkExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FreshMarkExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FreshMarkExtension.java) [homepage](https://github.com/diffplug/freshmark). [changelog](https://github.com/diffplug/freshmark/blob/master/CHANGES.md). FreshMark lets you generate markdown in the comments of your markdown. This helps to keep badges and links up-to-date (see the source for this file), and can also be helpful for generating complex tables (see the source for [the parent readme](../README.md)). @@ -411,7 +422,7 @@ spotless { ## Antlr4 -`com.diffplug.gradle.spotless.Antlr4Extension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/Antlr4Extension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/Antlr4Extension.java) +`com.diffplug.gradle.spotless.Antlr4Extension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/Antlr4Extension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/Antlr4Extension.java) ```gradle spotless { @@ -436,7 +447,7 @@ antlr4formatter('1.2.1') // version is optional ## SQL -`com.diffplug.gradle.spotless.SqlExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/SqlExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java) +`com.diffplug.gradle.spotless.SqlExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/SqlExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java) ```gradle spotless { @@ -476,7 +487,7 @@ sql.formatter.indent.size=4 ## Typescript -- `com.diffplug.gradle.spotless.TypescriptExtension` [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/TypescriptExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java) +- `com.diffplug.gradle.spotless.TypescriptExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/TypescriptExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java) ```gradle spotless { @@ -515,13 +526,36 @@ spotless { **Prerequisite: tsfmt requires a working NodeJS version** -tsfmt is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. -Spotless will try to auto-discover an npm installation. If that is not working for you, it is possible to directly configure the npm binary to use. +For details, see the [npm detection](#npm-detection) and [`.npmrc` detection](#npmrc-detection) sections of prettier, which apply also to tsfmt. + +## JSON + +- `com.diffplug.gradle.spotless.JsonExtension` [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/JsonExtension.html), [code](https://github.com/diffplug/spotless/blob/main/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JsonExtension.java) ```gradle spotless { - typescript { - tsfmt().npmExecutable('/usr/bin/npm').config(...) + json { + target 'src/**/*.json' // you have to set the target manually + simple() // has its own section below + prettier().config(['parser': 'json']) // see Prettier section below + eclipseWtp('json') // see Eclipse web tools platform section + } +} +``` + +### simple + +Uses a JSON pretty-printer that optionally allows configuring the number of spaces that are used to pretty print objects: + +```gradle +spotless { + json { + target 'src/**/*.json' + simple() + // optional: specify the number of spaces to use + simple().indentWithSpaces(6) + } +} ``` @@ -591,6 +625,17 @@ spotless { prettier().npmExecutable('/usr/bin/npm').config(...) ``` +### `.npmrc` detection + +Spotless picks up npm configuration stored in a `.npmrc` file either in the project directory or in your user home. +Alternatively you can supply spotless with a location of the `.npmrc` file to use. (This can be combined with `npmExecutable`, of course.) + +```gradle +spotless { + typescript { + prettier().npmrc("$projectDir/config/.npmrc").config(...) +``` + ## clang-format [homepage](https://clang.llvm.org/docs/ClangFormat.html). [changelog](https://releases.llvm.org/download.html). `clang-format` is a formatter for c, c++, c#, objective-c, protobuf, javascript, and java. You can use clang-format in any language-specific format, but usually you will be creating a generic format. @@ -629,7 +674,7 @@ spotless { format 'xml', { target 'src/**/*/xml' // must specify target eclipseWtp('xml') // must specify a type (table below) - eclipseWtp('xml', '4.7.3a') // optional version + eclipseWtp('xml', '4.13.0') // optional version // you can also specify an arbitrary number of config files eclipseWtp('xml').configFile('spotless.xml.prefs', 'spotless.common.properties' } @@ -671,7 +716,7 @@ Once a file's license header has a valid year, whether it is a year (`2020`) or * `2017` -> `2017-2020` * `2017-2019` -> `2017-2020` -See the [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.LicenseHeaderConfig.html) for a complete listing of options. +See the [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.LicenseHeaderConfig.html) for a complete listing of options. @@ -690,7 +735,7 @@ spotless { ratchetFrom 'origin/main' // only format files which have changed since origin/main ``` -In this mode, Spotless will apply only to files which have changed since `origin/main`. You can ratchet from [any point you want](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`. You can also set `ratchetFrom` per-format if you prefer (e.g. `spotless { java { ratchetFrom ...`). +In this mode, Spotless will apply only to files which have changed since `origin/main`. You can ratchet from [any point you want](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`. You can also set `ratchetFrom` per-format if you prefer (e.g. `spotless { java { ratchetFrom ...`). However, we strongly recommend that you use a non-local branch, such as a tag or `origin/main`. The problem with `HEAD` or any local branch is that as soon as you commit a file, that is now the canonical formatting, even if it was formatted incorrectly. By instead specifying `origin/main` or a tag, your CI server will fail unless every changed file is at least as good or better than it was before the change. @@ -738,9 +783,9 @@ spotless { custom 'lowercase', { str -> str.toLowerCase() } ``` -However, custom rules will disable up-to-date checking and caching, unless you read [this javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-) and follow its instructions carefully. +However, custom rules will disable up-to-date checking and caching, unless you read [this javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-) and follow its instructions carefully. -Another option is to create proper `FormatterStep` in your `buildSrc`, and then call [`addStep`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#addStep-com.diffplug.spotless.FormatterStep-). The contributing guide describes [how to do this](https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md#how-to-add-a-new-formatterstep). If the step is generally-useful, we hope you'll open a PR to share it! +Another option is to create proper `FormatterStep` in your `buildSrc`, and then call [`addStep`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#addStep-com.diffplug.spotless.FormatterStep-). The contributing guide describes [how to do this](https://github.com/diffplug/spotless/blob/main/CONTRIBUTING.md#how-to-add-a-new-formatterstep). If the step is generally-useful, we hope you'll open a PR to share it! ```gradle @@ -773,11 +818,11 @@ spotless { format 'foo', com.acme.FooLanguageExtension, { ``` -If you'd like to create a one-off Spotless task outside of the `check`/`apply` framework, see [`FormatExtension.createIndependentApplyTask`](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#createIndependentApplyTask-java.lang.String-). +If you'd like to create a one-off Spotless task outside of the `check`/`apply` framework, see [`FormatExtension.createIndependentApplyTask`](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#createIndependentApplyTask-java.lang.String-). ## Inception (languages within languages within...) -In very rare cases, you might want to format e.g. javascript which is written inside JSP templates, or maybe java within a markdown file, or something wacky like that. You can specify hunks within a file using either open/close tags or a regex with a single capturing group, and then specify rules within it, like so. See [javadoc](https://javadoc.io/static/com.diffplug.spotless/spotless-plugin-gradle/5.6.1/com/diffplug/gradle/spotless/FormatExtension.html#withinBlocks-java.lang.String-java.lang.String-java.lang.String-org.gradle.api.Action-) for more details. +In very rare cases, you might want to format e.g. javascript which is written inside JSP templates, or maybe java within a markdown file, or something wacky like that. You can specify hunks within a file using either open/close tags or a regex with a single capturing group, and then specify rules within it, like so. See [javadoc](https://javadoc.io/doc/com.diffplug.spotless/spotless-plugin-gradle/5.14.3/com/diffplug/gradle/spotless/FormatExtension.html#withinBlocks-java.lang.String-java.lang.String-java.lang.String-org.gradle.api.Action-) for more details. ```gradle import com.diffplug.gradle.spotless.JavaExtension diff --git a/plugin-gradle/build.gradle b/plugin-gradle/build.gradle index f24f2cd233..132412d005 100644 --- a/plugin-gradle/build.gradle +++ b/plugin-gradle/build.gradle @@ -9,7 +9,7 @@ apply plugin: 'com.gradle.plugin-publish' apply plugin: 'java-gradle-plugin' dependencies { - if (version.endsWith('-SNAPSHOT')) { + if (version.endsWith('-SNAPSHOT') || (rootProject.spotlessChangelog.versionNext == rootProject.spotlessChangelog.versionLast)) { api project(':lib') api project(':lib-extra') } else { @@ -69,6 +69,7 @@ if (version.endsWith('-SNAPSHOT')) { 'eclipse', 'ktlint', 'ktfmt', + 'diktat', 'tsfmt', 'prettier', 'scalafmt', diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java index 1f4f90352d..0e68d76e0f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,12 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Random; import java.util.TreeMap; -import java.util.stream.Stream; import javax.annotation.Nullable; import javax.inject.Inject; @@ -37,9 +36,9 @@ import org.gradle.api.GradleException; import org.gradle.api.Project; import org.gradle.api.Task; +import org.gradle.api.file.ConfigurableFileTree; import org.gradle.api.file.FileCollection; import org.gradle.api.plugins.BasePlugin; -import org.gradle.api.tasks.util.PatternFilterable; import com.diffplug.spotless.FormatExceptionPolicyStrict; import com.diffplug.spotless.FormatterFunc; @@ -58,11 +57,12 @@ import com.diffplug.spotless.generic.ReplaceRegexStep; import com.diffplug.spotless.generic.ReplaceStep; import com.diffplug.spotless.generic.TrimTrailingWhitespaceStep; +import com.diffplug.spotless.npm.NpmPathResolver; import com.diffplug.spotless.npm.PrettierFormatterStep; import groovy.lang.Closure; -/** Adds a `spotless{Name}Check` and `spotless{Name}Apply` task. */ +/** Adds a {@code spotless{Name}Check} and {@code spotless{Name}Apply} task. */ public class FormatExtension { final SpotlessExtension spotless; final List> lazyActions = new ArrayList<>(); @@ -195,15 +195,11 @@ private FileCollection parseTargetsIsExclude(Object[] targets, boolean isExclude } else if (targets.length == 1) { return parseTargetIsExclude(targets[0], isExclude); } else { - if (Stream.of(targets).allMatch(o -> o instanceof String)) { - return parseTargetIsExclude(Arrays.asList(targets), isExclude); - } else { - FileCollection union = getProject().files(); - for (Object target : targets) { - union = union.plus(parseTargetIsExclude(target, isExclude)); - } - return union; + FileCollection union = getProject().files(); + for (Object target : targets) { + union = union.plus(parseTargetIsExclude(target, isExclude)); } + return union; } } @@ -218,32 +214,24 @@ protected final FileCollection parseTarget(Object target) { } private final FileCollection parseTargetIsExclude(Object target, boolean isExclude) { - if (target instanceof FileCollection) { + if (target instanceof Collection) { + return parseTargetsIsExclude(((Collection) target).toArray(), isExclude); + } else if (target instanceof FileCollection) { return (FileCollection) target; - } else if (target instanceof String || - (target instanceof List && ((List) target).stream().allMatch(o -> o instanceof String))) { + } else if (target instanceof String) { File dir = getProject().getProjectDir(); - PatternFilterable userExact; // exactly the collection that the user specified - if (target instanceof String) { - userExact = getProject().fileTree(dir).include((String) target); - } else { - // target can only be a List at this point - @SuppressWarnings("unchecked") - List targetList = (List) target; - userExact = getProject().fileTree(dir).include(targetList); - } - boolean filterOutGitAndGradle; + ConfigurableFileTree matchedFiles = getProject().fileTree(dir); + String targetString = (String) target; + matchedFiles.include(targetString); + // since people are likely to do '**/*.md', we want to make sure to exclude folders // they don't want to format which will slow down the operation greatly // but we only want to do that if they are *including* - if they are specifying // what they want to exclude, we shouldn't filter at all - if (target instanceof String && !isExclude) { - String str = (String) target; - filterOutGitAndGradle = str.startsWith("**/*") || str.startsWith("**\\*"); - } else { - filterOutGitAndGradle = false; + if (isExclude) { + return matchedFiles; } - if (filterOutGitAndGradle) { + if (targetString.startsWith("**/") || targetString.startsWith("**\\")) { List excludes = new ArrayList<>(); // no git excludes.add(".git"); @@ -256,9 +244,9 @@ private final FileCollection parseTargetIsExclude(Object target, boolean isExclu for (Project subproject : getProject().getSubprojects()) { relativizeIfSubdir(excludes, dir, subproject.getBuildDir()); } - userExact = userExact.exclude(excludes); + matchedFiles.exclude(excludes); } - return (FileCollection) userExact; + return matchedFiles; } else { return getProject().files(target); } @@ -323,17 +311,17 @@ public void clearSteps() { } /** - * An optional performance optimization if you are using any of the `custom` - * methods. If you aren't explicitly calling `custom`, then this method + * An optional performance optimization if you are using any of the {@code custom} + * methods. If you aren't explicitly calling {@code custom}, then this method * has no effect. * * Spotless tracks what files have changed from run to run, so that it can run faster * by only checking files which have changed, or whose formatting steps have changed. - * If you use the `custom` methods, then gradle can never mark - * your files as `up-to-date`, because it can't know if perhaps the behavior of your + * If you use the {@code custom} methods, then gradle can never mark + * your files as {@code up-to-date}, because it can't know if perhaps the behavior of your * custom function has changed. * - * If you set `bumpThisNumberIfACustomStepChanges( )`, then spotless will + * If you set {@code bumpThisNumberIfACustomStepChanges( )}, then spotless will * assume that the custom rules have not changed if the number has not changed. If a * custom rule does change, then you must bump the number so that spotless will know * that it must recheck the files it has already checked. @@ -408,7 +396,7 @@ public void indentWithTabs() { /** * Created by {@link FormatExtension#licenseHeader(String, String)} or {@link FormatExtension#licenseHeaderFile(Object, String)}. - * For most language-specific formats (e.g. java, scala, etc.) you can omit the second `delimiter` argument, because it is supplied + * For most language-specific formats (e.g. java, scala, etc.) you can omit the second {@code delimiter} argument, because it is supplied * automatically ({@link HasBuiltinDelimiterForLicense}). */ public class LicenseHeaderConfig { @@ -441,7 +429,7 @@ public LicenseHeaderConfig yearSeparator(String yearSeparator) { /** * @param updateYearWithLatest - * Will turn `2004` into `2004-2020`, and `2004-2019` into `2004-2020` + * Will turn {@code 2004} into {@code 2004-2020}, and {@code 2004-2019} into {@code 2004-2020} * Default value is false, unless {@link SpotlessExtensionImpl#ratchetFrom(String)} is used, in which case default value is true. */ public LicenseHeaderConfig updateYearWithLatest(boolean updateYearWithLatest) { @@ -494,6 +482,9 @@ public abstract class NpmStepConfig> { @Nullable protected Object npmFile; + @Nullable + protected Object npmrcFile; + @SuppressWarnings("unchecked") public T npmExecutable(final Object npmFile) { this.npmFile = npmFile; @@ -501,7 +492,21 @@ public T npmExecutable(final Object npmFile) { return (T) this; } + public T npmrc(final Object npmrcFile) { + this.npmrcFile = npmrcFile; + replaceStep(createStep()); + return (T) this; + } + File npmFileOrNull() { + return fileOrNull(npmFile); + } + + File npmrcFileOrNull() { + return fileOrNull(npmrcFile); + } + + private File fileOrNull(Object npmFile) { return npmFile != null ? getProject().file(npmFile) : null; } @@ -541,7 +546,7 @@ FormatterStep createStep() { devDependencies, provisioner(), project.getBuildDir(), - npmFileOrNull(), + new NpmPathResolver(npmFileOrNull(), npmrcFileOrNull(), project.getProjectDir(), project.getRootDir()), new com.diffplug.spotless.npm.PrettierConfig( this.prettierConfigFile != null ? project.file(this.prettierConfigFile) : null, this.prettierConfig)); @@ -627,7 +632,7 @@ public EclipseWtpConfig eclipseWtp(EclipseWtpFormatterStep type, String version) } /** - * ```gradle + *
       	 * spotless {
       	 *   format 'examples', {
       	 *     target '*.md'
      @@ -635,7 +640,7 @@ public EclipseWtpConfig eclipseWtp(EclipseWtpFormatterStep type, String version)
       	 *       prettier().config(['parser': 'javascript'])
       	 *     }
       	 *     ...
      -	 * ```
      +	 * 
      */ public void withinBlocks(String name, String open, String close, Action configure) { withinBlocks(name, open, close, FormatExtension.class, configure); @@ -645,7 +650,7 @@ public void withinBlocks(String name, String open, String close, Action * spotless { * format 'examples', { * target '*.md' @@ -653,7 +658,7 @@ public void withinBlocks(String name, String open, String close, Action */ public void withinBlocks(String name, String open, String close, Class clazz, Action configure) { withinBlocksHelper(PipeStepPair.named(name).openClose(open, close), clazz, configure); @@ -692,7 +697,7 @@ public void toggleOffOn(String off, String on) { this.togglePair = PipeStepPair.named(PipeStepPair.defaultToggleName()).openClose(off, on).buildPair(); } - /** Disables formatting between `spotless:off` and `spotless:on`. */ + /** Disables formatting between {@code spotless:off} and {@code spotless:on}. */ public void toggleOffOn() { toggleOffOn(PipeStepPair.defaultToggleOff(), PipeStepPair.defaultToggleOn()); } @@ -738,12 +743,12 @@ protected Project getProject() { * Creates an independent {@link SpotlessApply} for (very) unusual circumstances. * * Most users will not want this method. In the rare case that you want to create - * a `SpotlessApply` which is independent of the normal Spotless machinery, this will + * a {@code SpotlessApply} which is independent of the normal Spotless machinery, this will * let you do that. * - * The returned task will not be hooked up to the global `spotlessApply`, and there will be no corresponding `check` task. + * The returned task will not be hooked up to the global {@code spotlessApply}, and there will be no corresponding {@code check} task. * - * NOTE: does not respect the rarely-used [`spotlessFiles` property](https://github.com/diffplug/spotless/blob/b7f8c551a97dcb92cc4b0ee665448da5013b30a3/plugin-gradle/README.md#can-i-apply-spotless-to-specific-files). + * NOTE: does not respect the rarely-used {@code spotlessFiles} property. */ public SpotlessApply createIndependentApplyTask(String taskName) { // create and setup the task diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java index afcc81c092..a638d50f87 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Dependency; import com.diffplug.common.base.Preconditions; import com.diffplug.common.collect.ImmutableList; @@ -64,11 +63,11 @@ static Provisioner fromRootBuildscript(Project project) { Objects.requireNonNull(project); return (withTransitives, mavenCoords) -> { try { - Dependency[] deps = mavenCoords.stream() + Configuration config = project.getRootProject().getBuildscript().getConfigurations().create("spotless" + + new Request(withTransitives, mavenCoords).hashCode()); + mavenCoords.stream() .map(project.getBuildscript().getDependencies()::create) - .toArray(Dependency[]::new); - - Configuration config = project.getRootProject().getBuildscript().getConfigurations().detachedConfiguration(deps); + .forEach(config.getDependencies()::add); config.setDescription(mavenCoords.toString()); config.setTransitive(withTransitives); return config.resolve(); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java index db9080f9c3..7924435b13 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,15 +71,15 @@ public void removeUnusedImports() { addStep(RemoveUnusedImportsStep.create(provisioner())); } - /** Uses the [google-java-format](https://github.com/google/google-java-format) jar to format source code. */ + /** Uses the google-java-format jar to format source code. */ public GoogleJavaFormatConfig googleJavaFormat() { return googleJavaFormat(GoogleJavaFormatStep.defaultVersion()); } /** - * Uses the given version of [google-java-format](https://github.com/google/google-java-format) to format source code. + * Uses the given version of google-java-format to format source code. * - * Limited to published versions. See [issue #33](https://github.com/diffplug/spotless/issues/33#issuecomment-252315095) + * Limited to published versions. See issue #33 * for an workaround for using snapshot versions. */ public GoogleJavaFormatConfig googleJavaFormat(String version) { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JsonExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JsonExtension.java new file mode 100644 index 0000000000..e15d395f3b --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JsonExtension.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016-2021 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 javax.inject.Inject; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.json.JsonSimpleStep; + +public class JsonExtension extends FormatExtension { + private static final int DEFAULT_INDENTATION = 4; + static final String NAME = "json"; + + @Inject + public JsonExtension(SpotlessExtension spotless) { + super(spotless); + } + + @Override + protected void setupTask(SpotlessTask task) { + if (target == null) { + throw noDefaultTargetException(); + } + super.setupTask(task); + } + + public SimpleConfig simple() { + return new SimpleConfig(DEFAULT_INDENTATION); + } + + public class SimpleConfig { + private int indent; + + public SimpleConfig(int indent) { + this.indent = indent; + addStep(createStep()); + } + + public void indentWithSpaces(int indent) { + this.indent = indent; + replaceStep(createStep()); + } + + private FormatterStep createStep() { + return JsonSimpleStep.create(indent, provisioner()); + } + } + +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java index e58129f5ac..d88b4aac7f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import static com.diffplug.spotless.kotlin.KotlinConstants.LICENSE_HEADER_DELIMITER; +import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.Objects; @@ -28,7 +29,9 @@ import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; +import com.diffplug.spotless.FileSignature; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.kotlin.DiktatStep; import com.diffplug.spotless.kotlin.KtLintStep; import com.diffplug.spotless.kotlin.KtfmtStep; import com.diffplug.spotless.kotlin.KtfmtStep.Style; @@ -51,7 +54,7 @@ public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) { return licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER); } - /** Adds the specified version of [ktlint](https://github.com/pinterest/ktlint). */ + /** Adds the specified version of ktlint. */ public KotlinFormatExtension ktlint(String version) { Objects.requireNonNull(version); return new KotlinFormatExtension(version, Collections.emptyMap()); @@ -84,13 +87,13 @@ private FormatterStep createStep() { } } - /** Uses the [ktfmt](https://github.com/facebookincubator/ktfmt) jar to format source code. */ + /** Uses the ktfmt jar to format source code. */ public KtfmtConfig ktfmt() { return ktfmt(KtfmtStep.defaultVersion()); } /** - * Uses the given version of [ktfmt](https://github.com/facebookincubator/ktfmt) and applies the dropbox style + * Uses the given version of ktfmt and applies the dropbox style * option to format source code. */ public KtfmtConfig ktfmt(String version) { @@ -109,7 +112,19 @@ public class KtfmtConfig { } public void dropboxStyle() { - style = Style.DROPBOX; + style(Style.DROPBOX); + } + + public void googleStyle() { + style(Style.GOOGLE); + } + + public void kotlinlangStyle() { + style(Style.KOTLINLANG); + } + + public void style(Style style) { + this.style = style; replaceStep(createStep()); } @@ -118,6 +133,42 @@ private FormatterStep createStep() { } } + /** Adds the specified version of diktat. */ + public DiktatFormatExtension diktat(String version) { + Objects.requireNonNull(version); + return new DiktatFormatExtension(version); + } + + public DiktatFormatExtension diktat() { + return diktat(DiktatStep.defaultVersionDiktat()); + } + + public class DiktatFormatExtension { + + private final String version; + private FileSignature config; + + DiktatFormatExtension(String version) { + this.version = version; + addStep(createStep()); + } + + public DiktatFormatExtension configFile(Object file) throws IOException { + // Specify the path to the configuration file + if (file == null) { + this.config = null; + } else { + this.config = FileSignature.signAsList(getProject().file(file)); + } + replaceStep(createStep()); + return this; + } + + private FormatterStep createStep() { + return DiktatStep.create(version, provisioner(), config); + } + } + /** If the user hasn't specified the files yet, we'll assume he/she means all of the kotlin files. */ @Override protected void setupTask(SpotlessTask task) { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java index fdc2f25be8..5ea3c29594 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/KotlinGradleExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.diffplug.gradle.spotless; +import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.Objects; @@ -22,7 +23,9 @@ import javax.inject.Inject; import com.diffplug.common.collect.ImmutableSortedMap; +import com.diffplug.spotless.FileSignature; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.kotlin.DiktatStep; import com.diffplug.spotless.kotlin.KtLintStep; import com.diffplug.spotless.kotlin.KtfmtStep; import com.diffplug.spotless.kotlin.KtfmtStep.Style; @@ -37,7 +40,7 @@ public KotlinGradleExtension(SpotlessExtension spotless) { super(spotless); } - /** Adds the specified version of [ktlint](https://github.com/pinterest/ktlint). */ + /** Adds the specified version of ktlint. */ public KotlinFormatExtension ktlint(String version) { Objects.requireNonNull(version, "version"); return new KotlinFormatExtension(version, Collections.emptyMap()); @@ -70,13 +73,13 @@ private FormatterStep createStep() { } } - /** Uses the [ktfmt](https://github.com/facebookincubator/ktfmt) jar to format source code. */ + /** Uses the ktfmt jar to format source code. */ public KtfmtConfig ktfmt() { return ktfmt(KtfmtStep.defaultVersion()); } /** - * Uses the given version of [ktfmt](https://github.com/facebookincubator/ktfmt) to format source + * Uses the given version of ktfmt to format source * code. */ public KtfmtConfig ktfmt(String version) { @@ -94,16 +97,64 @@ public class KtfmtConfig { addStep(createStep()); } - public void dropboxStyle() { - style = Style.DROPBOX; + public void style(Style style) { + this.style = style; replaceStep(createStep()); } + public void dropboxStyle() { + style(Style.DROPBOX); + } + + public void googleStyle() { + style(Style.GOOGLE); + } + + public void kotlinlangStyle() { + style(Style.KOTLINLANG); + } + private FormatterStep createStep() { return KtfmtStep.create(version, provisioner(), style); } } + /** Adds the specified version of diktat. */ + public DiktatFormatExtension diktat(String version) { + Objects.requireNonNull(version, "version"); + return new DiktatFormatExtension(version); + } + + public DiktatFormatExtension diktat() { + return diktat(DiktatStep.defaultVersionDiktat()); + } + + public class DiktatFormatExtension { + + private final String version; + private FileSignature config; + + DiktatFormatExtension(String version) { + this.version = version; + addStep(createStep()); + } + + public DiktatFormatExtension configFile(Object file) throws IOException { + // Specify the path to the configuration file + if (file == null) { + this.config = null; + } else { + this.config = FileSignature.signAsList(getProject().file(file)); + } + replaceStep(createStep()); + return this; + } + + private FormatterStep createStep() { + return DiktatStep.createForScript(version, provisioner(), config); + } + } + @Override protected void setupTask(SpotlessTask task) { if (target == null) { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java index ff23eb6ab4..cc8ea5ed20 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java @@ -20,6 +20,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; import org.gradle.api.DefaultTask; import org.gradle.api.execution.TaskExecutionGraph; @@ -49,11 +51,10 @@ public class RegisterDependenciesTask extends DefaultTask { public List getSteps() { List allSteps = new ArrayList<>(); TaskExecutionGraph taskGraph = getProject().getGradle().getTaskGraph(); - for (SpotlessTask task : tasks) { - if (taskGraph.hasTask(task)) { - allSteps.addAll(task.getSteps()); - } - } + tasks.stream() + .filter(taskGraph::hasTask) + .sorted() + .forEach(task -> allSteps.addAll(task.getSteps())); return allSteps; } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java index a815d5c33c..f96f2b1131 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,7 @@ import org.gradle.api.file.ConfigurableFileTree; import org.gradle.api.file.FileVisitDetails; import org.gradle.api.file.FileVisitor; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.TaskAction; public class SpotlessApply extends DefaultTask { @@ -40,8 +38,7 @@ void linkSource(SpotlessTask source) { private File spotlessOutDirectory; - @PathSensitive(PathSensitivity.RELATIVE) - @InputDirectory + @Internal public File getSpotlessOutDirectory() { return spotlessOutDirectory; } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessCheck.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessCheck.java index 0be634f603..3fb3e0e8c3 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessCheck.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessCheck.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,7 @@ import org.gradle.api.file.ConfigurableFileTree; import org.gradle.api.file.FileVisitDetails; import org.gradle.api.file.FileVisitor; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.TaskAction; import com.diffplug.spotless.FileSignature; @@ -43,8 +41,7 @@ public class SpotlessCheck extends DefaultTask { SpotlessTask source; private File spotlessOutDirectory; - @PathSensitive(PathSensitivity.RELATIVE) - @InputDirectory + @Internal public File getSpotlessOutDirectory() { return spotlessOutDirectory; } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index 1f55efc1ee..7959bdc71d 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,7 +86,7 @@ public void encoding(String charset) { /** * Limits the target to only the files which have changed since the given git reference, - * which is resolved according to [this](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-) + * which is resolved according to this */ public void setRatchetFrom(String ratchetFrom) { this.ratchetFrom = ratchetFrom; @@ -169,6 +169,12 @@ public void python(Action closure) { format(PythonExtension.NAME, PythonExtension.class, closure); } + /** Configures the special JSON-specific extension. */ + public void json(Action closure) { + requireNonNull(closure); + format(JsonExtension.NAME, JsonExtension.class, closure); + } + /** Configures a custom extension. */ public void format(String name, Action closure) { requireNonNull(name, "name"); @@ -187,16 +193,16 @@ public void removeFormat(String name) { boolean enforceCheck = true; - /** Returns `true` if Gradle's `check` task should run `spotlessCheck`; `false` otherwise. */ + /** Returns {@code true} if Gradle's {@code check} task should run {@code spotlessCheck}; {@code false} otherwise. */ public boolean isEnforceCheck() { return enforceCheck; } /** - * Configures Gradle's `check` task to run `spotlessCheck` if `true`, - * but to not do so if `false`. + * Configures Gradle's {@code check} task to run {@code spotlessCheck} if {@code true}, + * but to not do so if {@code false}. * - * `true` by default. + * {@code true} by default. */ public void setEnforceCheck(boolean enforceCheck) { this.enforceCheck = enforceCheck; diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java index e66586d10d..85a5993f5f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,23 +35,20 @@ public void apply(Project project) { if (project.hasProperty(SPOTLESS_MODERN)) { project.getLogger().warn("'spotlessModern' has no effect as of Spotless 5.0, recommend removing it."); } - // make sure there's a `clean` task + // make sure there's a {@code clean} task project.getPlugins().apply(BasePlugin.class); // setup the extension project.getExtensions().create(SpotlessExtension.class, SpotlessExtension.EXTENSION, SpotlessExtensionImpl.class, project); // clear spotless' cache when the user does a clean - project.getTasks().named(BasePlugin.CLEAN_TASK_NAME).configure(clean -> { - clean.doLast(unused -> { - // resolution for: https://github.com/diffplug/spotless/issues/243#issuecomment-564323856 - // project.getRootProject() is consistent across every project, so only of one the clears will - // actually happen (as desired) - // - // we use System.identityHashCode() to avoid a memory leak by hanging on to the reference directly - SpotlessCache.clearOnce(System.identityHashCode(project.getRootProject())); - }); - }); + // resolution for: https://github.com/diffplug/spotless/issues/243#issuecomment-564323856 + // project.getRootProject() is consistent across every project, so only of one the clears will + // actually happen (as desired) + // + // we use System.identityHashCode() to avoid a memory leak by hanging on to the reference directly + int cacheKey = System.identityHashCode(project.getRootProject()); + project.getTasks().named(BasePlugin.CLEAN_TASK_NAME).configure(clean -> clean.doLast(unused -> SpotlessCache.clearOnce(cacheKey))); } static String capitalize(String input) { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java index 23c0679558..b5351c701b 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,7 @@ private void processInputFile(Formatter formatter, File input) throws IOExceptio // Remove previous output if it exists Files.deleteIfExists(output.toPath()); } else if (dirtyState.didNotConverge()) { - getLogger().warn("Skipping '" + input + "' because it does not converge. Run `spotlessDiagnose` to understand why"); + getLogger().warn("Skipping '" + input + "' because it does not converge. Run {@code spotlessDiagnose} to understand why"); } else { Path parentDir = output.toPath().getParent(); if (parentDir == null) { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java index 08b2b463e6..58b9d4acbb 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/TypescriptExtension.java @@ -28,6 +28,7 @@ import org.gradle.api.Project; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.npm.NpmPathResolver; import com.diffplug.spotless.npm.PrettierFormatterStep; import com.diffplug.spotless.npm.TsConfigFileType; import com.diffplug.spotless.npm.TsFmtFormatterStep; @@ -109,7 +110,7 @@ public FormatterStep createStep() { devDependencies, provisioner(), project.getBuildDir(), - npmFileOrNull(), + new NpmPathResolver(npmFileOrNull(), npmrcFileOrNull(), project.getProjectDir(), project.getRootDir()), typedConfigFile(), config); } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JsonExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JsonExtensionTest.java new file mode 100644 index 0000000000..cd8c56ad4c --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JsonExtensionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 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.IOException; + +import org.junit.Test; + +public class JsonExtensionTest extends GradleIntegrationHarness { + @Test + public void defaultFormatting() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'java'", + " id 'com.diffplug.spotless'", + "}", + "spotless {", + " json {", + " target 'examples/**/*.json'", + " simple()", + "}", + "}"); + setFile("src/main/resources/example.json").toResource("json/nestedObjectBefore.json"); + setFile("examples/main/resources/example.json").toResource("json/nestedObjectBefore.json"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/resources/example.json").sameAsResource("json/nestedObjectBefore.json"); + assertFile("examples/main/resources/example.json").sameAsResource("json/nestedObjectAfter.json"); + } + + @Test + public void formattingWithCustomNumberOfSpaces() throws IOException { + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'java'", + " id 'com.diffplug.spotless'", + "}", + "spotless {", + " json {", + " target 'src/**/*.json'", + " simple().indentWithSpaces(6)", + "}", + "}"); + setFile("src/main/resources/example.json").toResource("json/singletonArrayBefore.json"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/resources/example.json").sameAsResource("json/singletonArrayAfter6Spaces.json"); + } +} diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java index e095ff75d5..672486fedb 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinExtensionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,24 @@ public void integration() throws IOException { assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktlint/basic.clean"); } + @Test + public void integrationDiktat() throws IOException { + setFile("build.gradle").toLines( + "plugins {", + " id 'org.jetbrains.kotlin.jvm' version '1.4.30'", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " diktat()", + " }", + "}"); + setFile("src/main/kotlin/com/example/Main.kt").toResource("kotlin/diktat/main.dirty"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/com/example/Main.kt").sameAsResource("kotlin/diktat/main.clean"); + } + @Test public void integrationKtfmt() throws IOException { // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. @@ -66,6 +84,46 @@ public void integrationKtfmt() throws IOException { assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktfmt/basic.clean"); } + @Test + public void integrationKtfmt_dropboxStyle_0_18() throws IOException { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + JreVersion.assume11OrGreater(); + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.3.72'", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " ktfmt('0.18').dropboxStyle()", + " }", + "}"); + setFile("src/main/kotlin/basic.kt").toResource("kotlin/ktfmt/basic.dirty"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktfmt/basic-dropboxstyle.clean"); + } + + @Test + public void integrationKtfmt_dropboxStyle_0_19() throws IOException { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + JreVersion.assume11OrGreater(); + setFile("build.gradle").toLines( + "plugins {", + " id 'nebula.kotlin' version '1.3.72'", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlin {", + " ktfmt('0.19').dropboxStyle()", + " }", + "}"); + setFile("src/main/kotlin/basic.kt").toResource("kotlin/ktfmt/basic.dirty"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("src/main/kotlin/basic.kt").sameAsResource("kotlin/ktfmt/basic-dropboxstyle.clean"); + } + @Test public void testWithIndentation() throws IOException { setFile("build.gradle").toLines( diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinGradleExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinGradleExtensionTest.java index d71e4d2773..71e083767c 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinGradleExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/KotlinGradleExtensionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,6 +75,25 @@ public void integration_default() throws IOException { assertFile("configuration.gradle.kts").sameAsResource("kotlin/ktlint/basic.clean"); } + @Test + public void integration_default_diktat() throws IOException { + setFile("build.gradle").toLines( + "plugins {", + " id 'org.jetbrains.kotlin.jvm' version '1.4.30'", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " kotlinGradle {", + " diktat()", + " }", + "}"); + setFile("configuration.gradle.kts").toResource("kotlin/diktat/basic.dirty"); + BuildResult result = gradleRunner().withArguments("spotlessApply").buildAndFail(); + assertThat(result.getOutput()).contains("[HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE] files that contain multiple " + + "or no classes should contain description of what is inside of this file: there are 0 declared classes and/or objects"); + } + @Test public void integration_pinterest() throws IOException { setFile("build.gradle").toLines( @@ -107,8 +126,7 @@ public void indentStep() throws IOException { " }", "}"); setFile("configuration.gradle.kts").toResource("kotlin/ktlint/basic.dirty"); - BuildResult result = gradleRunner().withArguments("spotlessApply").buildAndFail(); - assertThat(result.getOutput()).contains("Unexpected indentation (4) (it should be 6)"); + gradleRunner().withArguments("spotlessCheck").buildAndFail(); } @Test diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultipleTargetsTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultipleTargetsTest.java new file mode 100644 index 0000000000..360a20ac19 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultipleTargetsTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016-2021 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.IOException; +import java.util.List; + +import org.gradle.testkit.runner.BuildResult; +import org.junit.Test; + +import com.diffplug.common.collect.Lists; + +public class MultipleTargetsTest extends GradleIntegrationHarness { + private static final List TARGET_FILES = Lists.newArrayList("src/test.md", "src/test.1.txt", "src/test.2.txt"); + private static final List NON_TARGET_FILES = Lists.newArrayList(".git/test.1.txt", ".gradle/test.1.txt", "build/test.1.txt"); + + @Test + public void testSingleRecursiveTargetMatchingSuffix() throws IOException { + runTest("target '**/*.txt'"); + } + + @Test + public void testSingleRecursiveTargetMatchingPrefix() throws IOException { + runTest("target '**/test.*'"); + } + + @Test + public void testSingleRecursiveTargetMatchingSubdirectory() throws IOException { + runTest("target 'src/**/*.txt'"); + } + + @Test + public void testExplicitTargets() throws IOException { + runTest("target('src/test.1.txt', 'src/test.2.txt')"); + } + + @Test + public void testNonRecursiveTargets() throws IOException { + runTest("target('src/*.1.txt', 'src/*.2.txt')"); + } + + @Test + public void testTwoRecursiveTargetsMatchingDifferentFiles() throws IOException { + runTest("target('**/*.1.txt', '**/*.2.txt')"); + } + + @Test + public void testTwoRecursiveTargetsMatchingIdenticalFiles() throws IOException { + runTest("target('**/*.txt', '**/test.*')"); + } + + @Test + public void testTwoRecursiveTargetsProvidedAsList() throws IOException { + runTest("target(['**/*.1.txt', '**/*.2.txt'])"); + } + + private void runTest(String targets) throws IOException { + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "spotless {", + " format 'singleFile', {", + " target 'src/test.md'", + " custom 'lowercase', { it.toLowerCase(Locale.ROOT) }", + " bumpThisNumberIfACustomStepChanges(1)", + " }", + " format 'multipleFiles', {", + " " + targets, + " custom 'lowercase', { it.toLowerCase(Locale.ROOT) }", + " bumpThisNumberIfACustomStepChanges(1)", + " }", + "}"); + + initContent(TARGET_FILES, "A"); + initContent(NON_TARGET_FILES, "A"); + + BuildResult result = gradleRunner().withArguments("spotlessApply").build(); + + checkContent(TARGET_FILES, "a"); + checkContent(NON_TARGET_FILES, "A"); + } + + private void initContent(List files, String content) throws IOException { + for (String file : files) { + setFile(file).toContent(content); + } + } + + private void checkContent(List files, String content) throws IOException { + for (String file : files) { + assertFile(file).hasContent(content); + } + } +} diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java index 1e1b00c6b0..4025cf5288 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/PrettierIntegrationTest.java @@ -160,4 +160,50 @@ public void usePhpCommunityPlugin() throws IOException { Assertions.assertThat(spotlessApply.getOutput()).contains("BUILD SUCCESSFUL"); assertFile("php-example.php").sameAsResource("npm/prettier/plugins/php.clean"); } + + @Test + public void autodetectNpmrcFileConfig() throws IOException { + setFile(".npmrc").toLines( + "registry=https://i.do.no.exist.com"); + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "def prettierConfig = [:]", + "prettierConfig['printWidth'] = 50", + "prettierConfig['parser'] = 'typescript'", + "spotless {", + " format 'mytypescript', {", + " target 'test.ts'", + " prettier().config(prettierConfig)", + " }", + "}"); + setFile("test.ts").toResource("npm/prettier/config/typescript.dirty"); + final BuildResult spotlessApply = gradleRunner().withArguments("--stacktrace", "spotlessApply").buildAndFail(); + Assertions.assertThat(spotlessApply.getOutput()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } + + @Test + public void pickupNpmrcFileConfig() throws IOException { + setFile(".custom_npmrc").toLines( + "registry=https://i.do.no.exist.com"); + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "def prettierConfig = [:]", + "prettierConfig['printWidth'] = 50", + "prettierConfig['parser'] = 'typescript'", + "spotless {", + " format 'mytypescript', {", + " target 'test.ts'", + " prettier().npmrc('.custom_npmrc').config(prettierConfig)", + " }", + "}"); + setFile("test.ts").toResource("npm/prettier/config/typescript.dirty"); + final BuildResult spotlessApply = gradleRunner().withArguments("--stacktrace", "spotlessApply").buildAndFail(); + Assertions.assertThat(spotlessApply.getOutput()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ScalaExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ScalaExtensionTest.java index aa3bf7e926..865c660712 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ScalaExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ScalaExtensionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,6 @@ public void integration() throws IOException { setFile("scalafmt.conf").toResource("scala/scalafmt/scalafmt.conf"); setFile("src/main/scala/basic.scala").toResource("scala/scalafmt/basic.dirty"); gradleRunner().withArguments("spotlessApply").build(); - assertFile("src/main/scala/basic.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_2.0.1"); + assertFile("src/main/scala/basic.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_3.0.0"); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java index d6cf9c44a9..ae0986f996 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/SelfTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ private static Project createProject(Consumer test) throw return project; } - /** Runs against the `spotlessSelfApply.gradle` file. */ + /** Runs against the {@code spotlessSelfApply.gradle} file. */ static void runWithTestKit(String taskType) throws Exception { GradleRunner.create() .withPluginClasspath() diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 782a1e8705..65dacd15ce 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -4,6 +4,117 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +## [2.12.3] - 2021-08-20 +### Changed +* Added support for [scalafmt 3.0.0](https://github.com/scalameta/scalafmt/releases/tag/v3.0.0) and bump default scalafmt version to `3.0.0` ([#913](https://github.com/diffplug/spotless/pull/913)). +* Bump default versions ([#915](https://github.com/diffplug/spotless/pull/915)) + * `ktfmt` from `0.24` to `0.27` + * `ktlint` from `0.35.0` to `0.42.1` + * `google-java-format` from `1.10.0` to `1.11.0` + +## [2.12.2] - 2021-07-20 +### Fixed + * Improved [SQL formatting](https://github.com/diffplug/spotless/pull/897) with respect to comments + +## [2.12.1] - 2021-06-17 + +### Fixed +* Fixed IndexOutOfBoundsException in parallel execution of `eclipse-groovy` formatter ([#877](https://github.com/diffplug/spotless/issues/877)) + +## [2.12.0] - 2021-06-10 +### Added +* Added support for `eclipse-cdt` at `4.19.0`. Note that version requires Java 11 or higher. +* Added support for `eclipse-groovy` at `4.18.0` and `4.19.0`. +* Added support for `eclipse-wtp` at `4.19.0`. Note that version requires Java 11 or higher. +### Changed +* Bump `eclipse-groovy` default version from `4.17.0` to `4.19.0`. + +## [2.11.1] - 2021-05-13 +### Fixed +* Node is re-installed if some other build step removed it ([#863](https://github.com/diffplug/spotless/issues/863)) + +## [2.11.0] - 2021-05-03 +### Added +* Added support for [python](README.md#python), specifically [black](README.md#black). +### Changed +* Update ktfmt from 0.21 to 0.24 +### Fixed +* The `` field in the maven POM is now set correctly ([#798](https://github.com/diffplug/spotless/issues/798)) + +## [2.10.3] - 2021-04-21 +### Fixed +* Explicitly separate target file from git arguments when parsing year for license header to prevent command from failing on argument-like paths ([#847](https://github.com/diffplug/spotless/pull/847)) + +## [2.10.2] - 2021-04-20 +### Fixed +* LicenseHeaderStep treats address as copyright year ([#716](https://github.com/diffplug/spotless/issues/716)) + +## [2.10.1] - 2021-04-13 +### Fixed +* Fix license header bug for years in range ([#840](https://github.com/diffplug/spotless/pull/840)). + +## [2.10.0] - 2021-04-10 +### Added +* Added support for `eclipse-jdt` at `4.19.0`. +### Changed +* Bump `eclipse-jdt` default version from `4.18.0` to `4.19.0`. +* Bump `google-java-format` default version from `1.9` to `1.10.0`. +* Expose configuration exceptions from scalafmt ([#837](https://github.com/diffplug/spotless/issues/837)) + +## [2.9.0] - 2021-03-05 +### Added +* Bump ktfmt to 0.21 and add support to Google and Kotlinlang formats ([#812](https://github.com/diffplug/spotless/pull/812)) + +## [2.8.1] - 2021-02-16 +### Fixed +* Allow licence headers to be blank ([#801](https://github.com/diffplug/spotless/pull/801)). + +## [2.8.0] - 2021-02-09 +### Added +* Support for diktat ([#789](https://github.com/diffplug/spotless/pull/789)) + +## [2.7.0] - 2021-01-04 +### Added +* Added ability to specify dropbox style for ktfmt `` ([#764](https://github.com/diffplug/spotless/pull/764)) +* Added support for `eclipse-cdt`, `eclipse-jdt`, and `eclipse-wtp` at `4.18.0`. +### Changed +* Bump `eclipse-jdt` default version from `4.17.0` to `4.18.0`. +* Bump `eclipse-wtp` default version from `4.17.0` to `4.18.0`. +* Bump `ktfmt` default version from `0.16` to `0.19` ([#748](https://github.com/diffplug/spotless/issues/748) and [#773](https://github.com/diffplug/spotless/issues/773)). +### Fixed +* Fixed `ratchetFrom` support for git-submodule ([#746](https://github.com/diffplug/spotless/issues/746)). +* Fixed `ratchetFrom` excess memory consumption ([#735](https://github.com/diffplug/spotless/issues/735)). +* `ktfmt` v0.19+ with dropbox-style works again ([#765](https://github.com/diffplug/spotless/pull/765)). +* `prettier` no longer throws errors on empty files ([#751](https://github.com/diffplug/spotless/pull/751)). +* Fixed error when running on root of windows mountpoint ([#760](https://github.com/diffplug/spotless/pull/760)). +* Fix broken test for spotlessFiles parameter on windows ([#737](https://github.com/diffplug/spotless/pull/737)). + +## [2.6.1] - 2020-11-16 +### Fixed +* Fixed a bug which occurred if the root directory of the project was also the filesystem root ([#732](https://github.com/diffplug/spotless/pull/732)). +* Upgraded org.codehaus.plexus:plexus-utils to its latest version (3.3.0) to improve directory scanning time ([#729](https://github.com/diffplug/spotless/pull/729)). + * Whether this helps with the directory scanning time is unconfirmed, please report your experience in the issue above. + +## [2.6.0] - 2020-11-13 +### Added +* Added support to npm-based steps for picking up `.npmrc` files ([#727](https://github.com/diffplug/spotless/pull/727)) +### Fixed +* Fixed bug in import order which woudld cause trailing empty strings to get dropped ([731](https://github.com/diffplug/spotless/issues/731)) + * e.g. `java,javafx,com.mycompany,` +* Bump JGit from `5.8.0` to `5.9.0` to improve performance ([#726](https://github.com/diffplug/spotless/issues/726)) + +## [2.5.0] - 2020-10-20 +### Added +* Added support for eclipse-cdt 4.14.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-groovy 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-jdt 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Added support for eclipse-wtp 4.14.0, 4.15.0, 4.16.0 and 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +### Changed +* Updated default eclipse-cdt from 4.13.0 to 4.16.0 ([#722](https://github.com/diffplug/spotless/pull/722)). Note that version 4.17.0 is supported, but requires Java 11 or higher. +* Updated default eclipse-groovy from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-jdt from 4.16.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). +* Updated default eclipse-wtp from 4.13.0 to 4.17.0 ([#722](https://github.com/diffplug/spotless/pull/722)). + ## [2.4.2] - 2020-10-05 ### Fixed * Improve speed by ~4x when using `` ([#701](https://github.com/diffplug/spotless/pull/706)). @@ -56,7 +167,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [2.0.0] - 2020-07-02 ### Added -* You can now ratchet a project's style by limiting Spotless only to files which have changed since a given [git reference](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), e.g. `ratchetFrom 'origin/main'`. ([#590](https://github.com/diffplug/spotless/pull/590)) +* You can now ratchet a project's style by limiting Spotless only to files which have changed since a given [git reference](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), e.g. `ratchetFrom 'origin/main'`. ([#590](https://github.com/diffplug/spotless/pull/590)) * Huge speed improvement for multi-module projects thanks to improved cross-project classloader caching ([#571](https://github.com/diffplug/spotless/pull/571), fixes [#559](https://github.com/diffplug/spotless/issues/559)). * If you specify `-DspotlessSetLicenseHeaderYearsFromGitHistory=true`, Spotless will perform an expensive search through git history to determine the oldest and newest commits for each file, and uses that to determine license header years. ([#626](https://github.com/diffplug/spotless/pull/626)) * `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config` or `configFile` with the option `parser` or `filepath` ([#620](https://github.com/diffplug/spotless/pull/620)). diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 29447bd11e..fe854ce072 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -12,8 +12,8 @@ output = [ ].join('\n'); --> [![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.spotless%3Aspotless--maven--plugin-blue.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22) -[![Javadoc](https://img.shields.io/badge/javadoc-yes-blue.svg)](https://javadoc.io/doc/com.diffplug.spotless/spotless-maven-plugin/2.4.2/index.html) -[![Changelog](https://img.shields.io/badge/changelog-2.4.2-brightgreen.svg)](CHANGES.md) +[![Javadoc](https://img.shields.io/badge/javadoc-yes-blue.svg)](https://javadoc.io/doc/com.diffplug.spotless/spotless-maven-plugin/2.12.3/index.html) +[![Changelog](https://img.shields.io/badge/changelog-2.12.3-brightgreen.svg)](CHANGES.md) [![Circle CI](https://circleci.com/gh/diffplug/spotless/tree/main.svg?style=shield)](https://circleci.com/gh/diffplug/spotless/tree/main) [![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/spotless) @@ -45,17 +45,19 @@ user@machine repo % mvn spotless:check - [**Quickstart**](#quickstart) - [Requirements](#requirements) + - [Binding to maven phase](#binding-to-maven-phase) - **Languages** - [Java](#java) ([google-java-format](#google-java-format), [eclipse jdt](#eclipse-jdt), [prettier](#prettier)) - [Groovy](#groovy) ([eclipse groovy](#eclipse-groovy)) - - [Kotlin](#kotlin) ([ktlint](#ktlint), [ktfmt](#ktfmt), [prettier](#prettier)) + - [Kotlin](#kotlin) ([ktfmt](#ktfmt), [ktlint](#ktlint), [diktat](#diktat), [prettier](#prettier)) - [Scala](#scala) ([scalafmt](#scalafmt)) - [C/C++](#cc) ([eclipse cdt](#eclipse-cdt)) + - [Python](#python) ([black](#black)) - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter)) - [Sql](#sql) ([dbeaver](#dbeaver)) - [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier)) - Multiple languages - - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection)) + - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection)) - [eclipse web tools platform](#eclipse-web-tools-platform) - **Language independent** - [Generic steps](#generic-steps) @@ -131,6 +133,35 @@ Spotless requires Maven to be running on JRE 8+. +### Binding to maven phase + +By default, spotless:check is bound to verify maven phase. This means it is not required to +explicitly bind the plugin execution, and the following will suffice; + +```xml + + + + check + + + +``` + +with this `mvn verify` will run `spotless:check`. If you require the check goal to be run with +any other maven phase (i.e. compile) then it can be configured as below; + +```xml + + + + check + + compile + + +``` + ## Java [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/java). @@ -245,8 +276,9 @@ Groovy-Eclipse formatting errors/warnings lead per default to a build failure. T src/test/kotlin/**/*.kt - + + @@ -256,6 +288,17 @@ Groovy-Eclipse formatting errors/warnings lead per default to a build failure. T ``` +### ktfmt + +[homepage](https://github.com/facebookincubator/ktfmt). [changelog](https://github.com/facebookincubator/ktfmt/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java). + +```xml + + 0.18 + + +``` + ### ktlint @@ -268,16 +311,15 @@ Groovy-Eclipse formatting errors/warnings lead per default to a build failure. T ``` - +### diktat -### ktfmt - -[homepage](https://github.com/facebookincubator/ktfmt). [changelog](https://github.com/facebookincubator/ktfmt/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java). +[homepage](https://github.com/cqfn/diKTat). [changelog](https://github.com/cqfn/diKTat/releases). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Diktat.java). You can provide configuration path manually as `configFile`. ```xml - - 0.13 - + + 0.4.0 + full/path/to/diktat-analysis.yml + ``` @@ -356,6 +398,42 @@ Groovy-Eclipse formatting errors/warnings lead per default to a build failure. T ``` +## Python + +[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Python.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Black.java). + +```xml + + + + + src/main/**/*.py + + + + + +``` + +### black + +[homepage](https://github.com/psf/black). [changelog](https://github.com/psf/black/blob/master/CHANGES.md). + +```xml + + 19.10b0 + + C:/myuser/.pyenv/versions/3.8.0/scripts/black.exe + + +``` + ## Antlr4 [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/antlr4/Antlr4.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/antlr4). @@ -481,14 +559,7 @@ The auto-discovery of config files (up the file tree) will not work when using t **Prerequisite: tsfmt requires a working NodeJS version** -tsfmt is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless. -Spotless will try to auto-discover an npm installation. If that is not working for you, it is possible to directly configure the npm binary to use. - -```xml - - /usr/bin/npm - -``` +For details, see the [npm detection](#npm-detection) and [`.npmrc` detection](#npmrc-detection) sections of prettier, which apply also to tsfmt. @@ -614,6 +685,16 @@ Spotless will try to auto-discover an npm installation. If that is not working f /usr/bin/npm ``` +### `.npmrc` detection + +Spotless picks up npm configuration stored in a `.npmrc` file either in the project directory or in your user home. +Alternatively you can supply spotless with a location of the `.npmrc` file to use. (This can be combined with `npmExecutable`, of course.) + +```xml + + /usr/local/shared/.npmrc +``` + ## Eclipse web tools platform @@ -635,7 +716,7 @@ Spotless will try to auto-discover an npm installation. If that is not working f ${basedir}/xml.prefs ${basedir}/additional.properties - 4.7.3a + 4.13.0 @@ -736,7 +817,7 @@ If your project is not currently enforcing formatting, then it can be a noisy tr ``` -In this mode, Spotless will apply only to files which have changed since `origin/main`. You can ratchet from [any point you want](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`. You can also set `ratchetFrom` per-format if you prefer (e.g. `...`). +In this mode, Spotless will apply only to files which have changed since `origin/main`. You can ratchet from [any point you want](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`. You can also set `ratchetFrom` per-format if you prefer (e.g. `...`). However, we strongly recommend that you use a non-local branch, such as a tag or `origin/main`. The problem with `HEAD` or any local branch is that as soon as you commit a file, that is now the canonical formatting, even if it was formatted incorrectly. By instead specifying `origin/main` or a tag, your CI server will fail unless every changed file is at least as good or better than it was before the change. diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 84f7ce366b..cad0bd9382 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -61,7 +61,7 @@ String libVersion = version.endsWith('-SNAPSHOT') ? rootProject.spotlessChangelog.versionNext : rootProject.spotlessChangelog.versionLast dependencies { - if (version.endsWith('-SNAPSHOT')) { + if (version.endsWith('-SNAPSHOT') || (rootProject.spotlessChangelog.versionNext == rootProject.spotlessChangelog.versionLast)) { implementation project(':lib') implementation project(':lib-extra') } else { @@ -70,6 +70,12 @@ dependencies { } implementation "org.codehaus.plexus:plexus-resources:${VER_PLEXUS_RESOURCES}" + constraints { + implementation("org.codehaus.plexus:plexus-utils:3.4.1") { + because("version pulled by plexus-resources has a functional-bug affecting " + + "directory scanning times") + } + } compileOnly "org.apache.maven:maven-plugin-api:${VER_MAVEN_API}" compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:${VER_MAVEN_API}" diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index b7fd05451c..c39fc0a30c 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,7 @@ import com.diffplug.spotless.maven.groovy.Groovy; import com.diffplug.spotless.maven.java.Java; import com.diffplug.spotless.maven.kotlin.Kotlin; +import com.diffplug.spotless.maven.python.Python; import com.diffplug.spotless.maven.scala.Scala; import com.diffplug.spotless.maven.sql.Sql; import com.diffplug.spotless.maven.typescript.Typescript; @@ -122,6 +123,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter private Sql sql; + @Parameter + private Python python; + @Parameter(property = "spotlessFiles") private String filePatterns; @@ -254,7 +258,7 @@ private FileLocator getFileLocator() { } private List getFormatterFactories() { - return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, sql)) + return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, sql, python)) .filter(Objects::nonNull) .collect(toList()); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java index cfd31d9294..85684e85cd 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java @@ -24,6 +24,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.npm.NpmPathResolver; import com.diffplug.spotless.npm.PrettierConfig; import com.diffplug.spotless.npm.PrettierFormatterStep; @@ -49,6 +50,9 @@ public class Prettier implements FormatterStepFactory { @Parameter private String npmExecutable; + @Parameter + private String npmrc; + @Override public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { @@ -68,6 +72,8 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { File npm = npmExecutable != null ? stepConfig.getFileLocator().locateFile(npmExecutable) : null; + File npmrcFile = npmrc != null ? stepConfig.getFileLocator().locateFile(npmrc) : null; + // process config file or inline config File configFileHandler; if (this.configFile != null) { @@ -99,7 +105,8 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { // create the format step PrettierConfig prettierConfig = new PrettierConfig(configFileHandler, configInline); File buildDir = stepConfig.getFileLocator().getBuildDir(); - return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, prettierConfig); + NpmPathResolver npmPathResolver = new NpmPathResolver(npm, npmrcFile, stepConfig.getFileLocator().getBaseDir()); + return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npmPathResolver, prettierConfig); } private boolean moreThanOneNonNull(Object... objects) { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/ImportOrder.java index 6d7a29120b..6c15a8c5c9 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/ImportOrder.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/ImportOrder.java @@ -38,7 +38,7 @@ public FormatterStep newFormatterStep(FormatterStepConfig config) { File importsFile = config.getFileLocator().locateFile(file); return ImportOrderStep.forGroovy().createFrom(importsFile); } else { - return ImportOrderStep.forGroovy().createFrom(order.split(",")); + return ImportOrderStep.forGroovy().createFrom(order.split(",", -1)); } } else if (file == null && order == null) { return ImportOrderStep.forGroovy().createFrom(); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java index 9005760240..9ff62a1ee2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java @@ -38,7 +38,7 @@ public FormatterStep newFormatterStep(FormatterStepConfig config) { File importsFile = config.getFileLocator().locateFile(file); return ImportOrderStep.forJava().createFrom(importsFile); } else { - return ImportOrderStep.forJava().createFrom(order.split(",")); + return ImportOrderStep.forJava().createFrom(order.split(",", -1)); } } else if (file == null && order == null) { return ImportOrderStep.forJava().createFrom(); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Diktat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Diktat.java new file mode 100644 index 0000000000..97cbec07b2 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Diktat.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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.maven.kotlin; + +import java.util.Collections; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FileSignature; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.ThrowingEx; +import com.diffplug.spotless.kotlin.DiktatStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; + +public class Diktat implements FormatterStepFactory { + + @Parameter + private String version; + + @Parameter + private String configFile; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { + FileSignature config = null; + if (configFile != null) { + config = ThrowingEx.get(() -> FileSignature.signAsList(stepConfig.getFileLocator().locateFile(configFile))); + } + String diktatVersion = version != null ? version : DiktatStep.defaultVersionDiktat(); + return DiktatStep.create(diktatVersion, stepConfig.getProvisioner(), Collections.emptyMap(), config); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java index dcfce10fc4..cfb0aad39e 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Kotlin.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,4 +43,8 @@ public void addKtlint(Ktlint ktlint) { public void addKtfmt(Ktfmt ktfmt) { addStepFactory(ktfmt); } + + public void addDiktat(Diktat diktat) { + addStepFactory(diktat); + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java index a5d99f81f4..c1258a15fe 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/kotlin/Ktfmt.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.kotlin.KtfmtStep; +import com.diffplug.spotless.kotlin.KtfmtStep.Style; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; @@ -27,9 +28,13 @@ public class Ktfmt implements FormatterStepFactory { @Parameter private String version; + @Parameter + private String style; + @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { String version = this.version != null ? this.version : KtfmtStep.defaultVersion(); - return KtfmtStep.create(version, config.getProvisioner()); + String style = this.style != null ? this.style : KtfmtStep.defaultStyle(); + return KtfmtStep.create(version, config.getProvisioner(), Style.valueOf(style)); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Black.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Black.java new file mode 100644 index 0000000000..9c35ab4b90 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Black.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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.maven.python; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.python.BlackStep; + +public class Black implements FormatterStepFactory { + + @Parameter + private String version; + + @Parameter + private String pathToExe; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { + BlackStep black = BlackStep.withVersion(version == null ? BlackStep.defaultVersion() : version); + if (pathToExe != null) { + black = black.withPathToExe(pathToExe); + } + return black.create(); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Python.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Python.java new file mode 100644 index 0000000000..09443f070b --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/python/Python.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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.maven.python; + +import java.util.Collections; +import java.util.Set; + +import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.generic.LicenseHeader; + +/** + * A {@link FormatterFactory} implementation that corresponds to {@code ...} configuration element. + *

      + * It defines a formatter for python source files that can execute both language agnostic (e.g. {@link LicenseHeader}) + * and python-specific (e.g. {@link Black}) steps. + */ +public class Python extends FormatterFactory { + + @Override + public Set defaultIncludes() { + return Collections.emptySet(); + } + + @Override + public String licenseHeaderDelimiter() { + return null; + } + + public void addBlack(Black black) { + addStepFactory(black); + } + +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java index faea03f2a0..9ebb9ac503 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/typescript/Tsfmt.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.npm.NpmPathResolver; import com.diffplug.spotless.npm.TsConfigFileType; import com.diffplug.spotless.npm.TsFmtFormatterStep; import com.diffplug.spotless.npm.TypedTsFmtConfigFile; @@ -54,6 +55,9 @@ public class Tsfmt implements FormatterStepFactory { @Parameter private String npmExecutable; + @Parameter + private String npmrc; + @Parameter private Map config; @@ -72,6 +76,8 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { File npm = npmExecutable != null ? stepConfig.getFileLocator().locateFile(npmExecutable) : null; + File npmrcFile = npmrc != null ? stepConfig.getFileLocator().locateFile(npmrc) : null; + TypedTsFmtConfigFile configFile; Map configInline; // check that there is only 1 config file or inline config @@ -114,7 +120,8 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { } File buildDir = stepConfig.getFileLocator().getBuildDir(); - return TsFmtFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, configFile, configInline); + NpmPathResolver npmPathResolver = new NpmPathResolver(npm, npmrcFile, stepConfig.getFileLocator().getBaseDir()); + return TsFmtFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npmPathResolver, configFile, configInline); } private static IllegalArgumentException onlyOneConfig() { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java index 2d3c5d4ea3..81447cc96c 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ public class IncludesExcludesTest extends MavenIntegrationHarness { private static final String JAVA_FORMATTED = "java/eclipse/JavaCodeFormatted.test"; private static final String JAVA_UNFORMATTED = "java/eclipse/JavaCodeUnformatted.test"; private static final String SCALA_UNFORMATTED = "scala/scalafmt/basic.dirty"; - private static final String SCALA_FORMATTED = "scala/scalafmt/basic.clean_2.0.1"; + private static final String SCALA_FORMATTED = "scala/scalafmt/basic.clean_3.0.0"; @Test public void testDefaultIncludesJava() throws Exception { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java index 97a957c75a..12b56da41d 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,10 +45,10 @@ public class MavenIntegrationHarness extends ResourceHarness { /** - * To run tests in the IDE, run `gradlew :plugin-maven:changelogPrint`, then - * put the last version it prints into `SPOTLESS_MAVEN_VERSION_IDE`. From now - * on, if you run `gradlew :plugin-maven:runMavenBuild`, then you can run tests - * in the IDE and they will run against the results of the last `runMavenBuild` + * To run tests in the IDE, run {@code gradlew :plugin-maven:changelogPrint}, then + * put the last version it prints into {@code SPOTLESS_MAVEN_VERSION_IDE}. From now + * on, if you run {@code gradlew :plugin-maven:runMavenBuild}, then you can run tests + * in the IDE and they will run against the results of the last {@code runMavenBuild} */ private static final String SPOTLESS_MAVEN_VERSION_IDE = null; diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index c730fc6e9c..aebf3265fc 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ /** * Harness for running a maven build, same idea as the - * [GradleRunner from the gradle testkit](https://docs.gradle.org/current/javadoc/org/gradle/testkit/runner/GradleRunner.html). + * GradleRunner from the gradle testkit. */ public class MavenRunner { public static MavenRunner create() { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java index b2206a7ab6..de4180d54f 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,7 +93,7 @@ public void testConfigurationDependency() throws Exception { assertFile("two/src/main/java/test1.java").sameAsResource("java/eclipse/JavaCodeFormatted.test"); assertFile("two/src/test/java/test2.java").sameAsResource("java/eclipse/JavaCodeFormatted.test"); - assertFile("three/src/main/scala/test1.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_2.0.1"); - assertFile("three/src/test/scala/test2.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_2.0.1"); + assertFile("three/src/main/scala/test1.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_3.0.0"); + assertFile("three/src/test/scala/test2.scala").sameAsResource("scala/scalafmt/basic.cleanWithCustomConf_3.0.0"); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java index 3649cc7fd5..bfe746cbbf 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java @@ -16,17 +16,30 @@ package com.diffplug.spotless.maven; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import org.junit.Test; public class SpecificFilesTest extends MavenIntegrationHarness { private String testFile(int number, boolean absolute) throws IOException { String rel = "src/main/java/test" + number + ".java"; + Path path; if (absolute) { - return rootFolder() + "/" + rel; + path = Paths.get(rootFolder().getAbsolutePath(), rel); } else { - return rel; + path = Paths.get(rel); } + String result = path.toString(); + if (!isOnWindows()) { + return result; + } else { + return result.replace("\\", "\\\\"); + } + } + + private boolean isOnWindows() { + return System.getProperty("os.name").startsWith("Windows"); } private String testFile(int number) throws IOException { @@ -73,6 +86,11 @@ public void multiFile() throws IOException, InterruptedException { @Test public void regexp() throws IOException, InterruptedException { - integration(".*/src/main/java/test\\(1\\|3\\).java", true, false, true); + String pattern; + if (isOnWindows()) + pattern = "\".*\\\\src\\\\main\\\\java\\\\test(1|3).java\""; + else + pattern = "'.*/src/main/java/test(1|3).java'"; + integration(pattern, true, false, true); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/DiktatTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/DiktatTest.java new file mode 100644 index 0000000000..b9214fb3cf --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/DiktatTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 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.maven.kotlin; + +import java.io.File; + +import org.junit.Test; + +import com.diffplug.spotless.maven.MavenIntegrationHarness; + +public class DiktatTest extends MavenIntegrationHarness { + + @Test + public void testDiktat() throws Exception { + + writePomWithKotlinSteps(""); + + String path = "src/main/kotlin/Main.kt"; + setFile(path).toResource("kotlin/diktat/main.dirty"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(path).sameAsResource("kotlin/diktat/main.clean"); + + } + + @Test + public void testDiktatWithVersion() throws Exception { + + writePomWithKotlinSteps("0.4.0"); + + String path = "src/main/kotlin/Main.kt"; + setFile(path).toResource("kotlin/diktat/main.dirty"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(path).sameAsResource("kotlin/diktat/main.clean"); + } + + @Test + public void testDiktatConfig() throws Exception { + + String configPath = "src/main/kotlin/diktat-analysis.yml"; + File conf = setFile(configPath).toResource("kotlin/diktat/diktat-analysis.yml"); + writePomWithKotlinSteps("0.4.0" + conf.getAbsolutePath() + ""); + + String path = "src/main/kotlin/Main.kt"; + setFile(path).toResource("kotlin/diktat/main.dirty"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(path).sameAsResource("kotlin/diktat/main.clean"); + } + +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java index 53a0d336b9..774dbf0733 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/kotlin/KtfmtTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,4 +39,16 @@ public void testKtfmt() throws Exception { assertFile(path1).sameAsResource("kotlin/ktfmt/basic.clean"); assertFile(path2).sameAsResource("kotlin/ktfmt/basic.clean"); } + + @Test + public void testKtfmtStyle() throws Exception { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + JreVersion.assume11OrGreater(); + + writePomWithKotlinSteps(""); + + setFile("src/main/kotlin/main.kt").toResource("kotlin/ktfmt/basic.dirty"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile("src/main/kotlin/main.kt").sameAsResource("kotlin/ktfmt/basic-dropboxstyle.clean"); + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/prettier/PrettierFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/prettier/PrettierFormatStepTest.java index 3286972002..9dd285204c 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/prettier/PrettierFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/prettier/PrettierFormatStepTest.java @@ -24,19 +24,29 @@ import com.diffplug.spotless.category.NpmTest; import com.diffplug.spotless.maven.MavenIntegrationHarness; -import com.diffplug.spotless.maven.MavenRunner; +import com.diffplug.spotless.maven.MavenRunner.Result; import com.diffplug.spotless.maven.generic.Prettier; @Category(NpmTest.class) public class PrettierFormatStepTest extends MavenIntegrationHarness { private void run(String kind, String suffix) throws IOException, InterruptedException { + String path = prepareRun(kind, suffix); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(path).sameAsResource("npm/prettier/filetypes/" + kind + "/" + kind + ".clean"); + } + + private String prepareRun(String kind, String suffix) throws IOException { String configPath = ".prettierrc.yml"; setFile(configPath).toResource("npm/prettier/filetypes/" + kind + "/" + ".prettierrc.yml"); String path = "src/main/" + kind + "/test." + suffix; setFile(path).toResource("npm/prettier/filetypes/" + kind + "/" + kind + ".dirty"); - mavenRunner().withArguments("spotless:apply").runNoError(); - assertFile(path).sameAsResource("npm/prettier/filetypes/" + kind + "/" + kind + ".clean"); + return path; + } + + private Result runExpectingError(String kind, String suffix) throws IOException, InterruptedException { + String path = prepareRun(kind, suffix); + return mavenRunner().withArguments("spotless:apply").runHasError(); } @Test @@ -93,7 +103,7 @@ public void unique_dependency_config() throws Exception { " 1.16.4", ""); - MavenRunner.Result result = mavenRunner().withArguments("spotless:apply").runHasError(); + Result result = mavenRunner().withArguments("spotless:apply").runHasError(); assertThat(result.output()).contains(Prettier.ERROR_MESSAGE_ONLY_ONE_CONFIG); } @@ -134,4 +144,30 @@ public void autodetect_parser_based_on_filename() throws Exception { assertFile("dirty.json").sameAsResource("npm/prettier/filename/clean.json"); } + @Test + public void autodetect_npmrc_file() throws Exception { + setFile(".npmrc").toLines("registry=https://i.do.no.exist.com"); + String suffix = "ts"; + writePomWithPrettierSteps("**/*." + suffix, + "", + " 1.16.4", + " .prettierrc.yml", + ""); + Result result = runExpectingError("typescript", suffix); + assertThat(result.output()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } + + @Test + public void select_configured_npmrc_file() throws Exception { + setFile(".custom_npmrc").toLines("registry=https://i.do.no.exist.com"); + String suffix = "ts"; + writePomWithPrettierSteps("**/*." + suffix, + "", + " 1.16.4", + " .prettierrc.yml", + " ${basedir}/.custom_npmrc", + ""); + Result result = runExpectingError("typescript", suffix); + assertThat(result.output()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java index c1837d92e4..8f9e1a8c19 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ public class ScalafmtTest extends MavenIntegrationHarness { public void testScalafmtWithDefaultConfig() throws Exception { writePomWithScalaSteps(""); - runTest("scala/scalafmt/basic.clean_2.0.1"); + runTest("scala/scalafmt/basic.clean_3.0.0"); } @Test @@ -36,7 +36,7 @@ public void testScalafmtWithCustomConfig() throws Exception { " ${project.basedir}/scalafmt.conf", ""); - runTest("scala/scalafmt/basic.cleanWithCustomConf_2.0.1"); + runTest("scala/scalafmt/basic.cleanWithCustomConf_3.0.0"); } private void runTest(String s) throws Exception { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java index a8823b81fb..9521962a74 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/typescript/TypescriptFormatStepTest.java @@ -24,17 +24,27 @@ import com.diffplug.spotless.category.NpmTest; import com.diffplug.spotless.maven.MavenIntegrationHarness; -import com.diffplug.spotless.maven.MavenRunner; +import com.diffplug.spotless.maven.MavenRunner.Result; @Category(NpmTest.class) public class TypescriptFormatStepTest extends MavenIntegrationHarness { private void run(String kind) throws IOException, InterruptedException { - String path = "src/main/typescript/test.ts"; - setFile(path).toResource("npm/tsfmt/" + kind + "/" + kind + ".dirty"); + String path = prepareRun(kind); mavenRunner().withArguments("spotless:apply").runNoError(); assertFile(path).sameAsResource("npm/tsfmt/" + kind + "/" + kind + ".clean"); } + private String prepareRun(String kind) throws IOException { + String path = "src/main/typescript/test.ts"; + setFile(path).toResource("npm/tsfmt/" + kind + "/" + kind + ".dirty"); + return path; + } + + private Result runExpectingError(String kind) throws IOException, InterruptedException { + prepareRun(kind); + return mavenRunner().withArguments("spotless:apply").runHasError(); + } + @Test public void tslint() throws Exception { writePomWithTypescriptSteps( @@ -99,7 +109,32 @@ public void testTypescript_2_Configs() throws Exception { String path = "src/main/typescript/test.ts"; setFile(path).toResource("npm/tsfmt/tsfmt/tsfmt.dirty"); - MavenRunner.Result result = mavenRunner().withArguments("spotless:apply").runHasError(); + Result result = mavenRunner().withArguments("spotless:apply").runHasError(); assertThat(result.output()).contains("must specify exactly one configFile or config"); } + + @Test + public void testNpmrcIsAutoPickedUp() throws Exception { + setFile(".npmrc").toLines("registry=https://i.do.no.exist.com"); + writePomWithTypescriptSteps( + "", + " ${basedir}/tslint.json", + ""); + setFile("tslint.json").toResource("npm/tsfmt/tslint/tslint.json"); + Result result = runExpectingError("tslint"); + assertThat(result.output()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } + + @Test + public void testNpmrcIsConfigurativelyPickedUp() throws Exception { + setFile(".custom_npmrc").toLines("registry=https://i.do.no.exist.com"); + writePomWithTypescriptSteps( + "", + " ${basedir}/tslint.json", + " ${basedir}/.custom_npmrc", + ""); + setFile("tslint.json").toResource("npm/tsfmt/tslint/tslint.json"); + Result result = runExpectingError("tslint"); + assertThat(result.output()).containsPattern("Running npm command.*npm install.* failed with exit code: 1"); + } } diff --git a/settings.gradle b/settings.gradle index 67d03f33be..7fcd321542 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,28 @@ pluginManagement { plugins { - id 'com.diffplug.spotless' version '5.0.0' + // We are stuck dogfooding at 5.5.0 for a very strange reason: + // 5.8.0+ Cannot get property 'versionLast' on null object @ spotless-freshmark.gradle:58 + // 5.6.0+ Tried to add format named 'freshmark' of type class @ spotless-freshmark.gradle:55 + id 'com.diffplug.spotless' version '5.5.0' + // https://github.com/diffplug/goomph/blob/main/CHANGES.md + id 'com.diffplug.eclipse.resourcefilters' version '3.27.0' + // https://plugins.gradle.org/plugin/com.gradle.plugin-publish + id 'com.gradle.plugin-publish' version '0.14.0' + // https://github.com/gradle-nexus/publish-plugin/releases + id 'io.github.gradle-nexus.publish-plugin' version '1.0.0' + // https://github.com/spotbugs/spotbugs-gradle-plugin/releases + id 'com.github.spotbugs' version '4.7.0' + // https://github.com/diffplug/spotless-changelog + id 'com.diffplug.spotless-changelog' version '2.1.2' } } plugins { - id 'com.diffplug.spotless' apply false + id 'com.diffplug.spotless' apply false + id 'com.diffplug.eclipse.resourcefilters' apply false + id 'com.gradle.plugin-publish' apply false + id 'io.github.gradle-nexus.publish-plugin' apply false + id 'com.github.spotbugs' apply false + id 'com.diffplug.spotless-changelog' apply false } if (System.env['CI'] != null) { // use the remote buildcache on all CI builds @@ -34,7 +52,12 @@ if (System.env['CI'] != null) { } } -include 'ide' // easy dev setup +if (startParameter.getProjectProperties().get('release') != 'true') { + // the ide project screws up the release tasks + include 'ide' +} + +rootProject.name = 'spotless' include 'lib' // reusable library with no dependencies include 'testlib' // library for sharing test infrastructure between the projects below diff --git a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java index e8bf6fdb1a..f9382ced2c 100644 --- a/testlib/src/main/java/com/diffplug/spotless/StepHarness.java +++ b/testlib/src/main/java/com/diffplug/spotless/StepHarness.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.assertj.core.api.Assertions; import org.junit.Assert; -/** An api for testing a `FormatterStep` that doesn't depend on the File path. DO NOT ADD FILE SUPPORT TO THIS, use {@link StepHarnessWithFile} if you need that. */ +/** An api for testing a {@code FormatterStep} that doesn't depend on the File path. DO NOT ADD FILE SUPPORT TO THIS, use {@link StepHarnessWithFile} if you need that. */ public class StepHarness implements AutoCloseable { private final FormatterFunc formatter; diff --git a/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java b/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java index dced15cf47..d847f10901 100644 --- a/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java +++ b/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import org.assertj.core.api.Assertions; import org.junit.Assert; -/** An api for testing a `FormatterStep` that depends on the File path. */ +/** An api for testing a {@code FormatterStep} that depends on the File path. */ public class StepHarnessWithFile implements AutoCloseable { private final FormatterFunc formatter; diff --git a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java index a67f4b2ac9..d0ba60aa6d 100644 --- a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java +++ b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,15 +129,6 @@ private static Provisioner caching(String name, Supplier input) { }; } - /** Creates a Provisioner for the jcenter repo. */ - public static Provisioner jcenter() { - return jcenter.get(); - } - - private static final Supplier jcenter = Suppliers.memoize(() -> { - return caching("jcenter", () -> createWithRepositories(repo -> repo.jcenter())); - }); - /** Creates a Provisioner for the mavenCentral repo. */ public static Provisioner mavenCentral() { return mavenCentral.get(); diff --git a/testlib/src/main/resources/json/cucumberJsonSampleAfter.json b/testlib/src/main/resources/json/cucumberJsonSampleAfter.json new file mode 100644 index 0000000000..dc0f6f90f7 --- /dev/null +++ b/testlib/src/main/resources/json/cucumberJsonSampleAfter.json @@ -0,0 +1,550 @@ +[ + { + "line": 2, + "elements": [ + { + "line": 7, + "name": "Activate Credit Card", + "description": "Perfect background", + "keyword": "Background", + "type": "background", + "steps": [ + { + "result": { + "duration": 99107447000, + "status": "passed" + }, + "embeddings": [ + { + "data": "", + "mime_type": "image/url" + }, + { + "data": "", + "media": {"type": "text/plain"} + } + ], + "line": 8, + "name": "I have a new credit card", + "match": {"location": "ATMScenario.I_have_a_new_credit_card()"}, + "keyword": "Given " + }, + { + "result": { + "duration": 9520000, + "status": "passed" + }, + "line": 9, + "name": "My credit card is described as follow:", + "match": {"location": "ATMScenario.My_credit_card_is_described_as_follow"}, + "keyword": "And ", + "doc_string": { + "content_type": "", + "line": 10, + "value": "{\n\"issuer\": {\n\"name\": \"Real Bank Inc.\",\n\"isn:\": \"RB55800093842N\"\n},\n\"card_number\": \"4896 0215 8478 6325\",\n\"holder\": \"A guy\"\n}" + } + }, + { + "result": { + "duration": 7040000, + "status": "passed" + }, + "line": 18, + "name": "I confirm my pin number", + "match": {"location": "ATMScenario.I_confirm_my_pin_number()"}, + "keyword": "When ", + "rows": [ + { + "cells": [ + "Müller", + "Deutschland" + ], + "line": 2 + }, + { + "cells": [ + "Nováková", + "Česko" + ], + "line": 3 + }, + { + "cells": [ + "Kovačević", + "Hrvatska" + ], + "line": 4 + }, + { + "cells": [ + "Παπαδόπουλος", + "Παπαδόπουλος" + ], + "line": 5 + }, + { + "cells": [ + "罗/羅", + "中國" + ], + "line": 6 + } + ] + }, + { + "result": { + "duration": 111111, + "status": "passed" + }, + "line": 19, + "name": "the card should be activated", + "match": {"location": "ATMScenario.the_card_should_be_activated()"}, + "keyword": "Then " + } + ] + }, + { + "line": 33, + "name": "Account has ", + "description": "Account holder withdraws cash", + "id": "account-holder-withdraws-cash;account-has-'sufficient-funds';;2", + "after": [{ + "result": { + "duration": 60744700, + "error_message": "Completed", + "status": "passed" + }, + "match": {"location": "MachineFactory.timeout()"} + }], + "keyword": "Scenario Outline", + "type": "scenario", + "steps": [ + { + "result": { + "duration": 17007000, + "status": "passed" + }, + "line": 23, + "name": "the account balance is 100", + "match": { + "arguments": [{ + "val": "100", + "offset": 23 + }], + "location": "ATMScenario.createAccount(int)" + }, + "keyword": "Given " + }, + { + "result": { + "duration": 33444444, + "status": "passed" + }, + "line": 24, + "name": "the card is valid", + "match": { + "arguments": [{ + "val": "", + "offset": 0 + }], + "location": "ATMScenario.createCreditCard()" + }, + "keyword": "And " + }, + { + "result": { + "duration": 44333333, + "status": "passed" + }, + "line": 25, + "name": "100 is contained in the machine", + "match": { + "arguments": [{ + "val": "100", + "offset": 0 + }], + "location": "ATMScenario.createATM(int)" + }, + "matchedColumns": [1], + "keyword": "And " + }, + { + "result": { + "duration": 11000001, + "status": "passed" + }, + "line": 26, + "name": "the Account Holder requests 10, entering PIN 1234", + "match": { + "arguments": [ + { + "val": "10", + "offset": 28 + }, + { + "val": "1234", + "offset": 45 + } + ], + "location": "ATMScenario.requestMoney(int)" + }, + "matchedColumns": [2], + "keyword": "When " + }, + { + "result": { + "duration": 3220000, + "status": "passed" + }, + "line": 27, + "name": "the ATM should dispense 10 monetary units", + "match": { + "arguments": [ + { + "val": "10", + "offset": 24 + }, + { + "val": "", + "offset": 0 + } + ], + "location": "ATMScenario.checkMoney(int)" + }, + "matchedColumns": [3], + "keyword": "Then " + }, + { + "result": { + "duration": 30000000, + "status": "passed" + }, + "line": 28, + "name": "the account balance should be 90", + "match": {"location": "ATMScenario.checkBalance(int)"}, + "arguments": [{"rows": [ + {"cells": [ + "max", + "min" + ]}, + {"cells": [ + "20", + "3" + ]} + ]}], + "matchedColumns": [2], + "keyword": "And " + } + ], + "tags": [ + { + "line": 21, + "name": "@fast" + }, + { + "line": 1, + "name": "@featureTag" + }, + { + "line": 21, + "name": "@checkout" + } + ] + } + ], + "name": "1st feature", + "description": "This is description of the feature", + "id": "account-holder-withdraws-cash", + "keyword": "Feature", + "uri": "net/masterthought/example(s)/ATM:東京.feature", + "tags": [{ + "line": 1, + "name": "@featureTag" + }] + }, + { + "line": 1, + "elements": [ + { + "before": [ + { + "output": ["System version: beta3"], + "result": { + "duration": 10744700, + "status": "passed" + }, + "match": {"location": "MachineFactory.findCashMachine()"} + }, + { + "result": { + "duration": 1000001, + "error_message": " \n", + "status": "failed" + }, + "match": {"location": "MachineFactory.wait()"} + } + ], + "line": 19, + "name": "Account may not have sufficient funds", + "description": "Account holder withdraws more cash", + "id": "account-holder-withdraws-more-cash;account-has-sufficient-funds;;2", + "after": [{ + "result": { + "duration": 64700000, + "error_message": "Undefined step", + "status": "undefined" + }, + "embeddings": [{ + "data": "", + "mime_type": "image/png" + }], + "match": {"location": "any.error()"} + }], + "keyword": "Scenario Outline", + "type": "scenario", + "steps": [ + { + "result": {"status": "undefined"}, + "before": [{ + "embeddings": [{ + "data": "", + "mime_type": "text/plain" + }], + "result": { + "duration": 410802047, + "status": "failed" + } + }], + "line": 7, + "name": "the account balance is 100", + "match": {"arguments": [ + { + "val": "100", + "offset": 23 + }, + {} + ]}, + "matchedColumns": [0], + "keyword": "Given " + }, + { + "result": { + "duration": 13000, + "status": "passed" + }, + "line": 8, + "name": "the card is valid", + "match": { + "arguments": [{ + "val": "", + "offset": 17 + }], + "location": "ATMScenario.createCreditCard()" + }, + "after": [{ + "result": { + "duration": 410802048, + "status": "passed" + }, + "match": {"location": "StepHook.afterStep()"} + }], + "keyword": "And " + }, + { + "result": { + "duration": 36000, + "status": "passed" + }, + "line": 9, + "name": "the machine contains 100", + "match": { + "arguments": [{ + "val": "100", + "offset": 21 + }], + "location": "ATMScenario.createATM(int)" + }, + "matchedColumns": [1], + "keyword": "And " + }, + { + "result": { + "duration": 32000, + "status": "passed" + }, + "line": 10, + "name": "the Account Holder requests 20", + "match": { + "arguments": [{ + "val": "20", + "offset": 28 + }], + "location": "ATMScenario.requestMoney(int)" + }, + "matchedColumns": [2], + "keyword": "When " + }, + { + "result": { + "duration": 36000, + "status": "passed" + }, + "line": 11, + "name": "the ATM should dispense 20", + "match": { + "arguments": [{ + "val": "20", + "offset": 24 + }], + "location": "ATMScenario.checkMoney(int)" + }, + "matchedColumns": [3], + "keyword": "Then " + }, + { + "result": { + "duration": 1933000, + "error_message": "java.lang.AssertionError: \nExpected: is <80>\n got: <90>\n\n\tat org.junit.Assert.assertThat(Assert.java:780)\n\tat org.junit.Assert.assertThat(Assert.java:738)\n\tat net.masterthought.example.ATMScenario.checkBalance(ATMScenario.java:69)\n\tat ✽.And the account balance should be 90(net/masterthought/example/ATMK.feature:12)\n", + "status": "skipped" + }, + "embeddings": [ + { + "data": "", + "mime_type": "image/png", + "name": "Some PNG image" + }, + { + "data": "", + "mime_type": "image/jpeg" + }, + { + "data": "", + "mime_type": "text/plain" + }, + { + "data": "", + "mime_type": "text/html", + "name": "Some HTML embedding" + }, + { + "data": "", + "mime_type": "text/xml" + }, + { + "data": "", + "mime_type": "image/svg+xml" + }, + { + "data": "", + "mime_type": "js" + }, + { + "data": "", + "mime_type": "text/plain" + }, + { + "data": "", + "mime_type": "text/csv" + }, + { + "data": "", + "mime_type": "video/mp4" + } + ], + "line": 12, + "name": "the account balance should be 90", + "match": { + "arguments": [{ + "val": "90", + "offset": 30 + }], + "location": "ATMScenario.checkBalance(int)" + }, + "matchedColumns": [4], + "keyword": "And " + }, + { + "result": {"status": "pending"}, + "embeddings": [{ + "data": "", + "mime_type": "application/json" + }], + "line": 13, + "name": "the card should be returned", + "match": {"location": "ATMScenario.cardShouldBeReturned()"}, + "keyword": "And " + }, + { + "result": {"status": "skipped"}, + "output": [ + ["Could not connect to the server @Rocky@"], + ["Could not connect to the server @Mike@"] + ], + "line": 14, + "name": "its not implemented", + "match": {"location": "ATMScenario.its_not_implemented()"}, + "keyword": "And " + }, + { + "result": {"status": "failed"}, + "output": [ + "Checkpoints", + 232 + ], + "line": 15, + "name": "the card is valid", + "match": {"location": "ATMScenario.createCreditCard()"}, + "keyword": "And " + }, + { + "result": { + "duration": 90000000, + "status": "ambiguous" + }, + "line": 29, + "name": "the card should be returned", + "match": {"location": "ATMScenario.cardShouldBeReturned()"}, + "keyword": "And " + } + ], + "tags": [{ + "line": 101, + "name": "@checkout" + }] + }, + { + "line": 31, + "name": "Clean-up", + "id": "account-holder-withdraws-more-cash;clean-up", + "keyword": "Scenario", + "type": "scenario", + "steps": [{ + "result": { + "duration": 560000, + "status": "passed" + }, + "line": 32, + "name": "Stream closing", + "keyword": "Given " + }] + }, + { + "line": 35, + "name": "This step has no result...", + "id": "undefined-result", + "keyword": "Scenario", + "type": "scenario", + "steps": [{ + "line": 36, + "name": " - even it should", + "keyword": "Given " + }] + } + ], + "name": "Second feature", + "description": "As an Account Holder\nI want to withdraw cash from an ATM,
      so that I can get money when the bank is closed", + "id": "account-holder-withdraws-more-cash", + "keyword": "Feature", + "uri": "net/masterthought/example/ATMK.feature" + } +] diff --git a/testlib/src/main/resources/json/cucumberJsonSampleBefore.json b/testlib/src/main/resources/json/cucumberJsonSampleBefore.json new file mode 100644 index 0000000000..8250630cf7 --- /dev/null +++ b/testlib/src/main/resources/json/cucumberJsonSampleBefore.json @@ -0,0 +1,660 @@ +[ + { + "id": "account-holder-withdraws-cash", + "tags": [ + { + "name": "@featureTag", + "line": 1 + } + ], + "description": "This is description of the feature", + "name": "1st feature", + "keyword": "Feature", + "line": 2, + "elements": [ + { + "description": "Perfect background", + "name": "Activate Credit Card", + "keyword": "Background", + "line": 7, + "steps": [ + { + "result": { + "duration": 99107447000, + "status": "passed" + }, + "name": "I have a new credit card", + "keyword": "Given ", + "line": 8, + "match": { + "location": "ATMScenario.I_have_a_new_credit_card()" + }, + "embeddings": [ + { + "mime_type": "image/url", + "data": "" + }, + { + "data": "", + "media": { + "type": "text/plain" + } + } + ] + }, + { + "result": { + "duration": 9520000, + "status": "passed" + }, + "name": "My credit card is described as follow:", + "keyword": "And ", + "line": 9, + "match": { + "location": "ATMScenario.My_credit_card_is_described_as_follow" + }, + "doc_string": { + "content_type": "", + "line": 10, + "value": "{\n\"issuer\": {\n\"name\": \"Real Bank Inc.\",\n\"isn:\": \"RB55800093842N\"\n},\n\"card_number\": \"4896 0215 8478 6325\",\n\"holder\": \"A guy\"\n}" + } + }, + { + "result": { + "duration": 7040000, + "status": "passed" + }, + "name": "I confirm my pin number", + "keyword": "When ", + "line": 18, + "match": { + "location": "ATMScenario.I_confirm_my_pin_number()" + }, + "rows": [ + { + "cells": [ + "Müller", + "Deutschland" + ], + "line": 2 + }, + { + "cells": [ + "Nováková", + "Česko" + ], + "line": 3 + }, + { + "cells": [ + "Kovačević", + "Hrvatska" + ], + "line": 4 + }, + { + "cells": [ + "Παπαδόπουλος", + "Παπαδόπουλος" + ], + "line": 5 + }, + { + "cells": [ + "罗/羅", + "中國" + ], + "line": 6 + } + ] + }, + { + "result": { + "duration": 111111, + "status": "passed" + }, + "name": "the card should be activated", + "keyword": "Then ", + "line": 19, + "match": { + "location": "ATMScenario.the_card_should_be_activated()" + } + } + ], + "type": "background" + }, + { + "id": "account-holder-withdraws-cash;account-has-\u0027sufficient-funds\u0027;;2", + "tags": [ + { + "name": "@fast", + "line": 21 + }, + { + "name": "@featureTag", + "line": 1 + }, + { + "name": "@checkout", + "line": 21 + } + ], + "description": "Account holder withdraws cash", + "name": "Account has ", + "keyword": "Scenario Outline", + "line": 33, + "steps": [ + { + "result": { + "duration": 17007000, + "status": "passed" + }, + "name": "the account balance is 100", + "keyword": "Given ", + "line": 23, + "match": { + "arguments": [ + { + "val": "100", + "offset": 23 + } + ], + "location": "ATMScenario.createAccount(int)" + } + }, + { + "result": { + "duration": 33444444, + "status": "passed" + }, + "name": "the card is valid", + "keyword": "And ", + "line": 24, + "match": { + "arguments": [ + { + "val": "", + "offset": 0 + } + ], + "location": "ATMScenario.createCreditCard()" + } + }, + { + "result": { + "duration": 44333333, + "status": "passed" + }, + "name": "100 is contained in the machine", + "keyword": "And ", + "line": 25, + "match": { + "arguments": [ + { + "val": "100", + "offset": 0 + } + ], + "location": "ATMScenario.createATM(int)" + }, + "matchedColumns": [ + 1 + ] + }, + { + "result": { + "duration": 11000001, + "status": "passed" + }, + "name": "the Account Holder requests 10, entering PIN 1234", + "keyword": "When ", + "line": 26, + "match": { + "arguments": [ + { + "val": "10", + "offset": 28 + }, + { + "val": "1234", + "offset": 45 + } + ], + "location": "ATMScenario.requestMoney(int)" + }, + "matchedColumns": [ + 2 + ] + }, + { + "result": { + "duration": 3220000, + "status": "passed" + }, + "name": "the ATM should dispense 10 monetary units", + "keyword": "Then ", + "line": 27, + "match": { + "arguments": [ + { + "val": "10", + "offset": 24 + }, + { + "val": "", + "offset": 0 + } + ], + "location": "ATMScenario.checkMoney(int)" + }, + "matchedColumns": [ + 3 + ] + }, + { + "result": { + "duration": 30000000, + "status": "passed" + }, + "name": "the account balance should be 90", + "keyword": "And ", + "line": 28, + "arguments": [ + { + "rows": [ + { + "cells": [ + "max", + "min" + ] + }, + { + "cells": [ + "20", + "3" + ] + } + ] + } + ], + "match": { + "location": "ATMScenario.checkBalance(int)" + }, + "matchedColumns": [ + 2 + ] + } + ], + "type": "scenario", + "after": [ + { + "result": { + "duration": 60744700, + "status": "passed", + "error_message": "Completed" + }, + "match": { + "location": "MachineFactory.timeout()" + } + } + ] + } + ], + "uri": "net/masterthought/example(s)/ATM:東京.feature" + }, + { + "id": "account-holder-withdraws-more-cash", + "description": "As an Account Holder\nI want to withdraw cash from an ATM,
      so that I can get money when the bank is closed", + "name": "Second feature", + "keyword": "Feature", + "line": 1, + "elements": [ + { + "id": "account-holder-withdraws-more-cash;account-has-sufficient-funds;;2", + "tags": [ + { + "name": "@checkout", + "line": 101 + } + ], + "before": [ + { + "output": [ + "System version: beta3" + ], + "result": { + "duration": 10744700, + "status": "passed" + }, + "match": { + "location": "MachineFactory.findCashMachine()" + } + }, + { + "result": { + "duration": 1000001, + "status": "failed", + "error_message": " \n" + }, + "match": { + "location": "MachineFactory.wait()" + } + } + ], + "description": "Account holder withdraws more cash", + "name": "Account may not have sufficient funds", + "keyword": "Scenario Outline", + "line": 19, + "steps": [ + { + "result": { + "status": "undefined" + }, + "name": "the account balance is 100", + "keyword": "Given ", + "line": 7, + "match": { + "arguments": [ + { + "val": "100", + "offset": 23 + }, + {} + ] + }, + "matchedColumns": [ + 0 + ], + "before": [ + { + "embeddings": [ + { + "mime_type": "text/plain", + "data": "" + } + ], + "result": { + "duration": 410802047, + "status": "failed" + } + } + ] + }, + { + "result": { + "duration": 13000, + "status": "passed" + }, + "name": "the card is valid", + "keyword": "And ", + "line": 8, + "match": { + "arguments": [ + { + "val": "", + "offset": 17 + } + ], + "location": "ATMScenario.createCreditCard()" + }, + "after": [ + { + "result": { + "duration": 410802048, + "status": "passed" + }, + "match": { + "location": "StepHook.afterStep()" + } + } + ] + }, + { + "result": { + "duration": 36000, + "status": "passed" + }, + "name": "the machine contains 100", + "keyword": "And ", + "line": 9, + "match": { + "arguments": [ + { + "val": "100", + "offset": 21 + } + ], + "location": "ATMScenario.createATM(int)" + }, + "matchedColumns": [ + 1 + ] + }, + { + "result": { + "duration": 32000, + "status": "passed" + }, + "name": "the Account Holder requests 20", + "keyword": "When ", + "line": 10, + "match": { + "arguments": [ + { + "val": "20", + "offset": 28 + } + ], + "location": "ATMScenario.requestMoney(int)" + }, + "matchedColumns": [ + 2 + ] + }, + { + "result": { + "duration": 36000, + "status": "passed" + }, + "name": "the ATM should dispense 20", + "keyword": "Then ", + "line": 11, + "match": { + "arguments": [ + { + "val": "20", + "offset": 24 + } + ], + "location": "ATMScenario.checkMoney(int)" + }, + "matchedColumns": [ + 3 + ] + }, + { + "result": { + "duration": 1933000, + "status": "skipped", + "error_message": "java.lang.AssertionError: \nExpected: is \u003c80\u003e\n got: \u003c90\u003e\n\n\tat org.junit.Assert.assertThat(Assert.java:780)\n\tat org.junit.Assert.assertThat(Assert.java:738)\n\tat net.masterthought.example.ATMScenario.checkBalance(ATMScenario.java:69)\n\tat ✽.And the account balance should be 90(net/masterthought/example/ATMK.feature:12)\n" + }, + "name": "the account balance should be 90", + "keyword": "And ", + "line": 12, + "match": { + "arguments": [ + { + "val": "90", + "offset": 30 + } + ], + "location": "ATMScenario.checkBalance(int)" + }, + "matchedColumns": [ + 4 + ], + "embeddings": [ + { + "mime_type": "image/png", + "data": "", + "name": "Some PNG image" + }, + { + "mime_type": "image/jpeg", + "data": "" + }, + { + "mime_type": "text/plain", + "data": "" + }, + { + "mime_type": "text/html", + "data": "", + "name": "Some HTML embedding" + }, + { + "mime_type": "text/xml", + "data": "" + }, + { + "mime_type": "image/svg+xml", + "data": "" + }, + { + "mime_type": "js", + "data": "" + }, + { + "mime_type": "text/plain", + "data": "" + }, + { + "mime_type": "text/csv", + "data": "" + }, + { + "mime_type": "video/mp4", + "data": "" + } + ] + }, + { + "result": { + "status": "pending" + }, + "name": "the card should be returned", + "keyword": "And ", + "line": 13, + "match": { + "location": "ATMScenario.cardShouldBeReturned()" + }, + "embeddings": [ + { + "mime_type": "application/json", + "data": "" + } + ] + }, + { + "result": { + "status": "skipped" + }, + "name": "its not implemented", + "keyword": "And ", + "line": 14, + "match": { + "location": "ATMScenario.its_not_implemented()" + }, + "output": [ + [ + "Could not connect to the server @Rocky@" + ], + [ + "Could not connect to the server @Mike@" + ] + ] + }, + { + "result": { + "status": "failed" + }, + "name": "the card is valid", + "keyword": "And ", + "line": 15, + "match": { + "location": "ATMScenario.createCreditCard()" + }, + "output": [ + "Checkpoints", + 232 + ] + }, + { + "result": { + "duration": 90000000, + "status": "ambiguous" + }, + "name": "the card should be returned", + "keyword": "And ", + "line": 29, + "match": { + "location": "ATMScenario.cardShouldBeReturned()" + } + } + ], + "type": "scenario", + "after": [ + { + "result": { + "duration": 64700000, + "status": "undefined", + "error_message": "Undefined step" + }, + "match": { + "location": "any.error()" + }, + "embeddings": [ + { + "mime_type": "image/png", + "data": "" + } + ] + } + ] + }, + { + "id": "account-holder-withdraws-more-cash;clean-up", + "name": "Clean-up", + "keyword": "Scenario", + "line": 31, + "steps": [ + { + "result": { + "duration": 560000, + "status": "passed" + }, + "name": "Stream closing", + "keyword": "Given ", + "line": 32 + } + ], + "type": "scenario" + }, + { + "id": "undefined-result", + "name": "This step has no result...", + "keyword": "Scenario", + "line": 35, + "steps": [ + { + "name": " - even it should", + "keyword": "Given ", + "line": 36 + } + ], + "type": "scenario" + } + ], + "uri": "net/masterthought/example/ATMK.feature" + } +] diff --git a/testlib/src/main/resources/json/emptyAfter.json b/testlib/src/main/resources/json/emptyAfter.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testlib/src/main/resources/json/emptyBefore.json b/testlib/src/main/resources/json/emptyBefore.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testlib/src/main/resources/json/invalidJsonAfter.json b/testlib/src/main/resources/json/invalidJsonAfter.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testlib/src/main/resources/json/invalidJsonBefore.json b/testlib/src/main/resources/json/invalidJsonBefore.json new file mode 100644 index 0000000000..0a36b4c415 --- /dev/null +++ b/testlib/src/main/resources/json/invalidJsonBefore.json @@ -0,0 +1,2 @@ +{ +"a": f diff --git a/testlib/src/main/resources/json/nestedObjectAfter.json b/testlib/src/main/resources/json/nestedObjectAfter.json new file mode 100644 index 0000000000..070dfc481e --- /dev/null +++ b/testlib/src/main/resources/json/nestedObjectAfter.json @@ -0,0 +1,11 @@ +{ + "abc": "def", + "obj": { + "arr": [ + 1, + 2, + 3 + ], + "val": 5 + } +} diff --git a/testlib/src/main/resources/json/nestedObjectBefore.json b/testlib/src/main/resources/json/nestedObjectBefore.json new file mode 100644 index 0000000000..37a0e0b90c --- /dev/null +++ b/testlib/src/main/resources/json/nestedObjectBefore.json @@ -0,0 +1,7 @@ +{ "abc": "def", + "obj": { + "arr": [ + 1,2,3 + ], + "val": 5 + } } diff --git a/testlib/src/main/resources/json/notJsonAfter.json b/testlib/src/main/resources/json/notJsonAfter.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testlib/src/main/resources/json/notJsonBefore.json b/testlib/src/main/resources/json/notJsonBefore.json new file mode 100644 index 0000000000..358200a574 --- /dev/null +++ b/testlib/src/main/resources/json/notJsonBefore.json @@ -0,0 +1 @@ +#not valid JSON diff --git a/testlib/src/main/resources/json/objectWithNullAfter.json b/testlib/src/main/resources/json/objectWithNullAfter.json new file mode 100644 index 0000000000..5e47a73852 --- /dev/null +++ b/testlib/src/main/resources/json/objectWithNullAfter.json @@ -0,0 +1,4 @@ +{ + "another": 1, + "value": null +} diff --git a/testlib/src/main/resources/json/objectWithNullBefore.json b/testlib/src/main/resources/json/objectWithNullBefore.json new file mode 100644 index 0000000000..f68567c97c --- /dev/null +++ b/testlib/src/main/resources/json/objectWithNullBefore.json @@ -0,0 +1,4 @@ +{ +"value": null, +"another": 1 +} diff --git a/testlib/src/main/resources/json/singletonArrayAfter.json b/testlib/src/main/resources/json/singletonArrayAfter.json new file mode 100644 index 0000000000..fa3d04c724 --- /dev/null +++ b/testlib/src/main/resources/json/singletonArrayAfter.json @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3, + 4 +] diff --git a/testlib/src/main/resources/json/singletonArrayAfter0Spaces.json b/testlib/src/main/resources/json/singletonArrayAfter0Spaces.json new file mode 100644 index 0000000000..8adb9bb604 --- /dev/null +++ b/testlib/src/main/resources/json/singletonArrayAfter0Spaces.json @@ -0,0 +1 @@ +[1,2,3,4] diff --git a/testlib/src/main/resources/json/singletonArrayAfter6Spaces.json b/testlib/src/main/resources/json/singletonArrayAfter6Spaces.json new file mode 100644 index 0000000000..2550a537b5 --- /dev/null +++ b/testlib/src/main/resources/json/singletonArrayAfter6Spaces.json @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3, + 4 +] diff --git a/testlib/src/main/resources/json/singletonArrayAfterTabs.json b/testlib/src/main/resources/json/singletonArrayAfterTabs.json new file mode 100644 index 0000000000..6a8580f45d --- /dev/null +++ b/testlib/src/main/resources/json/singletonArrayAfterTabs.json @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3, + 4 +] diff --git a/testlib/src/main/resources/json/singletonArrayBefore.json b/testlib/src/main/resources/json/singletonArrayBefore.json new file mode 100644 index 0000000000..8290d39198 --- /dev/null +++ b/testlib/src/main/resources/json/singletonArrayBefore.json @@ -0,0 +1 @@ +[ 1, 2, 3, 4 ] diff --git a/testlib/src/main/resources/json/singletonObjectAfter.json b/testlib/src/main/resources/json/singletonObjectAfter.json new file mode 100644 index 0000000000..bbcc15e8cc --- /dev/null +++ b/testlib/src/main/resources/json/singletonObjectAfter.json @@ -0,0 +1 @@ +{"a": "b"} diff --git a/testlib/src/main/resources/json/singletonObjectBefore.json b/testlib/src/main/resources/json/singletonObjectBefore.json new file mode 100644 index 0000000000..611670e052 --- /dev/null +++ b/testlib/src/main/resources/json/singletonObjectBefore.json @@ -0,0 +1 @@ +{"a": "b"} diff --git a/testlib/src/main/resources/json/singletonObjectWithArrayAfter.json b/testlib/src/main/resources/json/singletonObjectWithArrayAfter.json new file mode 100644 index 0000000000..39c104af94 --- /dev/null +++ b/testlib/src/main/resources/json/singletonObjectWithArrayAfter.json @@ -0,0 +1 @@ +{"a": [1]} diff --git a/testlib/src/main/resources/json/singletonObjectWithArrayBefore.json b/testlib/src/main/resources/json/singletonObjectWithArrayBefore.json new file mode 100644 index 0000000000..c427907dc0 --- /dev/null +++ b/testlib/src/main/resources/json/singletonObjectWithArrayBefore.json @@ -0,0 +1 @@ +{"a": [1]} diff --git a/testlib/src/main/resources/kotlin/diktat/Unsolvable.kt b/testlib/src/main/resources/kotlin/diktat/Unsolvable.kt new file mode 100644 index 0000000000..88bd0b3f6d --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/Unsolvable.kt @@ -0,0 +1,15 @@ +package org.cqfn.diktat.example.gradle.multiproject.resources.kotlin.diktat + +/** + * @return print. + */ +class Unsolvable { + /** + * foo a [member] to this group. + * + */ + fun foo() { + println(";") + println(); + } +} diff --git a/testlib/src/main/resources/kotlin/diktat/basic.clean b/testlib/src/main/resources/kotlin/diktat/basic.clean new file mode 100644 index 0000000000..309b40e252 --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/basic.clean @@ -0,0 +1,13 @@ +/** + * @property main + / + +fun main() { + + /** + * @return print. + */ + fun name() { a(); return b } + println(";") + println() +} diff --git a/testlib/src/main/resources/kotlin/diktat/basic.dirty b/testlib/src/main/resources/kotlin/diktat/basic.dirty new file mode 100644 index 0000000000..ca4758f4f2 --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/basic.dirty @@ -0,0 +1,13 @@ +/** + * @property main + */ + +fun main() { + + /** + * @property name + */ + fun name() { a(); return b } + println(";") + println(); +} diff --git a/testlib/src/main/resources/kotlin/diktat/diktat-analysis.yml b/testlib/src/main/resources/kotlin/diktat/diktat-analysis.yml new file mode 100644 index 0000000000..8c88553907 --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/diktat-analysis.yml @@ -0,0 +1,298 @@ +- name: DIKTAT_COMMON + configuration: + # put your package name here - it will be autofixed and checked + domainName: org.cqfn.diktat.example.gradle.multiproject + testDirs: test +- name: CLASS_NAME_INCORRECT + enabled: true +- name: CONSTANT_UPPERCASE + enabled: true +- name: ENUM_VALUE + enabled: true +- name: EXCEPTION_SUFFIX + enabled: true +- name: FILE_NAME_INCORRECT + enabled: true +- name: FILE_NAME_MATCH_CLASS + enabled: true +- name: FUNCTION_BOOLEAN_PREFIX + enabled: true +- name: FUNCTION_NAME_INCORRECT_CASE + enabled: true +- name: GENERIC_NAME + enabled: true +- name: IDENTIFIER_LENGTH + enabled: true +- name: OBJECT_NAME_INCORRECT + enabled: true +- name: PACKAGE_NAME_INCORRECT_CASE + enabled: true # configuration domainName is taken from DIKTAT_COMMON +- name: PACKAGE_NAME_INCORRECT_PREFIX + enabled: false +- name: PACKAGE_NAME_INCORRECT_SYMBOLS + enabled: true +- name: PACKAGE_NAME_INCORRECT_PATH + enabled: true # configuration domainName is taken from DIKTAT_COMMON +- name: PACKAGE_NAME_MISSING + enabled: true +- name: VARIABLE_HAS_PREFIX + enabled: true +- name: VARIABLE_NAME_INCORRECT + enabled: true +- name: VARIABLE_NAME_INCORRECT_FORMAT + enabled: true +- name: MISSING_KDOC_ON_FUNCTION + enabled: true +- name: MISSING_KDOC_TOP_LEVEL + enabled: true +- name: MISSING_KDOC_CLASS_ELEMENTS + enabled: true +- name: KDOC_WITHOUT_PARAM_TAG + enabled: true +- name: KDOC_WITHOUT_RETURN_TAG + enabled: true +- name: KDOC_WITHOUT_THROWS_TAG + enabled: true +- name: KDOC_EMPTY_KDOC + enabled: true +- name: INCORRECT_PACKAGE_SEPARATOR + enabled: true +- name: KDOC_NO_DEPRECATED_TAG + enabled: true +- name: KDOC_NO_EMPTY_TAGS + enabled: true +- name: KDOC_WRONG_SPACES_AFTER_TAG + enabled: true +- name: KDOC_WRONG_TAGS_ORDER + enabled: true +- name: KDOC_NO_NEWLINES_BETWEEN_BASIC_TAGS + enabled: true +- name: KDOC_NEWLINES_BEFORE_BASIC_TAGS + enabled: true +- name: KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS + enabled: true +- name: KDOC_TRIVIAL_KDOC_ON_FUNCTION + enabled: 'true' +- name: HEADER_WRONG_FORMAT + enabled: true +- name: HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE + enabled: true +- name: HEADER_MISSING_OR_WRONG_COPYRIGHT + enabled: true + configuration: + isCopyrightMandatory: false + copyrightText: 'Copyright (c) Your Company Name Here. 2010-2021' +- name: HEADER_NOT_BEFORE_PACKAGE + enabled: true +- name: FILE_IS_TOO_LONG + enabled: true + configuration: + maxSize: '2000' + ignoreFolders: '' +- name: COMMENTED_OUT_CODE + enabled: true +- name: FILE_CONTAINS_ONLY_COMMENTS + enabled: true + # order imports alphabetically +- name: FILE_UNORDERED_IMPORTS + enabled: true + configuration: + # use logical imports grouping with sorting inside of a group + useRecommendedImportsOrder: true +- name: FILE_INCORRECT_BLOCKS_ORDER + enabled: true +- name: FILE_NO_BLANK_LINE_BETWEEN_BLOCKS + enabled: true +# Check: warns if wildcard imports are used except allows. (e.g. import org.cqfn.diktat.*) +- name: FILE_WILDCARD_IMPORTS + enabled: true + configuration: + allowedWildcards: "" # Allowed wildcards for imports (e.g. "import org.cqfn.diktat.*, import org.jetbrains.kotlin.*") + useRecommendedImportsOrder: true +- name: NO_BRACES_IN_CONDITIONALS_AND_LOOPS + enabled: true +- name: WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES + enabled: true +- name: BLANK_LINE_BETWEEN_PROPERTIES + enabled: true +- name: BRACES_BLOCK_STRUCTURE_ERROR + enabled: true + configuration: + openBraceNewline: 'True' + closeBraceNewline: 'True' +- name: WRONG_INDENTATION + enabled: true + configuration: + newlineAtEnd: true + extendedIndentOfParameters: true + alignedParameters: true + extendedIndentAfterOperators: true + indentationSize: 4 +- name: EMPTY_BLOCK_STRUCTURE_ERROR + enabled: true + configuration: + styleEmptyBlockWithNewline: 'True' + allowEmptyBlocks: 'False' +- name: MORE_THAN_ONE_STATEMENT_PER_LINE + enabled: true +- name: LONG_LINE + enabled: true + configuration: + lineLength: '120' +- name: REDUNDANT_SEMICOLON + enabled: true +- name: WRONG_NEWLINES + enabled: true + configuration: + maxParametersInOneLine: 2 +- name: TOO_MANY_CONSECUTIVE_SPACES + enabled: true + configuration: + max_spaces: '1' + saveInitialFormattingForEnums: false +- name: TOO_MANY_BLANK_LINES + enabled: true +- name: WRONG_WHITESPACE + enabled: true +- name: BACKTICKS_PROHIBITED + enabled: true +- name: STRING_CONCATENATION + enabled: true +- name: WHEN_WITHOUT_ELSE + enabled: true +- name: ANNOTATION_NEW_LINE + enabled: true +- name: ENUMS_SEPARATED + enabled: true +- name: LONG_NUMERICAL_VALUES_SEPARATED + enabled: true + configuration: + maxNumberLength: '5' + maxBlockLength: '3' +- name: WRONG_DECLARATIONS_ORDER + enabled: true + configuration: + sortEnum: true + sortProperty: true +- name: WRONG_MULTIPLE_MODIFIERS_ORDER + enabled: true +- name: CONFUSING_IDENTIFIER_NAMING + enabled: true +# Inspection that checks if there is a blank line before kDoc and none after +- name: WRONG_NEWLINES_AROUND_KDOC + enabled: true +# Inspection that checks if there is no blank lines before first comment +- name: FIRST_COMMENT_NO_SPACES + enabled: true +# Inspection that checks if there are blank lines between code and comment and between code start token and comment's text +- name: COMMENT_WHITE_SPACE + enabled: true + configuration: + maxSpacesBeforeComment: 2 + maxSpacesInComment: 1 +# Inspection that checks if all comment's are inside if-else code blocks. Exception is general if comment +- name: IF_ELSE_COMMENTS + enabled: true +- name: WRONG_COPYRIGHT_YEAR + enabled: true +# Inspection that checks if local variables are declared close to the first usage site +- name: LOCAL_VARIABLE_EARLY_DECLARATION + enabled: true +# Try to avoid initialize val by null (e.g. val a: Int? = null -> val a: Int = 0) +- name: NULLABLE_PROPERTY_TYPE + enabled: true +# Type aliases provide alternative names for existing types when type's reference text is longer 25 chars +- name: TYPE_ALIAS + enabled: true + configuration: + typeReferenceLength: '25' # max length of type reference +- name: SMART_CAST_NEEDED + enabled: true +- name: GENERIC_VARIABLE_WRONG_DECLARATION + enabled: true +# Inspection that checks if string template has redundant curly braces +- name: STRING_TEMPLATE_CURLY_BRACES + enabled: true +# Variables with `val` modifier - are immutable (read-only). Usage of such variables instead of `var` variables increases +# robustness and readability of code, because `var` variables can be reassigned several times in the business logic. +# This rule prohibits usage of `var`s as local variables - the only exception is accumulators and counters +- name: SAY_NO_TO_VAR + enabled: true +# Inspection that checks if string template has redundant quotes +- name: STRING_TEMPLATE_QUOTES + enabled: true +# Checks that floating-point values are not used in arithmetic expressions +- name: FLOAT_IN_ACCURATE_CALCULATIONS + enabled: true +# Checks that function length isn't too long +- name: TOO_LONG_FUNCTION + enabled: true + configuration: + maxFunctionLength: '30' # max length of function + isIncludeHeader: 'false' # count function's header +# Warns if there are nested functions +- name: AVOID_NESTED_FUNCTIONS + enabled: true +# Checks that lambda inside function parameters is in the end +- name: LAMBDA_IS_NOT_LAST_PARAMETER + enabled: true +# Checks that function doesn't contains too many parameters +- name: TOO_MANY_PARAMETERS + enabled: true + configuration: + maxParameterListSize: '5' # max parameters size +# Checks that function doesn't have too many nested blocks +- name: NESTED_BLOCK + enabled: true + configuration: + maxNestedBlockQuantity: '4' +# Checks that function use default values, instead overloading +- name: WRONG_OVERLOADING_FUNCTION_ARGUMENTS + enabled: true +# Checks that KDoc in constructor has property tag +- name: KDOC_NO_CONSTRUCTOR_PROPERTY + enabled: true +# Checks that KDoc in constructor has property tag but with comment inside constructor +- name: KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT + enabled: true +# if a class has single constructor, it should be converted to a primary constructor +- name: SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY + enabled: true +# Checks if class can be made as data class +- name: USE_DATA_CLASS + enabled: true +# Checks that never use the name of a variable in the custom getter or setter +- name: WRONG_NAME_OF_VARIABLE_INSIDE_ACCESSOR + enabled: true +# Checks that classes have only one init block +- name: MULTIPLE_INIT_BLOCKS + enabled: true +# Checks that there are abstract functions in abstract class +- name: CLASS_SHOULD_NOT_BE_ABSTRACT + enabled: true +# Checks if there are any trivial getters or setters +- name: TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED + enabled: true +# Checks that no custom getters and setters are used for properties. It is a more wide rule than TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED +# Kotlin compiler automatically generates `get` and `set` methods for properties and also lets the possibility to override it. +# But in all cases it is very confusing when `get` and `set` are overridden for a developer who uses this particular class. +# Developer expects to get the value of the property, but receives some unknown value and some extra side effect hidden by the custom getter/setter. +# Use extra functions for it instead. +- name: CUSTOM_GETTERS_SETTERS + enabled: true +# Checks if null-check was used explicitly (for example: if (a == null)) +# Try to avoid explicit null checks (explicit comparison with `null`) +# Kotlin is declared as [Null-safe](https://kotlinlang.org/docs/reference/null-safety.html) language. +# But Kotlin architects wanted Kotlin to be fully compatible with Java, that's why `null` keyword was also introduced in Kotlin. +# There are several code-structures that can be used in Kotlin to avoid null-checks. For example: `?:`, `.let {}`, `.also {}`, e.t.c +- name: AVOID_NULL_CHECKS + enabled: true +# Checks if class instantiation can be wrapped in `apply` for better readability +- name: COMPACT_OBJECT_INITIALIZATION + enabled: true +# Checks explicit supertype qualification +- name: USELESS_SUPERTYPE + enabled: true +# Checks if extension function with the same signature don't have related classes +- name: EXTENSION_FUNCTION_SAME_SIGNATURE + enabled: true diff --git a/testlib/src/main/resources/kotlin/diktat/main.clean b/testlib/src/main/resources/kotlin/diktat/main.clean new file mode 100644 index 0000000000..4405165ed5 --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/main.clean @@ -0,0 +1,15 @@ +package org.cqfn.diktat.example.gradle.multiproject + +/** + * @return print. + */ +class Main { + /** + * foo a [member] to this group. + * + */ + fun foo() { + println(";") + println() + } +} diff --git a/testlib/src/main/resources/kotlin/diktat/main.dirty b/testlib/src/main/resources/kotlin/diktat/main.dirty new file mode 100644 index 0000000000..5f7be993aa --- /dev/null +++ b/testlib/src/main/resources/kotlin/diktat/main.dirty @@ -0,0 +1,14 @@ +package org.cqfn.diktat.example.gradle.multiproject +/** + * @return print. + */ +class Main { + /** + * foo a [member] to this group. + * + */ + fun foo() { + println(";") + println(); + } +} diff --git a/testlib/src/main/resources/kotlin/ktfmt/basic-dropboxstyle.clean b/testlib/src/main/resources/kotlin/ktfmt/basic-dropboxstyle.clean new file mode 100644 index 0000000000..8287d56ae2 --- /dev/null +++ b/testlib/src/main/resources/kotlin/ktfmt/basic-dropboxstyle.clean @@ -0,0 +1,13 @@ +import a.* +import a.b +import a.b.c.* +import kotlinx.android.synthetic.main.layout_name.* + +fun main() { + fun name() { + a() + return b + } + println(";") + println() +} diff --git a/testlib/src/main/resources/scala/scalafmt/basic.cleanWithCustomConf_3.0.0 b/testlib/src/main/resources/scala/scalafmt/basic.cleanWithCustomConf_3.0.0 new file mode 100644 index 0000000000..fae835000a --- /dev/null +++ b/testlib/src/main/resources/scala/scalafmt/basic.cleanWithCustomConf_3.0.0 @@ -0,0 +1,27 @@ +@foobar( + "annot", { + val x = 2 + val y = 2 // y=2 + x + y + } +) +object a + extends b + with c { + def foo[ + T: Int#Double#Triple, + R <% String + ]( + @annot1 + x: Int @annot2 = + 2, + y: Int = 3 + ): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => + 2 + } + } +} diff --git a/testlib/src/main/resources/scala/scalafmt/basic.clean_3.0.0 b/testlib/src/main/resources/scala/scalafmt/basic.clean_3.0.0 new file mode 100644 index 0000000000..b531873bfa --- /dev/null +++ b/testlib/src/main/resources/scala/scalafmt/basic.clean_3.0.0 @@ -0,0 +1,20 @@ +@foobar( + "annot", { + val x = 2 + val y = 2 // y=2 + x + y + } +) +object a extends b with c { + def foo[T: Int#Double#Triple, R <% String]( + @annot1 + x: Int @annot2 = 2, + y: Int = 3 + ): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => 2 + } + } +} diff --git a/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.clean b/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.clean new file mode 100644 index 0000000000..b531873bfa --- /dev/null +++ b/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.clean @@ -0,0 +1,20 @@ +@foobar( + "annot", { + val x = 2 + val y = 2 // y=2 + x + y + } +) +object a extends b with c { + def foo[T: Int#Double#Triple, R <% String]( + @annot1 + x: Int @annot2 = 2, + y: Int = 3 + ): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => 2 + } + } +} diff --git a/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.cleanWithCustomConf b/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.cleanWithCustomConf new file mode 100644 index 0000000000..fae835000a --- /dev/null +++ b/testlib/src/main/resources/scala/scalafmt/basicPost3.0.0.cleanWithCustomConf @@ -0,0 +1,27 @@ +@foobar( + "annot", { + val x = 2 + val y = 2 // y=2 + x + y + } +) +object a + extends b + with c { + def foo[ + T: Int#Double#Triple, + R <% String + ]( + @annot1 + x: Int @annot2 = + 2, + y: Int = 3 + ): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => + 2 + } + } +} diff --git a/testlib/src/main/resources/scala/scalafmt/scalafmt.invalid.conf b/testlib/src/main/resources/scala/scalafmt/scalafmt.invalid.conf new file mode 100644 index 0000000000..3777f3f212 --- /dev/null +++ b/testlib/src/main/resources/scala/scalafmt/scalafmt.invalid.conf @@ -0,0 +1 @@ +invalidScalaFmtConfigField = true diff --git a/testlib/src/main/resources/sql/dbeaver/V1_initial.sql.clean b/testlib/src/main/resources/sql/dbeaver/V1_initial.sql.clean index 20d18b61ef..5acd532610 100644 --- a/testlib/src/main/resources/sql/dbeaver/V1_initial.sql.clean +++ b/testlib/src/main/resources/sql/dbeaver/V1_initial.sql.clean @@ -1,13 +1,12 @@ --- Account management - CREATE +CREATE TABLE account( id serial PRIMARY KEY, username VARCHAR(60) NOT NULL UNIQUE, email VARCHAR(513) NOT NULL UNIQUE, - name VARCHAR(255), - --NULLABLE - created_at TIMESTAMP NOT NULL, + name VARCHAR(255), --NULLABLE + created_at TIMESTAMP NOT NULL, created_ip inet NOT NULL, updated_at TIMESTAMP NOT NULL, updated_ip inet NOT NULL, @@ -38,13 +37,12 @@ CREATE ); --- Takes - CREATE +CREATE TABLE takerevision( id serial PRIMARY KEY, - parent_id INT REFERENCES takerevision(id), - --NULLABLE (null for root) - created_at TIMESTAMP NOT NULL, + parent_id INT REFERENCES takerevision(id), --NULLABLE (null for root) + created_at TIMESTAMP NOT NULL, created_ip inet NOT NULL, title VARCHAR(255) NOT NULL, blocks jsonb NOT NULL @@ -68,11 +66,9 @@ CREATE blocks jsonb NOT NULL, published_at TIMESTAMP NOT NULL, published_ip inet NOT NULL, - deleted_at TIMESTAMP, - --NULLABLE - deleted_ip inet, - --NULLABLE - count_view INT NOT NULL DEFAULT 0, + deleted_at TIMESTAMP, --NULLABLE + deleted_ip inet, --NULLABLE + count_view INT NOT NULL DEFAULT 0, count_like INT NOT NULL DEFAULT 0, count_bookmark INT NOT NULL DEFAULT 0, count_spam INT NOT NULL DEFAULT 0, @@ -80,7 +76,7 @@ CREATE ); -- /user/title must be unique, and fast to lookup - CREATE +CREATE UNIQUE INDEX takepublished_title_user ON takepublished( title_slug, @@ -105,8 +101,7 @@ CREATE take_id, user_id, kind - ), - --user can only have one of each kind of reaction per take - reacted_at TIMESTAMP NOT NULL, + ), --user can only have one of each kind of reaction per take + reacted_at TIMESTAMP NOT NULL, reacted_ip inet NOT NULL ); \ No newline at end of file diff --git a/testlib/src/main/resources/sql/dbeaver/create.clean b/testlib/src/main/resources/sql/dbeaver/create.clean index 38d9d560cb..1f21e7f246 100644 --- a/testlib/src/main/resources/sql/dbeaver/create.clean +++ b/testlib/src/main/resources/sql/dbeaver/create.clean @@ -1,3 +1,5 @@ +-- multiline +-- comment CREATE TABLE films( @@ -19,7 +21,7 @@ CREATE ); -- Create a table with a 2-dimensional array: - CREATE +CREATE TABLE array_int( vector INT [][] diff --git a/testlib/src/main/resources/sql/dbeaver/create.clean.alternative b/testlib/src/main/resources/sql/dbeaver/create.clean.alternative index 1cf1668ee4..37e3a199d1 100644 --- a/testlib/src/main/resources/sql/dbeaver/create.clean.alternative +++ b/testlib/src/main/resources/sql/dbeaver/create.clean.alternative @@ -1,3 +1,5 @@ +-- multiline +-- comment create table films( @@ -19,7 +21,7 @@ create ); -- Create a table with a 2-dimensional array: - create +create table array_int( vector int [][] diff --git a/testlib/src/main/resources/sql/dbeaver/create.dirty b/testlib/src/main/resources/sql/dbeaver/create.dirty index 60b852ba64..78bffb37f4 100644 --- a/testlib/src/main/resources/sql/dbeaver/create.dirty +++ b/testlib/src/main/resources/sql/dbeaver/create.dirty @@ -1,3 +1,5 @@ +-- multiline + -- comment CREATE TABLE films ( code char(5) CONSTRAINT firstkey PRIMARY KEY, title varchar(40) NOT NULL, diff --git a/testlib/src/test/java/com/diffplug/spotless/FileSignatureTest.java b/testlib/src/test/java/com/diffplug/spotless/FileSignatureTest.java index f69d573c04..f2a5d30cef 100644 --- a/testlib/src/test/java/com/diffplug/spotless/FileSignatureTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/FileSignatureTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.Test; public class FileSignatureTest extends ResourceHarness { @@ -79,4 +80,11 @@ private List getTestFiles(final String[] paths) throws IOException { public void testSubpath() { assertThat(FileSignature.subpath("root/", "root/child")).isEqualTo("child"); } + + @Test + public void windowsRoot() { + org.junit.Assume.assumeTrue(FileSignature.machineIsWin()); + String subpath = FileSignature.subpath("S://", "S:/build.gradle"); + Assertions.assertThat(subpath).isEqualTo("build.gradle"); + } } diff --git a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java index 85f44d8265..8c4c2ea054 100644 --- a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ public class LicenseHeaderStepTest extends ResourceHarness { private static final String FILE_NO_LICENSE = "license/FileWithoutLicenseHeader.test"; private static final String package_ = "package "; private static final String HEADER_WITH_$YEAR = "This is a fake license, $YEAR. ACME corp."; + private static final String HEADER_WITH_RANGE_TO_$YEAR = "This is a fake license with range, 2009-$YEAR. ACME corp."; @Test public void parseExistingYear() throws Exception { @@ -112,6 +113,25 @@ public void should_apply_license_containing_YEAR_token_with_custom_separator() t .test(hasHeaderYear("not a year"), hasHeaderYear(currentYear())); } + @Test + public void should_remove_header_when_empty() throws Throwable { + StepHarness.forStep(LicenseHeaderStep.headerDelimiter("", package_).build()) + .testUnaffected(getTestResource("license/MissingLicense.test")) + .test(getTestResource("license/HasLicense.test"), getTestResource("license/MissingLicense.test")); + } + + private String licenceWithAddress() { + return "Copyright © $YEAR FooBar Inc. All Rights Reserved.\n" + + " *\n" + + " * Use of this software is covered by inscrutable legal protection and\n" + + " * complex automation. Violaters of undisclosed terms must expect\n" + + " * unforeseen consequences.\n" + + " *\n" + + " * FooBar, Inc.\n" + + " * 9 Food Truck\n" + + " * Perry Derry, TX 55656 USA"; + } + private String header(String contents) throws IOException { return "/*\n" + " * " + contents + "\n" + @@ -130,6 +150,10 @@ private String hasHeaderYear(String years) throws IOException { return hasHeaderYear(HEADER_WITH_$YEAR, years); } + private String hasHeaderWithRangeAndWithYearTo(String toYear) throws IOException { + return hasHeaderYear(HEADER_WITH_RANGE_TO_$YEAR, toYear); + } + private static String currentYear() { return String.valueOf(YearMonth.now().getYear()); } @@ -194,4 +218,26 @@ protected FormatterStep create() { } }.testEquals(); } + + @Test + public void should_apply_license_containing_YEAR_token_in_range() throws Throwable { + FormatterStep step = LicenseHeaderStep.headerDelimiter(header(HEADER_WITH_RANGE_TO_$YEAR), package_).withYearMode(YearMode.UPDATE_TO_TODAY).build(); + StepHarness.forStep(step).test(hasHeaderWithRangeAndWithYearTo("2015"), hasHeaderWithRangeAndWithYearTo(currentYear())); + } + + @Test + public void should_update_year_for_license_with_address() throws Throwable { + FormatterStep step = LicenseHeaderStep.headerDelimiter(header(licenceWithAddress()), package_).withYearMode(YearMode.UPDATE_TO_TODAY).build(); + StepHarness.forStep(step).test( + hasHeader(licenceWithAddress().replace("$YEAR", "2015")), + hasHeader(licenceWithAddress().replace("$YEAR", "2015-2021"))); + } + + @Test + public void should_preserve_year_for_license_with_address() throws Throwable { + FormatterStep step = LicenseHeaderStep.headerDelimiter(header(licenceWithAddress()), package_).withYearMode(YearMode.PRESERVE).build(); + StepHarness.forStep(step).test( + hasHeader(licenceWithAddress().replace("$YEAR", "2015").replace("FooBar Inc. All", "FooBar Inc. All")), + hasHeader(licenceWithAddress().replace("$YEAR", "2015"))); + } } diff --git a/testlib/src/test/java/com/diffplug/spotless/json/JsonSimpleStepTest.java b/testlib/src/test/java/com/diffplug/spotless/json/JsonSimpleStepTest.java new file mode 100644 index 0000000000..0bbe1acdca --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/json/JsonSimpleStepTest.java @@ -0,0 +1,137 @@ +/* + * Copyright 2021 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.json; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.Test; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.SerializableEqualityTester; +import com.diffplug.spotless.StepHarness; +import com.diffplug.spotless.TestProvisioner; + +public class JsonSimpleStepTest { + + private static final int INDENT = 4; + + private final FormatterStep step = JsonSimpleStep.create(INDENT, TestProvisioner.mavenCentral()); + private final StepHarness stepHarness = StepHarness.forStep(step); + + @Test + public void cannotProvidedNullProvisioner() { + assertThatThrownBy(() -> JsonSimpleStep.create(INDENT, null)).isInstanceOf(NullPointerException.class).hasMessage("provisioner cannot be null"); + } + + @Test + public void handlesSingletonObject() throws Exception { + doWithResource(stepHarness, "singletonObject"); + } + + @Test + public void handlesSingletonObjectWithArray() throws Exception { + doWithResource(stepHarness, "singletonObjectWithArray"); + } + + @Test + public void handlesNestedObject() throws Exception { + doWithResource(stepHarness, "nestedObject"); + } + + @Test + public void handlesSingletonArray() throws Exception { + doWithResource(stepHarness, "singletonArray"); + } + + @Test + public void handlesEmptyFile() throws Exception { + doWithResource(stepHarness, "empty"); + } + + @Test + public void handlesComplexNestedObject() throws Exception { + doWithResource(stepHarness, "cucumberJsonSample"); + } + + @Test + public void handlesObjectWithNull() throws Exception { + doWithResource(stepHarness, "objectWithNull"); + } + + @Test + public void handlesInvalidJson() { + assertThatThrownBy(() -> doWithResource(stepHarness, "invalidJson")) + .isInstanceOf(AssertionError.class) + .hasMessage("Unable to format JSON") + .hasRootCauseMessage("Expected a ',' or '}' at 9 [character 0 line 3]"); + } + + @Test + public void handlesNotJson() { + assertThatThrownBy(() -> doWithResource(stepHarness, "notJson")) + .isInstanceOf(AssertionError.class) + .hasMessage("Unable to determine JSON type, expected a '{' or '[' but found '#'") + .hasNoCause(); + } + + @Test + public void canSetCustomIndentationLevel() throws Exception { + FormatterStep step = JsonSimpleStep.create(6, TestProvisioner.mavenCentral()); + StepHarness stepHarness = StepHarness.forStep(step); + + String before = "json/singletonArrayBefore.json"; + String after = "json/singletonArrayAfter6Spaces.json"; + stepHarness.testResource(before, after); + } + + @Test + public void canSetIndentationLevelTo0() throws Exception { + FormatterStep step = JsonSimpleStep.create(0, TestProvisioner.mavenCentral()); + StepHarness stepHarness = StepHarness.forStep(step); + + String before = "json/singletonArrayBefore.json"; + String after = "json/singletonArrayAfter0Spaces.json"; + stepHarness.testResource(before, after); + } + + @Test + public void equality() { + new SerializableEqualityTester() { + int spaces = 0; + + @Override + protected void setupTest(API api) { + // no changes, are the same + api.areDifferentThan(); + + // with different spacing + spaces = 1; + api.areDifferentThan(); + } + + @Override + protected FormatterStep create() { + return JsonSimpleStep.create(spaces, TestProvisioner.mavenCentral()); + } + }.testEquals(); + } + + private static void doWithResource(StepHarness stepHarness, String name) throws Exception { + String before = String.format("json/%sBefore.json", name); + String after = String.format("json/%sAfter.json", name); + stepHarness.testResource(before, after); + } +} diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/DiktatStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/DiktatStepTest.java new file mode 100644 index 0000000000..e201dabb66 --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/DiktatStepTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 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.kotlin; + +import static com.diffplug.spotless.FileSignature.signAsList; + +import java.io.File; +import java.util.Collections; + +import org.junit.Test; + +import com.diffplug.spotless.*; + +public class DiktatStepTest extends ResourceHarness { + + @Test + public void behavior() throws Exception { + FormatterStep step = DiktatStep.create(TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResourceException("kotlin/diktat/Unsolvable.kt", assertion -> { + assertion.isInstanceOf(AssertionError.class); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1 cannot be fixed automatically" + + System.lineSeparator() + "[FILE_NAME_INCORRECT] file name is incorrect - it should end with .kt extension and be in PascalCase: testlib" + + System.lineSeparator() + "Error on line: 1, column: 1 cannot be fixed automatically" + + System.lineSeparator() + "[FILE_NAME_MATCH_CLASS] file name is incorrect - it should match with the class described in it if there is the only one class declared: testlib vs Unsolvable"); + }); + } + + @Test + public void behaviorConf() throws Exception { + + String configPath = "src/main/kotlin/diktat-analysis.yml"; + File conf = setFile(configPath).toResource("kotlin/diktat/diktat-analysis.yml"); + FileSignature config = signAsList(conf); + + FormatterStep step = DiktatStep.create("0.3.0", TestProvisioner.mavenCentral(), Collections.emptyMap(), config); + StepHarness.forStep(step) + .testResourceException("kotlin/diktat/Unsolvable.kt", assertion -> { + assertion.isInstanceOf(AssertionError.class); + assertion.hasMessage("There are 2 unfixed errors:" + + System.lineSeparator() + "Error on line: 1, column: 1 cannot be fixed automatically" + + System.lineSeparator() + "[FILE_NAME_INCORRECT] file name is incorrect - it should end with .kt extension and be in PascalCase: testlib" + + System.lineSeparator() + "Error on line: 1, column: 1 cannot be fixed automatically" + + System.lineSeparator() + "[FILE_NAME_MATCH_CLASS] file name is incorrect - it should match with the class described in it if there is the only one class declared: testlib vs Unsolvable"); + }); + } + +} diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java index bfa2f77fc1..ac5c4a979f 100644 --- a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtLintStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,10 +32,11 @@ @Ignore public class KtLintStepTest extends ResourceHarness { @Test + @Ignore public void behavior() throws Exception { - // Must use jcenter because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. + // Must use jcenter (GONE) because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. // It is a dependency of ktlint. - FormatterStep step = KtLintStep.create(TestProvisioner.jcenter()); + FormatterStep step = KtLintStep.create(TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { @@ -46,10 +47,11 @@ public void behavior() throws Exception { } @Test + @Ignore public void worksShyiko() throws Exception { - // Must use jcenter because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. + // Must use jcenter (GONE) because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. // It is a dependency of ktlint. - FormatterStep step = KtLintStep.create("0.31.0", TestProvisioner.jcenter()); + FormatterStep step = KtLintStep.create("0.31.0", TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { @@ -63,10 +65,11 @@ public void worksShyiko() throws Exception { // but before 0.34. // https://github.com/diffplug/spotless/issues/419 @Test + @Ignore public void worksPinterestAndPre034() throws Exception { - // Must use jcenter because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. + // Must use jcenter (GONE) because `com.andreapivetta.kolor:kolor:0.0.2` isn't available on mavenCentral. // It is a dependency of ktlint. - FormatterStep step = KtLintStep.create("0.32.0", TestProvisioner.jcenter()); + FormatterStep step = KtLintStep.create("0.32.0", TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean") .testResourceException("kotlin/ktlint/unsolvable.dirty", assertion -> { @@ -80,7 +83,7 @@ public void worksPinterestAndPre034() throws Exception { // https://github.com/diffplug/spotless/issues/668 @Test public void worksAlpha1() throws Exception { - FormatterStep step = KtLintStep.create("0.38.0-alpha01", TestProvisioner.jcenter()); + FormatterStep step = KtLintStep.create("0.38.0-alpha01", TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("kotlin/ktlint/basic.dirty", "kotlin/ktlint/basic.clean"); } diff --git a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java index 9a4c398b9e..9a35167d40 100644 --- a/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/kotlin/KtfmtStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,22 @@ public void behavior() throws Exception { StepHarness.forStep(step).testResource("kotlin/ktfmt/basic.dirty", "kotlin/ktfmt/basic.clean"); } + @Test + public void dropboxStyle_0_18() throws Exception { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + JreVersion.assume11OrGreater(); + FormatterStep step = KtfmtStep.create("0.18", TestProvisioner.mavenCentral(), KtfmtStep.Style.DROPBOX); + StepHarness.forStep(step).testResource("kotlin/ktfmt/basic.dirty", "kotlin/ktfmt/basic-dropboxstyle.clean"); + } + + @Test + public void dropboxStyle_0_19() throws Exception { + // ktfmt's dependency, google-java-format 1.8 requires a minimum of JRE 11+. + JreVersion.assume11OrGreater(); + FormatterStep step = KtfmtStep.create("0.19", TestProvisioner.mavenCentral(), KtfmtStep.Style.DROPBOX); + StepHarness.forStep(step).testResource("kotlin/ktfmt/basic.dirty", "kotlin/ktfmt/basic-dropboxstyle.clean"); + } + @Test public void equality() throws Exception { new SerializableEqualityTester() { diff --git a/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java b/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java index 79b58ab5a9..16b1b29477 100644 --- a/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/NpmFormatterStepCommonTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,18 @@ public abstract class NpmFormatterStepCommonTests extends ResourceHarness { - protected File npmExecutable() { + protected NpmPathResolver npmPathResolver() { + return new NpmPathResolver(npmExecutable(), npmrc()); + } + + private File npmExecutable() { return NpmExecutableResolver.tryFind().orElseThrow(() -> new IllegalStateException("cannot detect node binary")); } + private File npmrc() { + return new NpmrcResolver().tryFind().orElse(null); + } + private File buildDir = null; protected File buildDir() throws IOException { diff --git a/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java index 1ac24e8422..b11971364a 100644 --- a/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/PrettierFormatterStepTest.java @@ -57,7 +57,7 @@ public void formattingUsingConfigFile() throws Exception { PrettierFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), new PrettierConfig(prettierRc, null)); try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { @@ -80,7 +80,7 @@ public void parserInferenceBasedOnExplicitFilepathIsWorking() throws Exception { PrettierFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), new PrettierConfig(null, ImmutableMap.of("filepath", "anyname.json"))); // should select parser based on this name try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { @@ -99,7 +99,7 @@ public void parserInferenceBasedOnFilenameIsWorking() throws Exception { PrettierFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), new PrettierConfig(null, Collections.emptyMap())); try (StepHarnessWithFile stepHarness = StepHarnessWithFile.forStep(formatterStep)) { @@ -113,7 +113,7 @@ public void verifyPrettierErrorMessageIsRelayed() throws Exception { PrettierFormatterStep.defaultDevDependenciesWithPrettier("2.0.5"), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), new PrettierConfig(null, ImmutableMap.of("parser", "postcss"))); try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { stepHarness.testResourceException("npm/prettier/filetypes/scss/scss.dirty", exception -> { @@ -138,7 +138,7 @@ public void runFormatTest(PrettierConfig config, String cleanFileNameSuffix) thr PrettierFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), config); // should select parser based on this name try (StepHarness stepHarness = StepHarness.forStep(formatterStep)) { diff --git a/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java b/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java index 41858d2faa..8ec4ce747b 100644 --- a/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/npm/TsFmtFormatterStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ public void formattingUsingConfigFile() throws Exception { TsFmtFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), TypedTsFmtConfigFile.named(configFileNameWithoutExtension, configFile), Collections.emptyMap()); @@ -86,7 +86,7 @@ public void formattingUsingInlineConfigWorks() throws Exception { TsFmtFormatterStep.defaultDevDependencies(), TestProvisioner.mavenCentral(), buildDir(), - npmExecutable(), + npmPathResolver(), null, inlineConfig); diff --git a/testlib/src/test/java/com/diffplug/spotless/scala/ScalaFmtStepTest.java b/testlib/src/test/java/com/diffplug/spotless/scala/ScalaFmtStepTest.java index 2177ce0e09..982510df97 100644 --- a/testlib/src/test/java/com/diffplug/spotless/scala/ScalaFmtStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/scala/ScalaFmtStepTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,18 @@ */ package com.diffplug.spotless.scala; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertThrows; + import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import org.junit.Test; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.ResourceHarness; import com.diffplug.spotless.SerializableEqualityTester; import com.diffplug.spotless.StepHarness; @@ -33,6 +39,8 @@ public void behaviorDefaultConfig() throws Exception { .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.clean_1.1.0"); StepHarness.forStep(ScalaFmtStep.create("2.0.1", TestProvisioner.mavenCentral(), null)) .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.clean_2.0.1"); + StepHarness.forStep(ScalaFmtStep.create("3.0.0", TestProvisioner.mavenCentral(), null)) + .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.clean_3.0.0"); } @Test @@ -41,6 +49,8 @@ public void behaviorCustomConfig() throws Exception { .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.cleanWithCustomConf_1.1.0"); StepHarness.forStep(ScalaFmtStep.create("2.0.1", TestProvisioner.mavenCentral(), createTestFile("scala/scalafmt/scalafmt.conf"))) .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.cleanWithCustomConf_2.0.1"); + StepHarness.forStep(ScalaFmtStep.create("3.0.0", TestProvisioner.mavenCentral(), createTestFile("scala/scalafmt/scalafmt.conf"))) + .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basic.cleanWithCustomConf_3.0.0"); } @Test @@ -57,6 +67,20 @@ public void behaviorCustomConfigVersion_2_0_0() throws Exception { .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basicPost2.0.0.cleanWithCustomConf"); } + @Test + public void behaviorDefaultConfigVersion_3_0_0() throws Exception { + FormatterStep step = ScalaFmtStep.create("3.0.0", TestProvisioner.mavenCentral(), null); + StepHarness.forStep(step) + .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basicPost3.0.0.clean"); + } + + @Test + public void behaviorCustomConfigVersion_3_0_0() throws Exception { + FormatterStep step = ScalaFmtStep.create("3.0.0", TestProvisioner.mavenCentral(), createTestFile("scala/scalafmt/scalafmt.conf")); + StepHarness.forStep(step) + .testResource("scala/scalafmt/basic.dirty", "scala/scalafmt/basicPost3.0.0.cleanWithCustomConf"); + } + @Test public void equality() throws Exception { new SerializableEqualityTester() { @@ -84,4 +108,25 @@ protected FormatterStep create() { } }.testEquals(); } + + @Test + public void invalidConfiguration() throws Exception { + File invalidConfFile = createTestFile("scala/scalafmt/scalafmt.invalid.conf"); + Provisioner provisioner = TestProvisioner.mavenCentral(); + + InvocationTargetException exception; + + exception = assertThrows(InvocationTargetException.class, + () -> StepHarness.forStep(ScalaFmtStep.create("1.1.0", provisioner, invalidConfFile)).test("", "")); + assertThat(exception.getTargetException().getMessage(), containsString("Invalid fields: invalidScalaFmtConfigField")); + exception.printStackTrace(); + + exception = assertThrows(InvocationTargetException.class, + () -> StepHarness.forStep(ScalaFmtStep.create("2.0.1", provisioner, invalidConfFile)).test("", "")); + assertThat(exception.getTargetException().getMessage(), containsString("Invalid field: invalidScalaFmtConfigField")); + + exception = assertThrows(InvocationTargetException.class, + () -> StepHarness.forStep(ScalaFmtStep.create("3.0.0", provisioner, invalidConfFile)).test("", "")); + assertThat(exception.getTargetException().getMessage(), containsString("found option 'invalidScalaFmtConfigField' which wasn't expected")); + } }