Skip to content

Commit 065604d

Browse files
author
Gilles Grousset
committed
Factorized Surefire code
1 parent d32590c commit 065604d

File tree

8 files changed

+240
-327
lines changed

8 files changed

+240
-327
lines changed

objclang/src/main/java/com/backelite/sonarqube/objectivec/surefire/SurefireParser.java renamed to commons/src/main/java/com/backelite/sonarqube/commons/surefire/BaseSurefireParser.java

+15-55
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Swift SonarQube Plugin - Objective-C module - Enables analysis of Swift and Objective-C projects into SonarQube.
2+
* commons - Enables analysis of Swift and Objective-C projects into SonarQube.
33
* Copyright © 2015 Backelite (${email})
44
*
55
* This program is free software: you can redistribute it and/or modify
@@ -15,50 +15,41 @@
1515
* You should have received a copy of the GNU Lesser General Public License
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18-
package com.backelite.sonarqube.objectivec.surefire;
18+
package com.backelite.sonarqube.commons.surefire;
1919

20-
import com.backelite.sonarqube.commons.surefire.SurefireStaxHandler;
21-
import com.backelite.sonarqube.commons.surefire.UnitTestClassReport;
22-
import com.backelite.sonarqube.commons.surefire.UnitTestIndex;
23-
import com.backelite.sonarqube.commons.surefire.UnitTestResult;
24-
import com.google.common.collect.ImmutableList;
2520
import org.slf4j.Logger;
2621
import org.slf4j.LoggerFactory;
2722
import org.sonar.api.batch.SensorContext;
2823
import org.sonar.api.batch.fs.FileSystem;
29-
import org.sonar.api.batch.fs.InputFile;
3024
import org.sonar.api.component.ResourcePerspectives;
3125
import org.sonar.api.measures.CoreMetrics;
3226
import org.sonar.api.measures.Metric;
33-
import org.sonar.api.resources.Project;
3427
import org.sonar.api.resources.Resource;
3528
import org.sonar.api.test.MutableTestPlan;
3629
import org.sonar.api.test.TestCase;
3730
import org.sonar.api.utils.ParsingUtils;
3831
import org.sonar.api.utils.StaxParser;
32+
3933
import javax.annotation.Nullable;
4034
import javax.xml.stream.XMLStreamException;
4135
import java.io.File;
4236
import java.io.FilenameFilter;
43-
import java.util.List;
4437
import java.util.Map;
4538

