From 7f40d4e2559b2f4920feaf9d609a79b7809a815c Mon Sep 17 00:00:00 2001 From: Valko Laszlo Date: Mon, 15 Apr 2019 01:51:21 +0200 Subject: [PATCH] Implemented option to specify version numbers to install/remove through an expression. --- pkgtool.pm | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/pkgtool.pm b/pkgtool.pm index c916e54..1a74fc8 100644 --- a/pkgtool.pm +++ b/pkgtool.pm @@ -96,7 +96,22 @@ my $pkgdef_syntax = { Type => 'string' }, 'patching-version' => { - Type => 'string' + Type => 'or', + Options => [{ + Type => 'string' + }, { + Type => 'struct', + Check => \&check_cfg_patching_version_struct, + Keywords => { + 'type' => { + Type => 'string', + Mandatory => 1 + }, + 'expression' => { + Type => 'string' + } + } + }] }, 'install-check' => { Type => 'string' @@ -517,10 +532,40 @@ my $global_cfg_syntax = { Type => 'string' }, 'remove-version' => { - Type => 'string' + Type => 'or', + Options => [{ + Type => 'string' + }, { + Type => 'struct', + Check => \&check_cfg_remove_version_struct, + Keywords => { + 'type' => { + Type => 'string', + Mandatory => 1 + }, + 'expression' => { + Type => 'string' + } + } + }] }, 'install-version' => { - Type => 'string' + Type => 'or', + Options => [{ + Type => 'string' + }, { + Type => 'struct', + Check => \&check_cfg_install_version_struct, + Keywords => { + 'type' => { + Type => 'string', + Mandatory => 1 + }, + 'expression' => { + Type => 'string' + } + } + }] }, 'patch-packages' => { Type => 'list', @@ -1223,6 +1268,66 @@ sub check_cfg_pkg_version_struct ($$) return 1; } +sub check_cfg_patching_version_struct ($$) +{ + my ($option, $label) = @_; + + my $type = $$option{type}; + + if ($type eq 'expression') { + if (! defined $$option{'expression'}) { + print_log('pkg', ERROR, 'Package patching version option missing "expression" at %s', $label); + return 0; + } + } + else { + print_log('pkg', ERROR, 'Unknown package patching version option type at %s', $label.': '.$type); + return 0; + } + + return 1; +} + +sub check_cfg_install_version_struct ($$) +{ + my ($option, $label) = @_; + + my $type = $$option{type}; + + if ($type eq 'expression') { + if (! defined $$option{'expression'}) { + print_log('pkg', ERROR, 'Install version option missing "expression" at %s', $label); + return 0; + } + } + else { + print_log('pkg', ERROR, 'Unknown install version option type at %s', $label.': '.$type); + return 0; + } + + return 1; +} + +sub check_cfg_remove_version_struct ($$) +{ + my ($option, $label) = @_; + + my $type = $$option{type}; + + if ($type eq 'expression') { + if (! defined $$option{'expression'}) { + print_log('pkg', ERROR, 'Remove version option missing "expression" at %s', $label); + return 0; + } + } + else { + print_log('pkg', ERROR, 'Unknown remove version option type at %s', $label.': '.$type); + return 0; + } + + return 1; +} + sub evaluate_expression ($$$$) { my ($channel, $vars, $inst, $expression) = @_; @@ -2157,6 +2262,30 @@ sub pkgdef_get_desired_version ($$$$$) { my ($config, $name, $base_directory, $def, $version) = @_; + return undef unless defined $version; + if (ref($version) eq 'HASH') { + my $etype = $$version{type}; + print_log('global', DEBUG4, 'Evaluating version reference %s in definition %s', + $etype, $$def{description}); + if ($etype eq 'expression') { + my $vars = get_default_vars($config); + set_datetime_vars($vars); + $$vars{pkgname} = $name; + my $appdir = substitute_variables($vars, $$def{'source-directory'}, 1, $base_directory, 'pkg'); + $$vars{appdir} = $appdir; + + my $expression = $$version{expression}; + my ($value, $error) = evaluate_expression('global', $vars, $def, $expression); + + if (defined $error && $error ne '') { + print_log('global', DEBUG4, 'Evaluating version reference expression %s failed: %s', + $expression, $error); + return undef; + } + print_log('global', DEBUG4, 'Version reference expression result: %s', defined $value ? $value : ''); + $version = $value; + } + } return undef unless defined $version; my $versions = $$def{'package-versions'}; if (defined $versions) {