import rt 3.4.6
[freeside.git] / rt / bin / rt.in
index b75e9e7..c80577f 100644 (file)
@@ -3,7 +3,7 @@
 # 
 # COPYRIGHT:
 #  
-# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC 
 #                                          <jesse@bestpractical.com>
 # 
 # (Except where explicitly superseded by other copyright notices)
@@ -23,9 +23,7 @@
 # 
 # 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/copyleft/gpl.html.
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 # 
 # 
 # CONTRIBUTION SUBMISSION POLICY:
@@ -46,6 +44,7 @@
 # those contributions and any derivatives thereof.
 # 
 # END BPS TAGGED BLOCK }}}
+
 # Designed and implemented for Best Practical Solutions, LLC by
 # Abhijit Menon-Sen <ams@wiw.org>
 
@@ -58,7 +57,6 @@ use Cwd;
 use LWP;
 use Text::ParseWords;
 use HTTP::Request::Common;
-use Term::ReadLine;
 
 # We derive configuration information from hardwired defaults, dotfiles,
 # and the RT* environment variables (in increasing order of precedence).
@@ -73,7 +71,7 @@ my %config = (
         debug   => 0,
         user    => eval{(getpwuid($<))[0]} || $ENV{USER} || $ENV{USERNAME},
         passwd  => undef,
-        server  => 'http://localhost/',
+        server  => 'http://localhost/rt/',
         query   => undef,
         orderby => undef,
     ),
