-
Notifications
You must be signed in to change notification settings - Fork 363
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 an XSLT pre-analyse step #1096
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- unit test is missing
- UI integration is missing
- think we need then hard coded properties?
- if we add UI: would start with 5 only (instead 10)
*/ | ||
public class CxxExternalRulesSensor extends CxxReportSensor { | ||
public static final Logger LOG = Loggers.get(CxxExternalRulesSensor.class); | ||
public static final String REPORT_PATH_KEY = "sonar.cxx.other.reportPath"; | ||
public static final String SONAR_CXX_XSLT_KEY = "sonar.cxx.xslt."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, but I think should be in an extra sensor and not within CxxReportSensor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If yes: must be clarified how to define order of sensor execution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was uncertain, too. I guess, it's a question of: Which other sensor could benefit? I don't see any use in transforming a report, that already fits to the sensor (which is the case elsewhere).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree with Stefan, this kind of transformation seems applicable only to external sensor since it's the only one that forces users to provide a specific format, @guwirth which other sensors do you think would benefit from this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also the XUnit sensor using a XSLT doing the same: https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/tests/xunit/CxxXunitSensor.java#L233. Question is if we wanna have two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in this case, i think so. the XunitSensor is feeding test metrics, this is to feed issues so they have different purposes. what we can do is to use the same transformation code, @stefanweiser you could take a look into the xunit sensor how its done move the logic to own class and then reuse in both external sensor and xunit sensor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To answer the question of being an extra sensor. This affects sensor execution order: I don't think, that we could enforce a specific order. The documentation do not say something about it. Somebody asked this already, but got not very much information: http://stackoverflow.com/q/42571579/3781684
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case we keep it for 'other' name must be sonar.cxx.other.xslt.xxx.
Think it's not hard to change later one. Let's start as part of 'other'. There is also no problem with the sequence then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo this should be like the https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/tests/xunit/CxxXunitSensor.java so no big complexity here
String outputKey = SONAR_CXX_XSLT_KEY + i + OUTPUT_KEY; | ||
|
||
String stylesheet = FilenameUtils.normalize(settings.getString(SONAR_CXX_XSLT_KEY + i + STYLESHEET_KEY)); | ||
String[] sources = settings.getStringArray(SONAR_CXX_XSLT_KEY + i + SOURCE_KEY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would not support comma separated list. Would use wildcard pattern instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought, that getStringArray would return an array of strings, that are comma-seperated in the settings file and I don't know how to solve wildcard patterns. Is there any reference implementation for this in sonar-cxx?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are doing this in CxxReportSensor.getReports. This is a static function, maybe we can move it https://github.com/SonarOpenCommunity/sonar-cxx/tree/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/utils to make it more general?
sonar-cxx/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/utils/CxxReportSensor.java
Line 126 in 056fbb3
public static List<File> getReports(Settings settings, final File moduleBaseDir, |
} else if ((stylesheet != null) || | ||
((sources != null) && (sources.length > 0)) || | ||
((outputs != null) && (outputs.length > 0))) { | ||
if (stylesheet == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think we need always all three. So one message would be sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do need always all three, but I appreciate a tool, that reports to me exactly what's wrong. Otherwise you have to do some research first to find the bug.
public void execute(SensorContext context) { | ||
try { | ||
transformFiles(); | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think try/catch is at the wrong place. If one transformation is failing no other is executed?
Would prefer: if one transformation is failing, should try the next one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing so would then result in a lot of errors if one transformation fails, because the source of the next transformation step would be missing. I know, that this would be more tolerant.
Its a design decision, which I would leave up to you. So if you want to go on transforming files, even there are errors, then I would implement it that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to now we have two modes: strict and tolerant
- strict: break whole analysis after an error
- tolerant: ignore and continue
This is hidden behind CxxUtils.validateRecovery.
In tolerant mode:
- should continue if one of the XSLT transformation fails and there are more source files in the comma separated list
- should continue with next XSLT transformation if one before was failing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you suggest different behavior for both modes? ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reasons to catch not only on highest level:
- Could be tool A needs transforming A and tool B needs transformation B. If A is failing B should nevertheless work (tolerant mode)
- Same if more then one file has to be transformed. If transformation A handles more then one file it should continue if one transformation is failing.
So you suggest different behavior for both modes? ;-)
Yes behavior of all sensors is different depending on setting of 'sonar.cxx.errorRecoveryEnabled'. But all what you have to do is to call:
https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/utils/CxxUtils.java#L88
@stefanweiser thanks a lot for providing this solution. I started a review with some general questions. |
I want to write a unit test for this, but I was not able get it to work. Seems, that I have to put more effort in this. What do you mean with UI-integration? How do I get that? |
unit test: maybe you can use this as an sample: https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/tests/xunit/CxxXunitSensorTest.java#L79 |
@stefanweiser on server side you can set the properties normally also in the UI <Administration/C++ (Community)>. These properties are defined here: https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java#L79 Question is if XSLT would be a new tab: (6) XSLT Transformation? |
OK, whether it is an own tab or not is a question of "Would it be an own sensor or is it part of a sensor", because in the first case the information is associated to the plugin and is of common nature. In the second case it belongs to the sensor and would be different for every sensor. Currently I believe, that it should belong as a utility class to each sensor. |
@stefanweiser point should be changed before we merge it:
|
@stefanweiser i would also recommend that the xslt in https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/tests/xunit/CxxXunitSensor.java to be moved to a utility library. and be reused in both xunit and external sensor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still in early stages to be merged, tests are missing and we have duplicated functionality in 2 places. so can be made a utility class.
*/ | ||
public class CxxExternalRulesSensor extends CxxReportSensor { | ||
public static final Logger LOG = Loggers.get(CxxExternalRulesSensor.class); | ||
public static final String REPORT_PATH_KEY = "sonar.cxx.other.reportPath"; | ||
public static final String SONAR_CXX_XSLT_KEY = "sonar.cxx.xslt."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo this should be like the https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/tests/xunit/CxxXunitSensor.java so no big complexity here
} | ||
} | ||
|
||
private void transformFile(File stylesheetFile, String source, String output) throws TransformerException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transformation can be done in memory, as the xunit sensor. it should speed up the analysis
Sorry, for being quiet for a long time. I was a bit busy. I integrated most of the change requests and got stuck with testing now. How can I debug these tests (propably just with printf). I added some test files, but it seems that my test will not generate any output files in the test scenario. |
@stefanweiser try intarget\surefire-reports usually all test data ouput is found under those files |
Thanks @jmecosta. This worked pretty well. I've pushed all changes and I hope, that I forgot nothing.
I hope, that you won't find some easter eggs in there. |
I would still try to do the transformation on memory, so the output
properties are really not required. I think the unit test is done like that
…On Thu, 13 Apr 2017, 17:27 Stefan Weiser, ***@***.***> wrote:
Thanks @jmecosta <https://github.com/jmecosta>. This worked pretty well.
I've pushed all changes and I hope, that I forgot nothing.
- The keys start now with: sonar.cxx.other.xslt.*
- Added two unit tests (one for invalid files and one for successful
transformation)
- I use getReports now, so wildcards are supported on the inputs (on
the outputs, there is no way, because it would not be possible to guess the
output names)
- Support for the tolerant and strict way
I hope, that you won't find some easter eggs in there.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1096 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA_jyGU4MFSugenmYtN_iXAsYm16HJEnks5rvjDpgaJpZM4MjmE0>
.
|
But if we would skip the temporaries and output just the last XMLs, you'd have much more to debug if one tranlation script in the midst is buggy. How realistic is the case, where multiple transformation steps are necessary? |
ok, but then the default behaviour should be without the outputs. in normal cases a end user would want to set only the xslt? |
I think the usual way is to set the XSLT, provide one or more input XML(s) and go. The configuration scheme should also change into something like this, if we don't want the intermediate output:
Then there is no need for the different blocks sonar.cxx.xslt.1, 2, 3... The way it is at the moment, we will have to configure more and get more build artifacts but IMHO it is better for debugging and more straight forward. |
Well it's not a big deal, should be ok then, try to rebase and squash to
get the build green
…On Mon, 24 Apr 2017, 14:26 Stefan Weiser, ***@***.***> wrote:
I think the usual way is to set the XSLT, provide one or more input XML(s)
and go. The configuration scheme should also change into something like
this, if we don't want the intermediate output:
sonar.cxx.xslt.stylesheets=MyStylesheet1.xslt,MyStylesheet2.xslt,MyStylesheet3.xslt
sonar.cxx.xslt.source=tool1/reports/xxx-1.xml,tool1/reports/xxx-2.xml
sonar.cxx.xslt.output=reports/other-tool1-1.xml,reports/other-tool1-2.xml
Then there is no need for the different blocks sonar.cxx.xslt.1, 2, 3...
The way it is at the moment, we will have to configure more and get more
build artifacts but IMHO it is better for debugging and more straight
forward.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1096 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA_jyO1-1h3t-7R0N3X1FF7dZZ2CZ0L7ks5rzIbSgaJpZM4MjmE0>
.
|
Now all checks are green. |
I fixed an issue on key naming (sonar.cxx is getting now prefixed by CxxLanguage), that exists since I merged the upstream branch into my fork. |
@stefanweiser thanks for providing this. It's also ok from my side besides minor issues:
|
ACK, renamed it in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stefanweiser Sorry, call me pedantic. But please add also variable and parameter names from <source(s)> to <input(s)>
public static final String KEY = "other"; | ||
public static final String OTHER_XSLT_KEY = KEY + ".xslt."; | ||
public static final String STYLESHEET_KEY = ".stylesheet"; | ||
public static final String SOURCE_KEY = ".inputs"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name should be INPUT_KEY
Boolean goOn = true; | ||
for (int i = 1; (i < 10) && goOn; i++) { | ||
String stylesheetKey = OTHER_XSLT_KEY + i + STYLESHEET_KEY; | ||
String sourceKey = OTHER_XSLT_KEY + i + SOURCE_KEY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name should be inputKey
String outputKey = OTHER_XSLT_KEY + i + OUTPUT_KEY; | ||
|
||
String stylesheet = resolveFilename(baseDir.getAbsolutePath(), cxxLanguage.getStringOption(stylesheetKey)); | ||
List<File> sources = getReports(cxxLanguage, baseDir, sourceKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name should be inputs
} | ||
} | ||
|
||
private void transformFileList(final String baseDir, File stylesheetFile, List<File> sources, List<String> outputs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sources => inputs
|
||
|
||
|
||
public static void transformFile(Source stylesheetFile, File source, File output) throws TransformerException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
source => input
Shame on me. I've just fixed that. |
Hi @stefanweiser thanks a lot. Maybe you can do a final rebase & squash before merge. AppVeyor problem seems to be a tool problem. |
@guwirth: The branch is already rebased. Do you want me to squash all my commits into one? |
@stefanweiser yes if possible. This will trigger a new build. |
@jmecosta can you restart AppVeyor to see if everything is green please. |
Yep, bit later in the day. Tought
…On Sat, 29 Apr 2017, 11:33 Günter Wirth, ***@***.***> wrote:
@jmecosta <https://github.com/jmecosta> can you restart AppVeyor to see
if everything is green please.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1096 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA_jyHu2pjzGGlxxtCm9BZnGX86dY4KPks5r0vXIgaJpZM4MjmE0>
.
|
Sorry for letting you wait. Squashed the feature into one commit. |
@stefanweiser thanks a lot for your contribution and the patience with us 😄. |
Hi folks,
I implemented an XSLT translation. I currently does not support wildcards (don't know how to get the concrete file list out of a wildcard pattern in Java), but multiple input and output files seperated by comma. The translation of files is done before using the report file of the output sensor, so:
`sonar.cxx.xslt.1.stylesheet=MyStylesheets1.xslt
sonar.cxx.xslt.1.source=tool1/reports/xxx-1.xml
sonar.cxx.xslt.1.output=reports/other-tool1-1.xml
sonar.cxx.xslt.2.stylesheet=MyStylesheets2.xslt
sonar.cxx.xslt.2.source=reports/other-tool1-1.xml
sonar.cxx.xslt.2.output=reports/other-tool2-2.xml
sonar.cxx.other.reportPath=reports/other-tool2-2.xml`
will report "reports/other-tool2-2.xml" after translation from tool1/reports/xxx-1.xml to reports/other-tool1-1.xml to reports/other-tool2-2.xml.
I tested it on our own server, but was not able to provide a test case. I think I'm not able to understand the unit test infrastructure...
close #1080
This change is