diff --git a/grails-app/conf/CodeNarcRuleSet.groovy b/grails-app/conf/CodeNarcRuleSet.groovy index 218bed82..2e1dde81 100644 --- a/grails-app/conf/CodeNarcRuleSet.groovy +++ b/grails-app/conf/CodeNarcRuleSet.groovy @@ -21,6 +21,10 @@ ruleset { // description = 'Use of Spring.autowire(...) can become unstable.' // } + rule('file:test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRule.groovy') { + description = 'Consecutive blank lines are not permitted.' + } + // rulesets/basic.xml AssertWithinFinallyBlock AssignmentInConditional @@ -163,7 +167,7 @@ ruleset { BracesForIfElse BracesForMethod BracesForTryCatchFinally - ClassJavadoc +// ClassJavadoc // LineLength SpaceAfterCatch // SpaceAfterClosingBrace diff --git a/scripts/Codenarc.groovy b/scripts/Codenarc.groovy index f7719ae5..ebdd9060 100644 --- a/scripts/Codenarc.groovy +++ b/scripts/Codenarc.groovy @@ -19,6 +19,26 @@ import grails.util.GrailsUtil import org.apache.tools.ant.BuildException +// Begin hack to replace CodeNarc 0.19's implementation of loadRuleScriptFile which blows up in recent Groovy. +// Remove this hack after https://github.com/CodeNarc/CodeNarc/pull/26 gets merged and released +// in future CodeNarc version to fix https://github.com/CodeNarc/CodeNarc/issues/25 +import org.codenarc.ruleset.RuleSetUtil +import org.codenarc.util.io.DefaultResourceFactory +import org.codenarc.util.io.ResourceFactory + +ResourceFactory RESOURCE_FACTORY = new DefaultResourceFactory() +RuleSetUtil.metaClass.'static'.loadRuleScriptFile = { String path -> + def inputStream = RESOURCE_FACTORY.getResource(path).inputStream + Class ruleClass + inputStream.withStream { InputStream input -> + GroovyClassLoader gcl = new GroovyClassLoader(getClass().classLoader) + ruleClass = gcl.parseClass(input.text) + } + RuleSetUtil.assertClassImplementsRuleInterface(ruleClass) + ruleClass.newInstance() +} +// End temporary hack for compatibility between CodeNarc 0.19 and Groovy 1.8.* + includeTargets << grailsScript('_GrailsCompile') target('codenarc': 'Run CodeNarc') { diff --git a/src/groovy/com/netflix/asgard/EntityType.groovy b/src/groovy/com/netflix/asgard/EntityType.groovy index 655c2ece..10073136 100644 --- a/src/groovy/com/netflix/asgard/EntityType.groovy +++ b/src/groovy/com/netflix/asgard/EntityType.groovy @@ -118,7 +118,6 @@ import java.lang.reflect.Modifier { "${it.workflowType.name}-${it.workflowType.version}" as String }) static final EntityType workflowDomain = create('Workflow Domain', { it.name }) - /** * Create an EntityType with specific attributes * diff --git a/src/groovy/com/netflix/asgard/Relationships.groovy b/src/groovy/com/netflix/asgard/Relationships.groovy index 080b725b..f1ec91c3 100644 --- a/src/groovy/com/netflix/asgard/Relationships.groovy +++ b/src/groovy/com/netflix/asgard/Relationships.groovy @@ -287,5 +287,3 @@ class Relationships { parts } } - - diff --git a/src/groovy/com/netflix/asgard/deployment/DeploymentActivities.groovy b/src/groovy/com/netflix/asgard/deployment/DeploymentActivities.groovy index 6c1a224f..51d1e4cf 100644 --- a/src/groovy/com/netflix/asgard/deployment/DeploymentActivities.groovy +++ b/src/groovy/com/netflix/asgard/deployment/DeploymentActivities.groovy @@ -38,7 +38,6 @@ interface DeploymentActivities { */ AsgDeploymentNames getAsgDeploymentNames(UserContext userContext, String clusterName) - /** * Creates the launch configuration for the next ASG in the cluster. * diff --git a/src/groovy/com/netflix/asgard/model/MetricNamespaces.groovy b/src/groovy/com/netflix/asgard/model/MetricNamespaces.groovy index bfb237e1..072317f9 100644 --- a/src/groovy/com/netflix/asgard/model/MetricNamespaces.groovy +++ b/src/groovy/com/netflix/asgard/model/MetricNamespaces.groovy @@ -231,7 +231,6 @@ class MetricNamespaces { private final ImmutableMap allNamespacesByName - /** * Construct MetricNamespaces with specified custom namespace metrics and dimensions. * diff --git a/test/unit/com/netflix/asgard/AwsAutoScalingServiceUnitSpec.groovy b/test/unit/com/netflix/asgard/AwsAutoScalingServiceUnitSpec.groovy index bda4f126..8519d4c3 100644 --- a/test/unit/com/netflix/asgard/AwsAutoScalingServiceUnitSpec.groovy +++ b/test/unit/com/netflix/asgard/AwsAutoScalingServiceUnitSpec.groovy @@ -268,7 +268,6 @@ scheduled actions #scheduleNames and suspended processes #processNames""") autoScalingGroupName: 'service1-int-v008', minSize: 1, desiredCapacity: 2, maxSize: 3)) } - def 'should determine healthy ASG due to no instances'() { awsAutoScalingService = Spy(AwsAutoScalingService) diff --git a/test/unit/com/netflix/asgard/FlowServiceUnitSpec.groovy b/test/unit/com/netflix/asgard/FlowServiceUnitSpec.groovy index d634d63a..99568870 100644 --- a/test/unit/com/netflix/asgard/FlowServiceUnitSpec.groovy +++ b/test/unit/com/netflix/asgard/FlowServiceUnitSpec.groovy @@ -31,7 +31,6 @@ class FlowServiceUnitSpec extends Specification { WorkflowClientFactory workflowClientFactory = new WorkflowClientFactory(Mock(AmazonSimpleWorkflow)) FlowService flowService = new FlowService(workflowClientFactory: workflowClientFactory) - def 'should get new workflow client'() { UserContext userContext = new UserContext(username: 'rtargaryen') Link link = new Link(type: EntityType.cluster, id: '123') @@ -73,5 +72,4 @@ class FlowServiceUnitSpec extends Specification { expect: flowService.getManualActivityCompletionClient('123') instanceof ManualActivityCompletionClient } - } diff --git a/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRule.groovy b/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRule.groovy new file mode 100644 index 00000000..fc9330c8 --- /dev/null +++ b/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRule.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013 Netflix, Inc. + * + * 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.netflix.asgard.codenarc + +import org.codenarc.rule.AbstractRule +import org.codenarc.source.SourceCode + +/** + * Makes sure there are no consecutive lines that are either blank or whitespace only. + */ +class ConsecutiveBlankLinesRule extends AbstractRule { + + String name = 'ConsecutiveBlankLines' + int priority = 3 + + /** + * Apply the rule to the given source, writing violations to the given list. + * @param sourceCode The source to check + * @param violations A list of Violations that may be added to. It can be an empty list + */ + @Override + void applyTo(SourceCode sourceCode, List violations) { + + List lines = sourceCode.getLines() + for (int index = 1; index < lines.size(); index++) { + String line = lines[index] + if (line.trim().isEmpty() && lines[index - 1].trim().isEmpty()) { + violations.add(createViolation(index, line, "File $sourceCode.name has consecutive blank lines")) + } + } + } +} diff --git a/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRuleTest.groovy b/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRuleTest.groovy new file mode 100644 index 00000000..840300bc --- /dev/null +++ b/test/unit/com/netflix/asgard/codenarc/ConsecutiveBlankLinesRuleTest.groovy @@ -0,0 +1,103 @@ +/* + * Copyright 2013 Netflix, Inc. + * + * 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.netflix.asgard.codenarc + +import org.codenarc.rule.AbstractRuleTestCase +import org.codenarc.rule.Rule +import org.junit.Test + +@SuppressWarnings('ConsecutiveBlankLines') +class ConsecutiveBlankLinesRuleTest extends AbstractRuleTestCase { + + @Test + void testRuleProperties() { + assert rule.priority == 3 + assert rule.name == 'ConsecutiveBlankLines' + } + + @Test + void testSuccessScenario() { + final SOURCE = ''' + class MyClass { + + def go() { /* ... */ } + def goSomewhere() { /* ... */ } + + def build() { /* ... */ } + def buildSomething() { /* ... */ } + + } + ''' + assertNoViolations(SOURCE) + } + + @Test + void testClassStartsWithDoubleBlankLines() { + final SOURCE = ''' + class MyClass { + + + void go() { /* ... */ } + } + ''' + assertSingleViolation(SOURCE, 3, '', "File null has consecutive blank lines") + } + + @Test + void testFileStartsWithDoubleBlankLines() { + final SOURCE = ''' + + class MyClass { + void go() { /* ... */ } + } + ''' + assertSingleViolation(SOURCE, 1, '', "File null has consecutive blank lines") + } + + @Test + void testDoubleBlankLinesBetweenMethods() { + final SOURCE = ''' + class MyClass { + void go() { /* ... */ } + + + void stop() { /* ... */ } + + + void run() { /* ... */ } + } + ''' + assertTwoViolations(SOURCE, 4, '', 7, '') + } + + @Test + void testTripleBlankLines() { + final SOURCE = ''' + class MyClass { + void go() { /* ... */ } + + + + void stop() { /* ... */ } + } + ''' + assertTwoViolations(SOURCE, 4, '', 5, '') + } + + protected Rule createRule() { + new ConsecutiveBlankLinesRule() + } +}