-
Notifications
You must be signed in to change notification settings - Fork 22
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
[MGPG-81] check format in constructor #11
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.
can you split this into individual PRs for each issue? That makes it much easier to review and track in Jira and release notes.
int otherValue = Integer.parseInt( otherSegments[index] ); | ||
|
||
int compareValue = Integer.compare( thisValue, otherValue ); | ||
int compareValue = Integer.compare( thisSegments[index], otherSegments[index] ); |
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.
can this be a simple int comparison? e.g.
if (thisSegments[index] != otherSegments[index]) {
return thisSegments[index] - otherSegments[index]
}
(Double check my order there)
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 think it would be preferable to adhere to the contract of Integer#compareTo / Integer#compare, which is internally implemented as (x < y) ? -1 : ((x == y) ? 0 : 1)
, because this class is in my opinion just a container for an int array and should behave as such.
But your solution works of course, too. Your call.
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.
Yes. We should adhere to the contract. The contract is more lenient than the current implementation. It just requires negative, positive, or zero at the appropriate places, not -1, 0, or +1 specifically.
int otherValue = Integer.parseInt( otherSegments[index] ); | ||
|
||
int compareValue = Integer.compare( thisValue, otherValue ); | ||
int compareValue = Integer.compare( thisSegments[index], otherSegments[index] ); |
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.
Yes. We should adhere to the contract. The contract is more lenient than the current implementation. It just requires negative, positive, or zero at the appropriate places, not -1, 0, or +1 specifically.
} | ||
|
||
@Override | ||
public int compareTo( GpgVersion other ) | ||
public static GpgVersion parse( String rawVersion ) |
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.
Where does this version string come from? That is, what is it the version of? Is it ever anything that does not match this pattern? E.g. 3.45.2-beta?
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.
As far as I can see the original author of this class made the assumption that it will always be a sequence of numbers delimited by dots (although the original author wrote in the class-level comment, that this is a SemVer parser).
The raw version string is read from the output of gpg --version
apparently.
Unfortunately I am in no position to evaluate whether GPG will continue using this versioning scheme, but it seems they have consistently used it up until now: https://files.gpg4win.org/
In my opinion we can make the assumption, that GPG will continue using a three segment wide versioning scheme just as the original author implemented it.
String[] thisSegments; | ||
Matcher m = p.matcher( rawVersion ); | ||
if ( m.find() ) | ||
final Matcher versionMatcher = VERSION_PATTERN.matcher( rawVersion ); |
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.
The regex might be overkill. Looks like you can just catch and convert the number format exception below.
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.
The original author implemented it in a way, that the full output of gpg --version
(e.g. gpg (GnuPG) 2.2.1
or gpg (GnuPG) 2.0.26 (Gpg4win 2.2.3)
) is passed to this function.
They used the regex to extract the version part out of that output.
It is debatable whether that is the best way to extract the version number (personally I would have extracted the version number part already in GpgVersionParser.GpgVersionConsumer before passing it in here), but I would like to avoid introducing new bugs by breaking with the existing external contract of this class.
In the end it's your call again; I could widen the scope of the refactoring to the whole GPG version parser.
In that case we could change the contract to expect a dot-separated sequence of numbers, move the regex to GpgVersionParser.GpgVersionConsumer
and simply parse it here via splitting.
// EDIT
IMO widening the scope would break the scope of the ticket. The goal was to refactor this class to use IllegalArgumentException
in a proper semantic way by moving the actual parsing from compareTo
to the time the object is created.
give me a minute to run this through jenkins |
{ | ||
this.rawVersion = rawVersion; | ||
} | ||
private static final Pattern VERSION_PATTERN = Pattern.compile( "(\\d+\\.)+(\\d+)" ); |
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 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 are two patterns AFAIK: One in GpgVersionParser.GpgVersionConsumer and this one here.
This one could possibly be removed and GpgVersionParser.GpgVersionConsumer
could pass the extracted version number to GpgVersion
.
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.
It might be even better to use gpgconf --query-swdb gnupg
instead of gpg --version
, because gpgconf returns machine-readable output.
$ gpgconf --query-swdb gnupg
gnupg:2.2.27:-::32849:::::::
although I don't know if that would work with all distributions.
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.
Works on mac, too:
$ gpgconf --query-swdb gnupg
gnupg:2.2.21:-::32849:::::::
Provides an refactored implementation of GpgVersion to address MGPG-81.
The parsing logic is being moved from "GpgVersion#compareTo" to "GpgVersion#parse" to throw IllegalArgumentException in a semantically correct way.