Skip to content

Commit ae8ce7f

Browse files
Merge pull request #4 from scalastyle/enhance-config-location
enhanced configuration file resolution -> fixes Issue 1
2 parents 08147a5 + 0a351d6 commit ae8ce7f

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)