Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ DESCRIPTION
This function arranges for the following directories to be installed, if
they exist (assuming "RTx('RT-Extension-Example')"):

./bin => $RT::LocalPluginPath/RT-Extension-Example/bin
./etc => $RT::LocalPluginPath/RT-Extension-Example/etc
./html => $RT::LocalPluginPath/RT-Extension-Example/html
./lib => $RT::LocalPluginPath/RT-Extension-Example/lib
./po => $RT::LocalPluginPath/RT-Extension-Example/po
./sbin => $RT::LocalPluginPath/RT-Extension-Example/sbin
./static => $RT::LocalPluginPath/RT-Extension-Example/static
./var => $RT::LocalPluginPath/RT-Extension-Example/var
./bin => $RT::LocalPluginPath/RT-Extension-Example/bin
./etc => $RT::LocalPluginPath/RT-Extension-Example/etc
./html => $RT::LocalPluginPath/RT-Extension-Example/html
./lib => $RT::LocalPluginPath/RT-Extension-Example/lib
./po => $RT::LocalPluginPath/RT-Extension-Example/po
./sbin => $RT::LocalPluginPath/RT-Extension-Example/sbin
./static => $RT::LocalPluginPath/RT-Extension-Example/static
./var => $RT::LocalPluginPath/RT-Extension-Example/var
./patches => If this directory/sub directory(s) contain one or more
p1 unified diffs they will be applied to the RT
installation. Invoked in your plugin as make patch

Accepts an optional argument hashref after the extension name with two
possible keys
Expand Down
34 changes: 26 additions & 8 deletions lib/Module/Install/RTx.pm
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ install ::
$has_etc{upgrade}++;
}

my %has_patches;
if ( -d 'patches' ) {
$has_patches{patches}++;
}

$self->postamble("$postamble\n");
if ( $path{lib} ) {
$self->makemaker_args( INSTALLSITELIB => $path{'lib'} );
Expand Down Expand Up @@ -181,6 +186,16 @@ install ::
}
}

if (%has_patches) {
print "For first-time installation, type 'make patch'.\n";
my $patch = qq|\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxPatch(qw(/usr/bin/patch apply ./patches))"\n|;
$self->postamble("patch ::\n$patch\n");

print "For patch removal, type 'make unpatch'.\n";
my $unpatch = qq|\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxPatch(qw(/usr/bin/patch remove ./patches))"\n|;
$self->postamble("unpatch ::\n$unpatch\n");
}

}