@@ -83,8 +81,6 @@ my %config = (
 my $session = new Session("$HOME/.rt_sessions");
 my $REST = "$config{server}/REST/1.0";
 
-my $prompt = 'rt> ';
-
 sub whine;
 sub DEBUG { warn @_ if $config{debug} >= shift }
 
@@ -117,8 +113,6 @@ my %handlers = (
     link        => ["link", "ln"],
     merge       => ["merge"],
     grant       => ["grant", "revoke"],
-    take        => ["take", "steal", "untake"],
-    quit        => ["quit", "exit"],
 );
 
 my %actions;
@@ -133,16 +127,10 @@ foreach my $fn (keys %handlers) {
 sub handler {
     my $action;
 
-    push @ARGV, 'shell' if (!@ARGV);    # default to shell mode
-    shift @ARGV if ($ARGV[0] eq 'rt');    # ignore a leading 'rt'
     if (@ARGV && exists $actions{$ARGV[0]}) {
         $action = shift @ARGV;
-        $actions{$action}->($action);
-    }
-    else {
-        print STDERR "rt: Unknown command '@ARGV'.\n";
-        print STDERR "rt: For help, run 'rt help'.\n";
     }
+    $actions{$action || "help"}->($action || ());
 }
 
 handler();
@@ -155,13 +143,16 @@ exit;
 
 sub shell {
     $|=1;
-    my $term = new Term::ReadLine 'RT CLI';
-    while ( defined ($_ = $term->readline($prompt)) ) {
+    print "rt> ";
+    while (<>) {
+        chomp;
         next if /^#/ || /^\s*$/;
 
         @ARGV = shellwords($_);
         handler();
+        print "rt> ";
     }
+    print "\n";
 }
 
 sub version {
@@ -172,11 +163,6 @@ sub logout {
     submit("$REST/logout") if defined $session->cookie;
 }
 
-sub quit {
-    logout();
-    exit;
-}
-
 my %help;
 sub help {
     my ($action, $type) = @_;
@@ -282,8 +268,7 @@ sub list {
         whine "No $item specified.";
         $bad = 1;
     }
-    #return help("list", $type) if $bad;
-    return suggest_help("list", $type) if $bad;
+    return help("list", $type) if $bad;
 
     my $r = submit("$REST/search/$type", { query => $q, %data });
     print $r->content;
@@ -340,18 +325,10 @@ sub show {
         whine "No objects specified.";
         $bad = 1;
     }
-    #return help("show", $type) if $bad;
-    return suggest_help("show", $type) if $bad;
+    return help("show", $type) if $bad;
 
     my $r = submit("$REST/show", { id => \@objects, %data });
-    my $c = $r->content;
-    # if this isn't a text reply, remove the trailing newline so we
-    # don't corrupt things like tarballs when people do
-    # show ticket/id/attachments/id/content > foo.tar.gz
-    if ($r->content_type !~ /^text\//) {
-        chomp($c);
-    }
-    print $c;
+    print $r->content;
 }
 
 # To create a new object, we ask the server for a form with the defaults
@@ -455,23 +432,18 @@ sub edit {
         }
         @objects = ("$type/new");
     }
-    #return help($action, $type) if $bad;
-    return suggest_help($action, $type) if $bad;
+    return help($action, $type) if $bad;
 
     # We need a form to make changes to. We usually ask the server for
     # one, but we can avoid that if we are fed one on STDIN, or if the
     # user doesn't want to edit the form by hand, and the command line
-    # specifies only simple variable assignments.  We *should* get a
-    # form if we're creating a new ticket, so that the default values
-    # get filled in properly.
-
-    my @new_objects = grep /\/new$/, @objects;
+    # specifies only simple variable assignments.
 
     if ($input) {
         local $/ = undef;
         $text = <STDIN>;
     }
-    elsif ($edit || %add || %del || !$cl || @new_objects) {
+    elsif ($edit || %add || %del || !$cl) {
         my $r = submit("$REST/show", { id => \@objects, format => 'l' });
         $text = $r->content;
     }
@@ -627,8 +599,7 @@ sub comment {
         whine "No object specified.";
         $bad = 1;
     }
-    #return help($action, "ticket") if $bad;
-    return suggest_help($action, "ticket") if $bad;
+    return help($action, "ticket") if $bad;
 
     my $form = [
         "",
@@ -681,7 +652,7 @@ sub comment {
     }
     $data{content} = $text;
 
-    my $r = submit("$REST/ticket/$id/comment", \%data);
+    my $r = submit("$REST/ticket/comment/$id", \%data);
     print $r->content;
 }
 
@@ -708,10 +679,9 @@ sub merge {
         whine "Too $evil arguments specified.";
         $bad = 1;
     }
-    #return help("merge", "ticket") if $bad;
-    return suggest_help("merge", "ticket") if $bad;
+    return help("merge", "ticket") if $bad;
 
-    my $r = submit("$REST/ticket/$id[0]/merge/$id[1]");
+    my $r = submit("$REST/ticket/merge/$id[0]", {into => $id[1]});
     print $r->content;
 }
 
@@ -752,51 +722,12 @@ sub link {
         whine "Too $bad arguments specified.";
         $bad = 1;
     }
-    #return help("link", "ticket") if $bad;
-    return suggest_help("link", "ticket") if $bad;
+    return help("link", "ticket") if $bad;
 
     my $r = submit("$REST/ticket/link", \%data);
     print $r->content;
 }
 
-# Take/steal a ticket
-sub take {
-    my ($cmd) = @_;
-    my ($bad, %data) = (0, ());
-
-    my $id;
-
-    # get the ticket id
-    if (@ARGV == 1) {
-        ($id) = @ARGV;
-        unless ($id =~ /^\d+$/) {
-            whine "Invalid ticket ID $id specified.";
-            $bad = 1;
-        }
-        my $form = [
-            "",
-            [ "Ticket", "Action" ],
-            {
-                Ticket => $id,
-                Action => $cmd,
-                Status => '',
-            }
-        ];
-
-        my $text = Form::compose([ $form ]);
-        $data{content} = $text;
-    }
-    else {
-        $bad = @ARGV < 1 ? "few" : "many";
-        whine "Too $bad arguments specified.";
-        $bad = 1;
-    }
-    return suggest_help("take", "ticket") if $bad;
-
-    my $r = submit("$REST/ticket/$id/take", \%data);
-    print $r->content;
-}
-
 # Grant/revoke a user's rights.
 
 sub grant {
@@ -908,7 +839,7 @@ sub submit {
             # For anything else, we just die.
             elsif ($res->code != 409) {
                 warn "rt: ", $res->content;
-                #exit;
+                exit;
             }
         }
     }
@@ -1337,29 +1268,17 @@ sub vsplit {
     return \@words;
 }
 
-# WARN: this code is duplicated in lib/RT/Interface/REST.pm
-# change both functions at once
 sub expand_list {
     my ($list) = @_;
+    my ($elt, @elts, %elts);
 
-    my @elts;
-    foreach (split /,/, $list) {
-        push @elts, /^(\d+)-(\d+)$/? ($1..$2): $_;
+    foreach $elt (split /,/, $list) {
+        if ($elt =~ /^(\d+)-(\d+)$/) { push @elts, ($1..$2) }
+        else                         { push @elts, $elt }
     }
 
-    return map $_->[0], # schwartzian transform
-        sort {
-            defined $a->[1] && defined $b->[1]?
-                # both numbers
-                $a->[1] <=> $b->[1]
-                :!defined $a->[1] && !defined $b->[1]?
-                    # both letters
-                    $a->[2] cmp $b->[2]
-                    # mix, number must be first
-                    :defined $a->[1]? -1: 1
-        }
-        map [ $_, (defined( /^(\d+)$/ )? $1: undef), lc($_) ],
-        @elts;
+    @elts{@elts}=();
+    return sort {$a<=>$b} keys %elts;
 }
 
 sub get_type_argument {
@@ -1409,23 +1328,16 @@ sub is_object_spec {
     return;
 }
 
-sub suggest_help {
-    my ($action, $type) = @_;
-
-    print STDERR "rt: For help, run 'rt help $action'.\n" if defined $action;
-    print STDERR "rt: For help, run 'rt help $type'.\n" if defined $type;
-}
-
 __DATA__
 
 Title: intro
 Title: introduction
 Text:
 
-     ** THIS IS AN UNSUPPORTED PREVIEW RELEASE **
-     ** PLEASE REPORT BUGS TO rt-bugs@bestpractical.com **
+    ** THIS IS AN UNSUPPORTED PREVIEW RELEASE **
+    ** PLEASE REPORT BUGS TO rt-bugs@fsck.com **
 
-    This is a command-line interface to RT 3.0 or newer
+    This is a command-line interface to RT 3.
 
     It allows you to interact with an RT server over HTTP, and offers an
     interface to RT's functionality that is better-suited to automation
@@ -1437,10 +1349,9 @@ Text:
 
     For more information:
 
-        - rt help usage         (syntax information)
-        - rt help objects       (how to specify objects)
         - rt help actions       (a list of possible actions)
-        - rt help types         (a list of object types)
+        - rt help objects       (how to specify objects)
+        - rt help usage         (syntax information)
 
         - rt help config        (configuration details)
         - rt help examples      (a few useful examples)
@@ -1455,8 +1366,6 @@ Text:
     Syntax:
 
         rt <action> [options] [arguments]
-      or
-        rt shell
 
     Each invocation of this program must specify an action (e.g. "edit",
     "create"), options to modify behaviour, and other arguments required
@@ -1467,10 +1376,6 @@ Text:
     "rt help <action>". Some actions may be referred to by more than one
     name ("create" is the same as "new", for example).  
 
-    You may also call "rt shell", which will give you an 'rt>' prompt at
-    which you can issue commands of the form "<action> [options] 
-    [arguments]".  See "rt help shell" for details.
-
     Objects are identified by a type and an ID (which can be a name or a
     number, depending on the type). For some actions, the object type is
     implied (you can only comment on tickets); for others, the user must
@@ -1485,7 +1390,6 @@ Text:
         - rt help objects       (how to specify objects)
         - rt help actions       (a list of actions)
         - rt help types         (a list of object types)
-        - rt help shell         (how to use the shell)
 
 --
 
@@ -1838,7 +1742,7 @@ Text:
         rt ls -t tickets -i 'Priority > 5' | rt edit - set status=resolved
         rt edit ticket/4 set priority=3 owner=bar@example.com \
                          add cc=foo@example.com bcc=quux@example.net
-        rt create -t ticket set subject='new ticket' priority=10 \
+        rt create -t ticket subject='new ticket' priority=10 \
                             add cc=foo@example.com
 
 --
@@ -1884,7 +1788,7 @@ Text:
 
         rt merge <from-id> <to-id>
 
-    Merges the first ticket specified into the second ticket specified.
+    Merges the two specified tickets.
 
 --
 
@@ -1959,11 +1863,7 @@ Text:
 Title: topics
 Text:
 
-    Syntax:
-
-        rt help <topic>
-
-    Get help on any of the following subjects:
+    Use "rt help <topic>" for help on any of the following subjects:
 
         - tickets, users, groups, queues.
         - show, edit, ls/list/search, new/create.
@@ -1990,71 +1890,3 @@ Text:
     For the moment, please consult examples provided with each action.
 
 --
-
-Title: shell
-Text:
-
-    Syntax:
-
-        rt shell
-
-    Opens an interactive shell, at which you can issue commands of 
-    the form "<action> [options] [arguments]".
-
-    To exit the shell, type "quit" or "exit".
-
-    Commands can be given at the shell in the same form as they would 
-    be given at the command line without the leading 'rt' invocation.
-
-    Example:
-        $ rt shell
-        rt> create -t ticket set subject='new' add cc=foo@example.com
-        # Ticket 8 created.
-        rt> quit
-        $
-
---
-
-Title: take
-Title: untake
-Title: steal
-Text:
-
-    Syntax:
-
-        rt <take|untake|steal> <ticket-id>
-
-    Sets the owner of the specified ticket to the current user, 
-    assuming said user has the bits to do so, or releases the 
-    ticket.  
-    
-    'Take' is used on tickets which are not currently owned 
-    (Owner: Nobody), 'steal' is used on tickets which *are* 
-    currently owned, and 'untake' is used to "release" a ticket 
-    (reset its Owner to Nobody).  'Take' cannot be used on
-    tickets which are currently owned.
-
-    Example:
-        alice$ rt create -t ticket set subject="New ticket"
-        # Ticket 7 created.
-        alice$ rt take 7
-        # Owner changed from Nobody to alice
-        alice$ su bob
-        bob$ rt steal 7
-        # Owner changed from alice to bob
-        bob$ rt untake 7
-        # Owner changed from bob to Nobody
-
---
-
-Title: quit
-Title: exit
-Text:
-
-    Use "quit" or "exit" to leave the shell.  Only valid within shell 
-    mode.
-
-    Example:
-        $ rt shell
-        rt> quit
-        $