diff --git a/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/BuildEnforcerExtension.groovy b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/BuildEnforcerExtension.groovy index 39b383dd..6088fb4a 100644 --- a/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/BuildEnforcerExtension.groovy +++ b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/BuildEnforcerExtension.groovy @@ -57,16 +57,4 @@ interface BuildEnforcerExtension extends EnforcerExtension { * Configure rules for all matching projects. */ void projects(List projectPaths, Action configurer) - - interface EnforcerRuleConfiguration { - /** - * Define a rule. - */ - public void rule(Class ruleType) - - /** - * Define and con figure a rule. - */ - public void rule(Class ruleType, Action configurer) - } } diff --git a/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerExtension.groovy b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerExtension.groovy index 29335c32..fbb21036 100644 --- a/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerExtension.groovy +++ b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerExtension.groovy @@ -25,7 +25,7 @@ import org.gradle.api.provider.Property * @since 0.1.0 */ @CompileStatic -interface EnforcerExtension { +interface EnforcerExtension extends EnforcerRuleConfiguration { /** * Whether enforcer behavior is enabled or not. Defaults to {@code true}. */ diff --git a/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerRuleConfiguration.groovy b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerRuleConfiguration.groovy new file mode 100644 index 00000000..ae0e59c2 --- /dev/null +++ b/core/enforcer-api/src/main/groovy/org/kordamp/gradle/plugin/enforcer/api/EnforcerRuleConfiguration.groovy @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2020 The author and/or original authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.kordamp.gradle.plugin.enforcer.api + +import org.gradle.api.Action + +import groovy.transform.CompileStatic + + +@CompileStatic +interface EnforcerRuleConfiguration { + /** + * Define a rule. + */ + public void rule(Class ruleType) + + /** + * Define and configure a rule. + */ + public void rule(Class ruleType, Action configurer) +} diff --git a/plugins/enforcer-gradle-plugin/enforcer-gradle-plugin.gradle b/plugins/enforcer-gradle-plugin/enforcer-gradle-plugin.gradle index d601e69b..dd829348 100644 --- a/plugins/enforcer-gradle-plugin/enforcer-gradle-plugin.gradle +++ b/plugins/enforcer-gradle-plugin/enforcer-gradle-plugin.gradle @@ -17,6 +17,7 @@ */ plugins{ id 'org.kordamp.gradle.integration-test' + id 'org.jetbrains.kotlin.jvm' version '1.4.10' } dependencies { @@ -73,6 +74,6 @@ integrationTest { project(':enforcer-api').jar, project(':enforcer-rules').jar, jar - ].collect { "'${it.destinationDirectory.get().asFile.absolutePath}'" } + ].collect { "'${it.destinationDirectory.get().asFile.absolutePath.replace('\\', '/')}'" } .join(',') } diff --git a/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/BuildEnforcerPluginKotlinIntegrationTest.groovy b/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/BuildEnforcerPluginKotlinIntegrationTest.groovy new file mode 100644 index 00000000..3d362182 --- /dev/null +++ b/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/BuildEnforcerPluginKotlinIntegrationTest.groovy @@ -0,0 +1,178 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2020 The author and/or original authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.kordamp.gradle.plugin.enforcer + +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder + +import spock.lang.IgnoreRest +import spock.lang.Specification + +class BuildEnforcerPluginKotlinIntegrationTest extends Specification { + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + + File buildFile + File settingsFile + + def setup() { + buildFile = testProjectDir.newFile('build.gradle.kts') + buildFile << """ + plugins { + id ("base") + } + """ + + settingsFile = testProjectDir.newFile('settings.gradle.kts') + settingsFile << """ + import org.kordamp.gradle.plugin.enforcer.rule + import org.kordamp.gradle.plugin.enforcer.api.BuildEnforcerExtension + + buildscript { + repositories { + gradlePluginPortal() + flatDir { dirs (${System.getProperty('jars.dir').replace("'", '"')}) } + } + dependencies { + classpath ("org.kordamp.gradle:enforcer-api:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-rules:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-gradle-plugin:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-gradle-plugin-tests:${System.getProperty('project.version')}") + classpath ("org.apache.commons:commons-lang3:${System.getProperty('commonsLang3Version')}") + classpath ("commons-codec:commons-codec:${System.getProperty('commonsCodecVersion')}") + classpath ("org.apache.maven:maven-artifact:${System.getProperty('mavenVersion')}") + classpath ("kr.motd.maven:os-maven-plugin:${System.getProperty('osMavenPluginVersion')}") + } + } + apply(plugin= "org.kordamp.gradle.enforcer") + """ + } + + def "Can disable all enforcer rules"() { + given: + settingsFile << """ + configure { + enabled.set(false) + rule() +// allprojects { +// rule() +// } + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .build() + + then: + result.task(':clean').outcome == UP_TO_DATE + } + + def "Can disable a single enforcer rule"() { + given: + settingsFile << """ + configure { + rule { + enabled.set(false) + } + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .build() + + then: + result.task(':clean').outcome == UP_TO_DATE + } + + def "Can fail a build"() { + given: + settingsFile << """ + configure { + rule () + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains("[BEFORE_BUILD] An Enforcer rule has failed") + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + } + + def "Can fail a build fast"() { + given: + settingsFile << """ + configure { + failFast.set(true) + rule() + rule() + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains("[BEFORE_BUILD] An Enforcer rule has failed") + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + } + + def "Can fail multiple rules in the same phase"() { + given: + settingsFile << """ + configure { + failFast.set(false) + rule() + rule() + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains('[BEFORE_BUILD] 2 Enforcer rules have failed') + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + result.output.contains("Enforcer rule 'org.kordamp.gradle.plugin.enforcer.Fail' was triggered.") + } +} diff --git a/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/ProjectEnforcerPluginKotlinIntegrationTest.groovy b/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/ProjectEnforcerPluginKotlinIntegrationTest.groovy new file mode 100644 index 00000000..638c39f9 --- /dev/null +++ b/plugins/enforcer-gradle-plugin/src/integration-test/groovy/org/kordamp/gradle/plugin/enforcer/ProjectEnforcerPluginKotlinIntegrationTest.groovy @@ -0,0 +1,179 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2020 The author and/or original authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.kordamp.gradle.plugin.enforcer + +import spock.lang.* + +import org.gradle.testkit.runner.* +import org.junit.Rule +import org.junit.rules.TemporaryFolder + +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + +class ProjectEnforcerPluginKotlinIntegrationTest extends Specification { + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + + File buildFile + File settingsFile + + def setup() { + buildFile = testProjectDir.newFile('build.gradle.kts') + buildFile << """ + import org.kordamp.gradle.plugin.enforcer.rule + import org.kordamp.gradle.plugin.enforcer.api.ProjectEnforcerExtension + + plugins { + id ("base") + // id ("org.kordamp.gradle.project-enforcer") + } + + apply(plugin= "org.kordamp.gradle.project-enforcer") + """ + + settingsFile = testProjectDir.newFile('settings.gradle.kts') + settingsFile << """ + + buildscript { + repositories { + gradlePluginPortal() + flatDir { dirs (${System.getProperty('jars.dir').replace("'", '"')}) } + } + dependencies { + classpath ("org.kordamp.gradle:enforcer-api:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-rules:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-gradle-plugin:${System.getProperty('project.version')}") + classpath ("org.kordamp.gradle:enforcer-gradle-plugin-tests:${System.getProperty('project.version')}") + classpath ("org.apache.commons:commons-lang3:${System.getProperty('commonsLang3Version')}") + classpath ("commons-codec:commons-codec:${System.getProperty('commonsCodecVersion')}") + classpath ("org.apache.maven:maven-artifact:${System.getProperty('mavenVersion')}") + classpath ("kr.motd.maven:os-maven-plugin:${System.getProperty('osMavenPluginVersion')}") + } + } + """ + } + + def "Can disable all enforcer rules"() { + given: + buildFile << """ + configure { + enabled.set(false) + rule() +// allprojects { +// rule() +// } + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .build() + + then: + result.task(':clean').outcome == UP_TO_DATE + } + + def "Can disable a single enforcer rule"() { + given: + buildFile << """ + configure { + rule { + enabled.set(false) + } + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .build() + + then: + result.task(':clean').outcome == UP_TO_DATE + } + + def "Can fail a build"() { + given: + buildFile << """ + configure { + rule() + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains("[AFTER_PROJECT :] An Enforcer rule has failed") + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + } + + def "Can fail a build fast"() { + given: + buildFile << """ + configure { + failFast.set(true) + rule() + rule() + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains("[AFTER_PROJECT :] An Enforcer rule has failed") + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + } + + def "Can fail multiple rules in the same phase"() { + given: + buildFile << """ + configure { + failFast.set(false) + rule() + rule() + } + """ + + when: + BuildResult result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('clean', '--stacktrace') + .withPluginClasspath() + .buildAndFail() + + then: + result.output.contains('[AFTER_PROJECT :] 2 Enforcer rules have failed') + result.output.contains("Enforcer rule 'enforcer.rules.AlwaysFail' was triggered.") + result.output.contains("Enforcer rule 'org.kordamp.gradle.plugin.enforcer.Fail' was triggered.") + } +} diff --git a/plugins/enforcer-gradle-plugin/src/main/groovy/org/kordamp/gradle/plugin/enforcer/internal/DefaultBuildEnforcerExtension.groovy b/plugins/enforcer-gradle-plugin/src/main/groovy/org/kordamp/gradle/plugin/enforcer/internal/DefaultBuildEnforcerExtension.groovy index 05dd0444..d5a9defb 100644 --- a/plugins/enforcer-gradle-plugin/src/main/groovy/org/kordamp/gradle/plugin/enforcer/internal/DefaultBuildEnforcerExtension.groovy +++ b/plugins/enforcer-gradle-plugin/src/main/groovy/org/kordamp/gradle/plugin/enforcer/internal/DefaultBuildEnforcerExtension.groovy @@ -17,6 +17,8 @@ */ package org.kordamp.gradle.plugin.enforcer.internal +import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleConfiguration + import groovy.transform.CompileStatic import org.gradle.api.Action import org.gradle.api.model.ObjectFactory diff --git a/plugins/enforcer-gradle-plugin/src/main/kotlin/org/kordamp/gradle/plugin/enforcer/EnforcerExtensions.kt b/plugins/enforcer-gradle-plugin/src/main/kotlin/org/kordamp/gradle/plugin/enforcer/EnforcerExtensions.kt new file mode 100644 index 00000000..d7c60ff0 --- /dev/null +++ b/plugins/enforcer-gradle-plugin/src/main/kotlin/org/kordamp/gradle/plugin/enforcer/EnforcerExtensions.kt @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2020 The author and/or original authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.kordamp.gradle.plugin.enforcer + +import org.gradle.api.Action +import org.gradle.api.reflect.TypeOf +import org.kordamp.gradle.plugin.enforcer.api.BuildEnforcerExtension +import org.kordamp.gradle.plugin.enforcer.api.EnforcerRule +import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleConfiguration +import org.kordamp.gradle.plugin.enforcer.api.ProjectEnforcerExtension + +/** + * Creates an instance of [TypeOf] for the given parameterized type. + * + * @param T the type + * @return the [TypeOf] that captures the generic type of the given parameterized type + */ +inline fun typeOf(): TypeOf = + object : TypeOf() {} + +/** + * Configure rules for this extension. + * + * Parameter should be loaded from the classpath. + */ +inline fun > BuildEnforcerExtension.configure(): Unit = + typeOf().let { type -> + configure(type.concreteClass) + } + +/** + * Configure rules for this project. + * + * Parameter should be loaded from the classpath. + */ +inline fun > ProjectEnforcerExtension.configure(): Unit = + typeOf().let { type -> + configure(type.concreteClass) + } + +/** + * Define a rule + */ +inline fun EnforcerRuleConfiguration.rule(): Unit = + typeOf().let { type -> + rule(type.concreteClass) + } + +/** + * Define and configure a rule + */ +inline fun EnforcerRuleConfiguration.rule(noinline configuration: T.() -> Unit): Unit = + typeOf().let { type -> + rule(type.concreteClass, configuration) + }