sub requires_rt {
Expand Down Expand Up @@ -304,14 +319,17 @@ installing RT extensions:
This function arranges for the following directories to be installed, if
they exist (assuming C<RTx('RT-Extension-Example')>):

./bin => $RT::LocalPluginPath/RT-Extension-Example/bin
./etc => $RT::LocalPluginPath/RT-Extension-Example/etc
./html => $RT::LocalPluginPath/RT-Extension-Example/html
./lib => $RT::LocalPluginPath/RT-Extension-Example/lib
./po => $RT::LocalPluginPath/RT-Extension-Example/po
./sbin => $RT::LocalPluginPath/RT-Extension-Example/sbin
./static => $RT::LocalPluginPath/RT-Extension-Example/static
./var => $RT::LocalPluginPath/RT-Extension-Example/var
./bin => $RT::LocalPluginPath/RT-Extension-Example/bin
./etc => $RT::LocalPluginPath/RT-Extension-Example/etc
./html => $RT::LocalPluginPath/RT-Extension-Example/html
./lib => $RT::LocalPluginPath/RT-Extension-Example/lib
./po => $RT::LocalPluginPath/RT-Extension-Example/po
./sbin => $RT::LocalPluginPath/RT-Extension-Example/sbin
./static => $RT::LocalPluginPath/RT-Extension-Example/static
./var => $RT::LocalPluginPath/RT-Extension-Example/var
./patches => If this directory/sub directory(s) contain one or more
p1 unified diffs they will be applied to the RT
installation. Invoked in your plugin as make patch

Accepts an optional argument hashref after the extension name with two possible keys

Expand Down
137 changes: 136 additions & 1 deletion lib/Module/Install/RTx/Runtime.pm
Original file line number Diff line number Diff line change
@@ -1,10 +1,111 @@
package Module::Install::RTx::Runtime;

use base 'Exporter';
our @EXPORT = qw/RTxDatabase RTxPlugin/;
our @EXPORT = qw/RTxDatabase RTxPatch RTxPlugin/;

use strict;
use File::Basename ();
use POSIX qw (WIFEXITED);
use File::Find;
use Carp;
use Cwd;


# Switch
my $dispatch ={
'>' => \&_greater_than,
'<' => \&_less_than,
'-' => \&_in_range,
'=' => \&_equal,
};

sub _in_range {
my ($rt_ver, $dir) = @_;

# Get our lower and upper versions
my ($start_ver, $end_ver) = $dir =~ m/([\d\.]+)-([\d\.]+)/xms;

# Check if rt_ver is between range of version values
return 1 if &_greater_than($rt_ver, $start_ver)
and &_less_than($rt_ver, $end_ver);
return 1 if &_equal($rt_ver, $start_ver);
return 1 if &_equal($rt_ver, $end_ver);
return 0;
}

sub _greater_than {
my ($rt_ver, $patch_ver) = @_;

$patch_ver =~ s/\A>//xms;
$patch_ver = _convert_version($patch_ver);
$rt_ver = _convert_version($rt_ver);

# Return TRUE if we are greater than the patch
return 1 if $rt_ver > $patch_ver;
return 0;
}

sub _less_than {
my ($rt_ver, $patch_ver) = @_;

$patch_ver =~ s/\A<//xms;
$patch_ver = _convert_version($patch_ver);
$rt_ver = _convert_version($rt_ver);

# Return TRUE if we are less than the patch
return 1 if $rt_ver < $patch_ver;
return 0;
}

sub _equal {
my ($rt_ver, $patch_ver) = @_;

$patch_ver = _convert_version($patch_ver);
$rt_ver = _convert_version($rt_ver);

# Check if the versions are equal
return 1 if $rt_ver == $patch_ver;
return 0;
}

sub _convert_version {
my $version = shift @_;
my @nums;
my $num;

# Pass version straight back if no "." is found in it
# else convert to a float in the format \d+.\d+
if ($version =~ m/\./xms) {
@nums = split(/\./, $version);
$num = shift @nums;
$num .= '.';
$num .= join('0', @nums);
return $num;
}
else {
return $version;
}
}

sub _required_patch {
my ($path, $version) = @_;

# We are pretty safe doing this as the ./patches path is hardcoded
my @dirs = split('/', $path);
my $dir = $dirs[2];

# Check range of versions
return $dispatch->{'-'}($version, $dir) if $dir =~ m/[\d.]+.\d-\d.[\d.]+/xms;
# Check greater than
return $dispatch->{'>'}($version, $dir) if $dir =~ m/\A>[\d.]+\z/xms;
# Check less than
return $dispatch->{'<'}($version, $dir) if $dir =~ m/\A<[\d.]+\z/xms;
# Check if equal
return $dispatch->{'='}($version, $dir) if $dir =~ m/\A\d.\d+\z/xms;

# If none of the above match then just apply the patch(s) regardless
return 1;
}

sub _rt_runtime_load {
require RT;
Expand Down Expand Up @@ -54,6 +155,40 @@ sub RTxDatabase {
(system($^X, @args) == 0) or die "...returned with error: $?\n";
}

sub RTxPatch {
my ($patch, $action, $dir) = @_;
my @cmd;

_rt_runtime_load();

# Check to see if we are adding or removing a patch set
if ( $action =~ m/\Aapply\z/xms ) {
@cmd = ($patch, '-d', $RT::BasePath, '-p1', '-i');
}
else {
@cmd = ($patch, '-R', '-d', $RT::BasePath, '-p1', '-i');
}

# Anonymous subroutine to apply all patches in a directory structure
my $patch_rt = sub {

# Next entry if not a file
return unless -f $_;

# Next entry if not approprate version of patch
return unless &_required_patch($File::Find::dir, $RT::VERSION);

if ($_ =~ m/\.patch\z/xms) {
push @cmd, getcwd . "/$_";
WIFEXITED(system(@cmd))
or croak "Couldn't run: " . join(' ', @cmd) . "($?)\n";
pop @cmd;
}
};

find {wanted => $patch_rt}, $dir;
}

sub RTxPlugin {
my ($name) = @_;

Expand Down
94 changes: 94 additions & 0 deletions t/1-runtime.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/perl

use Test::More;

require Module::Install::RTx::Runtime;

is ( Module::Install::RTx::Runtime::_convert_version('1'), '1',
'is 1 converted to 1');
is ( Module::Install::RTx::Runtime::_convert_version('1.0'), '1.0',
'is 1.0 converted to 1.0');
is ( Module::Install::RTx::Runtime::_convert_version('0.1'), '0.1',
'is 0.1 converted to 0.1');
is ( Module::Install::RTx::Runtime::_convert_version('0.0.1'), '0.001',
'is 0.0.1 converted to 0.001');
is ( Module::Install::RTx::Runtime::_convert_version('11'), '11',
'is 11 converted to 11');
is ( Module::Install::RTx::Runtime::_convert_version('11.0'), '11.0',
'is 11.0 converted to 11.0');
is ( Module::Install::RTx::Runtime::_convert_version('4.4.18'), '4.4018',
'is 4.4.18 converted to 4.4018');
is ( Module::Install::RTx::Runtime::_convert_version('4.40.18'), '4.40018',
'is 4.40.18 converted to 4.40018');
is ( Module::Install::RTx::Runtime::_convert_version('440.18'), '440.18',
'is 440.18 converted to 440.18');
is ( Module::Install::RTx::Runtime::_convert_version('4.4.1.8'), '4.40108',
'is 4.4.1.8 converted to 4.40108');

is ( Module::Install::RTx::Runtime::_equal('1', '1'), 1,
'1 is equal to 1');
is ( Module::Install::RTx::Runtime::_equal('0.1', '0.1'), 1,
'0.1 is equal to 0.1');
is ( Module::Install::RTx::Runtime::_equal('11', '1.1'), 0,
'11 is not equal to 1.1');
is ( Module::Install::RTx::Runtime::_equal('1.1', '11'), 0,
'1.1 is not equal to 11');
is ( Module::Install::RTx::Runtime::_equal('1.1', '1.1'), 1,
'1.1 is equal to 1.1');
is ( Module::Install::RTx::Runtime::_equal('1.1.1', '1.1.1'), 1,
'1.1.1 is equal to 1.1.1');
is ( Module::Install::RTx::Runtime::_equal('1.11.1', '1.11.1'), 1,
'1.11.1 is equal to 1.11.1');
is ( Module::Install::RTx::Runtime::_equal('1.1.1', '1.11'), 0,
'1.1.1 is not equal to 1.11');
is ( Module::Install::RTx::Runtime::_equal('1.11.1', '1.111'), 0,
'1.11.1 is not equal to 1.111');
is ( Module::Install::RTx::Runtime::_equal('1.11.1', '1111'), 0,
'1.11.1 is not equal to 1111');

is ( Module::Install::RTx::Runtime::_greater_than('2', '>1'), 1,
'2 is greater than 1' );
is ( Module::Install::RTx::Runtime::_greater_than('1.1', '>1.1'), 0,
'1.1 is not greater than 1.1' );
is ( Module::Install::RTx::Runtime::_greater_than('1.1', '>1'), 1,
'1.1 is greater than 1' );
is ( Module::Install::RTx::Runtime::_greater_than('1.1', '>2'), 0,
'1.1 is not greater than 2' );
is ( Module::Install::RTx::Runtime::_greater_than('1.1', '>11'), 0,
'1.1 is not greater than 11' );
is ( Module::Install::RTx::Runtime::_greater_than('1.11', '>11.1'), 0,
'1.11 is not greater than 11.1' );
is ( Module::Install::RTx::Runtime::_greater_than('111', '>11.1'), 1,
'111 is greater than 11.1' );

is ( Module::Install::RTx::Runtime::_less_than('2', '<1'), 0,
'2 is not less than 1' );
is ( Module::Install::RTx::Runtime::_less_than('1.1', '<1.1'), 0,
'1.1 is not less than 1.1' );
is ( Module::Install::RTx::Runtime::_less_than('1.1', '<1'), 0,
'1.1 is not less than 1' );
is ( Module::Install::RTx::Runtime::_less_than('1.1', '<2'), 1,
'1.1 is less than 2' );
is ( Module::Install::RTx::Runtime::_less_than('1.1', '<11'), 1,
'1.1 is less than 11' );
is ( Module::Install::RTx::Runtime::_less_than('1.11', '<11.1'), 1,
'1.11 is less than 11.1' );
is ( Module::Install::RTx::Runtime::_less_than('111', '<11.1'), 0,
'111 is not less than 11.1' );

is ( Module::Install::RTx::Runtime::_in_range('1.1', '1-1.5'), 1,
'1.1 is in range 1 and 1.5' );
is ( Module::Install::RTx::Runtime::_in_range('0.1', '1-1.5'), 0,
'0.1 is not in range 1 and 1.5' );
is ( Module::Install::RTx::Runtime::_in_range('2.1', '2-3'), 1,
'2.1 is in range 2 and 3' );
is ( Module::Install::RTx::Runtime::_in_range('2', '2-3'), 1,
'2 is between 2 and 3' );
is ( Module::Install::RTx::Runtime::_in_range('2.0', '2-3'), 1,
'2.0 is in range 2 and 3' );
is ( Module::Install::RTx::Runtime::_in_range('2', '2-2'), 1,
'2 is in range 2 and 2' );

done_testing($number_of_tests);

1;