Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for transforming Checkstyle XML output to JUnit XML #283

Merged
merged 12 commits into from
Aug 16, 2024
1 change: 1 addition & 0 deletions java/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ alias(
exports_files([
"checkstyle-strict.xml",
"google-checks.xml",
"checkstyle2junit.xslt",
])

checkstyle_config(
Expand Down
46 changes: 46 additions & 0 deletions java/checkstyle2junit.xslt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml"></xsl:output>

<xsl:template match="/">
<testsuites>
<testsuite package="Checkstyle">
<xsl:attribute name="name">
<xsl:value-of select="//checkstyle/file/@name" />
</xsl:attribute>
<xsl:attribute name="tests">
<xsl:value-of select="count(.//error)" />
</xsl:attribute>
<xsl:attribute name="errors">
<xsl:value-of select="count(.//error)" />
</xsl:attribute>
<xsl:for-each select="//checkstyle">
<xsl:apply-templates />
</xsl:for-each>
</testsuite>
</testsuites>
</xsl:template>

<xsl:template match="error">
<testcase>
<xsl:attribute name="name">
<xsl:value-of select="@source" />
</xsl:attribute>
<xsl:attribute name="classname">
<xsl:value-of select="../@name" />
</xsl:attribute>
<error>
<xsl:attribute name="type">
<xsl:value-of select="@source" />
</xsl:attribute>
<xsl:attribute name="message">
<xsl:text>Line </xsl:text>
<xsl:value-of select="@line" />
<xsl:text>: </xsl:text>
<xsl:value-of select="@message" />
</xsl:attribute>
</error>
</testcase>
</xsl:template>

</xsl:stylesheet>
32 changes: 22 additions & 10 deletions java/private/checkstyle.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@ Checkstyle rule implementation
def _checkstyle_impl(ctx):
info = ctx.attr.config[CheckStyleInfo]
config = info.config_file
output_format = info.output_format

config_dir = paths.dirname(config.short_path)
maybe_cd_config_dir = ["cd {}".format(config_dir)] if config_dir else []

script = "\n".join([
"#!/usr/bin/env bash",
"set -o pipefail",
"set -e",
"set +e",
"OLDPWD=$PWD",
] + maybe_cd_config_dir + [
"$OLDPWD/{lib} -f {output_format} -c {config} {srcs} |sed s:$OLDPWD/::g".format(
"$OLDPWD/{lib} -o checkstyle.xml -f xml -c {config} {srcs}".format(
lib = info.checkstyle.short_path,
output_format = output_format,
config = config.basename,
srcs = " ".join(["$OLDPWD/" + f.short_path for f in ctx.files.srcs]),
),
"checkstyle_exit_code=$?",
# Apply sed to the file in place
"sed s:$OLDPWD/::g checkstyle.xml > checkstyle-stripped.xml",
# Run the Java XSLT transformation tool
"$OLDPWD/{xslt_transformer} checkstyle-stripped.xml $OLDPWD/{xslt} > $XML_OUTPUT_FILE".format(
xslt_transformer = ctx.executable._xslt_transformer.short_path,
xslt = ctx.file.xslt.short_path,
),
"exit $checkstyle_exit_code",
])
out = ctx.actions.declare_file(ctx.label.name + "exec")

Expand All @@ -35,8 +42,8 @@ def _checkstyle_impl(ctx):
)

runfiles = ctx.runfiles(
files = ctx.files.srcs + [info.checkstyle],
)
files = ctx.files.srcs + [info.checkstyle, ctx.file.xslt],
).merge(ctx.attr._xslt_transformer[DefaultInfo].default_runfiles)

return [
DefaultInfo(
Expand Down Expand Up @@ -64,10 +71,15 @@ _checkstyle_test = rule(
[CheckStyleInfo],
],
),
"output_format": attr.string(
doc = "Output Format can be plain or xml. Defaults to plain",
values = ["plain", "xml"],
default = "plain",
"xslt": attr.label(
doc = "Path to the checkstyle2junit.xslt file",
allow_single_file = True,
default = "@contrib_rules_jvm//java:checkstyle2junit.xslt",
),
"_xslt_transformer": attr.label(
default = "@contrib_rules_jvm//java/src/com/github/bazel_contrib/contrib_rules_jvm/xml:XSLTTransformer",
executable = True,
cfg = "exec",
),
},
executable = True,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@rules_java//java:defs.bzl", "java_binary", "java_library")

java_library(
name = "xml",
srcs = ["XSLTTransformer.java"],
visibility = ["//:__subpackages__"],
)

java_binary(
name = "XSLTTransformer",
main_class = "XSLTTransformer",
visibility = ["//visibility:public"],
runtime_deps = [":xml"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class XSLTTransformer {
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: java XSLTTransformer <input.xml> <transform.xslt>");
System.exit(1);
}

String inputXML = args[0];
String xsltFile = args[1];

// Create transformer factory
TransformerFactory factory = TransformerFactory.newInstance();

// Load the XSLT file
StreamSource xslt = new StreamSource(new File(xsltFile));

// Create a transformer
Transformer transformer = factory.newTransformer(xslt);

// Load the input XML file
StreamSource xmlInput = new StreamSource(new File(inputXML));

// Set the output file
StreamResult xmlOutput = new StreamResult(System.out);

// Perform the transformation
transformer.transform(xmlInput, xmlOutput);
}
}
Loading