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

Exit sputnik with error code if checks fail #205

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

marquiswang
Copy link
Contributor

This allows scripts/tools to take the return result into account.

Furthermore, Extensions of sputnik like the sputnik-maven-plugin can use
a return value of the Engine to communicate the result of a run and do
something like fail a build.

Implement this by adding a Score object (with the review label and the
score value as fields) and return that in Engine.run().

If a failing score value (< 0) is returned, then call System.exit with
the score as the error status.

@codecov-io
Copy link

codecov-io commented Oct 15, 2019

Codecov Report

Merging #205 into master will decrease coverage by 0.79%.
The diff coverage is 66.96%.

Impacted file tree graph

@@             Coverage Diff             @@
##             master     #205     +/-   ##
===========================================
- Coverage     72.52%   71.72%   -0.8%     
- Complexity      592      608     +16     
===========================================
  Files           142      147      +5     
  Lines          1889     1956     +67     
  Branches        121      129      +8     
===========================================
+ Hits           1370     1403     +33     
- Misses          462      490     +28     
- Partials         57       63      +6
Impacted Files Coverage Δ Complexity Δ
...in/java/pl/touk/sputnik/engine/VisitorBuilder.java 100% <ø> (ø) 9 <0> (-5) ⬇️
...c/main/java/pl/touk/sputnik/review/ReviewFile.java 92.3% <ø> (ø) 7 <0> (ø) ⬇️
src/main/java/pl/touk/sputnik/engine/Engine.java 0% <0%> (ø) 0 <0> (ø) ⬇️
src/main/java/pl/touk/sputnik/Main.java 0% <0%> (ø) 0 <0> (ø) ⬇️
...ain/java/pl/touk/sputnik/connector/Connectors.java 0% <0%> (ø) 0 <0> (ø) ⬇️
src/main/java/pl/touk/sputnik/review/Review.java 65% <100%> (ø) 13 <1> (+1) ⬆️
.../java/pl/touk/sputnik/connector/ConnectorType.java 66.66% <100%> (+2.38%) 3 <0> (ø) ⬇️
...a/pl/touk/sputnik/configuration/GeneralOption.java 98.36% <100%> (ø) 3 <0> (ø) ⬇️
...ouk/sputnik/engine/score/ScoreStrategyFactory.java 100% <100%> (ø) 7 <7> (?)
...uk/sputnik/connector/local/LocalFacadeBuilder.java 14.28% <14.28%> (ø) 1 <1> (?)
... and 16 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f4d3393...0355151. Read the comment docs.

@@ -15,6 +16,7 @@
StashFacadeBuilder stashFacadeBuilder = new StashFacadeBuilder();
GithubFacadeBuilder githubFacadeBuilder = new GithubFacadeBuilder();
SaasFacadeBuilder saasFacadeBuilder = new SaasFacadeBuilder();
LocalFacadeBuilder localFacadeBuilder = new LocalFacadeBuilder();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Checkstyle] ERROR: Variable 'localFacadeBuilder' must be private and have accessor methods.

@@ -11,6 +11,8 @@
import pl.touk.sputnik.review.Review;
import pl.touk.sputnik.review.ReviewFile;

import java.util.ArrayList;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Checkstyle] ERROR: Unused import - java.util.ArrayList.

Copy link
Collaborator

@SpOOnman SpOOnman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your idea. What do you think of a Score object? Can it be better than enum?


import java.io.IOException;

public class LocalFacadeBuilder {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase with sputnik:master so these diffs will go away.

Comment on lines 55 to 66
String scoreStrategyName = scoreStrategyName();
if (!ScoreStrategy.isValidScoreStrategy(scoreStrategyName)) {
log.warn("Score strategy {} not found, using default ScoreAlwaysPass", scoreStrategyName);
}

Score score = ScoreStrategy.of(scoreStrategyName).score(review);
review.setScore(score);
log.info("{} violations found, {} errors. Adding score {}",
review.getTotalViolationCount(),
review.getViolationCount().get(Severity.ERROR),
score);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a class or a visitor to me. What do you think?

}

@NotNull
private String scoreStrategyName() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code does not belong to Engine. It should be moved elsewhere.

@@ -0,0 +1,9 @@
package pl.touk.sputnik.engine.score;

public enum Score {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we miss opportunity here. There is a degradation of how much information we have. I'm not sure how much information this object should contain for now, but I feel this is too little.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought is that old code returned a singleton map of label and score. However, the label and numerical score were never affected by the review processors - it was just configuration that was passed through. The only actual information that is necessary is the pass condition.

In fact, the label and numerical score is unused by all of the ReviewPublishers except for the Gerrit one. This felt more generic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right about previous implementation. I just thought we can pass an object here with enum inside and some other information in future.

}

@NotNull
private ScoreStrategy getScoreStrategy(String aScoreStrategy, String aS) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aScoreStrategy is not used here and aS is too short for a parameter name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How embarrassing. I'll fix this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thank you.

};


private static final String NOSCORE = "NOSCORE";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a code duplication here. It's the same code as in ScoreStrategies.


import java.util.Set;

public enum ScoreStrategy {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not happy with this refactoring. This is a business login implementation within enum methods. You've moved builder into a map. I prefer it the way it was before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention was to use implement a strategy pattern with enums, since there's no state so there only needs to be one instance of each one. I can revert this to ScoreStrategy being an interface with 4 implementations if you prefer. You no longer need a builder because there's nothing to build.

The advantage of this is that you can still do logging. Yeah that's a good advantage. I will do that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

}

@NotNull
private GerritScoreLabeler scoreLabeler(Configuration configuration) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this fits more to ReviewInputBuilder.

@SpOOnman
Copy link
Collaborator

I've made a change in master branch that fixed one but so I guess you must rebase again.

Robot comments show up in the Findings tab, instead of in the comments.
This makes it much easier to differentiate from them a reviewer's
comments.

The API requires a "runId" for the comment. I've chosen to just send a
random UUID for now, but eventually we could wire in something like a
build number or something.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants