[Bps-public-commit] RT-Extension-SLA branch, performance-stats, created. 0.03-39-gafb655c
Ruslan Zakirov
ruz at bestpractical.com
Thu Jun 2 18:26:58 EDT 2011
The branch, performance-stats has been created
at afb655c376a8816af5f4c85de10ff9aad9a766c8 (commit)
- Log -----------------------------------------------------------------
commit 2e7e0eb36361c9bab4e42998ef0890caef37ad8b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Apr 27 19:04:02 2009 +0000
fist pass on a reporting
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
new file mode 100644
index 0000000..afbae9e
--- /dev/null
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -0,0 +1,98 @@
+use 5.8.0;
+use strict;
+use warnings;
+
+package RT::Extension::SLA::Report;
+
+sub new {}
+
+sub init {}
+
+sub State {
+ my $self = shift;
+ return $self->{State} ||= {};
+}
+
+{ my $cache;
+sub Handlers {
+ my $self = shift;
+
+ return $cache if $cache;
+
+ $cache = {
+ Create => 'OnCreate',
+ Set => {
+ Owner => 'OnOwnerChange',
+ },
+ Correpond => 'OnResponse',
+ CustomField => { map $_ => 'OnServiceLevelChange', $self->ServiceLevelCustomFields },
+ };
+
+ return $cache;
+}
+
+sub Drive {
+ my $self = shift;
+ my $txns = shift;
+
+ my $state = $self->State;
+ my $handler = $self->Handlers;
+
+ while ( my $txn = $txns->Next ) {
+ my ($type, $field) = ($txn->Type, $txn->Field);
+
+ my $h = $handler->{ $type };
+ unless ( $h ) {
+ $RT::Logger->debug( "No handler for $type transaction, skipping" );
+ } elsif ( ref $h ) {
+ unless ( $h = $h->{ $field } ) {
+ $RT::Logger->debug( "No handler for ($type, $field) transaction, skipping" );
+ }
+ }
+ next unless $h;
+
+ $self->$h( Transaction => $txn, State => $state );
+ }
+}
+
+sub InitialServiceLevel {
+ my $self = shift;
+ my $ticket = shift;
+
+ my $txns = $ticket->Transactions;
+ foreach my $cf ( $self->ServiceLevelCustomFields ) {
+ $txns->_OpenParen('ServiceLevelCustomFields');
+ $txns->Limit(
+ SUBCLAUSE => 'ServiceLevelCustomFields',
+ ENTRYAGGREGATOR => 'OR',
+ FIELD => 'Type',
+ VALUE => 'CustomField',
+ );
+ $txns->Limit(
+ SUBCLAUSE => 'ServiceLevelCustomFields',
+ ENTRYAGGREGATOR => 'AND',
+ FIELD => 'Field',
+ VALUE => $cf->id,
+ );
+ $txns->_CloseParen('ServiceLevelCustomFields');
+ }
+
+ return $self;
+}
+
+{ my @cache = ();
+sub ServiceLevelCustomFields {
+ my $self = shift;
+ return @cache if @cache;
+
+ my $cfs = RT::CustomFields->new( $RT::SystemUser );
+ $cfs->Limit( FIELD => 'Name', VALUE => 'SLA' );
+ $cfs->Limit( FIELD => 'LookupType', VALUE => RT::Ticket->CustomFieldLookupType );
+ # XXX: limit to applied custom fields only
+
+ push @cache, $_ while $_ = $cfs->Next;
+
+ return @cache;
+} }
+
+1;
commit 7f1f29c234beb02013dad72959767d94c78c1906
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Wed Apr 29 20:54:43 2009 +0000
another pass on reporting
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
index afbae9e..52a254e 100644
--- a/lib/RT/Extension/SLA/Report.pm
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -24,12 +24,14 @@ sub Handlers {
Set => {
Owner => 'OnOwnerChange',
},
- Correpond => 'OnResponse',
+ Correspond => 'OnResponse',
CustomField => { map $_ => 'OnServiceLevelChange', $self->ServiceLevelCustomFields },
+ AddWatcher => { Requestor => 'OnRequestorChange' },
+ DelWatcher => { Requestor => 'OnRequestorChange' },
};
return $cache;
-}
+} }
sub Drive {
my $self = shift;
@@ -55,29 +57,157 @@ sub Drive {
}
}
+sub OnCreate {
+ my $self = shift;
+ my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
+
+ my $level = $self->InitialServiceLevel( $args{'Ticket'} );
+
+ my $state = $args{'State'};
+ %$state = ();
+ $state->{'level'} = $level;
+ $state->{'transaction'} = $args{'Transaction'};
+ $state->{'requestors'} = [ $self->InitialRequestors( $args{'Ticket'} ) ];
+ $state->{'owner'} = $self->InitialOwner( $args{'Ticket'} );
+ return;
+}
+
+sub OnRequestorChange {
+ my $self = shift;
+ my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
+
+ my $requestors = $self->State->{'requestors'};
+ if ( $args{'Transaction'}->Type eq 'AddWatcher' ) {
+ push @$requestors, $args{'Transaction'}->NewValue;
+ }
+ else {
+ my $id = $args{'Transaction'}->OldValue;
+ @$requestors = grep $_ != $id, @$requestors;
+ }
+}
+
+sub OnResponse {
+ my $self = shift;
+ my $self
+}
+
+sub IsRequestorsAct {
+ my $self = shift;
+ my $txn = shift;
+
+ my $actor = $txn->Creator;
+
+ # owner is always treated as non-requestor
+ return 0 if $actor == $self->State->{'owner'};
+ return 1 if grep $_ == $actor, @{ $self->State->{'requestors'} };
+
+ # in case requestor is a group
+ foreach my $id ( @{ $self->State->{'requestors'} } ){
+ my $cgm = RT::CachedGroupMember->new( $RT::SystemUser );
+ $cgm->LoadByCols( GroupId => $id, MemberId => $actor, Disabled => 0 );
+ return 1 if $cgm->id;
+ }
+ return 1;
+}
+
sub InitialServiceLevel {
my $self = shift;
my $ticket = shift;
+ return $self->InitialValue(
+ Ticket => $ticket,
+ Current => $ticket->FirstCustomFieldValue('SLA'),
+ Criteria => { CustomField => [ map $_->id, $self->ServiceLevelCustomFields ] },
+ );
+}
+
+sub InitialRequestors {
+ my $self = shift;
+ my $ticket = shift;
+
+ my @current = map $_->Member, @{ $ticket->Requestors->MembersObj->ItemsArrayRef };
+
+ my $txns = $self->Transactions(
+ Ticket => $ticket,
+ Order => 'DESC',
+ Criteria => { 'AddWatcher' => 'Requestor', DelWatcher => 'Requestor' },
+ );
+ while ( my $txn = $txns->Next ) {
+ if ( $txn->Type eq 'AddWatcher' ) {
+ my $id = $txn->NewValue;
+ @current = grep $_ != $id, @current;
+ }
+ else {
+ push @current, $txn->OldValue;
+ }
+ }
+
+ return @current;
+}
+
+sub InitialOwner {
+ my $self = shift;
+ my $ticket = shift;
+
+ return $self->InitialValue(
+ %args,
+ Current => $ticket->Owner,
+ Criteria => { 'Set', 'Owner' },
+ );
+}
+
+sub InitialValue {
+ my $self = shift;
+ my %args = ( Ticket => undef, Current => undef, Criteria => {}, @_ );
+
+ my $txns = $self->Transactions( %args );
+ if ( my $first_change = $txns->First ) {
+ # intial value is old value of the first change
+ return $first_change->OldValue;
+ }
+
+ # no change -> initial value is the current
+ return $args{'Current'};
+}
+
+sub Transactions {
+ my $self = shift;
+ my %args = (Ticket => undef, Criteria => undef, Order => 'ASC', @_);
+
my $txns = $ticket->Transactions;
- foreach my $cf ( $self->ServiceLevelCustomFields ) {
- $txns->_OpenParen('ServiceLevelCustomFields');
+
+ my $clause = 'ByTypeAndField';
+ while ( my ($type, $field) = each %{ $args{'Criteria'} } ) {
+ $txns->_OpenParen( $clause );
$txns->Limit(
- SUBCLAUSE => 'ServiceLevelCustomFields',
ENTRYAGGREGATOR => 'OR',
+ SUBCLAUSE => $clause,
FIELD => 'Type',
- VALUE => 'CustomField',
- );
- $txns->Limit(
- SUBCLAUSE => 'ServiceLevelCustomFields',
- ENTRYAGGREGATOR => 'AND',
- FIELD => 'Field',
- VALUE => $cf->id,
+ VALUE => $type,
);
- $txns->_CloseParen('ServiceLevelCustomFields');
+ if ( $field ) {
+ my $tmp = ref $field? $field : [$field];
+ $txns->_OpenParen( $clause );
+ my $first = 1;
+ foreach my $value ( @$tmp ) {
+ $txns->Limit(
+ SUBCLAUSE => $clause,
+ ENTRYAGGREGATOR => $first? 'AND' : 'OR',
+ FIELD => 'Field',
+ VALUE => $value,
+ );
+ $first = 0;
+ }
+ $txns->_CloseParen( $clause );
+ }
+ $txns->_CloseParen( $clause );
}
+ $txns->OrderByCols(
+ { FIELD => 'Created', ORDER => $args{'Order'} },
+ { FIELD => 'id', ORDER => $args{'Order'} },
+ );
- return $self;
+ return $txns;
}
{ my @cache = ();
commit 2d62d176c8d8c4c3cfeb84c62638208e3951ad2c
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Sat May 2 22:49:34 2009 +0000
another round, close to something testable
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index 1b51c6b..6a98ce2 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -14,6 +14,14 @@ RT::Extension::SLA - Service Level Agreements for RT
RT extension to implement automated due dates using service levels.
+=head1 UPGRADING
+
+On upgrade you shouldn't run 'make initdb'.
+
+If you were using 0.02 or older version of this extension with
+RT 3.8.1 then you have to uninstall that manually. List of files
+you can find in the MANIFEST.
+
=head1 INSTALL
=over 4
@@ -45,7 +53,7 @@ There is no WebUI in the current version. Almost everything is
controlled in the RT's config using option C<%RT::ServiceAgreements>
and C<%RT::ServiceBusinessHours>. For example:
- %RT::ServiceAgreements = (
+ Set( %ServiceAgreements,
Default => '4h',
QueueDefault => {
'Incident' => '2h',
@@ -248,7 +256,7 @@ of requests that came into the system during the last night.
In the config you can set one or more work schedules. Use the following
format:
- %RT::ServiceBusinessHours = (
+ Set( %ServiceBusinessHours,
'Default' => {
... description ...
},
@@ -274,7 +282,7 @@ hours.
then %RT::ServiceBusinessHours should have the corresponding definition:
- %RT::ServiceBusinessHours = (
+ Set( %ServiceBusinessHours,
'work just in Monday' => {
1 => { Name => 'Monday', Start => '9:00', End => '18:00' },
},
@@ -286,14 +294,14 @@ Default Business Hours setting is in $RT::ServiceBusinessHours{'Default'}.
In the config you can set per queue defaults, using:
- %RT::ServiceAgreements = (
+ Set( %ServiceAgreements,
Default => 'global default level of service',
QueueDefault => {
'queue name' => 'default value for this queue',
...
},
...
- };
+ );
=head2 Access control
@@ -427,6 +435,12 @@ sub GetDefaultServiceLevel {
return $RT::ServiceAgreements{'Default'};
}
+sub ReportOnTicket {
+ my $self = shift;
+ my $id = shift;
+
+}
+
=head1 TODO
* [implemented, TODO: tests for options in the config] default SLA for queues
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
index 52a254e..65ee23d 100644
--- a/lib/RT/Extension/SLA/Report.pm
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -4,13 +4,29 @@ use warnings;
package RT::Extension::SLA::Report;
-sub new {}
+sub new {
+ my $proto = shift;
+ my $self = bless {}, ref($proto)||$proto;
+ return $self->init( @_ );
+}
-sub init {}
+sub init {
+ my $self = shift;
+ my %args = (Ticket => undef, @_);
+ $self->{'Ticket'} = $args{'Ticket'} || die "boo";
+ $self->{'State'} = {};
+ $self->{'Stats'} = [];
+ return $self;
+}
sub State {
my $self = shift;
- return $self->{State} ||= {};
+ return $self->{State};
+}
+
+sub Stats {
+ my $self = shift;
+ return $self->{Stats};
}
{ my $cache;
@@ -33,9 +49,9 @@ sub Handlers {
return $cache;
} }
-sub Drive {
+sub Run {
my $self = shift;
- my $txns = shift;
+ my $txns = shift || $self->{'Ticket'}->Transactions;
my $state = $self->State;
my $handler = $self->Handlers;
@@ -53,20 +69,18 @@ sub Drive {
}
next unless $h;
- $self->$h( Transaction => $txn, State => $state );
+ $self->$h( Ticket => $self->{'Ticket'}, Transaction => $txn, State => $state );
}
+ return $self;
}
sub OnCreate {
my $self = shift;
my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
- my $level = $self->InitialServiceLevel( $args{'Ticket'} );
-
my $state = $args{'State'};
%$state = ();
- $state->{'level'} = $level;
- $state->{'transaction'} = $args{'Transaction'};
+ $state->{'level'} = $self->InitialServiceLevel( $args{'Ticket'} );
$state->{'requestors'} = [ $self->InitialRequestors( $args{'Ticket'} ) ];
$state->{'owner'} = $self->InitialOwner( $args{'Ticket'} );
return;
@@ -88,7 +102,76 @@ sub OnRequestorChange {
sub OnResponse {
my $self = shift;
- my $self
+ my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
+
+ my $txn = $args{'Transaction'};
+ unless ( $args{'State'}->{'level'} ) {
+ $RT::Logger->debug('No service level -> ignore txn #'. $txn->id );
+ return;
+ }
+
+ my $act = $args{'State'}->{'act'};
+ if ( $self->IsRequestorsAct( $txn ) ) {
+ if ( $act && $act->{'requestor'} ) {
+ # several requestors' acts in a row don't move deadlines
+ return;
+ }
+ $act ||= $args{'State'}->{'act'} = {};
+
+ $act->{'requestor'} = 1;
+ $act->{'acted'} = $txn->CreatedObj->Unix;
+ } else {
+ unless ( $act ) {
+ die "not yet implemented";
+ }
+ unless ( $act->{'requestor'} ) {
+ # check keep in loop
+ my $deadline = RT::Extension::SLA->Due(
+ Type => 'KeepInLoop',
+ Level => $args{'State'}->{'level'},
+ Time => $args{'State'}->{'acted'},
+ );
+ unless ( defined $deadline ) {
+ $RT::Logger->debug( "Multiple non-requestors replies in a raw, without keep in loop deadline");
+ return;
+ }
+ # keep in loop
+ my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
+ my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
+ my $stat = {
+ type => 'KeepInLoop',
+ owner => $args{'State'}->{'owner'},
+ failed => $failed,
+ owner_act => $owner,
+ shift => $txn->CreatedObj->Unix - $deadline,
+ };
+ push @{ $self->Stats }, $stat;
+ }
+ else {
+ # check response
+ my $deadline = RT::Extension::SLA->Due(
+ Type => 'Response',
+ Level => $args{'State'}->{'level'},
+ Time => $args{'State'}->{'acted'},
+ );
+ unless ( defined $deadline ) {
+ $RT::Logger->debug( "Non-requestors' reply after requestors', without response deadline");
+ return;
+ }
+
+ # repsonse
+ my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
+ my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
+ my $stat = {
+ type => 'KeepInLoop',
+ owner => $args{'State'}->{'owner'},
+ failed => $failed,
+ owner_act => $owner,
+ shift => $txn->CreatedObj->Unix - $deadline,
+ };
+ push @{ $self->Stats }, $stat;
+ }
+ }
}
sub IsRequestorsAct {
@@ -107,7 +190,7 @@ sub IsRequestorsAct {
$cgm->LoadByCols( GroupId => $id, MemberId => $actor, Disabled => 0 );
return 1 if $cgm->id;
}
- return 1;
+ return 0;
}
sub InitialServiceLevel {
@@ -147,11 +230,10 @@ sub InitialRequestors {
sub InitialOwner {
my $self = shift;
- my $ticket = shift;
-
+ my %args = (Ticket => undef, @_);
return $self->InitialValue(
%args,
- Current => $ticket->Owner,
+ Current => $args{'Ticket'}->Owner,
Criteria => { 'Set', 'Owner' },
);
}
@@ -174,7 +256,7 @@ sub Transactions {
my $self = shift;
my %args = (Ticket => undef, Criteria => undef, Order => 'ASC', @_);
- my $txns = $ticket->Transactions;
+ my $txns = $args{'Ticket'}->Transactions;
my $clause = 'ByTypeAndField';
while ( my ($type, $field) = each %{ $args{'Criteria'} } ) {
diff --git a/t/basics.t b/t/basics.t
index 8d73e46..998b596 100644
--- a/t/basics.t
+++ b/t/basics.t
@@ -3,9 +3,10 @@
use strict;
use warnings;
-use Test::More tests => 1;
+use Test::More tests => 2;
use_ok 'RT::Extension::SLA';
+use_ok 'RT::Extension::SLA::Report';
1;
commit ef5d140e7594f7146a4983db5b9cbfcbaa6c124c
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon May 4 19:13:52 2009 +0000
update TODO with some ideas
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index 6a98ce2..8642296 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -441,7 +441,20 @@ sub ReportOnTicket {
}
-=head1 TODO
+=head1 TODO and CAVEATS
+
+ * [not implemented] KeepInLoop and Response deadlines need adjusting. For example
+ KeepInLoop is 2h and Response is 2h as well. Owner replies at point 0, deadline
+ is 2h, at 1h requestor replies with anything -> deadline is moved according to
+ response deadline to 3h when it must stay at 2h waiting for KeepInLoop follow up
+ from owner and then move to another KeepInLoop deadline at 4h.
+
+ * [not implemented] Manually entered Due date should be treated as Resolve deadline.
+ We should store it and use later, so this module can be used for projects. For
+ example: Response 4 hours, KeepInLoop 1 day, Resolve 5 b.days; these are defaults,
+ but any manual change to Due date changes Resolve deadline.
+
+ * [not implemented] WebUI
* [implemented, TODO: tests for options in the config] default SLA for queues
@@ -451,8 +464,6 @@ sub ReportOnTicket {
something else). So people would be able to handle tickets in the right
order using Due dates.
- * [not implemented] WebUI
-
=head1 DESIGN
=head2 Classes
commit 665cceb7b8a41e80e912b84aede37ce46b95a092
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon May 4 22:32:51 2009 +0000
more changes here and there regarding reporting
* new Summary.pm to help combine multiple reports
together
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index 8642296..aa4911c 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -435,10 +435,12 @@ sub GetDefaultServiceLevel {
return $RT::ServiceAgreements{'Default'};
}
-sub ReportOnTicket {
+sub Report {
my $self = shift;
- my $id = shift;
+ my $ticket = shift;
+ require RT::Extension::SLA::Report;
+ return RT::Extension::SLA::Report->new( Ticket => $ticket )->Run;
}
=head1 TODO and CAVEATS
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
index 65ee23d..dbb10ff 100644
--- a/lib/RT/Extension/SLA/Report.pm
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -19,6 +19,31 @@ sub init {
return $self;
}
+sub Run {
+ my $self = shift;
+ my $txns = shift || $self->{'Ticket'}->Transactions;
+
+ my $state = $self->State;
+ my $handler = $self->Handlers;
+
+ while ( my $txn = $txns->Next ) {
+ my ($type, $field) = ($txn->Type, $txn->Field);
+
+ my $h = $handler->{ $type };
+ unless ( $h ) {
+ $RT::Logger->debug( "No handler for $type transaction, skipping" );
+ } elsif ( ref $h ) {
+ unless ( $h = $h->{ $field } ) {
+ $RT::Logger->debug( "No handler for ($type, $field) transaction, skipping" );
+ }
+ }
+ next unless $h;
+
+ $self->$h( Ticket => $self->{'Ticket'}, Transaction => $txn, State => $state );
+ }
+ return $self;
+}
+
sub State {
my $self = shift;
return $self->{State};
@@ -41,49 +66,27 @@ sub Handlers {
Owner => 'OnOwnerChange',
},
Correspond => 'OnResponse',
- CustomField => { map $_ => 'OnServiceLevelChange', $self->ServiceLevelCustomFields },
+ CustomField => { map { $_->id => 'OnServiceLevelChange' } $self->ServiceLevelCustomFields },
AddWatcher => { Requestor => 'OnRequestorChange' },
DelWatcher => { Requestor => 'OnRequestorChange' },
};
+ use Data::Dumper;
+ Test::More::diag( Dumper $cache );
+
return $cache;
} }
-sub Run {
- my $self = shift;
- my $txns = shift || $self->{'Ticket'}->Transactions;
-
- my $state = $self->State;
- my $handler = $self->Handlers;
-
- while ( my $txn = $txns->Next ) {
- my ($type, $field) = ($txn->Type, $txn->Field);
-
- my $h = $handler->{ $type };
- unless ( $h ) {
- $RT::Logger->debug( "No handler for $type transaction, skipping" );
- } elsif ( ref $h ) {
- unless ( $h = $h->{ $field } ) {
- $RT::Logger->debug( "No handler for ($type, $field) transaction, skipping" );
- }
- }
- next unless $h;
-
- $self->$h( Ticket => $self->{'Ticket'}, Transaction => $txn, State => $state );
- }
- return $self;
-}
-
sub OnCreate {
my $self = shift;
my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
my $state = $args{'State'};
%$state = ();
- $state->{'level'} = $self->InitialServiceLevel( $args{'Ticket'} );
- $state->{'requestors'} = [ $self->InitialRequestors( $args{'Ticket'} ) ];
- $state->{'owner'} = $self->InitialOwner( $args{'Ticket'} );
- return;
+ $state->{'level'} = $self->InitialServiceLevel( Ticket => $args{'Ticket'} );
+ $state->{'requestors'} = [ $self->InitialRequestors( Ticket => $args{'Ticket'} ) ];
+ $state->{'owner'} = $self->InitialOwner( Ticket => $args{'Ticket'} );
+ return $self->OnResponse( %args );
}
sub OnRequestorChange {
@@ -100,15 +103,21 @@ sub OnRequestorChange {
}
}
+sub OnServiceLevelChange {
+ my $self = shift;
+ my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
+ $self->State->{'level'} = $args{'Transaction'}->NewValue;
+}
+
sub OnResponse {
my $self = shift;
my %args = ( Ticket => undef, Transaction => undef, State => undef, @_);
my $txn = $args{'Transaction'};
- unless ( $args{'State'}->{'level'} ) {
- $RT::Logger->debug('No service level -> ignore txn #'. $txn->id );
- return;
- }
+# unless ( $args{'State'}->{'level'} ) {
+# $RT::Logger->debug('No service level -> ignore txn #'. $txn->id );
+# return;
+# }
my $act = $args{'State'}->{'act'};
if ( $self->IsRequestorsAct( $txn ) ) {
@@ -143,6 +152,7 @@ sub OnResponse {
owner => $args{'State'}->{'owner'},
failed => $failed,
owner_act => $owner,
+ actor => $txn->Creator,
shift => $txn->CreatedObj->Unix - $deadline,
};
push @{ $self->Stats }, $stat;
@@ -152,22 +162,25 @@ sub OnResponse {
my $deadline = RT::Extension::SLA->Due(
Type => 'Response',
Level => $args{'State'}->{'level'},
- Time => $args{'State'}->{'acted'},
+ Time => $args{'State'}->{'act'}->{'acted'},
);
unless ( defined $deadline ) {
$RT::Logger->debug( "Non-requestors' reply after requestors', without response deadline");
return;
}
+ Test::More::diag( 'deadline '. $deadline .' '. Dumper( $args{'State'} ) );
+
# repsonse
my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
my $stat = {
- type => 'KeepInLoop',
+ type => 'Response',
owner => $args{'State'}->{'owner'},
failed => $failed,
owner_act => $owner,
- shift => $txn->CreatedObj->Unix - $deadline,
+ actor => $txn->Creator,
+ shift => ($txn->CreatedObj->Unix - $deadline),
};
push @{ $self->Stats }, $stat;
}
@@ -195,23 +208,23 @@ sub IsRequestorsAct {
sub InitialServiceLevel {
my $self = shift;
- my $ticket = shift;
+ my %args = @_;
return $self->InitialValue(
- Ticket => $ticket,
- Current => $ticket->FirstCustomFieldValue('SLA'),
+ Ticket => $args{'Ticket'},
+ Current => $args{'Ticket'}->FirstCustomFieldValue('SLA'),
Criteria => { CustomField => [ map $_->id, $self->ServiceLevelCustomFields ] },
);
}
sub InitialRequestors {
my $self = shift;
- my $ticket = shift;
+ my %args = @_;
- my @current = map $_->Member, @{ $ticket->Requestors->MembersObj->ItemsArrayRef };
+ my @current = map $_->MemberId, @{ $args{'Ticket'}->Requestors->MembersObj->ItemsArrayRef };
my $txns = $self->Transactions(
- Ticket => $ticket,
+ Ticket => $args{'Ticket'},
Order => 'DESC',
Criteria => { 'AddWatcher' => 'Requestor', DelWatcher => 'Requestor' },
);
@@ -302,9 +315,7 @@ sub ServiceLevelCustomFields {
$cfs->Limit( FIELD => 'LookupType', VALUE => RT::Ticket->CustomFieldLookupType );
# XXX: limit to applied custom fields only
- push @cache, $_ while $_ = $cfs->Next;
-
- return @cache;
+ return @cache = @{ $cfs->ItemsArrayRef };
} }
1;
diff --git a/lib/RT/Extension/SLA/Summary.pm b/lib/RT/Extension/SLA/Summary.pm
new file mode 100644
index 0000000..b59ba9d
--- /dev/null
+++ b/lib/RT/Extension/SLA/Summary.pm
@@ -0,0 +1,68 @@
+use 5.8.0;
+use strict;
+use warnings;
+
+package RT::Extension::SLA::Summary;
+
+sub new {
+ my $proto = shift;
+ my $self = bless {}, ref($proto)||$proto;
+ return $self->init( @_ );
+}
+
+sub init {
+ my $self = shift;
+ return $self;
+}
+
+sub Result {
+ my $self = shift;
+ return $self->{'Result'} ||= { };
+}
+
+sub AddReport {
+ my $self = shift;
+ my $report = shift;
+
+ my $new = $self->OnReport( $report );
+
+ my $total = $self->Result;
+ while ( my ($user, $stat) = each %$new ) {
+ my $tmp = $total->{$user} ||= {};
+ while ( my ($action, $count) = each %$stat ) {
+ $tmp->{$action} += $count;
+ }
+ }
+
+ return $self;
+}
+
+sub OnReport {
+ my $self = shift;
+ my $report = shift;
+
+ my $res = {};
+ foreach my $stat ( @{ $report->Stats } ) {
+ if ( $stat->{'owner_act'} ) {
+ my $owner = $res->{ $stat->{'owner'} } ||= { };
+ if ( $stat->{'failed'} ) {
+ $owner->{'failed'}++;
+ } else {
+ $owner->{'passed'}++;
+ }
+ } else {
+ my $owner = $res->{ $stat->{'owner'} } ||= { };
+ my $actor = $res->{ $stat->{'actor'} } ||= { };
+ if ( $stat->{'failed'} ) {
+ $owner->{'failed'}++;
+ $actor->{'late help'}++;
+ } else {
+ $owner->{'got help'}++;
+ $actor->{'helped'}++;
+ }
+ }
+ }
+ return $res;
+}
+
+1;
commit 247c990a939bd152f77ad64cdb681742dde96b36
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue May 5 01:11:11 2009 +0000
add first html, more simple tests and changes Summary
diff --git a/META.yml b/META.yml
index c96930b..89aa5fb 100644
--- a/META.yml
+++ b/META.yml
@@ -17,6 +17,7 @@ name: RT-Extension-SLA
no_index:
directory:
- etc
+ - html
- inc
- t
requires:
diff --git a/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default b/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
new file mode 100644
index 0000000..73c310b
--- /dev/null
+++ b/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
@@ -0,0 +1,9 @@
+<%ARGS>
+$tabs => {}
+</%ARGS>
+<%INIT>
+$tabs->{'s'} = {
+ title => loc('Service Level Aggreements'),
+ path => 'Tools/Reports/SLA.html',
+};
+</%INIT>
diff --git a/html/Tools/Reports/SLA.html b/html/Tools/Reports/SLA.html
new file mode 100644
index 0000000..1cdeb03
--- /dev/null
+++ b/html/Tools/Reports/SLA.html
@@ -0,0 +1,43 @@
+<& /Elements/Header, Title => $title &>
+<& /Tools/Reports/Elements/Tabs, current_tab => 'Tools/Reports/SLA.html', Title => $title &>
+
+<table>
+<tr>
+<th><% loc('Owner') %></th>
+% my @columns = $summary->Labels;
+% my $i = 0;
+% foreach ( map $_->[0], grep $i++%2, @columns ) {
+<th><% loc($_) %></th>
+% }
+</tr>
+
+% while ( my ($owner, $stats) = each %$result ) {
+ <tr><td><% $owner %><td>
+% my $i = 1;
+% foreach ( map $stats->{ $_ }, grep $i++%2, @columns ) {
+<td><% $_ || 0 %></td>
+% }
+ </tr>
+% }
+</table>
+
+<%ARGS>
+$Query => undef
+</%ARGS>
+<%INIT>
+my $title = loc("Report on Service Level Agreements");
+
+use RT::Extension::SLA::Summary;
+my $summary = new RT::Extension::SLA::Summary;
+
+my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$tickets->FromSQL( $Query );
+$tickets->OrderByCols( {FIELD => 'id', ORDER => 'ASC'} );
+while ( my $ticket = $tickets->Next ) {
+ my $report = RT::Extension::SLA->Report( Ticket => $ticket );
+ $summary->AddReport( $report );
+}
+
+my $result = $summary->Result;
+
+</%INIT>
diff --git a/lib/RT/Extension/SLA/Summary.pm b/lib/RT/Extension/SLA/Summary.pm
index b59ba9d..a0dc52f 100644
--- a/lib/RT/Extension/SLA/Summary.pm
+++ b/lib/RT/Extension/SLA/Summary.pm
@@ -20,6 +20,18 @@ sub Result {
return $self->{'Result'} ||= { };
}
+our @known_stats = (
+ 'passed' => ['Passed', 'Replied before a deadline'],
+ 'failed' => ['Failed', 'Replied after a deadline or not replied at all'],
+ 'helped' => ['Helped', 'Helped another user to reach a deadline'],
+ 'late help' => ['Helped (late)', 'Helped another user, however failed a deadline'],
+ 'got help' => ['Got help', 'Got help from another user within a deadline'],
+);
+
+sub Labels {
+ return @known_stats;
+}
+
sub AddReport {
my $self = shift;
my $report = shift;
diff --git a/t/basics.t b/t/basics.t
index 998b596..08d6b46 100644
--- a/t/basics.t
+++ b/t/basics.t
@@ -3,10 +3,11 @@
use strict;
use warnings;
-use Test::More tests => 2;
+use Test::More tests => 3;
use_ok 'RT::Extension::SLA';
use_ok 'RT::Extension::SLA::Report';
+use_ok 'RT::Extension::SLA::Summary';
1;
commit a9834df159c55da4e98cb1288e31c00fceeeca62
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue May 5 01:50:43 2009 +0000
cleanup debug code
* fix some bugs
diff --git a/html/Tools/Reports/SLA.html b/html/Tools/Reports/SLA.html
index 1cdeb03..df07885 100644
--- a/html/Tools/Reports/SLA.html
+++ b/html/Tools/Reports/SLA.html
@@ -12,12 +12,13 @@
</tr>
% while ( my ($owner, $stats) = each %$result ) {
- <tr><td><% $owner %><td>
+<tr>
+<td><% $owner %></td>
% my $i = 1;
% foreach ( map $stats->{ $_ }, grep $i++%2, @columns ) {
<td><% $_ || 0 %></td>
% }
- </tr>
+</tr>
% }
</table>
@@ -34,10 +35,9 @@ my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
$tickets->FromSQL( $Query );
$tickets->OrderByCols( {FIELD => 'id', ORDER => 'ASC'} );
while ( my $ticket = $tickets->Next ) {
- my $report = RT::Extension::SLA->Report( Ticket => $ticket );
+ my $report = RT::Extension::SLA->Report( $ticket );
$summary->AddReport( $report );
}
my $result = $summary->Result;
-
</%INIT>
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
index dbb10ff..9d0d8c2 100644
--- a/lib/RT/Extension/SLA/Report.pm
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -39,6 +39,8 @@ sub Run {
}
next unless $h;
+ $RT::Logger->debug( "Handling transaction #". $txn->id ." ($type, $field) of ticket #". $self->{'Ticket'}->id );
+
$self->$h( Ticket => $self->{'Ticket'}, Transaction => $txn, State => $state );
}
return $self;
@@ -71,9 +73,6 @@ sub Handlers {
DelWatcher => { Requestor => 'OnRequestorChange' },
};
- use Data::Dumper;
- Test::More::diag( Dumper $cache );
-
return $cache;
} }
@@ -131,7 +130,10 @@ sub OnResponse {
$act->{'acted'} = $txn->CreatedObj->Unix;
} else {
unless ( $act ) {
- die "not yet implemented";
+ $act = $args{'State'}->{'act'} = {};
+ $act->{'requestor'} = 0;
+ $act->{'acted'} = $txn->CreatedObj->Unix;
+ return;
}
unless ( $act->{'requestor'} ) {
# check keep in loop
@@ -169,8 +171,6 @@ sub OnResponse {
return;
}
- Test::More::diag( 'deadline '. $deadline .' '. Dumper( $args{'State'} ) );
-
# repsonse
my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
commit 9cbc83669fb5e477c134b3eef510813077e86dbd
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue May 5 14:46:40 2009 +0000
show user using a component
* show some simple form
diff --git a/html/Tools/Reports/SLA.html b/html/Tools/Reports/SLA.html
index df07885..d50bbc8 100644
--- a/html/Tools/Reports/SLA.html
+++ b/html/Tools/Reports/SLA.html
@@ -12,8 +12,10 @@
</tr>
% while ( my ($owner, $stats) = each %$result ) {
+% my $user = RT::User->new( $session{'CurrentUser'} );
+% $user->Load( $owner );
<tr>
-<td><% $owner %></td>
+<td><& /Elements/ShowUser, User => $user &></td>
% my $i = 1;
% foreach ( map $stats->{ $_ }, grep $i++%2, @columns ) {
<td><% $_ || 0 %></td>
@@ -22,6 +24,11 @@
% }
</table>
+<form method="post" action="SLA.html">
+<&|/l&>Query</&>:<textarea cols="60" rows="20" name="Query"><% $Query %></textarea>
+<& /Elements/Submit, Label => loc('Update report') &>
+</form>
+
<%ARGS>
$Query => undef
</%ARGS>
commit 56dceb3fe9ff8aa0d990068794d460594818d86d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue May 5 15:36:23 2009 +0000
new test file, basics of reporting
diff --git a/t/reporting/basic.t b/t/reporting/basic.t
new file mode 100644
index 0000000..55befef
--- /dev/null
+++ b/t/reporting/basic.t
@@ -0,0 +1,114 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::MockTime qw(set_fixed_time);
+
+use Test::More tests => 72;
+
+require 't/utils.pl';
+
+use_ok 'RT';
+RT::LoadConfig();
+$RT::LogToScreen = $ENV{'TEST_VERBOSE'} ? 'debug': 'warning';
+RT::Init();
+
+use_ok 'RT::Ticket';
+use_ok 'RT::Extension::SLA::Report';
+
+my $root = RT::User->new( $RT::SystemUser );
+$root->LoadByEmail('root at localhost');
+ok $root->id, 'loaded root user';
+
+diag '';
+{
+ %RT::ServiceAgreements = (
+ Default => '2',
+ Levels => {
+ '2' => { Response => { RealMinutes => 60*2 } },
+ },
+ );
+
+ set_fixed_time('2009-05-05T10:00:00Z');
+
+ my $time = time;
+
+ # requestor creates
+ my $id;
+ {
+ my $ticket = RT::Ticket->new( $root );
+ ($id) = $ticket->Create( Queue => 'General', Subject => 'xxx', Requestor => $root->id );
+ ok $id, "created ticket #$id";
+
+ is $ticket->FirstCustomFieldValue('SLA'), '2', 'default sla';
+
+ my $due = $ticket->DueObj->Unix;
+ is $due, $time + 2*60*60, 'Due date is two hours from "now"';
+ }
+
+ set_fixed_time('2009-05-05T11:00:00Z');
+
+ # non-requestor reply
+ {
+ my $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, "loaded ticket #$id";
+ $ticket->Correspond( Content => 'we are working on this.' );
+ }
+
+ my $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket->Load( $id );
+ my $report = RT::Extension::SLA::Report->new( Ticket => $ticket )->Run;
+ is_deeply $report->Stats,
+ [ {type => 'Response', owner => $RT::Nobody->id, owner_act => 0, failed => 0, shift => -3600 } ],
+ 'correct stats'
+ ;
+}
+
+
+diag '';
+{
+ %RT::ServiceAgreements = (
+ Default => '2',
+ Levels => {
+ '2' => { Response => { RealMinutes => 60*2 } },
+ },
+ );
+
+ set_fixed_time('2009-05-05T10:00:00Z');
+
+ my $time = time;
+
+ # requestor creates
+ my $id;
+ {
+ my $ticket = RT::Ticket->new( $root );
+ ($id) = $ticket->Create( Queue => 'General', Subject => 'xxx', Requestor => $root->id );
+ ok $id, "created ticket #$id";
+
+ is $ticket->FirstCustomFieldValue('SLA'), '2', 'default sla';
+
+ my $due = $ticket->DueObj->Unix;
+ is $due, $time + 2*60*60, 'Due date is two hours from "now"';
+ }
+
+ set_fixed_time('2009-05-05T11:00:00Z');
+
+ # non-requestor reply
+ {
+ my $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket->Load( $id );
+ ok $ticket->id, "loaded ticket #$id";
+ $ticket->Correspond( Content => 'we are working on this.' );
+ }
+
+ my $ticket = RT::Ticket->new( $RT::SystemUser );
+ $ticket->Load( $id );
+ my $report = RT::Extension::SLA::Report->new( Ticket => $ticket )->Run;
+ is_deeply $report->Stats,
+ [ {type => 'Response', owner => $RT::Nobody->id, owner_act => 0, failed => 0, shift => -3600 } ],
+ 'correct stats'
+ ;
+}
+
+
commit ea3e755479c5e577557530cc293f6e482893b72b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Tue May 5 15:37:19 2009 +0000
bump dev. version, update manifest and meta
diff --git a/MANIFEST b/MANIFEST
index 22c271a..c76a77e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,5 +1,7 @@
Changes
etc/initialdata
+html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
+html/Tools/Reports/SLA.html
inc/Module/AutoInstall.pm
inc/Module/Install.pm
inc/Module/Install/AutoInstall.pm
@@ -23,6 +25,8 @@ lib/RT/Condition/SLA_RequireDefault.pm
lib/RT/Condition/SLA_RequireDueSet.pm
lib/RT/Condition/SLA_RequireStartsSet.pm
lib/RT/Extension/SLA.pm
+lib/RT/Extension/SLA/Report.pm
+lib/RT/Extension/SLA/Summary.pm
lib/RT/Queue_SLA.pm
Makefile.PL
MANIFEST This list of files
@@ -31,5 +35,6 @@ t/basics.t
t/business_hours.t
t/due.t
t/queue.t
+t/reporting/basic.t
t/starts.t
t/utils.pl
diff --git a/META.yml b/META.yml
index 89aa5fb..4c8edd2 100644
--- a/META.yml
+++ b/META.yml
@@ -25,4 +25,4 @@ requires:
perl: 5.8.0
resources:
license: http://opensource.org/licenses/gpl-2.0.php
-version: 0.03
+version: 0.03_01
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index aa4911c..a8af3eb 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -4,7 +4,7 @@ use warnings;
package RT::Extension::SLA;
-our $VERSION = '0.03';
+our $VERSION = '0.03_01';
=head1 NAME
commit 2acbcef68d6bf9ffa82cc12e58998eb337ecce31
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Wed May 13 21:56:44 2009 +0000
update M::I
diff --git a/inc/Module/AutoInstall.pm b/inc/Module/AutoInstall.pm
index 739bc85..38c98f5 100644
--- a/inc/Module/AutoInstall.pm
+++ b/inc/Module/AutoInstall.pm
@@ -18,7 +18,9 @@ my %FeatureMap = (
# various lexical flags
my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $HasCPANPLUS );
-my ( $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly );
+my (
+ $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps
+);
my ( $PostambleActions, $PostambleUsed );
# See if it's a testing or non-interactive session
@@ -73,6 +75,9 @@ sub _init {
elsif ( $arg =~ /^--test(?:only)?$/ ) {
$TestOnly = 1;
}
+ elsif ( $arg =~ /^--all(?:deps)?$/ ) {
+ $AllDeps = 1;
+ }
}
}
@@ -115,7 +120,12 @@ sub import {
)[0]
);
- $UnderCPAN = _check_lock(1); # check for $UnderCPAN
+ # We want to know if we're under CPAN early to avoid prompting, but
+ # if we aren't going to try and install anything anyway then skip the
+ # check entirely since we don't want to have to load (and configure)
+ # an old CPAN just for a cosmetic message
+
+ $UnderCPAN = _check_lock(1) unless $SkipInstall;
while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
my ( @required, @tests, @skiptests );
@@ -187,6 +197,7 @@ sub import {
and (
$CheckOnly
or ($mandatory and $UnderCPAN)
+ or $AllDeps
or _prompt(
qq{==> Auto-install the }
. ( @required / 2 )
@@ -235,21 +246,35 @@ sub import {
*{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
}
+sub _running_under {
+ my $thing = shift;
+ print <<"END_MESSAGE";
+*** Since we're running under ${thing}, I'll just let it take care
+ of the dependency's installation later.
+END_MESSAGE
+ return 1;
+}
+
# Check to see if we are currently running under CPAN.pm and/or CPANPLUS;
# if we are, then we simply let it taking care of our dependencies
sub _check_lock {
return unless @Missing or @_;
+ my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING};
+
if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
- print <<'END_MESSAGE';
+ return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS');
+ }
-*** Since we're running under CPANPLUS, I'll just let it take care
- of the dependency's installation later.
-END_MESSAGE
- return 1;
+ require CPAN;
+
+ if ($CPAN::VERSION > '1.89' && $cpan_env) {
+ return _running_under('CPAN');
}
- _load_cpan();
+ # last ditch attempt, this -will- configure CPAN, very sorry
+
+ _load_cpan(1); # force initialize even though it's already loaded
# Find the CPAN lock-file
my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" );
@@ -633,7 +658,7 @@ sub _load {
# Load CPAN.pm and it's configuration
sub _load_cpan {
- return if $CPAN::VERSION;
+ return if $CPAN::VERSION and not @_;
require CPAN;
if ( $CPAN::HandleConfig::VERSION ) {
# Newer versions of CPAN have a HandleConfig module
@@ -766,4 +791,4 @@ END_MAKE
__END__
-#line 1004
+#line 1045
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index 5b9ddbf..fadb682 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -28,7 +28,7 @@ BEGIN {
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
- $VERSION = '0.85';
+ $VERSION = '0.87';
# Storage for the pseudo-singleton
$MAIN = undef;
diff --git a/inc/Module/Install/AutoInstall.pm b/inc/Module/Install/AutoInstall.pm
index b7e92a5..562bd0a 100644
--- a/inc/Module/Install/AutoInstall.pm
+++ b/inc/Module/Install/AutoInstall.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index ac416c9..211585a 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
use strict 'vars';
use vars qw{$VERSION};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
}
# Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 3e2d523..ef98ee4 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -9,7 +9,7 @@ use ExtUtils::MakeMaker ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 0a62208..763732d 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index 92aad58..406da54 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 2b80f0f..b1854f6 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -7,7 +7,7 @@ use ExtUtils::MakeMaker ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index ca16db7..6852f9a 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index c00da94..5d11a43 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index df3900a..a73f351 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.85';
+ $VERSION = '0.87';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
commit 2f1294f01335c2e1ea561a9771958e73d6578ed1
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Wed May 13 21:58:49 2009 +0000
add protection by a right
diff --git a/META.yml b/META.yml
index 4c8edd2..a510d6f 100644
--- a/META.yml
+++ b/META.yml
@@ -8,7 +8,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 6.42
distribution_type: module
-generated_by: 'Module::Install version 0.85'
+generated_by: 'Module::Install version 0.87'
license: gpl2
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
diff --git a/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default b/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
index 73c310b..d1f352c 100644
--- a/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
+++ b/html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
@@ -2,6 +2,9 @@
$tabs => {}
</%ARGS>
<%INIT>
+return unless $session{'CurrentUser'}->PrincipalObj->HasRight(
+ Object => $RT::System, Right => 'SeeSLAReports',
+);
$tabs->{'s'} = {
title => loc('Service Level Aggreements'),
path => 'Tools/Reports/SLA.html',
diff --git a/html/Tools/Reports/SLA.html b/html/Tools/Reports/SLA.html
index d50bbc8..ee2f6ae 100644
--- a/html/Tools/Reports/SLA.html
+++ b/html/Tools/Reports/SLA.html
@@ -33,6 +33,14 @@
$Query => undef
</%ARGS>
<%INIT>
+unless (
+ $session{'CurrentUser'}->PrincipalObj->HasRight(
+ Object => $RT::System, Right => 'SeeSLAReports',
+ )
+) {
+ Abort("You're not allowed to see SLA reports.");
+}
+
my $title = loc("Report on Service Level Agreements");
use RT::Extension::SLA::Summary;
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index a8af3eb..8a021d3 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -316,6 +316,14 @@ Just grant them ModifyCustomField right.
=cut
+{
+ my $right = 'SeeSLAReports';
+ use RT::System;
+ $RT::System::Rights->{$right} = 'See service level performance reports';
+ use RT::ACE;
+ $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+}
+
sub BusinessHours {
my $self = shift;
my $name = shift || 'Default';
commit 5548273e39c39d0bfb3c02e39e0e0a65d75c1bba
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Wed May 13 22:00:18 2009 +0000
add tabs to tickets so you can jump to a report right after search
diff --git a/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default b/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
new file mode 100644
index 0000000..d8bbb01
--- /dev/null
+++ b/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
@@ -0,0 +1,15 @@
+<%ARGS>
+$Query => undef
+$tabs => {}
+</%ARGS>
+<%INIT>
+
+$Query ||= $session{'CurrentSearchHash'}->{'Query'};
+
+return unless $Query;
+
+$tabs->{"m"} = {
+ path => "Tools/Reports/SLA.html?". $m->comp( '/Elements/QueryString', Query => $Query ),
+ title => loc('Report SLA'),
+};
+</%INIT>
commit 50b61707c22e1970103500d3eb0d16a7337ff024
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Thu May 14 14:27:44 2009 +0000
add report per ticket for debugging and analysis
diff --git a/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default b/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
index d8bbb01..76253a0 100644
--- a/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
+++ b/html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
@@ -1,15 +1,24 @@
<%ARGS>
$Query => undef
$tabs => {}
+$Ticket => undef
</%ARGS>
<%INIT>
-$Query ||= $session{'CurrentSearchHash'}->{'Query'};
+return unless $session{'CurrentUser'}->PrincipalObj->HasRight(
+ Object => $RT::System, Right => 'SeeSLAReports',
+);
-return unless $Query;
-
-$tabs->{"m"} = {
- path => "Tools/Reports/SLA.html?". $m->comp( '/Elements/QueryString', Query => $Query ),
- title => loc('Report SLA'),
-};
+if ( $Ticket ) {
+ $tabs->{'this'}->{"subtabs"}->{'_DA'} = {
+ path => "Ticket/SLA.html?id=". $Ticket->id,
+ title => loc('Report SLA'),
+ };
+}
+elsif ( $Query ||= $session{'CurrentSearchHash'}->{'Query'} ) {
+ $tabs->{"m"} = {
+ path => "Tools/Reports/SLA.html?". $m->comp( '/Elements/QueryString', Query => $Query ),
+ title => loc('Report SLA'),
+ };
+}
</%INIT>
diff --git a/html/Ticket/SLA.html b/html/Ticket/SLA.html
new file mode 100644
index 0000000..0cde6da
--- /dev/null
+++ b/html/Ticket/SLA.html
@@ -0,0 +1,46 @@
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $ticket,
+ current_tab => "Ticket/SLA.html?id=$id",
+ Title => $title,
+&>
+
+<table>
+<tr><th>#</th><th>Description</th><th>Type</th><th>Owner</th><th>Failed</th><th>Shift</th></tr>
+% foreach my $stat ( @{ $report->Stats } ) {
+<tr>
+<td><% $stat->{transaction}->id %></td>
+<td><% $stat->{transaction}->Description %></td>
+<td><% $stat->{owner_act}? 'yes' : 'no' %></td>
+<td><% $stat->{failed}? 'yes' : 'no' %></td>
+<td><% $stat->{shift} %></td>
+</tr>
+% }
+</table>
+
+<%ARGS>
+$id => undef
+</%ARGS>
+<%INIT>
+
+unless (
+ $session{'CurrentUser'}->PrincipalObj->HasRight(
+ Object => $RT::System, Right => 'SeeSLAReports',
+ )
+) {
+ Abort("You're not allowed to see SLA reports.");
+}
+
+my $ticket = LoadTicket($id);
+unless ($ticket->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+$id = $ARGS{'id'} = $ticket->id;
+
+my $title = loc("SLA performance on ticket #[_1]", $id);
+
+use RT::Extension::SLA;
+my $report = RT::Extension::SLA->Report( $ticket );
+use Data::Dumper;
+$RT::Logger->crit( Dumper $report );
+</%INIT>
commit 3f16054f3f851d748c606c2772618a0736b73344
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Thu May 14 14:29:08 2009 +0000
store txn in the stats
diff --git a/lib/RT/Extension/SLA/Report.pm b/lib/RT/Extension/SLA/Report.pm
index 9d0d8c2..94290cd 100644
--- a/lib/RT/Extension/SLA/Report.pm
+++ b/lib/RT/Extension/SLA/Report.pm
@@ -150,12 +150,13 @@ sub OnResponse {
my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
my $stat = {
- type => 'KeepInLoop',
- owner => $args{'State'}->{'owner'},
- failed => $failed,
- owner_act => $owner,
- actor => $txn->Creator,
- shift => $txn->CreatedObj->Unix - $deadline,
+ type => 'KeepInLoop',
+ owner => $args{'State'}->{'owner'},
+ failed => $failed,
+ owner_act => $owner,
+ transaction => $txn,
+ actor => $txn->Creator,
+ shift => $txn->CreatedObj->Unix - $deadline,
};
push @{ $self->Stats }, $stat;
}
@@ -175,12 +176,13 @@ sub OnResponse {
my $failed = $txn->CreatedObj->Unix > $deadline? 1 : 0;
my $owner = $args{'State'}->{'owner'} == $txn->Creator? 1 : 0;
my $stat = {
- type => 'Response',
- owner => $args{'State'}->{'owner'},
- failed => $failed,
- owner_act => $owner,
- actor => $txn->Creator,
- shift => ($txn->CreatedObj->Unix - $deadline),
+ type => 'Response',
+ owner => $args{'State'}->{'owner'},
+ failed => $failed,
+ owner_act => $owner,
+ transaction => $txn,
+ actor => $txn->Creator,
+ shift => ($txn->CreatedObj->Unix - $deadline),
};
push @{ $self->Stats }, $stat;
}
commit 260414ce190fe977775123e557364e4a8a657877
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Thu May 14 15:07:41 2009 +0000
update manifest
diff --git a/MANIFEST b/MANIFEST
index c76a77e..ad65521 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,8 @@
Changes
etc/initialdata
+html/Callbacks/RT-Extension-SLA/Ticket/Elements/Tabs/Default
html/Callbacks/RT-Extension-SLA/Tools/Reports/Elements/Tabs/Default
+html/Ticket/SLA.html
html/Tools/Reports/SLA.html
inc/Module/AutoInstall.pm
inc/Module/Install.pm
commit f38dd47548d498e713e70a280bda0627c5c64cfc
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Thu May 14 15:08:02 2009 +0000
update M::I
diff --git a/META.yml b/META.yml
index a510d6f..0317c5a 100644
--- a/META.yml
+++ b/META.yml
@@ -8,7 +8,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 6.42
distribution_type: module
-generated_by: 'Module::Install version 0.87'
+generated_by: 'Module::Install version 0.88'
license: gpl2
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
diff --git a/inc/Module/AutoInstall.pm b/inc/Module/AutoInstall.pm
index 38c98f5..807fa7b 100644
--- a/inc/Module/AutoInstall.pm
+++ b/inc/Module/AutoInstall.pm
@@ -175,15 +175,24 @@ sub import {
}
# XXX: check for conflicts and uninstalls(!) them.
- if (
- defined( my $cur = _version_check( _load($mod), $arg ||= 0 ) ) )
+ my $cur = _load($mod);
+ if (_version_cmp ($cur, $arg) >= 0)
{
print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n";
push @Existing, $mod => $arg;
$DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
}
else {
- print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
+ if (not defined $cur) # indeed missing
+ {
+ print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
+ }
+ else
+ {
+ # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above
+ print "too old. ($cur < $arg)\n";
+ }
+
push @required, $mod => $arg;
}
}
@@ -268,8 +277,11 @@ sub _check_lock {
require CPAN;
- if ($CPAN::VERSION > '1.89' && $cpan_env) {
- return _running_under('CPAN');
+ if ($CPAN::VERSION > '1.89') {
+ if ($cpan_env) {
+ return _running_under('CPAN');
+ }
+ return; # CPAN.pm new enough, don't need to check further
}
# last ditch attempt, this -will- configure CPAN, very sorry
@@ -310,7 +322,7 @@ sub install {
while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) {
# grep out those already installed
- if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+ if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
push @installed, $pkg;
}
else {
@@ -349,7 +361,7 @@ sub install {
# see if we have successfully installed them
while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
- if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+ if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
push @installed, $pkg;
}
elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) {
@@ -404,7 +416,7 @@ sub _install_cpanplus {
my $success;
my $obj = $modtree->{$pkg};
- if ( $obj and defined( _version_check( $obj->{version}, $ver ) ) ) {
+ if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) {
my $pathname = $pkg;
$pathname =~ s/::/\\W/;
@@ -497,7 +509,7 @@ sub _install_cpan {
my $obj = CPAN::Shell->expand( Module => $pkg );
my $success = 0;
- if ( $obj and defined( _version_check( $obj->cpan_version, $ver ) ) ) {
+ if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) {
my $pathname = $pkg;
$pathname =~ s/::/\\W/;
@@ -561,7 +573,7 @@ sub _update_to {
my $ver = shift;
return
- if defined( _version_check( _load($class), $ver ) ); # no need to upgrade
+ if _version_cmp( _load($class), $ver ) >= 0; # no need to upgrade
if (
_prompt( "==> A newer version of $class ($ver) is required. Install?",
@@ -670,9 +682,11 @@ sub _load_cpan {
}
# compare two versions, either use Sort::Versions or plain comparison
-sub _version_check {
+# return values same as <=>
+sub _version_cmp {
my ( $cur, $min ) = @_;
- return unless defined $cur;
+ return -1 unless defined $cur; # if 0 keep comparing
+ return 1 unless $min;
$cur =~ s/\s+$//;
@@ -683,16 +697,13 @@ sub _version_check {
) {
# use version.pm if it is installed.
- return (
- ( version->new($cur) >= version->new($min) ) ? $cur : undef );
+ return version->new($cur) <=> version->new($min);
}
elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) )
{
# use Sort::Versions as the sorting algorithm for a.b.c versions
- return ( ( Sort::Versions::versioncmp( $cur, $min ) != -1 )
- ? $cur
- : undef );
+ return Sort::Versions::versioncmp( $cur, $min );
}
warn "Cannot reliably compare non-decimal formatted versions.\n"
@@ -701,7 +712,7 @@ sub _version_check {
# plain comparison
local $^W = 0; # shuts off 'not numeric' bugs
- return ( $cur >= $min ? $cur : undef );
+ return $cur <=> $min;
}
# nothing; this usage is deprecated.
@@ -791,4 +802,4 @@ END_MAKE
__END__
-#line 1045
+#line 1056
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index fadb682..d39e460 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -28,7 +28,7 @@ BEGIN {
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
- $VERSION = '0.87';
+ $VERSION = '0.88';
# Storage for the pseudo-singleton
$MAIN = undef;
@@ -353,7 +353,7 @@ sub _read {
if ( $] >= 5.006 ) {
open( FH, '<', $_[0] ) or die "open($_[0]): $!";
} else {
- open( FH, "< $_[0]" ) or die "open($_[0]): $!";
+ open( FH, "< $_[0]" ) or die "open($_[0]): $!";
}
my $string = do { local $/; <FH> };
close FH or die "close($_[0]): $!";
@@ -384,7 +384,7 @@ sub _write {
if ( $] >= 5.006 ) {
open( FH, '>', $_[0] ) or die "open($_[0]): $!";
} else {
- open( FH, "> $_[0]" ) or die "open($_[0]): $!";
+ open( FH, "> $_[0]" ) or die "open($_[0]): $!";
}
foreach ( 1 .. $#_ ) {
print FH $_[$_] or die "print($_[0]): $!";
diff --git a/inc/Module/Install/AutoInstall.pm b/inc/Module/Install/AutoInstall.pm
index 562bd0a..32f1423 100644
--- a/inc/Module/Install/AutoInstall.pm
+++ b/inc/Module/Install/AutoInstall.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 211585a..c08b3f0 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
use strict 'vars';
use vars qw{$VERSION};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
}
# Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index ef98ee4..fd64344 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -9,7 +9,7 @@ use ExtUtils::MakeMaker ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 763732d..e0acf6b 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index 406da54..6324bd5 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index b1854f6..3d10124 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -7,7 +7,7 @@ use ExtUtils::MakeMaker ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 6852f9a..6fd221f 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
@@ -511,7 +511,7 @@ sub requires_from {
# Also, convert double-part versions (eg, 5.8)
sub _perl_version {
my $v = $_[-1];
- $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e;
+ $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e;
$v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e;
$v =~ s/(\.\d\d\d)000$/$1/;
$v =~ s/_.+$//;
@@ -534,7 +534,7 @@ sub WriteMyMeta {
sub write_mymeta {
my $self = shift;
-
+
# If there's no existing META.yml there is nothing we can do
return unless -f 'META.yml';
@@ -574,7 +574,7 @@ sub write_mymeta {
# Save as the MYMETA.yml file
print "Writing MYMETA.yml\n";
- YAML::Tiny::DumpFile('MYMETA.yml', $meta);
+ YAML::Tiny::DumpFile('MYMETA.yml', $meta);
}
1;
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index 5d11a43..d91b287 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index a73f351..e82f5d3 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.87';
+ $VERSION = '0.88';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
commit afb655c376a8816af5f4c85de10ff9aad9a766c8
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Thu May 14 15:09:25 2009 +0000
bump version
diff --git a/META.yml b/META.yml
index 0317c5a..a894f6d 100644
--- a/META.yml
+++ b/META.yml
@@ -25,4 +25,4 @@ requires:
perl: 5.8.0
resources:
license: http://opensource.org/licenses/gpl-2.0.php
-version: 0.03_01
+version: 0.03_02
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index 8a021d3..e909e27 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -4,7 +4,7 @@ use warnings;
package RT::Extension::SLA;
-our $VERSION = '0.03_01';
+our $VERSION = '0.03_02';
=head1 NAME
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list