Skip to content

Commit

Permalink
[#310] Support for inputEncoding and outputEncoding
Browse files Browse the repository at this point in the history
PIT 1.8.1+. In plugin named inputCharset and outputCharset.
  • Loading branch information
szpak committed Aug 19, 2022
1 parent 1086db2 commit c1d957d
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 1.9.0 - Unreleased

- PIT 1.9.4 by default
- Support for inputEncoding and outputEncoding - [#310](https://github.com/szpak/gradle-pitest-plugin/issues/310)
- Add pitest dependencies only during configuration resolution - [#313](https://github.com/szpak/gradle-pitest-plugin/issues/313) - PR by [Ian O'Malley](https://github.com/omalleyian)
- Improve build cache hit cache with relative path - [#315](https://github.com/szpak/gradle-pitest-plugin/issues/315) - PR by [Siddardha Bezawada](https://github.com/SidB3)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package info.solidsoft.gradle.pitest
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.gradle.api.Incubating
import org.gradle.api.provider.Property
import org.gradle.workers.WorkAction
import org.pitest.aggregate.ReportAggregator
import org.pitest.mutationtest.config.DirectoryResultOutputStrategy
import org.pitest.mutationtest.config.UndatedReportDirCreationStrategy

import java.util.function.Consumer

@Slf4j
@Incubating
@CompileStatic
Expand All @@ -23,6 +26,9 @@ abstract class AggregateReportGenerator implements WorkAction<AggregateReportWor
parameters.sourceDirs.each { file -> builder.addSourceCodeDirectory(file) }
parameters.additionalClasspath.each { file -> builder.addCompiledCodeDirectory(file) }

consumeIfPropertyIsSet(parameters.inputCharset) { charset -> builder.inputCharSet(charset) }
consumeIfPropertyIsSet(parameters.outputCharset) { charset -> builder.outputCharset(charset) }

ReportAggregator aggregator = builder.resultOutputStrategy(new DirectoryResultOutputStrategy(
parameters.reportDir.asFile.get().absolutePath,
new UndatedReportDirCreationStrategy()))
Expand All @@ -32,4 +38,10 @@ abstract class AggregateReportGenerator implements WorkAction<AggregateReportWor
log.info("Aggregated report ${parameters.reportFile.asFile.get().absolutePath}")
}

private static <T> void consumeIfPropertyIsSet(Property<T> property, Consumer<T> applyPropertyCode) {
if (property.isPresent()) {
applyPropertyCode.accept(property.get())
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
Expand All @@ -19,6 +22,7 @@ import org.gradle.workers.WorkQueue
import org.gradle.workers.WorkerExecutor

import javax.inject.Inject
import java.nio.charset.Charset

/**
* Task to aggregate pitest report
Expand Down Expand Up @@ -60,6 +64,14 @@ abstract class AggregateReportTask extends DefaultTask {
@Classpath
abstract ConfigurableFileCollection getPitestReportClasspath()

@Input
@Optional
final Property<Charset> inputCharset

@Input
@Optional
final Property<Charset> outputCharset

@Inject
abstract WorkerExecutor getWorkerExecutor()

Expand All @@ -71,6 +83,8 @@ abstract class AggregateReportTask extends DefaultTask {
additionalClasspath = of.fileCollection()
mutationFiles = of.fileCollection()
lineCoverageFiles = of.fileCollection()
inputCharset = of.property(Charset)
outputCharset = of.property(Charset)
}

@TaskAction
Expand All @@ -87,6 +101,8 @@ abstract class AggregateReportTask extends DefaultTask {
parameters.additionalClasspath.from(additionalClasspath)
parameters.mutationFiles.from(mutationFiles)
parameters.lineCoverageFiles.from(lineCoverageFiles)
parameters.inputCharset.set(this.inputCharset)
parameters.outputCharset.set(this.outputCharset)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import org.gradle.api.Incubating
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.workers.WorkParameters

import java.nio.charset.Charset

@Incubating
interface AggregateReportWorkParameters extends WorkParameters {

Expand All @@ -15,5 +18,7 @@ interface AggregateReportWorkParameters extends WorkParameters {
ConfigurableFileCollection getAdditionalClasspath()
ConfigurableFileCollection getMutationFiles()
ConfigurableFileCollection getLineCoverageFiles()
Property<Charset> getInputCharset()
Property<Charset> getOutputCharset()

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.reporting.ReportingExtension
import org.gradle.api.tasks.TaskCollection

import java.util.function.Consumer
import java.util.stream.Collectors

/**
Expand Down Expand Up @@ -64,7 +65,7 @@ class PitestAggregatorPlugin implements Plugin<Project> {
}

private void configureTaskDefaults(AggregateReportTask aggregateReportTask) {
aggregateReportTask.with {
aggregateReportTask.with { task ->
reportDir.set(new File(getReportBaseDirectory(), PitestPlugin.PITEST_REPORT_DIRECTORY_NAME))
reportFile.set(reportDir.file("index.html"))

Expand All @@ -75,22 +76,30 @@ class PitestAggregatorPlugin implements Plugin<Project> {
Set<Project> projectsWithPitest = getProjectsWithPitestPlugin()
mutationFiles.from = collectMutationFiles(projectsWithPitest)
lineCoverageFiles.from = collectLineCoverageFiles(projectsWithPitest)

findPluginExtension().ifPresent({ PitestPluginExtension extension ->
inputCharset.set(extension.inputCharset)
outputCharset.set(extension.outputCharset)
} as Consumer<PitestPluginExtension>) //Simplify with Groovy 3+
}
}

private void addPitAggregateReportDependency(Configuration pitestReportConfiguration) {
pitestReportConfiguration.withDependencies { dependencies ->
Optional<PitestPluginExtension> maybeExtension = Optional.ofNullable(project.extensions.findByType(PitestPluginExtension))
.map { extension -> Optional.of(extension) } //Optional::of with Groovy 3
.orElseGet { findPitestExtensionInSubprojects(project) }
String pitestVersion = maybeExtension
String pitestVersion = findPluginExtension()
.map { extension -> extension.pitestVersion.get() }
.orElse(PitestPlugin.DEFAULT_PITEST_VERSION)

dependencies.add(project.dependencies.create("org.pitest:pitest-aggregator:$pitestVersion"))
}
}

private Optional<PitestPluginExtension> findPluginExtension() {
return Optional.ofNullable(project.extensions.findByType(PitestPluginExtension))
.map { extension -> Optional.of(extension) } //Optional::of with Groovy 3
.orElseGet { findPitestExtensionInSubprojects(project) }
}

private File getReportBaseDirectory() {
if (project.extensions.findByType(ReportingExtension)) {
return project.extensions.getByType(ReportingExtension).baseDir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ class PitestPlugin implements Plugin<Project> {
task.pluginConfiguration.set(extension.pluginConfiguration)
task.maxSurviving.set(extension.maxSurviving)
task.useClasspathJar.set(extension.useClasspathJar)
task.inputEncoding.set(extension.inputCharset)
task.outputEncoding.set(extension.outputCharset)
task.features.set(extension.features)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.SourceSet

import java.nio.charset.Charset

/**
* Extension class with configurable parameters for Pitest plugin.
*
Expand Down Expand Up @@ -178,8 +180,11 @@ class PitestPluginExtension {
@Incubating
final Property<Boolean> useClasspathJar //new in PIT 1.4.2 (GPP 1.4.6)

final Property<Charset> inputCharset //new in PIT 1.8.1 as inputEncoding (GPP 1.9.0)
final Property<Charset> outputCharset //new in PIT 1.8.1 as outputEncoding (GPP 1.9.0)

/**
* Turnes on/off features in PIT itself and its plugins.
* Turns on/off features in PIT itself and its plugins.
*
* Some details: https://github.com/hcoles/pitest/releases/tag/pitest-parent-1.2.1
*
Expand Down Expand Up @@ -263,6 +268,8 @@ class PitestPluginExtension {
pluginConfiguration = nullMapPropertyOf(p, String, String)
maxSurviving = of.property(Integer)
useClasspathJar = of.property(Boolean)
inputCharset = of.property(Charset)
outputCharset = of.property(Charset)
features = nullListPropertyOf(p, String)
fileExtensionsToFilter = nullListPropertyOf(p, String)
}
Expand Down Expand Up @@ -296,6 +303,16 @@ class PitestPluginExtension {
this.enableDefaultIncrementalAnalysis.set(withHistory)
}

@Deprecated //Alias for inputCharset to keep naming compatibility with PIT
void setInputEncoding(Charset inputCharset) {
this.inputCharset.set(inputCharset)
}

@Deprecated //Alias for outputCharset to keep naming compatibility with PIT
void setOutputEncoding(Charset outputCharset) {
this.outputCharset.set(outputCharset)
}

private static <T> SetProperty<T> nullSetPropertyOf(Project p, Class<T> clazz) {
return p.objects.setProperty(clazz).convention(p.providers.provider { null } as Provider) //coercion due to "red" warning in Idea
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/groovy/info/solidsoft/gradle/pitest/PitestTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.options.Option

import java.nio.charset.Charset

/**
* Gradle task implementation for Pitest.
*/
Expand Down Expand Up @@ -223,6 +225,14 @@ class PitestTask extends JavaExec {
@Optional
final Property<Boolean> useClasspathJar

@Input
@Optional
final Property<Charset> inputEncoding

@Input
@Optional
final Property<Charset> outputEncoding

@Input
@Optional
final ListProperty<String> features
Expand Down Expand Up @@ -285,6 +295,8 @@ class PitestTask extends JavaExec {
pluginConfiguration = of.mapProperty(String, String)
maxSurviving = of.property(Integer)
useClasspathJar = of.property(Boolean)
inputEncoding = of.property(Charset)
outputEncoding = of.property(Charset)
additionalClasspath = of.fileCollection()
useAdditionalClasspathFile = of.property(Boolean)
additionalClasspathFile = of.fileProperty()
Expand Down Expand Up @@ -367,6 +379,8 @@ class PitestTask extends JavaExec {
map['jvmPath'] = getJvmPath()?.getOrNull()?.asFile?.absolutePath
map['maxSurviving'] = optionalPropertyAsString(maxSurviving)
map['useClasspathJar'] = optionalPropertyAsString(useClasspathJar)
map['inputEncoding'] = optionalPropertyAsString(inputEncoding)
map['outputEncoding'] = optionalPropertyAsString(outputEncoding)
map['features'] = (features.getOrElse([]) + (additionalFeatures ?: []))?.join(',')
map.putAll(prepareMapWithClasspathConfiguration())
map.putAll(prepareMapWithIncrementalAnalysisConfiguration())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class PitestAggregatorPluginTest extends Specification {

// void "use pitest version from subproject project configuration"() {} //TODO: Can be implemented with ProjectBuilder? withParent()?

// void "use configured charset in aggregation"() {} //TODO: Can be tested in "unit" way?

private void assertThatTasksAreInGroup(List<String> taskNames, String group) {
taskNames.each { String taskName ->
Task task = project.tasks[taskName]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package info.solidsoft.gradle.pitest
import groovy.transform.CompileDynamic
import spock.lang.Issue

import java.nio.charset.Charset

//TODO: Think if task initialization with WithPitestTaskInitialization is not performed to early
// (see PitestTaskTestPluginConfigurationSpec for corner case with login in PitestPlugin)
@CompileDynamic
Expand Down Expand Up @@ -56,6 +58,8 @@ class PitestTaskConfigurationSpec extends BasicProjectBuilderSpec implements Wit
'jvmPath',
'maxSurviving',
'useClasspathJar',
'inputEncoding',
'outputEncoding',
'features',
'historyInputLocation',
'historyOutputLocation',
Expand Down Expand Up @@ -168,6 +172,9 @@ class PitestTaskConfigurationSpec extends BasicProjectBuilderSpec implements Wit
//pluginConfiguration tested separately
"maxSurviving" | 20 || "20"
"useClasspathJar" | true || "true"
//inputCharset and outputCharset tested separately - they set inputEncoding and outputEncoding in PIT
"inputEncoding" | Charset.forName("ISO-8859-2") || "ISO-8859-2"
"outputEncoding" | Charset.forName("ISO-8859-1") || "ISO-8859-1"
"features" | ["-FOO", "+BAR(a[1] a[2])"] || "-FOO,+BAR(a[1] a[2])"
//fileExtensionsToFilter not passed to PIT, tested separately
}
Expand Down Expand Up @@ -249,6 +256,18 @@ class PitestTaskConfigurationSpec extends BasicProjectBuilderSpec implements Wit
] as Set
}
void "should set input/output encoding in PIT for input/output charset"() {
given:
String inputEncodingAsString = "ISO-8859-2"
String outputEncodingAsString = "ISO-8859-1"
and:
project.pitest.inputCharset = Charset.forName(inputEncodingAsString)
project.pitest.outputCharset = Charset.forName(outputEncodingAsString)
expect:
task.taskArgumentMap()['inputEncoding'] == inputEncodingAsString
task.taskArgumentMap()['outputEncoding'] == outputEncodingAsString
}
private Set<String> assembleMainSourceDirAsStringSet() {
return ["resources", "java"].collect { String dirName ->
new File(project.projectDir, "src/main/${dirName}")
Expand Down

0 comments on commit c1d957d

Please sign in to comment.