4639
/**
47-
* Created by gillesgrousset on 06/01/15.
40+
* Created by gillesgrousset on 28/08/2018.
4841
*/
49-
public class SurefireParser {
42+
public abstract class BaseSurefireParser {
5043

51-
private static final Logger LOGGER = LoggerFactory.getLogger(SurefireParser.class);
44+
protected static final Logger LOGGER = LoggerFactory.getLogger(BaseSurefireParser.class);
5245

53-
private final Project project;
54-
private final FileSystem fileSystem;
55-
private final ResourcePerspectives perspectives;
56-
private final SensorContext context;
46+
protected final FileSystem fileSystem;
47+
protected final SensorContext context;
48+
protected final ResourcePerspectives perspectives;
5749

58-
public SurefireParser(Project project, FileSystem fileSystem, ResourcePerspectives resourcePerspectives, SensorContext context) {
59-
this.project = project;
50+
protected BaseSurefireParser(FileSystem fileSystem, ResourcePerspectives perspectives, SensorContext context) {
6051
this.fileSystem = fileSystem;
61-
this.perspectives = resourcePerspectives;
52+
this.perspectives = perspectives;
6253
this.context = context;
6354
}
6455

@@ -75,19 +66,15 @@ public void collect(File reportsDir) {
7566
}
7667

7768
private File[] getReports(File dir) {
69+
7870
if (dir == null || !dir.isDirectory() || !dir.exists()) {
7971
return new File[0];
8072
}
8173

82-
File[] list = dir.listFiles(new FilenameFilter() {
83-
public boolean accept(File dir, String name) {
84-
return name.startsWith("TEST") && name.endsWith(".xml");
85-
}
86-
});
87-
8874
return dir.listFiles(new FilenameFilter() {
8975
public boolean accept(File dir, String name) {
90-
return name.startsWith("TEST") && name.endsWith(".xml");
76+
// .junit is for fastlane support
77+
return (name.startsWith("TEST") && name.endsWith(".xml")) || (name.endsWith(".junit"));
9178
}
9279
});
9380
}
@@ -164,34 +151,7 @@ protected void saveResults(Resource testFile, UnitTestClassReport report) {
164151
}
165152

166153
@Nullable
167-
public Resource getUnitTestResource(String classname) {
168-
169-
String fileName = classname.replace('.', '/') + ".m";
170-
171-
InputFile inputFile = fileSystem.inputFile(fileSystem.predicates().hasPath(fileName));
172-
173-
/*
174-
* Most xcodebuild JUnit parsers don't include the path to the class in the class field, so search for it if it
175-
* wasn't found in the root.
176-
*/
177-
if (inputFile == null) {
178-
List<InputFile> files = ImmutableList.copyOf(fileSystem.inputFiles(fileSystem.predicates().and(
179-
fileSystem.predicates().hasType(InputFile.Type.TEST),
180-
fileSystem.predicates().matchesPathPattern("**/" + fileName.replace("_", "+")))));
181-
182-
if (files.isEmpty()) {
183-
LOGGER.info("Unable to locate test source file {}", fileName);
184-
} else {
185-
/*
186-
* Lazily get the first file, since we wouldn't be able to determine the correct one from just the
187-
* test class name in the event that there are multiple matches.
188-
*/
189-
inputFile = files.get(0);
190-
}
191-
}
192-
193-
return inputFile == null ? null : context.getResource(inputFile);
194-
}
154+
public abstract Resource getUnitTestResource(String classname);
195155

196156
private void saveMeasure(Resource resource, Metric metric, double value) {
197157
if (!Double.isNaN(value)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* commons - Enables analysis of Swift and Objective-C projects into SonarQube.
3+
* Copyright © 2015 Backelite (${email})
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.backelite.sonarqube.commons.surefire;
19+
20+
import com.backelite.sonarqube.commons.Constants;
21+
import org.apache.commons.lang.StringUtils;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
import org.sonar.api.batch.Sensor;
25+
import org.sonar.api.batch.SensorContext;
26+
import org.sonar.api.batch.fs.FileSystem;
27+
import org.sonar.api.component.ResourcePerspectives;
28+
import org.sonar.api.config.Settings;
29+
import org.sonar.api.resources.Project;
30+
import org.sonar.api.scan.filesystem.PathResolver;
31+
32+
import java.io.File;
33+
34+
/**
35+
* Created by gillesgrousset on 28/08/2018.
36+
*/
37+
public abstract class BaseSurefireSensor implements Sensor {
38+
39+
protected static final Logger LOGGER = LoggerFactory.getLogger(BaseSurefireSensor.class);
40+
41+
public static final String REPORTS_PATH_KEY = Constants.PROPERTY_PREFIX + ".surefire.junit.reportsPath";
42+
public static final String DEFAULT_REPORTS_PATH = "sonar-reports/";
43+
44+
45+
protected final FileSystem fileSystem;
46+
protected final PathResolver pathResolver;
47+
protected final ResourcePerspectives resourcePerspectives;
48+
protected final Settings settings;
49+
50+
protected BaseSurefireSensor(FileSystem fileSystem, PathResolver pathResolver, ResourcePerspectives resourcePerspectives, Settings settings) {
51+
this.fileSystem = fileSystem;
52+
this.pathResolver = pathResolver;
53+
this.resourcePerspectives = resourcePerspectives;
54+
this.settings = settings;
55+
}
56+
57+
@Override
58+
public abstract boolean shouldExecuteOnProject(Project project);
59+
60+
@Override
61+
public void analyse(Project project, SensorContext context) {
62+
63+
String path = this.reportPath();
64+
File reportsDir = pathResolver.relativeFile(fileSystem.baseDir(), path);
65+
66+
LOGGER.info("Processing test reports in {}", reportsDir);
67+
68+
if (!reportsDir.isDirectory()) {
69+
LOGGER.warn("JUnit report directory not found at {}", reportsDir);
70+
return;
71+
}
72+
73+
collect(context, reportsDir);
74+
}
75+
76+
protected abstract void collect(SensorContext context, File reportsDir);
77+
78+
protected String reportPath() {
79+
String reportPath = settings.getString(REPORTS_PATH_KEY);
80+
if (reportPath == null) {
81+
reportPath = DEFAULT_REPORTS_PATH;
82+
}
83+
return reportPath;
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Swift SonarQube Plugin - Objective-C module - Enables analysis of Swift and Objective-C projects into SonarQube.
3+
* Copyright © 2015 Backelite (${email})
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.backelite.sonarqube.objectivec.surefire;
19+
20+
import com.backelite.sonarqube.commons.surefire.BaseSurefireParser;
21+
import com.google.common.collect.ImmutableList;
22+
import org.sonar.api.batch.SensorContext;
23+
import org.sonar.api.batch.fs.FileSystem;
24+
import org.sonar.api.batch.fs.InputFile;
25+
import org.sonar.api.component.ResourcePerspectives;
26+
import org.sonar.api.resources.Project;
27+
import org.sonar.api.resources.Resource;
28+
29+
import javax.annotation.Nullable;
30+
import java.util.List;
31+
32+
/**
33+
* Created by gillesgrousset on 06/01/15.
34+
*/
35+
public class ObjectiveCSurefireParser extends BaseSurefireParser {
36+
37+
public ObjectiveCSurefireParser(FileSystem fileSystem, ResourcePerspectives resourcePerspectives, SensorContext context) {
38+
super(fileSystem, resourcePerspectives, context);
39+
}
40+
41+
@Nullable
42+
public Resource getUnitTestResource(String classname) {
43+
44+
String fileName = classname.replace('.', '/') + ".m";
45+
46+
InputFile inputFile = fileSystem.inputFile(fileSystem.predicates().hasPath(fileName));
47+
48+
/*
49+
* Most xcodebuild JUnit parsers don't include the path to the class in the class field, so search for it if it
50+
* wasn't found in the root.
51+
*/
52+
if (inputFile == null) {
53+
List<InputFile> files = ImmutableList.copyOf(fileSystem.inputFiles(fileSystem.predicates().and(
54+
fileSystem.predicates().hasType(InputFile.Type.TEST),
55+
fileSystem.predicates().matchesPathPattern("**/" + fileName.replace("_", "+")))));
56+
57+
if (files.isEmpty()) {
58+
LOGGER.info("Unable to locate test source file {}", fileName);
59+
} else {
60+
/*
61+
* Lazily get the first file, since we wouldn't be able to determine the correct one from just the
62+
* test class name in the event that there are multiple matches.
63+
*/
64+
inputFile = files.get(0);
65+
}
66+
}
67+
68+
return inputFile == null ? null : context.getResource(inputFile);
69+
}
70+
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Swift SonarQube Plugin - Objective-C module - Enables analysis of Swift and Objective-C projects into SonarQube.
3+
* Copyright © 2015 Backelite (${email})
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.backelite.sonarqube.objectivec.surefire;
19+
20+
import com.backelite.sonarqube.commons.surefire.BaseSurefireSensor;
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
23+
import org.sonar.api.batch.CoverageExtension;
24+
import org.sonar.api.batch.DependsUpon;
25+
import org.sonar.api.batch.Sensor;
26+
import org.sonar.api.batch.SensorContext;
27+
import org.sonar.api.batch.fs.FileSystem;
28+
import org.sonar.api.component.ResourcePerspectives;
29+
import org.sonar.api.config.Settings;
30+
import org.sonar.api.resources.Project;
31+
import com.backelite.sonarqube.objectivec.lang.core.ObjectiveC;
32+
import org.sonar.api.scan.filesystem.PathResolver;
33+
34+
import java.io.File;
35+
36+
public class ObjectiveCSurefireSensor extends BaseSurefireSensor {
37+
38+
public ObjectiveCSurefireSensor(final FileSystem fileSystem, final PathResolver pathResolver, final Settings settings, final ResourcePerspectives resourcePerspectives) {
39+
super(fileSystem, pathResolver, resourcePerspectives, settings);
40+
}
41+
42+
@Override
43+
public boolean shouldExecuteOnProject(Project project) {
44+
45+
return project.isRoot() && fileSystem.hasFiles(fileSystem.predicates().hasLanguage(ObjectiveC.KEY));
46+
}
47+
48+
@Override
49+
protected void collect(SensorContext context, File reportsDir) {
50+
LOGGER.info("parsing {}", reportsDir);
51+
new ObjectiveCSurefireParser(fileSystem, resourcePerspectives, context).collect(reportsDir);
52+
}
53+
54+
@Override
55+
public String toString() {
56+
return "Objective-C Surefire Sensor";
57+
}
58+
59+
60+
}

0 commit comments

Comments
 (0)