Add convenient way to access version information to Bro.

With the introduction of the package manager, it will get more common
that applications are able to get information about the currently
running version of Bro. With this commit, scripts can easily compare
which version of Bro they are running.

Commonly, this probably will either look like this (both lines check if
the current Bro version is greater or equal to 2.5)

@if ( Version::num >= 20500 )
or
@if ( Version::greater_equal("2.5") )

Version::info contains detailed information about the running version of
Bro, including beta flags, etc.
This commit is contained in:
Johanna Amann 2016-09-29 12:45:48 -07:00
parent b6a0802227
commit 35465aaf30
8 changed files with 154 additions and 3 deletions

View file

@ -80,3 +80,4 @@
@load base/misc/find-checksum-offloading @load base/misc/find-checksum-offloading
@load base/misc/find-filtered-trace @load base/misc/find-filtered-trace
@load base/misc/version

View file

@ -0,0 +1,90 @@
##! Set information about the currently running Bro version.
##! The most convenient way to access this are the Version::num
##! and Version::info constants.
@load base/frameworks/reporter
@load base/utils/strings
module Version;
export {
## A type exactly describing a bro version
type VersionDescription: record {
## Number representing the version which can be used for easy comparison.
## The format of the number is ABBCC with A being the major version,
## bb being the minor version (2 digits) and CC being the patchlevel (2 digits).
## As an example, Bro 2.4.1 results in the number 20401
version_num: count;
## Major version number (e.g. 2 for 2.5)
major: count;
## Minor version number (e.g. 5 for 2.5)
minor: count;
## Patch version number (e.g. 0 for 2.5 or 1 for 2.4.1)
patch: count;
## Commit number for development versions, e.g. 12 for 2.4-12. 0 for non-development versions
commit: count;
## If set to true, the version is a beta build of bro
beta: bool;
## If set to true, the version is a debug build
debug: bool;
## String representation of this version
version_string: string;
};
## Parse a given version string.
##
## version_string: Bro version string.
##
## Returns: `VersionDescription` record.
global parse: function(version_string: string): VersionDescription;
## Test if the current running version of Bro is greater or equal to the given version
## string.
##
## version_string: Version to check against the current running version.
##
## Returns: True if running version greater or equal to the given version.
global greater_equal: function(version_string: string): bool;
}
function parse(version_string: string): VersionDescription
{
if ( /[[:digit:]]\.[[:digit:]][[:digit:]]?(\.[[:digit:]][[:digit:]]?)?(\-beta)?(-[[:digit:]]+)?(\-debug)?/ != version_string )
{
Reporter::error(fmt("Version string %s cannot be parsed", version_string));
return VersionDescription($version_num=0, $major=0, $minor=0, $patch=0, $commit=0, $beta=F, $debug=F, $version_string=version_string);
}
local components = split_string1(version_string, /\-/);
local version_split = split_string(components[0], /\./);
local major = to_count(version_split[0]);
local minor = to_count(version_split[1]);
local patchlevel = ( |version_split| > 2) ? to_count(version_split[2]) : 0;
local version_num = major*10000+minor*100+patchlevel;
local beta = /\-beta/ in version_string;
local debug = /\-debug/ in version_string;
local commit = 0;
if ( |components| > 1 )
{
local commitpart = find_last(components[1], /\-[[:digit:]]+/);
commit = ( |commitpart| > 0 ) ? to_count(sub_bytes(commitpart, 2, 999)) : 0;
}
return VersionDescription($version_num=version_num, $major=major, $minor=minor, $patch=patchlevel, $commit=commit, $beta=beta, $debug=debug, $version_string=version_string);
}
export {
## version number of the currently running version of Bro as a numeric representation.
## The format of the number is ABBCC with A being the major version,
## bb being the minor version (2 digits) and CC being the patchlevel (2 digits).
## As an example, Bro 2.4.1 results in the number 20401
const num = Version::parse(bro_version())$version_num;
## `VersionDescription` record pertaining to the currently running version of Bro.
const info = Version::parse(bro_version());
}
function greater_equal(version_string: string): bool
{
return Version::parse(version_string)$version_num >= Version::num;
}

