Skip to content

Commit

Permalink
Allow setting execution phase in standard rules. Fixes #10. Fixes #12
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmiray committed Oct 30, 2020
1 parent 9fceb09 commit 842de79
Show file tree
Hide file tree
Showing 39 changed files with 395 additions and 290 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,20 @@ abstract class AbstractEnforcerRule implements EnforcerRule {
}
}

@Override
void validate(EnforcerContext context) throws EnforcerRuleException {
context.logger.debug("Validating rule ${resolveClassName()} on ${context}")
doValidate(context)
}

@Override
void execute(EnforcerContext context) throws EnforcerRuleException {
context.logger.debug("Enforcing rule ${resolveClassName()} on ${context}")
doExecute(context)
}

protected abstract void doValidate(EnforcerContext context) throws EnforcerRuleException

protected abstract void doExecute(EnforcerContext context) throws EnforcerRuleException

protected String resolveClassName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,19 @@ interface EnforcerRule {

void setEnforcerLevel(String level)

/**
* Validates this rule with the given context.
*
* @param context the context for this rule.
* @throws EnforcerRuleException if the rule's configuration is invalid for the given context
*/
void validate(EnforcerContext context) throws EnforcerRuleException

/**
* Executes this rule with the given context.
*
* @param context the context for this rule.
* @throws EnforcerRuleException if the rule is triggered or if there is an evaluation failure.
*/
void execute(EnforcerContext context) throws EnforcerRuleException
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ package enforcer.rules

import groovy.transform.CompileStatic
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.kordamp.gradle.plugin.enforcer.api.AbstractEnforcerRule
import org.kordamp.gradle.plugin.enforcer.api.EnforcerContext
import org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase
import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleException

import static java.lang.System.arraycopy

/**
* @author Andres Almiray
* @since 0.1.0
*/
@CompileStatic
abstract class AbstractFilteringEnforcerRule extends AbstractEnforcerRule {
final EnforcerPhase[] allowedPhases
final ListProperty<EnforcerPhase> phases
private final List<EnforcerPhase> allowedPhases = new ArrayList<>()

AbstractFilteringEnforcerRule(ObjectFactory objects) {
this(objects, EnforcerPhase.values())
Expand All @@ -41,17 +41,36 @@ abstract class AbstractFilteringEnforcerRule extends AbstractEnforcerRule {
AbstractFilteringEnforcerRule(ObjectFactory objects, EnforcerPhase[] allowedPhases) {
super(objects)
if (allowedPhases == null || allowedPhases.length == 0) {
this.allowedPhases = EnforcerPhase.values()
this.allowedPhases.addAll(EnforcerPhase.values().toList())
} else {
this.allowedPhases = new EnforcerPhase[allowedPhases.length]
arraycopy(allowedPhases, 0, this.allowedPhases, 0, allowedPhases.length)
this.allowedPhases.addAll(allowedPhases.toList())
}

phases = objects.listProperty(EnforcerPhase).convention(this.allowedPhases)
}

void setPhases(List<String> list) {
if (!list) {
throw new IllegalArgumentException('Phase list must not be empty nor null')
}

for (String phase : list) {
phases.add(EnforcerPhase.valueOf(phase?.trim()?.toUpperCase()))
}
}

@Override
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
List<EnforcerPhase> list = new ArrayList<>(phases.get())
list.removeAll(allowedPhases)
if (!list.isEmpty()) {
throw fail("Phase${list.size() > 0 ? 's' : ''} not allowed: ${list*.name()}")
}
Arrays.sort(this.allowedPhases)
}

@Override
void execute(EnforcerContext context) throws EnforcerRuleException {
if (Arrays.binarySearch(allowedPhases, context.enforcerPhase) > -1) {
if (phases.get().contains(context.enforcerPhase)) {
context.logger.debug("Enforcing rule ${resolveClassName()} on ${context}")

doExecute(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import org.codehaus.plexus.util.DirectoryScanner
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.kordamp.gradle.plugin.enforcer.api.AbstractEnforcerRule
import org.kordamp.gradle.plugin.enforcer.api.EnforcerContext
import org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase
import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleException

import static org.apache.commons.lang3.StringUtils.isNotBlank
Expand All @@ -40,22 +38,19 @@ import static org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase.BEFORE_BUILD
* @since 0.1.0
*/
@CompileStatic
abstract class AbstractRequireFiles extends AbstractEnforcerRule {
final Property<String> message
abstract class AbstractRequireFiles extends AbstractStandardEnforcerRule {
final Property<Boolean> allowNulls
final ListProperty<File> files
final ListProperty<String> includePatterns
final ListProperty<String> excludePatterns
final ListProperty<EnforcerPhase> phases

AbstractRequireFiles(ObjectFactory objects) {
super(objects)
message = objects.property(String)
allowNulls = objects.property(Boolean).convention(false)
files = objects.listProperty(File).convention([])
includePatterns = objects.listProperty(String).convention([])
excludePatterns = objects.listProperty(String).convention([])
phases = objects.listProperty(EnforcerPhase).convention([BEFORE_BUILD])
phases.set([BEFORE_BUILD])
}

void include(String str) {
Expand Down Expand Up @@ -83,20 +78,20 @@ abstract class AbstractRequireFiles extends AbstractEnforcerRule {
}

@Override
void execute(EnforcerContext context) throws EnforcerRuleException {
if (context.enforcerPhase in phases.get()) {
context.logger.debug("Enforcing rule ${resolveClassName()} on ${context}")
doExecute(context)
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
if (phases.get().isEmpty()) {
throw fail('No explicit phase(s) defined.')
}
}

protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
if (!allowNulls.get() && files.get().isEmpty()) {
if (includePatterns.get().isEmpty() && excludePatterns.get().isEmpty()) {
throw fail('The file list is empty and Null files are disabled.')
}
}
}

@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
List<File> failures = []
for (File file : files.get()) {
if (!allowNulls.get() && !file) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,39 +61,43 @@ abstract class AbstractVersionEnforcerRule extends AbstractStandardEnforcerRule
version = objects.property(String)
}

@Override
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
String requiredVersionRange = version.get()

if (isBlank(requiredVersionRange)) {
throw fail(variableName + " version can't be empty.")
}
}

@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
ArtifactVersion detectedVersion = detectVersion(context)
String requiredVersionRange = version.get()

if (isBlank(requiredVersionRange)) {
throw new EnforcerRuleException(this.class, variableName + " version can't be empty.")
String msg = 'Detected ' + variableName + ' Version: ' + detectedVersion

// short circuit check if the strings are exactly equal
if (detectedVersion.toString().equals(requiredVersionRange)) {
context.logger.info(msg + ' is allowed in the range ' + requiredVersionRange + '.')
} else {
VersionRange vr = null
String msg = 'Detected ' + variableName + ' Version: ' + detectedVersion

// short circuit check if the strings are exactly equal
if (detectedVersion.toString().equals(requiredVersionRange)) {
context.logger.info(msg + ' is allowed in the range ' + requiredVersionRange + '.')
} else {
try {
vr = VersionRange.createFromVersionSpec(requiredVersionRange)

if (containsVersion(vr, detectedVersion)) {
context.logger.info(msg + ' is allowed in the range ' + requiredVersionRange + '.')
} else {
String m = message.orNull

if (isBlank(m)) {
m = msg + ' is not in the allowed range ' + vr + '.'
}

throw fail(m)
try {
VersionRange vr = VersionRange.createFromVersionSpec(requiredVersionRange)

if (containsVersion(vr, detectedVersion)) {
context.logger.info(msg + ' is allowed in the range ' + requiredVersionRange + '.')
} else {
String m = message.orNull

if (isBlank(m)) {
m = msg + ' is not in the allowed range ' + vr + '.'
}
} catch (InvalidVersionSpecificationException e) {
throw fail('The requested ' + variableName + ' version '
+ requiredVersionRange + ' is invalid.', e)

throw fail(m)
}
} catch (InvalidVersionSpecificationException e) {
throw fail('The requested ' + variableName + ' version '
+ requiredVersionRange + ' is invalid.', e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,7 @@ class BanDuplicateClasses extends AbstractResolveDependencies {

@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
if (context.enforcerPhase == AFTER_PROJECTS) {
enforceBanDuplicates(context)
} else {
enforceBanDuplicates(context)
}
enforceBanDuplicates(context)
}

private void enforceBanDuplicates(EnforcerContext context) throws EnforcerRuleException {
Expand Down Expand Up @@ -303,7 +299,7 @@ class BanDuplicateClasses extends AbstractResolveDependencies {
}

void ignore(String str) {
if(isNotBlank(str)) ignoreClasses.add(str)
if (isNotBlank(str)) ignoreClasses.add(str)
}

void dependency(String str, Action<? extends Dependency> configurer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import static org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase.AFTER_PROJECT
* Enforcer rule that will check the bytecode version of each class of each dependency.
*
* Adapted from {@code org.apache.maven.plugins.enforcer.EnforceBytecodeVersion}.
* @see <a href="http://en.wikipedia.org/wiki/Java_class_file#General_layout">Java class file general layout</a>
* @see <a href="http://en.wikipedia.org/wiki/Java_class_file#General_layout" >Java class file general layout</a>
*
* @author Andres Almiray
* @since 0.1.0
Expand Down Expand Up @@ -138,6 +138,39 @@ class EnforceBytecodeVersion extends AbstractResolveDependencies {
showErrors = objects.property(Boolean).convention(false)
}

@Override
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
if (maxJdkVersion.present && maxJavaMajorVersionNumber.getOrElse(-1) != -1) {
throw illegalArgumentException('Only maxJdkVersion or maxJavaMajorVersionNumber '
+ 'configuration parameters should be set. Not both.')
}
if (!maxJdkVersion.present && maxJavaMajorVersionNumber.getOrElse(-1) == -1) {
throw illegalArgumentException('Exactly one of maxJdkVersion or '
+ 'maxJavaMajorVersionNumber options should be set.')
}
if (maxJdkVersion.present) {
Integer needle = JDK_TO_MAJOR_VERSION_NUMBER_MAPPING.get(maxJdkVersion.get())
if (!needle) {
throw illegalArgumentException('Unknown JDK version given. Should be something like ' +
'"1.7", "8", "11", "12"')
}
maxJavaMajorVersionNumber.set(needle)
if (needle < 53) {
IgnorableDependency ignoreModuleInfoDependency = new IgnorableDependency()
ignoreModuleInfoDependency.applyIgnoreClasses(DEFAULT_CLASSES_IGNORE_BEFORE_JDK_9)
ignorableDependencies.add(ignoreModuleInfoDependency)
}
}
if (maxJavaMajorVersionNumber.getOrElse(-1) == -1) {
throw fail('maxJavaMajorVersionNumber must be set in the plugin configuration')
}
if (ignoreClasses.get()) {
IgnorableDependency ignorableDependency = new IgnorableDependency()
ignorableDependency.applyIgnoreClasses((List<String>) ignoreClasses.get())
ignorableDependencies.add(ignorableDependency)
}
}

@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
if (context.enforcerPhase == AFTER_PROJECTS) {
Expand All @@ -148,8 +181,6 @@ class EnforceBytecodeVersion extends AbstractResolveDependencies {
}

private void enforceAfterProjectsEvaluated(EnforcerContext context) throws EnforcerRuleException {
computeParameters()

Set<ResolvedArtifact> artifactsSeen = []
Map<ResolvedArtifact, String> allProblems = [:]
context.project.configurations.each { Configuration c ->
Expand All @@ -168,8 +199,6 @@ class EnforceBytecodeVersion extends AbstractResolveDependencies {
}

private void enforceAfterProjectEvaluated(EnforcerContext context) throws EnforcerRuleException {
computeParameters()

Set<ResolvedArtifact> artifactsSeen = []
Map<ResolvedArtifact, String> allProblems = [:]
context.project.configurations.each { Configuration c ->
Expand All @@ -180,38 +209,6 @@ class EnforceBytecodeVersion extends AbstractResolveDependencies {
reportProblems(context, allProblems)
}

private void computeParameters() throws EnforcerRuleException {
if (maxJdkVersion.present && maxJavaMajorVersionNumber.getOrElse(-1) != -1) {
throw illegalArgumentException('Only maxJdkVersion or maxJavaMajorVersionNumber '
+ 'configuration parameters should be set. Not both.')
}
if (!maxJdkVersion.present && maxJavaMajorVersionNumber.getOrElse(-1) == -1) {
throw illegalArgumentException('Exactly one of maxJdkVersion or '
+ 'maxJavaMajorVersionNumber options should be set.')
}
if (maxJdkVersion.present) {
Integer needle = JDK_TO_MAJOR_VERSION_NUMBER_MAPPING.get(maxJdkVersion.get())
if (!needle) {
throw illegalArgumentException('Unknown JDK version given. Should be something like ' +
'"1.7", "8", "11", "12"')
}
maxJavaMajorVersionNumber.set(needle)
if (needle < 53) {
IgnorableDependency ignoreModuleInfoDependency = new IgnorableDependency()
ignoreModuleInfoDependency.applyIgnoreClasses(DEFAULT_CLASSES_IGNORE_BEFORE_JDK_9)
ignorableDependencies.add(ignoreModuleInfoDependency)
}
}
if (maxJavaMajorVersionNumber.getOrElse(-1) == -1) {
throw fail('maxJavaMajorVersionNumber must be set in the plugin configuration')
}
if (ignoreClasses.get()) {
IgnorableDependency ignorableDependency = new IgnorableDependency()
ignorableDependency.applyIgnoreClasses((List<String>) ignoreClasses.get())
ignorableDependencies.add(ignorableDependency)
}
}

private void handleConfiguration(EnforcerContext context,
Configuration configuration,
Map<ResolvedArtifact, String> problemAccumulator,
Expand Down Expand Up @@ -450,7 +447,7 @@ class EnforceBytecodeVersion extends AbstractResolveDependencies {
}

void ignore(String str) {
if(isNotBlank(str)) ignoreClasses.add(str)
if (isNotBlank(str)) ignoreClasses.add(str)
}

void include(String str) {
Expand Down
Loading

0 comments on commit 842de79

Please sign in to comment.