patternjavaMinor
Parsing version number from a Java source file
Viewed 0 times
numberfileversionsourcejavaparsingfrom
Problem
I'm extracting the version number from a file like this one. It works, but I find it clumsy and longer than probably needed.
I'd also appreciate some sanity checks as long as they don't make the code noticeably longer (It's just a script, no full Java parser. Something similar to Guava's getOnlyElement would be nice).
I'd also appreciate some sanity checks as long as they don't make the code noticeably longer (It's just a script, no full Java parser. Something similar to Guava's getOnlyElement would be nice).
version = {->
def lines = file('src/main/org/h2/engine/Constants.java').readLines();
def extract = {name ->
lines.grep {it =~ /public static final int $name =/}[0].replaceFirst(/.*=\s*(\d+);.*/, '$1')
}
extract('VERSION_MAJOR') + '.' + extract('VERSION_MINOR') + '.' + extract('BUILD_ID')
}()Solution
Since you are only looking for a single occurrence of the variable in the file you could match the whole file at once. For example like this:
Instead of getting the lines this script reads the file to one single
In order to do this, we first make sure that the
Although the regular expression is slightly more involved, this way makes it easier to check whether the replacement has worked and prevents a
version = {->
def text = file('src/main/org/h2/engine/Constants.java').text
def extract = {name ->
nameValue = text.replaceAll(/(?s)^.*public\s+static\s+final\s+int\s+$name\s+=\s*(\d+);.*$/, '$1')
text.length() == nameValue.length() ? "Cannot find name" : nameValue;
}
extract('VERSION_MAJOR') + '.' + extract('VERSION_MINOR') + '.' + extract('BUILD_ID')
}()Instead of getting the lines this script reads the file to one single
String, and then uses a regular expression to replace the while text with the variable of interest. In order to do this, we first make sure that the
. in the regexp will match newlines by adding (?s) to the pattern. We then match everything from the start (^.) up until public static final int $name, capture the value with (\d+), and then match everything to the end of the file with .$.Although the regular expression is slightly more involved, this way makes it easier to check whether the replacement has worked and prevents a
NullPointerException. We can now simply compare the length of the original text with the length of the result. If they are the same the replacement has not succeeded and we can return a custom error-message, otherwise we found the variable of interest.Code Snippets
version = {->
def text = file('src/main/org/h2/engine/Constants.java').text
def extract = {name ->
nameValue = text.replaceAll(/(?s)^.*public\s+static\s+final\s+int\s+$name\s+=\s*(\d+);.*$/, '$1')
text.length() == nameValue.length() ? "Cannot find name" : nameValue;
}
extract('VERSION_MAJOR') + '.' + extract('VERSION_MINOR') + '.' + extract('BUILD_ID')
}()Context
StackExchange Code Review Q#54219, answer score: 2
Revisions (0)
No revisions yet.