All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codenarc.CodeNarcRunner.groovy Maven / Gradle / Ivy

There is a newer version: 3.5.0-groovy-4.0
Show newest version
/*
 * Copyright 2009 the original author or 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
 *
 *      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 org.codenarc

import org.codenarc.analyzer.SourceAnalyzer
import org.codenarc.plugin.CodeNarcPlugin
import org.codenarc.plugin.FileViolations
import org.codenarc.report.ReportWriter
import org.codenarc.results.FileResults
import org.codenarc.results.Results
import org.codenarc.rule.Rule
import org.codenarc.ruleregistry.RuleRegistryInitializer
import org.codenarc.ruleset.*

/**
 * Helper class to run CodeNarc.
 * 

* The following properties must be configured before invoking the execute() method: *

    *
  • ruleSetFiles - The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a * single file path, or multiple paths separated by commas.
  • *
  • sourceAnalyzer - An instance of a org.codenarc.analyzer.SourceAnalyzer implementation.
  • *
  • reportWriters - The list of ReportWriter instances. A report is generated * for each element in this list. At least one ReportWriter must be configured.
  • *
* * NOTE: This is an internal class. Its API is subject to change. * * @author Chris Mair */ class CodeNarcRunner { public static final String PLUGINS_PROPERTY = 'org.codenarc.plugins' public static final String STANDARD_PLUGIN_CLASSES = 'org.codenarc.plugin.disablerules.DisableRulesInCommentsPlugin' String ruleSetFiles String ruleSetString SourceAnalyzer sourceAnalyzer List reportWriters = [] String propertiesFilename protected final List plugins = [] protected RuleSetConfigurer ruleSetConfigurer = new PropertiesFileRuleSetConfigurer() /** * The main entry point for this class. Runs CodeNarc and returns the results. Processing steps include: *
    *
  1. Register standard CodeNarcPlugins.
  2. *
  3. Register any CodeNarcPlugins specified by the "org.codenarc.plugins" system property.
  4. *
  5. Call initialize() for each registered CodeNarcPlugin.
  6. *
  7. Parse the ruleSetFiles or ruleSetString property to create a RuleSet. * - ruleSetFiles: Each path may be optionally prefixed by * any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute filesystem path), * or "http:". If it is a URL, its path may be optionally URL-encoded. That can be useful if the path contains * any problematic characters, such as comma (',') or hash ('#'). See {@link URLEncoder#encode(java.lang.String, java.lang.String)}. * - ruleSetString: string containing a ruleSet in JSON format (if set, ruleSetFiles will be ignored) *
  8. *
  9. Call processRules(List) for each registered CodeNarcPlugin
  10. *
  11. Call PropertiesFileRuleSetConfigurer to configure the RuleSet from the "codenarc.properties" file (or propertiesFilename if set).
  12. *
  13. Apply the configured SourceAnalyzer.
  14. *
  15. Call processViolationsForFile(FileViolations) for each file with violations
  16. *
  17. Call processReports(List) for each registered CodeNarcPlugin
  18. *
  19. Generate a report for each configured ReportWriter.
  20. *
  21. Return the Results object representing the analysis results.
  22. *
* @returns the Results object containing the results of the CodeNarc analysis. */ @SuppressWarnings('Println') Results execute() { assert ruleSetFiles || ruleSetString, 'The ruleSetFiles or ruleSetString property must be set' assert sourceAnalyzer, 'The sourceAnalyzer property must be set to a valid SourceAnalyzer' def startTime = System.currentTimeMillis() initializeRuleRegistry() initializePlugins() def ruleSet = buildRuleSet() def results = sourceAnalyzer.analyze(ruleSet) applyPluginsProcessViolationsForAllFiles(results) String countsText = buildCountsText(results) def elapsedTime = System.currentTimeMillis() - startTime def analysisContext = new AnalysisContext(ruleSet:ruleSet, sourceDirectories:sourceAnalyzer.sourceDirectories) writeReports(analysisContext, results) def resultsMessage = 'CodeNarc completed: ' + countsText + " ${elapsedTime}ms" println resultsMessage results } void registerPlugin(CodeNarcPlugin plugin) { assert plugin this.plugins << plugin } List getPlugins() { return plugins } void registerPluginsForClassNames(String pluginClassNames) { if (pluginClassNames) { def classNamesList = pluginClassNames.tokenize(',')*.trim() classNamesList.each { className -> registerPluginForClassName(className) } } } // Helper methods private void initializeRuleRegistry() { new RuleRegistryInitializer().initializeRuleRegistry() } private void initializePlugins() { initializeStandardPlugins() initializePluginsFromSystemProperty() this.plugins.each { plugin -> plugin.initialize() } } private RuleSet buildRuleSet() { RuleSet initialRuleSet = createInitialRuleSet() List rules = applyPluginsProcessRules(initialRuleSet) RuleSet ruleSet = new ListRuleSet(rules) ruleSetConfigurer.configure(ruleSet, propertiesFilename) return ruleSet } private List applyPluginsProcessRules(RuleSet ruleSet) { List rules = new ArrayList(ruleSet.getRules()) // need it mutable this.plugins.each { plugin -> plugin.processRules(rules) } return rules } private void applyPluginsProcessViolationsForAllFiles(Results results) { if (plugins) { if (results.isFile()) { applyPluginsProcessViolationsForFile(results) } results.children.each { childResults -> applyPluginsProcessViolationsForAllFiles(childResults) } } } private void applyPluginsProcessViolationsForFile(FileResults fileResults) { FileViolations fileViolations = new FileViolations(fileResults) this.plugins.each { plugin -> plugin.processViolationsForFile(fileViolations) } } /** * Create and return the RuleSet that provides the source of Rules to be applied. * The returned RuleSet may aggregate multiple underlying RuleSets. * @return a single RuleSet */ protected RuleSet createInitialRuleSet() { (ruleSetString) ? createInitialRuleSetFromString() : createInitialRuleSetFromFiles() } private RuleSet createInitialRuleSetFromString() { return RuleSetUtil.loadRuleSetFromString(ruleSetString) } // Create ruleset from XML, JSON or Groovy files private RuleSet createInitialRuleSetFromFiles() { def paths = ruleSetFiles.tokenize(',') def newRuleSet = new CompositeRuleSet() paths.each { path -> def ruleSet = RuleSetUtil.loadRuleSetFile(path.trim()) newRuleSet.addRuleSet(ruleSet) } newRuleSet } private void writeReports(AnalysisContext analysisContext, Results results) { this.plugins.each { plugin -> plugin.processReports(reportWriters) } reportWriters.each { reportWriter -> reportWriter.writeReport(analysisContext, results) } } private void initializeStandardPlugins() { registerPluginsForClassNames(STANDARD_PLUGIN_CLASSES) } private void initializePluginsFromSystemProperty() { String pluginClassNames = System.getProperty(PLUGINS_PROPERTY) registerPluginsForClassNames(pluginClassNames) } private void registerPluginForClassName(String className) { def pluginClass = getClass().classLoader.loadClass(className) assert CodeNarcPlugin.isAssignableFrom(pluginClass), "The className [$className] is not a CodeNarcPlugin" def plugin = pluginClass.newInstance() registerPlugin(plugin) } private String buildCountsText(Results results) { def p1 = results.getNumberOfViolationsWithPriority(1, true) def p2 = results.getNumberOfViolationsWithPriority(2, true) def p3 = results.getNumberOfViolationsWithPriority(3, true) return "(p1=$p1; p2=$p2; p3=$p3)" } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy