[Rt-commit] rt branch, 4.2/fixup-version-history, created. rt-4.1.23-9-g9997e36

Alex Vandiver alexmv at bestpractical.com
Thu Sep 5 02:46:24 EDT 2013


The branch, 4.2/fixup-version-history has been created
        at  9997e36142bd9df6ec566fd5482cc3f46814048f (commit)

- Log -----------------------------------------------------------------
commit bc69cf4910bed4e61fa5e6a773539e74d8b05efe
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Jul 5 10:58:45 2013 -0400

    Hide upgrade history from global attributes on config page
    
    Skipped the entry in code since applying a Limit removed the
    upgrade history when calling the attribute methods in the
    Upgrade history section later on the page.

diff --git a/share/html/Admin/Tools/Configuration.html b/share/html/Admin/Tools/Configuration.html
index 71d1702..0802938 100644
--- a/share/html/Admin/Tools/Configuration.html
+++ b/share/html/Admin/Tools/Configuration.html
@@ -216,6 +216,7 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged
 % my $attrs = $RT::System->Attributes;
 % my $index_size = 0;
 % while ( my $attr = $attrs->Next ) {
+% next if $attr->Name eq 'UpgradeHistory';
 <tr class="<% $index_size%2 ? 'oddline' : 'evenline'%>">
 % if ($attr->Name eq 'UserLogo') {
 %   my $content = $attr->Content;

commit 5cd96f453e241944f2611d80d7007b8a33192c5a
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Aug 9 09:29:03 2013 -0400

    Add ids to recorded upgrade entries to track success/failure
    
    Installations and upgrades can run into issues that cause the
    upgrade scripts to die. Add ids to track this history and aid
    in future troubleshooting.
    
    full_id: An id for multi-step upgrades from 'make upgrade-database'
    The full_id tags each individual upgrade step as part of the larger
    upgrade to unambiguously show that individual upgrades were run as
    part of a full upgrade.
    
    individual_id: An id to bookend the start and end of an upgrade
    step and identify if a step failed to complete.
    
    Adds Data::GUID as a guid generator.

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 8ae023e..38540f8 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -70,6 +70,7 @@ BEGIN { # BEGIN RT CMD BOILERPLATE
 
 use Term::ReadKey;
 use Getopt::Long;
+use Data::GUID;
 
 $| = 1; # unbuffer all output.
 
@@ -193,6 +194,7 @@ print "Working with:\n"
 
 my $package = $args{'package'} || 'RT';
 my $ext_version = $args{'ext-version'};
+my $full_id = Data::GUID->new->as_string;
 
 foreach my $action ( @actions ) {
     no strict 'refs';
@@ -285,6 +287,7 @@ sub action_insert {
     $file = $RT::EtcPath . "/initialdata" if $init && !$file;
     $file ||= $args{'datadir'}."/content";
 
+    my $individual_id = Data::GUID->new->as_string();
     my @ret;
 
     my $upgrade = sub { @ret = $RT::Handle->InsertData( $file, $root_password ) };
@@ -319,7 +322,10 @@ sub action_insert {
         action   => 'insert',
         filename => Cwd::abs_path($file),
         content  => $content,
-        stage    => 'after',);
+        stage    => 'after',
+        type     => 'process initialdata',
+        full_id => $full_id,
+        individual_id => $individual_id );
 
     $upgrade_data{'ext_version'} = $ext_version if $ext_version;
 
@@ -422,12 +428,16 @@ sub action_upgrade {
         from      => $upgrading_from,
         to        => $upgrading_to,
         versions  => [@versions],
+        full_id => $full_id,
+        individual_id => $full_id
     });
 
     my $previous = $upgrading_from;
     my ( $ret, $msg );
     foreach my $n ( 0..$#versions ) {
         my $v = $versions[$n];
+        my $individual_id = Data::GUID->new->as_string();
+
         my @back = grep {-e $_} map {"$base_dir/$versions[$_]/backcompat"} $n+1..$#versions;
         print "Processing $v\n";
 
@@ -437,6 +447,8 @@ sub action_upgrade {
             stage  => 'before',
             from   => $previous,
             to     => $v,
+            full_id => $full_id,
+            individual_id => $individual_id,
         });
 
         my %tmp = (%args, datadir => "$base_dir/$v", datafile => undef, backcompat => \@back);
@@ -469,6 +481,8 @@ sub action_upgrade {
             stage  => 'after',
             from   => $previous,
             to     => $v,
+            full_id => $full_id,
+            individual_id => $individual_id,
         });
 
         $previous = $v;
@@ -481,6 +495,8 @@ sub action_upgrade {
         from      => $upgrading_from,
         to        => $upgrading_to,
         versions  => [@versions],
+        full_id => $full_id,
+        individual_id => $full_id,
     });
 
     return 1;
diff --git a/sbin/rt-test-dependencies.in b/sbin/rt-test-dependencies.in
index f96fea2..6aba4c1 100644
--- a/sbin/rt-test-dependencies.in
+++ b/sbin/rt-test-dependencies.in
@@ -182,6 +182,7 @@ CGI::PSGI 0.12
 Class::Accessor 0.34
 Crypt::Eksblowfish
 CSS::Squish 0.06
+Data::GUID
 Date::Extract 0.02
 Date::Manip
 DateTime 0.44

commit 7cd6af7096e60c2142daf7a1bd8820002958c080
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Aug 9 10:03:59 2013 -0400

    Add before entry to insert actions
    
    Add a before to the upgrade history to track progress on
    possible failures and match the other before/after upgrade
    history pairs. Capture the return code in the after entry.

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 38540f8..c3ec380 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -288,6 +288,19 @@ sub action_insert {
     $file ||= $args{'datadir'}."/content";
 
     my $individual_id = Data::GUID->new->as_string();
+
+    my %upgrade_data = (
+        action   => 'insert',
+        filename => Cwd::abs_path($file),
+        stage    => 'before',
+        type     => 'process initialdata',
+        full_id => $full_id,
+        individual_id => $individual_id );
+
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
     my @ret;
 
     my $upgrade = sub { @ret = $RT::Handle->InsertData( $file, $root_password ) };
@@ -318,12 +331,13 @@ sub action_insert {
 
     RT->ConnectToDatabase();
 
-    my %upgrade_data = (
+    %upgrade_data = (
         action   => 'insert',
         filename => Cwd::abs_path($file),
         content  => $content,
         stage    => 'after',
         type     => 'process initialdata',
+        return_value => join (', ', @ret),
         full_id => $full_id,
         individual_id => $individual_id );
 

commit 87bd612b88e0f037c6721d5b5e51db4030f75a9b
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:43:13 2013 -0400

    Transform flat start/end events into an upgrade hierarchy

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 9842af0..272db04 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -258,6 +258,55 @@ sub UpgradeHistory {
     return $upgrade_history;
 }
 
+sub ParsedUpgradeHistory {
+    my $self = shift;
+    my $package = shift;
+
+    my $version_status = "Current version: ";
+    if ( $package eq 'RT' ){
+        $version_status .= $RT::VERSION;
+    } elsif ( grep {/$package/} @{RT->Config->Get('Plugins')} ) {
+        no strict 'refs';
+        $version_status .= ${ $package . '::VERSION' };
+    } else {
+        $version_status = "Not currently loaded";
+    }
+
+    my %ids;
+    my @lines;
+
+    my @events = $self->UpgradeHistory( $package );
+    for my $event (@events) {
+        if ($event->{stage} eq 'before') {
+            if ($ids{$event->{full_id}}) {
+                my $kids = $ids{$event->{full_id}}{sub_events} ||= [];
+                # Stitch non-"upgrade"s beneath the previous "upgrade"
+                if ( @{$kids} and $event->{action} ne 'upgrade' and $kids->[-1]{action} eq 'upgrade') {
+                    push @{ $kids->[-1]{sub_events} }, $event;
+                } else {
+                    push @{ $kids }, $event;
+                }
+            } else {
+                push @lines, $event;
+            }
+            $ids{$event->{individual_id}} = $event;
+        } elsif ($event->{stage} eq 'after') {
+            if ($ids{$event->{individual_id}}) {
+                my $end = $event;
+                $event = $ids{$event->{individual_id}};
+                $event->{end} = $end->{timestamp};
+
+                $event->{return_value} = [ split ', ', $end->{return_value}, 2 ]
+                    if $end->{return_value};
+                $event->{content} ||= $end->{content};
+            }
+        }
+    }
+
+    return ($version_status, @lines);
+}
+
+
 RT::Base->_ImportOverlays();
 
 1;

commit db56b1aa2084a89f540ad6dfc8787fda362807bd
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:47:07 2013 -0400

    Store the actual return value data structure, to allow for reconstruction

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 272db04..002d256 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -296,8 +296,9 @@ sub ParsedUpgradeHistory {
                 $event = $ids{$event->{individual_id}};
                 $event->{end} = $end->{timestamp};
 
-                $event->{return_value} = [ split ', ', $end->{return_value}, 2 ]
-                    if $end->{return_value};
+                $end->{return_value} = [ split ', ', $end->{return_value}, 2 ]
+                    if $end->{return_value} and not ref $end->{return_value};
+                $event->{return_value} = $end->{return_value};
                 $event->{content} ||= $end->{content};
             }
         }
diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index c3ec380..e31b7a8 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -337,7 +337,7 @@ sub action_insert {
         content  => $content,
         stage    => 'after',
         type     => 'process initialdata',
-        return_value => join (', ', @ret),
+        return_value => [ @ret ],
         full_id => $full_id,
         individual_id => $individual_id );
 

commit 15ade9594c6149073061b9384a83860261d268c7
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:48:07 2013 -0400

    Make the "after" stage merely metadata; ther is no need to repeat the data

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index e31b7a8..7452c54 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -288,17 +288,18 @@ sub action_insert {
     $file ||= $args{'datadir'}."/content";
 
     my $individual_id = Data::GUID->new->as_string();
-
     my %upgrade_data = (
         action   => 'insert',
         filename => Cwd::abs_path($file),
         stage    => 'before',
-        type     => 'process initialdata',
-        full_id => $full_id,
-        individual_id => $individual_id );
-
+        full_id  => $full_id,
+        individual_id => $individual_id
+    );
     $upgrade_data{'ext_version'} = $ext_version if $ext_version;
 
+    open my $handle, '<', $file or warn "Unable to open $file: $!";
+    $upgrade_data{content} = do {local $/; <$handle>} if $handle;
+
     RT->System->AddUpgradeHistory($package => \%upgrade_data);
 
     my @ret;
@@ -318,30 +319,16 @@ sub action_insert {
 
     $upgrade->();
 
-    my $content;
-    open my $handle, '<', $file or warn "Unable to open $file: $!";
-    if ($handle) {
-        local $/; # slurp
-        $content = <$handle>;
-    }
-
     # XXX Reconnecting to insert the history entry
     # until we can sort out removing
     # the disconnect at the end of InsertData.
-
     RT->ConnectToDatabase();
 
     %upgrade_data = (
-        action   => 'insert',
-        filename => Cwd::abs_path($file),
-        content  => $content,
-        stage    => 'after',
-        type     => 'process initialdata',
-        return_value => [ @ret ],
-        full_id => $full_id,
-        individual_id => $individual_id );
-
-    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
 
     RT->System->AddUpgradeHistory($package => \%upgrade_data);
 
@@ -490,12 +477,7 @@ sub action_upgrade {
         RT->ConnectToDatabase();
 
         RT->System->AddUpgradeHistory($package => {
-            action => 'upgrade',
-            type   => 'individual upgrade',
-            stage  => 'after',
-            from   => $previous,
-            to     => $v,
-            full_id => $full_id,
+            stage         => 'after',
             individual_id => $individual_id,
         });
 
@@ -503,13 +485,7 @@ sub action_upgrade {
     }
 
     RT->System->AddUpgradeHistory($package => {
-        type      => 'full upgrade',
-        action    => 'upgrade',
-        stage     => 'after',
-        from      => $upgrading_from,
-        to        => $upgrading_to,
-        versions  => [@versions],
-        full_id => $full_id,
+        stage         => 'after',
         individual_id => $full_id,
     });
 

commit 7ce6b127563c33d4757fc4874e8866687c90feff
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:48:52 2013 -0400

    Store schema and acl events as well

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 7452c54..0e23477 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -238,8 +238,28 @@ sub action_schema {
     my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'schema' );
     return ($status, $msg) unless $status;
 
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'schema',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
     print "Now populating database schema.\n";
-    return RT::Handle->InsertSchema( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertSchema( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
+    return @ret;
 }
 
 sub action_acl {
@@ -248,19 +268,63 @@ sub action_acl {
     my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'acl' );
     return ($status, $msg) unless $status;
 
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'acl',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
     print "Now inserting database ACLs.\n";
-    return RT::Handle->InsertACL( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertACL( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
+    return @ret;
 }
 
 sub action_indexes {
     my %args = @_;
+    RT->ConnectToDatabase;
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'indexes',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
     my $dbh = get_admin_dbh();
     $RT::Handle = RT::Handle->new;
     $RT::Handle->dbh( $dbh );
     RT::InitLogging();
 
     print "Now inserting database indexes.\n";
-    return RT::Handle->InsertIndexes( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertIndexes( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    $RT::Handle = RT::Handle->new;
+    $RT::Handle->dbh( undef );
+    RT->ConnectToDatabase;
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
+    return @ret;
 }
 
 sub action_coredata {

commit 5f8f38c0557183ea80b902665a3ff42ab989d24a
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:50:47 2013 -0400

    Recursively walk through the parsed history to display it

diff --git a/share/html/Admin/Elements/UpgradeHistory b/share/html/Admin/Elements/UpgradeHistory
new file mode 100644
index 0000000..4e96a6d
--- /dev/null
+++ b/share/html/Admin/Elements/UpgradeHistory
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% for my $package (@packages) {
+%   my ($version_status, @lines) = RT->System->ParsedUpgradeHistory($package);
+<h4><% $package %> (<% $version_status %>)</h4>
+<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection upgrade-history">
+<thead>
+<tr class="collection-as-table">
+<th class="collection-as-table"> </th>
+<th class="collection-as-table"><&|/l&>Action</&></th>
+<th class="collection-as-table"><&|/l&>Date</&></th>
+<th class="collection-as-table"><&|/l&>Elapsed</&></th>
+<th class="collection-as-table"><&|/l, $package &>[_1] Version</&></th>
+</tr></thead>
+
+% my $i = 0;
+% for my $upgrade (@lines) {
+<& UpgradeHistoryRow, i => \$i, row => $upgrade &>
+% }
+</table>
+% }
+
+<%init>
+my $upgrade_history = RT->System->UpgradeHistory;
+my @packages = ('RT', sort grep { $_ ne 'RT' } keys %$upgrade_history);
+</%init>
diff --git a/share/html/Admin/Elements/UpgradeHistoryRow b/share/html/Admin/Elements/UpgradeHistoryRow
new file mode 100644
index 0000000..b9f579a
--- /dev/null
+++ b/share/html/Admin/Elements/UpgradeHistoryRow
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<tr class="<% join ' ', map {CSSClass($_)} @classes %>">
+    <td class="upgrade-history-parent" id="parent-upgrade-history-<% $row->{individual_id} %>">
+% if ($top) {
+    <span class="widget"><a href="#" onclick="toggle_upgrade_history(this, '.upgrade-history-' + <% $row->{full_id} | n,j %>); return false";"></a></span>
+% }
+    </td>
+    <td class="collection-as-table" style="padding-left: <% $indent * 3%>em">
+%       if ($row->{'action'} eq 'upgrade') { # type is more specific for upgrades
+<&|/l, $row->{'from'}, $row->{'to'} &>Upgrade from [_1] to [_2]</&>
+%       } elsif ( $row->{'action'} eq 'insert' ) {
+<&|/l, $row->{filename} &>Insert from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'schema' ) {
+<&|/l, $row->{filename} &>Schema updates from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'acl' ) {
+<&|/l, $row->{filename} &>ACL updates from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'indexes' ) {
+<&|/l, $row->{filename} &>Index updates from [_1]</&>
+%       } else {
+<% ucfirst($row->{action}) %>
+%       }
+    </td>
+    <td class="collection-as-table"><% $timestamp->AsString %></td>
+    <td class="collection-as-table"><% $duration %></td>
+    <td class="collection-as-table"><% $row->{ext_version} || $row->{rt_version} %></td>
+</tr>
+% for (@{$kids || []}) {
+<& UpgradeHistoryRow, row => $_, indent => $indent+1, i => $i &>
+% }
+<%args>
+$indent => 0
+$i
+$row
+</%args>
+<%init>
+my $complete = $row->{return_value} ? $row->{return_value}[0] : $row->{end};
+my $kids     = $row->{sub_events};
+my $top      = $row->{full_id} eq $row->{individual_id};
+
+my @classes;
+push @classes, $complete ? 'complete' : 'incomplete';
+push @classes, $$i++ % 2 ? 'oddline' : 'evenline';
+push @classes, 'upgrade-history-'.$row->{full_id} unless $top;
+
+my $timestamp = RT::Date->new($session{CurrentUser});
+$timestamp->Set(Value => $row->{timestamp});
+
+my $duration = $row->{end} ? $timestamp->DurationAsString($row->{end} - $row->{timestamp}) : '';
+</%init>
diff --git a/share/html/Admin/Tools/Configuration.html b/share/html/Admin/Tools/Configuration.html
index 0802938..a4ba3e8 100644
--- a/share/html/Admin/Tools/Configuration.html
+++ b/share/html/Admin/Tools/Configuration.html
@@ -268,49 +268,7 @@ if ($item =~ /^\s*(.*?)\s*v(\S+);/) {
 </&>
 
 <&|/Widgets/TitleBox, title => loc("RT upgrade history")&>
-
-% my $upgrade_history = RT->System->UpgradeHistory;
-% my @packages = ('RT', sort grep { $_ ne 'RT' } keys %$upgrade_history);
-% for my $package (@packages) {
-<h4><% $package %></h4>
-<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection">
-<tr class="collection-as-table">
-<th class="collection-as-table"><&|/l&>Action</&></th>
-<th class="collection-as-table"><&|/l&>Using RT Version</&></th>
-<th class="collection-as-table"><&|/l&>Time</&></th>
-<th class="collection-as-table"><&|/l&>Extra</&></th>
-
-<%perl>
-    my $i = 0;
-    for my $upgrade (@{ $upgrade_history->{$package} }) {
-        # only list completed upgrades
-        next unless $upgrade->{stage} eq 'after';
-</%perl>
-<tr class="<% $i++ %2 ? 'oddline' : 'evenline'%>">
-    <td class="collection-as-table">
-% if ($upgrade->{action} eq 'upgrade') { # type is more specific for upgrades
-    <% $upgrade->{type} %>
-% } else {
-    <% $upgrade->{action} %>
-% }
-    </td>
-    <td class="collection-as-table">
-        <% $upgrade->{rt_version} %>
-    </td>
-    <td class="collection-as-table">
-%          my $timestamp = RT::Date->new($session{CurrentUser});
-%          $timestamp->Set(Value => $upgrade->{timestamp});
-           <% $timestamp->AsString %>
-    </td>
-    <td class="collection-as-table">
-% if ($upgrade->{action} eq 'upgrade') {
-    <&|/l, $upgrade->{from}, $upgrade->{to} &>from [_1] to [_2]</&>
-% }
-    </td>
-</tr>
-% }
-</table>
-% }
+<& /Admin/Elements/UpgradeHistory &>
 </&>
 
 <&|/Widgets/TitleBox, title => loc("Perl configuration") &>
diff --git a/share/static/css/base/admin.css b/share/static/css/base/admin.css
index 46cc05f..95c5878 100644
--- a/share/static/css/base/admin.css
+++ b/share/static/css/base/admin.css
@@ -61,3 +61,24 @@ textarea[name="SMIMECertificate"] {
     width: 50em;
     height: 25em;
 }
+
+table.upgrade-history .incomplete {
+    font-weight: bold;
+    color: #900;
+}
+
+table.upgrade-history .upgrade-history-parent .widget a {
+  display: block;
+  margin: 0;
+  width: 20px;
+
+  background: url(../../../static/images/css/rollup-arrow.gif) no-repeat;
+  background-position: center 0;
+
+  padding: 7px 0 0 0;
+  overflow: hidden;
+}
+
+table.upgrade-history .upgrade-history-parent .widget a.rolled-up {
+    background-image: url(../../../static/images/css/rolldown-arrow.gif);
+}
diff --git a/share/static/js/util.js b/share/static/js/util.js
index 50df9f9..5a34647 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -30,6 +30,11 @@ function switchVisibility(id1, id2) {
     return false;
 }
 
+function toggle_upgrade_history(widget, selector) {
+    jQuery(selector).toggle();
+    jQuery(widget).toggleClass("rolled-up");
+}
+
 /* Classes */
 function jQueryWrap( id ) {
     return typeof id == 'object' ? jQuery(id) : jQuery('#'+id);

commit 9997e36142bd9df6ec566fd5482cc3f46814048f
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:51:18 2013 -0400

    Reconstruct hierarchy on pre-GUID history records

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 002d256..d549cba 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -78,6 +78,7 @@ with "RT::Record::Role::Roles",
 
 use RT::ACL;
 use RT::ACE;
+use Data::GUID;
 
 __PACKAGE__->AddRight( Admin   => SuperUser           => 'Do anything and everything'); # loc_pair
 __PACKAGE__->AddRight( Staff   => ShowUserHistory     => 'Show history of public user properties'); # loc_pair
@@ -277,7 +278,17 @@ sub ParsedUpgradeHistory {
 
     my @events = $self->UpgradeHistory( $package );
     for my $event (@events) {
-        if ($event->{stage} eq 'before') {
+        if ($event->{stage} eq 'before' or (($event->{action}||'') eq 'insert' and not $event->{full_id})) {
+            if (not $event->{full_id}) {
+                # For upgrade done in the 4.1 series without GUIDs
+                if (($event->{type}||'') eq 'full upgrade') {
+                    $event->{full_id} = $event->{individual_id} = Data::GUID->new->as_string;
+                } else {
+                    $event->{individual_id} = Data::GUID->new->as_string;
+                    $event->{full_id} = (@lines ? $lines[-1]{full_id} : Data::GUID->new->as_string);
+                }
+                $event->{return_value} = [1] if $event->{stage} eq 'after';
+            }
             if ($ids{$event->{full_id}}) {
                 my $kids = $ids{$event->{full_id}}{sub_events} ||= [];
                 # Stitch non-"upgrade"s beneath the previous "upgrade"
@@ -291,7 +302,14 @@ sub ParsedUpgradeHistory {
             }
             $ids{$event->{individual_id}} = $event;
         } elsif ($event->{stage} eq 'after') {
-            if ($ids{$event->{individual_id}}) {
+            if (not $event->{individual_id}) {
+                if (($event->{type}||'') eq 'full upgrade') {
+                    $lines[-1]{end} = $event->{timestamp} if @lines;
+                } elsif (($event->{type}||'') eq 'individual upgrade') {
+                    $lines[-1]{sub_events}[-1]{end} = $event->{timestamp}
+                        if @lines and @{ $lines[-1]{sub_events} };
+                }
+            } elsif ($ids{$event->{individual_id}}) {
                 my $end = $event;
                 $event = $ids{$event->{individual_id}};
                 $event->{end} = $end->{timestamp};

-----------------------------------------------------------------------


More information about the Rt-commit mailing list