Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIP-325 Able to parse an app and print property file names #6

Merged
merged 5 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/groovy/com/avioconsulting/mule/MuleLinter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.avioconsulting.mule.linter.rule.pom.MuleMavenPluginVersionRule
import com.avioconsulting.mule.linter.rule.pom.MunitVersionRule
import com.avioconsulting.mule.linter.rule.pom.MuleRuntimeVersionRule
import com.avioconsulting.mule.linter.rule.pom.PomExistsRule
import com.avioconsulting.mule.linter.rule.property.PropertyFileNamingRule

class MuleLinter {

Expand All @@ -23,6 +24,7 @@ class MuleLinter {
rules.addRule(new MuleMavenPluginVersionRule('3.3.5'))
rules.addRule(new MunitVersionRule('2.2.1'))
rules.addRule(new MuleRuntimeVersionRule('4.2.1'))
rules.addRule(new PropertyFileNamingRule(['dev', 'test']))

// Create the executor
RuleExecutor exe = new RuleExecutor(app, rules)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import picocli.CommandLine
@CommandLine.Command(name = 'MuleLinter', header = '%n@|green Mule Linter|@')
class MuleLinterCli implements Runnable {

@CommandLine.Option(names = ['-r', '--rules'], required = true, description = 'Rule definition file')
@CommandLine.Option(names = ['-r', '--rules'], required = false, description = 'Rule definition file')
String rules

@CommandLine.Option(names = ['-d', '--dir'], required = true, description = 'Application Directory')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,33 @@ class Application {
static final String POM_FILE = 'pom.xml'

File applicationPath
List<ProjectFile> files = []
List<PropertyFile> propertyFiles = []
PomFile pomFile
String name

Application(File applicationPath) {
this.applicationPath = applicationPath
if (!this.applicationPath.exists()) {
throw new FileNotFoundException( APPLICATION_DOES_NOT_EXIST + applicationPath.absolutePath)
}
pomFile = new PomFile(applicationPath, POM_FILE)
this.name = pomFile.getArtifactId()

File resourcePath = new File(applicationPath, 'src/main/resources')
if (!resourcePath.exists()) {
throw new FileNotFoundException( APPLICATION_DOES_NOT_EXIST + resourcePath.absolutePath)
}
resourcePath.eachDirRecurse { dir ->
dir.eachFileMatch(~/.*.properties/) { file ->
propertyFiles.add(new PropertyFile(file))
}
}
kkingavio marked this conversation as resolved.
Show resolved Hide resolved
}

File getApplicationPath() {
return applicationPath
}

void setApplicationPath(File applicationPath) {
this.applicationPath = applicationPath
}

PomFile getPomFile() {
return pomFile
}
Expand All @@ -34,4 +42,12 @@ class Application {
return file.exists()
}

String getName() {
return name
}

List<PropertyFile> getPropertyFiles() {
return propertyFiles
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ class PomFile extends ProjectFile {
this(new File(application, fileName))
}

String getArtifactId() {
return exists ? model?.artifactId : ''
}

void setArtifactId(String artifactId) {
this.artifactId = artifactId
}

Boolean doesExist() {
return exists
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.avioconsulting.mule.linter.model
class ProjectFile {

File file
String name

ProjectFile(File f) {
file = f
this.name = f.name
}

File getFile() {
Expand All @@ -16,4 +18,12 @@ class ProjectFile {
this.file = file
}

String getName() {
return name
}

void setName(String name) {
this.name = name
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.avioconsulting.mule.linter.model

class PropertyFile {

File file
String name
Properties properties

PropertyFile(File file) {
this.file = file
this.name = file.name
loadProperties()
}

void loadProperties() {
// TODO Odd scenario, where if i use the properties variable here, I get an error:
// Cannot invoke method load() on null object
Properties props = new Properties()
file.withInputStream {
props.load(it)
}
properties = props
}

File getFile() {
return file
}

Integer getPropertyCount() {
return properties.size()
}

String getProperty(String propertyName) {
return properties.getProperty(propertyName)
}

void setFile(File file) {
this.file = file
}

String getName() {
return name
}

void setName(String name) {
this.name = name
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.avioconsulting.mule.linter.rule.property

import com.avioconsulting.mule.linter.model.Application
import com.avioconsulting.mule.linter.model.RuleViolation
import com.avioconsulting.mule.linter.model.Rule
import groovy.text.SimpleTemplateEngine

@SuppressWarnings(['GStringExpressionWithinString'])
class PropertyFileNamingRule extends Rule {

static final String RULE_ID = 'PROPERTY_FILE_NAMING'
static final String RULE_NAME = 'Property File Naming Rule'
static final String RULE_VIOLATION_MESSAGE = 'Missing property file, files must match naming pattern: '
static final String DEFAULT_PATTERN = '${appname}-${env}.properties'

String[] environments
String pattern

/**
* A new PropertyFileNamingRule for a list of environments. This ensures that
* there is at least one file that matches the pattern '${appname}-${env}.properties'
* for each environment.
*
* @param environments List of environments to check for files
*/
PropertyFileNamingRule(List<String> environments) {
this(environments, DEFAULT_PATTERN)
}

/**
* A new PropertyFileNamingRule for a list of environments. This ensures that
* there is at least one file that matches the pattern for each environment.
* Possible pattern variables ${env} and ${appname}.
*
* @param environments List of environments to check for files
* @param pattern String pattern to search. ex. '${appname}-${env}.properties'
*/
PropertyFileNamingRule(List<String> environments, String pattern) {
this.ruleId = RULE_ID
this.ruleName = RULE_NAME
this.environments = environments
this.pattern = pattern
}

@Override
List<RuleViolation> execute(Application app) {
List<RuleViolation> violations = []

List propertyFilenames = app.propertyFiles*.getName()

environments.each { env ->
Map<String, String> binding = ['appname':app.name, 'env':env]
String fileName = new SimpleTemplateEngine().createTemplate(pattern).make(binding)
if (!(fileName in propertyFilenames)) {
violations.add(new RuleViolation(this, fileName, 0, RULE_VIOLATION_MESSAGE + pattern))
}
}

return violations
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.avioconsulting.mule.linter.rule.property

import com.avioconsulting.mule.linter.model.Application
import com.avioconsulting.mule.linter.model.Rule
import com.avioconsulting.mule.linter.model.RuleViolation
import spock.lang.Specification

@SuppressWarnings(['MethodName', 'MethodReturnTypeRequired', 'GStringExpressionWithinString'])
class PropertyFileNamingRuleTest extends Specification {

private static final List<String> ENVS = ['dev', 'test', 'prod']
private static final String NAMING_PATTERN = '${appname}.${env}.properties'
private static final String APP_NAME = 'SampleMuleApp'

def 'Property File Naming Rule check with pattern'() {
given:
Rule rule = new PropertyFileNamingRule(ENVS, NAMING_PATTERN)

when:
File appDir = new File(this.class.classLoader.getResource(application).file)
Application app = new Application(appDir)
List<RuleViolation> violations = rule.execute(app)

then:
violations.size() == size
violations[0].fileName == 'sample-mule-app.dev.properties'
violations[0].message.contains(NAMING_PATTERN)

where:
application | size
APP_NAME | 1
}

def 'Property File Naming Rule check default pattern'() {
given:
Rule rule = new PropertyFileNamingRule(ENVS)

when:
File appDir = new File(this.class.classLoader.getResource(application).file)
Application app = new Application(appDir)
List<RuleViolation> violations = rule.execute(app)

then:
violations.size() == size
violations[0].fileName == 'sample-mule-app-prod.properties'

where:
application | size
APP_NAME | 1
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prop=value
6 changes: 2 additions & 4 deletions src/test/resources/SampleMuleApp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.avioconsulting.bc</groupId>
<artifactId>np-store-product-sys-api</artifactId>
<!-- IMPORTANT:- Make sure you change this version in your application's
global property(pomVersion) as well to log this current application version -->
<groupId>com.avioconsulting.mulelinter</groupId>
<artifactId>sample-mule-app</artifactId>
<version>1.0.0</version>
<packaging>mule-application</packaging>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
user=jallen
password=![abcdef==]

db.port = 1521
db.host = localhost
db.user = areed
db.secret = BillsRule!
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
user=jallen
password=![abcdef==]

db.port = 1521
db.host = localhost
db.user = areed
db.secret = BillsRule!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
user=jallen
password=![abcdef==]
db.port = 1521
db.host = localhost
db.user = areed
db.secret = BillsRule!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
user=jallen
password=![abcdef==]
db.port = 1521
db.host = localhost
db.user = areed
db.secret = BillsRule!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
user=jallen
password=![abcdef==]
db.port = 1521
db.host = localhost
db.user = areed
db.secret = BillsRule!