View file

@ -349,7 +349,8 @@ static int match_prefix(int s_len, const char* s, int t_len, const char* t)
VectorVal* do_split_string(StringVal* str_val, RE_Matcher* re, int incl_sep, VectorVal* do_split_string(StringVal* str_val, RE_Matcher* re, int incl_sep,
int max_num_sep) int max_num_sep)
{ {
VectorVal* rval = new VectorVal(string_vec); // string_vec is used early in the version script - do not use the NetVar.
VectorVal* rval = new VectorVal(internal_type("string_vec")->AsVectorType());
const u_char* s = str_val->Bytes(); const u_char* s = str_val->Bytes();
int n = str_val->Len(); int n = str_val->Len();
const u_char* end_of_s = s + n; const u_char* end_of_s = s + n;

View file

@ -0,0 +1,3 @@
yup
yup
yup

View file

@ -0,0 +1,4 @@
error in /Users/johanna/bro/master/scripts/base/misc/version.bro, line 54: Version string 1 cannot be parsed
error in /Users/johanna/bro/master/scripts/base/misc/version.bro, line 54: Version string 12.5 cannot be parsed
error in /Users/johanna/bro/master/scripts/base/misc/version.bro, line 54: Version string 1.12-beta-drunk cannot be parsed
error in /Users/johanna/bro/master/scripts/base/misc/version.bro, line 54: Version string JustARandomString cannot be parsed

View file

@ -0,0 +1,12 @@
[version_num=10500, major=1, minor=5, patch=0, commit=0, beta=F, debug=F, version_string=1.5]
[version_num=20000, major=2, minor=0, patch=0, commit=0, beta=F, debug=F, version_string=2.0]
[version_num=20500, major=2, minor=5, patch=0, commit=0, beta=T, debug=F, version_string=2.5-beta]
[version_num=20501, major=2, minor=5, patch=1, commit=0, beta=F, debug=T, version_string=2.5.1-debug]
[version_num=20500, major=2, minor=5, patch=0, commit=12, beta=T, debug=F, version_string=2.5-beta-12]
[version_num=20500, major=2, minor=5, patch=0, commit=0, beta=F, debug=T, version_string=2.5-12-debug]
[version_num=20502, major=2, minor=5, patch=2, commit=12, beta=T, debug=T, version_string=2.5.2-beta-12-debug]
[version_num=11220, major=1, minor=12, patch=20, commit=2562, beta=T, debug=T, version_string=1.12.20-beta-2562-debug]
[version_num=0, major=0, minor=0, patch=0, commit=0, beta=F, debug=F, version_string=1]
[version_num=0, major=0, minor=0, patch=0, commit=0, beta=F, debug=F, version_string=12.5]
[version_num=0, major=0, minor=0, patch=0, commit=0, beta=F, debug=F, version_string=1.12-beta-drunk]
[version_num=0, major=0, minor=0, patch=0, commit=0, beta=F, debug=F, version_string=JustARandomString]

View file

@ -0,0 +1,40 @@
# @TEST-EXEC: bro %INPUT
# @TEST-EXEC: btest-diff .stdout
# @TEST-EXEC: btest-diff .stderr
# good versions
print Version::parse("1.5");
print Version::parse("2.0");
print Version::parse("2.5-beta");
print Version::parse("2.5.1-debug");
print Version::parse("2.5-beta-12");
print Version::parse("2.5-12-debug");
print Version::parse("2.5.2-beta-12-debug");
print Version::parse("1.12.20-beta-2562-debug");
# bad versions
print Version::parse("1");
print Version::parse("12.5");
print Version::parse("1.12-beta-drunk");
print Version::parse("JustARandomString");
# check that current running version of Bro parses without error
Version::parse(bro_version());
@TEST-START-NEXT
@if ( Version::num >= 20500 )
print "yup";
@endif
@if ( Version::parse("1.5")$version_num < 20500 )
print "yup";
@endif
@if ( Version::greater_equal("2.5") )
print "yup";
@endif
@if ( Version::greater_equal("2.4") )
print "no";
@endif