Skip to content

Commit 0a351d6

Browse files
committed
enhanced configuration file resolution
Supports default configuration from scalastyle jar Classpath resource can be specified Configuration location can be web URL Configuration file can be resolved from jar by adding dependency to plugin
1 parent 08147a5 commit 0a351d6

File tree

10 files changed

+215
-13
lines changed

10 files changed

+215
-13
lines changed

pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@
4444
<version>3.2</version>
4545
<scope>provided</scope>
4646
</dependency>
47+
<dependency>
48+
<groupId>org.apache.maven</groupId>
49+
<artifactId>maven-core</artifactId>
50+
<version>${maven.version}</version>
51+
<scope>provided</scope>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.codehaus.plexus</groupId>
55+
<artifactId>plexus-resources</artifactId>
56+
<version>1.0-alpha-7</version>
57+
</dependency>
4758

4859
<dependency>
4960
<groupId>junit</groupId>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
invoker.goals=clean compile
2+
invoker.buildResult=success

src/it/classpath_config/pom.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<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">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>it.scalastyle-maven-plugin</groupId>
7+
<artifactId>classpath-config</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
<name>Test classpath config file</name>
10+
<description>Test that scalastyle config file acn be resolved from classpath</description>
11+
<packaging>pom</packaging>
12+
<dependencies>
13+
</dependencies>
14+
15+
<build>
16+
<plugins>
17+
<plugin>
18+
<groupId>@project.groupId@</groupId>
19+
<artifactId>@project.artifactId@</artifactId>
20+
<version>@project.version@</version>
21+
<configuration>
22+
<verbose>true</verbose>
23+
<failOnViolation>true</failOnViolation>
24+
<includeTestSourceDirectory>true</includeTestSourceDirectory>
25+
<failOnWarning>false</failOnWarning>
26+
<sourceDirectories>
27+
<dir>${src.it}/testsrc</dir>
28+
</sourceDirectories>
29+
<configLocation>org/scalastyle/classpath_scalastyle_config.xml</configLocation>
30+
</configuration>
31+
<executions>
32+
<execution>
33+
<id>scalastyle</id>
34+
<phase>process-sources</phase>
35+
<goals>
36+
<goal>check</goal>
37+
</goals>
38+
</execution>
39+
</executions>
40+
</plugin>
41+
</plugins>
42+
</build>
43+
</project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<scalastyle>
2+
<name>Scalastyle standard configuration for maven tests</name>
3+
<check level="warning" class="org.scalastyle.file.FileLengthChecker" enabled="true">
4+
<parameters>
5+
<parameter name="maxFileLength">1</parameter>
6+
</parameters>
7+
</check>
8+
</scalastyle>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
try {
2+
3+
def file = new File(basedir, 'target')
4+
assert !file.exists()
5+
6+
assert new File(basedir, "build.log").readLines().grep(~/.*warning.*Foobar.scala message=File length exceeds.*/).size() == 1
7+
8+
return true
9+
10+
} catch(Throwable e) {
11+
e.printStackTrace()
12+
return false
13+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
invoker.goals=clean compile
2+
invoker.buildResult=success

src/it/default_config/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<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">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>it.scalastyle-maven-plugin</groupId>
7+
<artifactId>classpath-config</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
<name>Test scalastyle default config file</name>
10+
<description>Test that scalastyle config file can be resolved as default if none is specified</description>
11+
<packaging>pom</packaging>
12+
<dependencies>
13+
</dependencies>
14+
15+
<build>
16+
<plugins>
17+
<plugin>
18+
<groupId>@project.groupId@</groupId>
19+
<artifactId>@project.artifactId@</artifactId>
20+
<version>@project.version@</version>
21+
<configuration>
22+
<verbose>true</verbose>
23+
<failOnViolation>true</failOnViolation>
24+
<includeTestSourceDirectory>true</includeTestSourceDirectory>
25+
<failOnWarning>false</failOnWarning>
26+
<sourceDirectories>
27+
<dir>${src.it}/testsrc</dir>
28+
</sourceDirectories>
29+
</configuration>
30+
<executions>
31+
<execution>
32+
<id>scalastyle</id>
33+
<phase>process-sources</phase>
34+
<goals>
35+
<goal>check</goal>
36+
</goals>
37+
</execution>
38+
</executions>
39+
</plugin>
40+
</plugins>
41+
</build>
42+
</project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
try {
2+
3+
def file = new File(basedir, 'target')
4+
assert !file.exists()
5+
6+
assert new File(basedir, "build.log").readLines().grep(~/.*warning.*Header does not match expected text.*/).size() == 1
7+
8+
return true
9+
10+
} catch(Throwable e) {
11+
e.printStackTrace()
12+
return false
13+
}

src/it/no_config/validate.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ try {
33
def file = new File(basedir, 'target')
44
assert !file.exists()
55

6-
assert new File(basedir, "build.log").readLines().grep(~/.*\[ERROR\].*configLocation.*does not exist.*/).size() == 1
6+
assert new File(basedir, "build.log").readLines().grep(~/.*\[ERROR\].*Unable to find configuration file at location.*/).size() == 1
77

88
return true
99

src/main/java/org/scalastyle/maven/plugin/ScalastyleViolationCheckMojo.java

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,24 @@
1818

1919
import java.io.File;
2020
import java.math.BigInteger;
21+
import java.net.URL;
22+
import java.net.URLClassLoader;
2123
import java.util.ArrayList;
2224
import java.util.Arrays;
2325
import java.util.Collections;
2426
import java.util.Date;
2527
import java.util.LinkedList;
2628
import java.util.List;
2729

30+
import org.apache.maven.model.Resource;
2831
import org.apache.maven.plugin.AbstractMojo;
2932
import org.apache.maven.plugin.MojoExecutionException;
3033
import org.apache.maven.plugin.MojoFailureException;
31-
import org.apache.maven.plugins.annotations.LifecyclePhase;
32-
import org.apache.maven.plugins.annotations.Mojo;
33-
import org.apache.maven.plugins.annotations.Parameter;
34+
import org.apache.maven.plugins.annotations.*;
35+
import org.apache.maven.project.MavenProject;
36+
import org.codehaus.plexus.resource.ResourceManager;
37+
import org.codehaus.plexus.resource.loader.FileResourceCreationException;
38+
import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
3439
import org.scalastyle.Directory;
3540
import org.scalastyle.FileSpec;
3641
import org.scalastyle.Message;
@@ -45,12 +50,25 @@
4550
/**
4651
* Entry point for scalastyle maven plugin.
4752
*/
48-
@Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY, requiresProject = true)
53+
@Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY, requiresProject = true, requiresDependencyResolution = ResolutionScope.TEST)
4954
public class ScalastyleViolationCheckMojo extends AbstractMojo {
55+
5056
/**
51-
* Specifies the configuration file location
57+
* <p>
58+
* Specifies the location of the scalstyle XML configuration file to use.
59+
* </p>
60+
* <p>
61+
* Potential values are a filesystem path, a URL, or a classpath resource.
62+
* </p>
63+
* <p>
64+
* This parameter is resolved as file, classpath resource then URL.
65+
* </p>
66+
* <p>
67+
* <b>default_config.xml</b> from scalastyle classpath jar is used if non is specified in configuration
68+
* </p>
69+
* <p/>
5270
*/
53-
@Parameter(property = "scalastyle.config.location", required = true)
71+
@Parameter(property = "scalastyle.config.location", required = true, defaultValue = "default_config.xml")
5472
private String configLocation;
5573

5674
/**
@@ -147,6 +165,16 @@ public class ScalastyleViolationCheckMojo extends AbstractMojo {
147165
@Parameter(property = "scalastyle.input.encoding")
148166
private String inputEncoding;
149167

168+
169+
/**
170+
* The Maven Project Object.
171+
*/
172+
@Component
173+
protected MavenProject project;
174+
175+
@Component
176+
private ResourceManager resourceManager;
177+
150178
public void execute() throws MojoFailureException, MojoExecutionException {
151179
if (Boolean.TRUE.equals(skip)) {
152180
getLog().warn("Scalastyle:check is skipped as scalastyle.skip=true");
@@ -175,10 +203,8 @@ public void execute() throws MojoFailureException, MojoExecutionException {
175203
}
176204

177205
private void performCheck() throws MojoFailureException, MojoExecutionException {
178-
checkConfigFile(configLocation);
179-
180206
try {
181-
ScalastyleConfiguration configuration = ScalastyleConfiguration.readFromXml(configLocation);
207+
ScalastyleConfiguration configuration = ScalastyleConfiguration.readFromXml(getConfigFile(configLocation));
182208
long start = now();
183209
List<Message<FileSpec>> messages = new ScalastyleChecker<FileSpec>().checkFilesAsJava(configuration, getFilesToProcess());
184210

@@ -221,14 +247,55 @@ private long now() {
221247
return new Date().getTime();
222248
}
223249

224-
private void checkConfigFile(String configLocation) throws MojoFailureException, MojoExecutionException {
250+
private String getConfigFile(String configLocation) throws MojoFailureException {
225251
if (configLocation == null) {
226252
throw new MojoFailureException("configLocation is required");
227253
}
228254

229-
if (!new File(configLocation).exists()) {
230-
throw new MojoFailureException("configLocation " + configLocation + " does not exist");
255+
if (new File(configLocation).exists()) {
256+
return configLocation;
257+
}
258+
259+
ClassLoader original = Thread.currentThread().getContextClassLoader();
260+
try {
261+
Thread.currentThread().setContextClassLoader(getClassLoaderWithProjectResources());
262+
File configFile = resourceManager.getResourceAsFile(configLocation);
263+
if ( configFile == null ){
264+
throw new MojoFailureException("Unable to process configuration file at location "+ configLocation);
265+
}
266+
return configFile.getAbsolutePath();
267+
} catch (ResourceNotFoundException e) {
268+
throw new MojoFailureException("Unable to find configuration file at location "+ configLocation);
269+
} catch (FileResourceCreationException e) {
270+
throw new MojoFailureException("Unable to process configuration file at location "+ configLocation,e);
271+
}finally {
272+
Thread.currentThread().setContextClassLoader(original);
273+
}
274+
275+
}
276+
277+
private URLClassLoader getClassLoaderWithProjectResources() throws MojoFailureException {
278+
List<String> classPathStrings = new ArrayList<String>();
279+
List<URL> urls = new ArrayList<URL>( classPathStrings.size() );
280+
281+
try {
282+
classPathStrings.addAll(project.getTestCompileSourceRoots());
283+
classPathStrings.addAll(project.getCompileSourceRoots());
284+
285+
for(Resource resource:project.getTestResources()){
286+
classPathStrings.add(resource.getDirectory());
287+
}
288+
for(Resource resource:project.getResources()){
289+
classPathStrings.add(resource.getDirectory());
290+
}
291+
for ( String path : classPathStrings ){
292+
urls.add(new File(path).toURI().toURL());
293+
}
294+
} catch (Exception e) {
295+
throw new MojoFailureException(e.getMessage(),e);
231296
}
297+
298+
return new URLClassLoader(urls.toArray(new URL[urls.size()]), Thread.currentThread().getContextClassLoader());
232299
}
233300

234301
private List<FileSpec> getFilesToProcess() {
@@ -271,3 +338,4 @@ private List<File> arrayOrValue(File[] array, File value) {
271338
return (array != null) ? Arrays.asList(array) : Collections.singletonList(value);
272339
}
273340
}
341+

0 commit comments

Comments
 (0)