scapegoat icon indicating copy to clipboard operation
scapegoat copied to clipboard

The scapegoat Gradle plugin should not overwrite the source with the test analysis

Open carlspring opened this issue 6 years ago • 3 comments

We're using Scapegoat 3.11. When running:

gradle build

It runs compileScala and compileTestScala, (among other tasks) and both of these are of type ScalaCompile. The documentation specifies that we should use:

tasks.withType(ScalaCompile) {
  scalaCompileOptions.additionalParameters = [
    "-Xplugin:" + configurations.scalaCompilerPlugin.asPath,
    "-P:scapegoat:dataDir:" + buildDir + "/scapegoat"
  ]
}

We did this and it overwrites the scapegoat.xml file of the sources with the one for the tests.

The documentation also states that -P:scapegoat:sourcePrefix: defaults to src/main/scala and that this is not a required setting. We've actually tried specifying this and it didn't help.

If you do the following, you will get a separate file for sources and unit tests:

  tasks.withType(ScalaCompile) {

        scalaCompileOptions.additionalParameters = [
                "-feature",
                "-Xplugin:" + configurations.scalaCompilerPlugin.asPath,
                "-P:scapegoat:dataDir:${buildDir}/reports/scapegoat",
                "-P:scapegoat:reports:xml",
                "-P:scapegoat:sourcePrefix:src/main/scala",
        ]
        options.compilerArgs << "-Xlint:all,-path" << "-Werror"

        doLast {
            def scapegoat_output = "${buildDir}/reports/scapegoat/scapegoat.xml"
            if(file(scapegoat_output).exists()) {
                try {
                    copy {
                        from(scapegoat_output)
                        into("${buildDir}/reports/scapegoat/")
                        rename("scapegoat.xml", "scapegoat-${name}.xml")
                        fileMode = 755
                    }
                    delete scapegoat_output
                } catch (GradleException e) {
                    throw new GradleException("$e.message: $e.cause", e.cause)
                }
            }
        }
    }

This looks like a bug.

Of course, if you're trying to be really strict, you might want to also check your tests, but, generally, you're mainly interested in your production sources.

Would it be possible to change this behaviour, or add an option to be able to control it?

Thanks! :)

carlspring avatar Nov 04 '19 17:11 carlspring

I don't think it's a scapegoat issue. Also, it's not a Gradle plugin, but scala compiler plugin. What is happening here is:

  • scala compiler is started to compile sources for production code and executes analysis on production sources during build step
  • scala compiler is started to compile test code during the test step, analysis is executed and results overwrite the build analysis result.

I think the solution will be either:

  • to trigger analysis only on the build phase in the Gradle configuration.
  • execute build command like ./gradlew build -x test, which will not compile test sources at all.

Another good solution is to write an actual Gradle plugin that will handle the issue for you.

eugene-sy avatar Nov 08 '19 12:11 eugene-sy

@eugene-sy ,

Thanks for your reply!

I agree, I should have worded it properly. It's not a Gradle plugin, but a Scala compiler plugin.

Would you mind illustrating what you meant here:

  • to trigger analysis only on the build phase in the Gradle configuration.

Perhaps there's a better way than what we're doing...?

Thanks! :)

carlspring avatar Nov 08 '19 12:11 carlspring

@carlspring At the moment I cannot think about any solution better than you have. I'm actually trying to solve the same problem at the moment, so there might be a solution sooner or later. Or otherwise a gradle plugin migth appear...

eugene-sy avatar Nov 12 '19 08:11 eugene-sy