[Rt-commit] rt branch, 4.2/forbid-circular-dependson-and-memberof, updated. rt-4.0.4-381-gf0e3ae8

? sunnavy sunnavy at bestpractical.com
Sat Jan 28 15:04:44 EST 2012


The branch, 4.2/forbid-circular-dependson-and-memberof has been updated
       via  f0e3ae82c3abfab940452ebae35aff8de9485b84 (commit)
      from  c1dd5d57b5639518f39fc5abaffa17647db17f48 (commit)

Summary of changes:
 configure.ac                                       |    1 +
 ...ences-viewer.in => rt-circular-relationship.in} |  132 ++++++++++++--------
 sbin/rt-test-dependencies.in                       |    1 +
 3 files changed, 83 insertions(+), 51 deletions(-)
 copy sbin/{rt-preferences-viewer.in => rt-circular-relationship.in} (56%)
 mode change 100644 => 100755

- Log -----------------------------------------------------------------
commit f0e3ae82c3abfab940452ebae35aff8de9485b84
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sun Jan 29 01:03:19 2012 +0800

    added sbin/rt-test-dependencies to find circular relationships

diff --git a/configure.ac b/configure.ac
index e405243..568a633 100755
--- a/configure.ac
+++ b/configure.ac
@@ -432,6 +432,7 @@ AC_CONFIG_FILES([
                  sbin/rt-fulltext-indexer
                  bin/rt-crontool
                  bin/rt-mailgate
+                 sbin/rt-circular-relationship
                  bin/rt],
                 [chmod ug+x $ac_file]
                )
diff --git a/sbin/rt-circular-relationship.in b/sbin/rt-circular-relationship.in
new file mode 100755
index 0000000..1cc555f
--- /dev/null
+++ b/sbin/rt-circular-relationship.in
@@ -0,0 +1,179 @@
+#!@PERL@ -w
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2012 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 }}}
+use strict;
+use warnings;
+
+# fix lib paths, some may be relative
+BEGIN {
+    require File::Spec;
+    my @libs = ( "@RT_LIB_PATH@", "@LOCAL_LIB_PATH@" );
+    my $bin_path;
+
+    for my $lib (@libs) {
+        unless ( File::Spec->file_name_is_absolute($lib) ) {
+            unless ($bin_path) {
+                if ( File::Spec->file_name_is_absolute(__FILE__) ) {
+                    $bin_path = ( File::Spec->splitpath(__FILE__) )[1];
+                }
+                else {
+                    require FindBin;
+                    no warnings "once";
+                    $bin_path = $FindBin::Bin;
+                }
+            }
+            $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib );
+        }
+        unshift @INC, $lib;
+    }
+
+}
+
+my %opt = ();
+use Getopt::Long;
+GetOptions( \%opt, 'help|h', 'search=s', 'search-arg=s' );
+
+use RT;
+RT->LoadConfig;
+RT->Init;
+
+if ($opt{help}) {
+    require Pod::Usage;
+    print Pod::Usage::pod2usage( { verbose => 2 } );
+    exit;
+}
+
+use RT::Tickets;
+my $tickets = RT::Tickets->new($RT::SystemUser);
+
+if ($opt{search}) {
+    require UNIVERSAL::require;
+    $opt{search}->require or die $@;
+    my $search = $opt{search}->new(
+        TicketsObj  => $tickets,
+        Argument    => $opt{'search-arg'},
+        CurrentUser => $RT::SystemUser,
+    );
+    $search->Prepare();
+}
+else {
+    $tickets->UnLimit;
+}
+
+use Scalar::Util 'weaken', 'isweak';
+use Devel::Cycle;
+use List::MoreUtils 'uniq';
+
+$tickets = $tickets->ItemsArrayRef;
+for my $type (qw/DependsOn Members/) {
+    print "$type:\n";
+    my %map;
+    for my $ticket (@$tickets) {
+        my $links = $ticket->$type;
+        my $object_method = $type eq 'DependsOn' ? 'TargetObj' : 'BaseObj';
+        while ( my $link = $links->Next ) {
+            my $object = $link->$object_method;
+            next unless $object->isa('RT::Ticket');
+            my $id = $object->id;
+            $map{ $ticket->id }{$id} = $map{$id} ||= {};
+        }
+    }
+
+    my @cycles;
+
+    find_cycle(
+        \%map,
+        sub {
+            my $path = shift;
+            my @lines;
+            for (@$path) {
+                my ( $type, $index, $ref, $value ) = @$_;
+                weaken( $map{$index} ) unless isweak( $map{$index} );
+                push @lines, $index;
+            }
+            push @cycles, \@lines;
+        }
+    );
+
+    my @out;
+    for my $cycle (@cycles) {
+        my @nodes = @$cycle;
+        while ( $nodes[0] != $nodes[-1] ) {
+
+            # e.g. 1 -> 5 -> 6 -> 5
+            # we want 5 -> 6 -> 5
+            shift @nodes;
+        }
+        push @out, join " -> ", @nodes;
+    }
+
+    if (@out) {
+        for ( uniq @out ) {
+            print "    $_\n";
+        }
+    }
+    else {
+        print "    no circular relationship\n";
+    }
+}
+
+__END__
+
+=head1 NAME
+
+rt-circular-relationship - circular replationship in tickets
+
+=head1 SYNOPSIS
+
+    rt-circular-relationship 
+    rt-circular-relationship --search RT::Search::ActiveTicketsInQueue  --search-arg General 
+
+=head1 DESCRIPTION
+
+This script reports circular replationship in tickets.
+
diff --git a/sbin/rt-test-dependencies.in b/sbin/rt-test-dependencies.in
index 97a0a8e..a5be025 100755
--- a/sbin/rt-test-dependencies.in
+++ b/sbin/rt-test-dependencies.in
@@ -223,6 +223,7 @@ Net::CIDR
 Regexp::Common::net::CIDR
 Regexp::IPv6
 Symbol::Global::Name
+Devel::Cycle
 .
 
 $deps{'MASON'} = [ text_to_hash( << '.') ];

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


More information about the Rt-commit mailing list