[Bps-public-commit] SD branch, master, updated. 0.73-43-gb8b7de9

Ruslan Zakirov ruz at bestpractical.com
Wed Jan 27 03:59:16 EST 2010


The branch, master has been updated
       via  b8b7de9cd8bb3d535acb64a60c83b0e0f35bfa6b (commit)
       via  657480943012211ac0d22e22480746eaf8718199 (commit)
       via  df20d4c354c536d0f0dbfc42b16585715f82f7e5 (commit)
      from  f6382766737c7d96ec7c6c286a94b9bbe8d90ab0 (commit)

Summary of changes:
 lib/App/SD/CLI/Command/Ticket/Review.pm |  186 +++++++++++++++++++++++++++++++
 lib/App/SD/CLI/Dispatcher.pm            |    1 +
 2 files changed, 187 insertions(+), 0 deletions(-)
 create mode 100644 lib/App/SD/CLI/Command/Ticket/Review.pm

- Log -----------------------------------------------------------------
commit df20d4c354c536d0f0dbfc42b16585715f82f7e5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Jan 18 07:15:52 2010 +0300

    very simple review command implementation

diff --git a/lib/App/SD/CLI/Command/Ticket/Review.pm b/lib/App/SD/CLI/Command/Ticket/Review.pm
new file mode 100644
index 0000000..8e6e788
--- /dev/null
+++ b/lib/App/SD/CLI/Command/Ticket/Review.pm
@@ -0,0 +1,113 @@
+package App::SD::CLI::Command::Ticket::Review;
+use Any::Moose;
+extends 'App::SD::CLI::Command::Ticket::Search';
+#with 'App::SD::CLI::Command';
+
+override usage_msg => sub {
+    my $self = shift;
+    my $script = $self->cli->get_script_name;
+
+    my @primary_commands = @{ $self->context->primary_commands };
+
+    # if primary commands was only length 1, the type was not specified
+    # and we should indicate that a type is expected
+    push @primary_commands, '<record-type>' if @primary_commands <= 1;
+
+    my $type_and_subcmd = join( q{ }, @primary_commands );
+
+    return <<"END_USAGE";
+usage: ${script}${type_and_subcmd}
+       ${script}${type_and_subcmd} -- summary=~foo status!~new|open
+END_USAGE
+};
+
+before run => sub {
+    Prophet::CLI->end_pager();
+};
+
+after out_record => sub {
+    my $self = shift;
+    my $record = shift;
+
+    my $keys = $self->out_widget( $record );
+    ASK_AGAIN:
+    print "Update> ";
+
+    my $action = <>;
+    chomp $action;
+    $action =~ s/^\s+//;
+    $action =~ s/\s+$//;
+
+    return unless length $action;
+
+    my $do = $keys->{ $action };
+    unless ( $do ) {
+        print "No action binded to '$action', try again...\n";
+        goto ASK_AGAIN;
+    }
+
+    if ( $do->{'action'} eq 'status' ) {
+        $record->set_prop( name => 'status', value => $do->{'value'} );
+        print "Done\n";
+    }
+    else {
+        print "Not implemented, patches are welcome\n";
+        goto ASK_AGAIN;
+    }
+};
+
+sub out_widget {
+    my $self = shift;
+    my $record = shift;
+    my %keys = (
+        b => { line => 0, order => 0, action => 'show', value=> 'basics', display => 'show [b]asics' },
+        d => { line => 0, order => 1, action => 'show', value=> 'details', display => '[d]etails' },
+        m => { line => 1, order => 0, action => 'milestone', display => '[m]ilestone' },
+        c => { line => 1, order => 1, action => 'component', display => '[c]omponent' },
+    );
+    {
+        my $order = 0;
+        my @statuses = @{ $record->app_handle->setting( label => 'statuses' )->get };
+        foreach my $status ( @statuses ) {
+            my $letter = ''; my $pos = 0;
+            do {
+                $letter = substr $status, $pos++, 1;
+            } while ( exists $keys{$letter} && $pos < length $status );
+            
+            my $display = $status;
+            substr $display, $pos-1, 0, '[';
+            substr $display, $pos+1, 0, ']';
+            $keys{$letter} = {
+                line => 2, order => $order++,
+                action => 'status', value => $status,
+                display => $display,
+            };
+        }
+    }
+
+    my $status = $record->prop('status');
+
+    my $res = '';
+    my $line = 0;
+    foreach my $key ( sort {$a->{'line'} <=> $b->{'line'} || $a->{'order'} <=> $b->{'order'}} values %keys ) {
+        next if $key->{'action'} eq 'status' && $key->{'value'} eq $status;
+
+        if ( $key->{'line'} != $line ) {
+            print $res, "\n";
+            $res = '';
+            $line = $key->{'line'};
+        }
+        
+        $res .= ', ' if $res;
+        $res .= $key->{'display'};
+    }
+    print $res, "\n";
+
+    return \%keys;
+}
+
+__PACKAGE__->meta->make_immutable;
+no Any::Moose;
+
+1;
+

commit 657480943012211ac0d22e22480746eaf8718199
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Jan 18 07:16:25 2010 +0300

    register review command

diff --git a/lib/App/SD/CLI/Dispatcher.pm b/lib/App/SD/CLI/Dispatcher.pm
index 7102025..9635a52 100644
--- a/lib/App/SD/CLI/Dispatcher.pm
+++ b/lib/App/SD/CLI/Dispatcher.pm
@@ -130,6 +130,7 @@ under ticket => sub {
     on [ [ 'show'   , 'display' ] ]   => run_command('Ticket::Show');
     on [ [ 'update' , 'edit' ] ]      => run_command('Ticket::Update');
     on [ [ 'search', 'list', 'ls' ] ] => run_command('Ticket::Search');
+    on review   => run_command('Ticket::Review');
     on details  => run_command('Ticket::Details');
     on basics   => run_command('Ticket::Basics');
     on comment  => run_command('Ticket::Comment');

commit b8b7de9cd8bb3d535acb64a60c83b0e0f35bfa6b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Jan 27 11:57:15 2010 +0300

    reimplement ticket review command
    
    * now it supports multiple actions at once via '+'
    * supports all common props with defined values
    * two chars minimum for set property action, but it's better than
      conflicts

diff --git a/lib/App/SD/CLI/Command/Ticket/Review.pm b/lib/App/SD/CLI/Command/Ticket/Review.pm
index 8e6e788..1d64588 100644
--- a/lib/App/SD/CLI/Command/Ticket/Review.pm
+++ b/lib/App/SD/CLI/Command/Ticket/Review.pm
@@ -25,89 +25,162 @@ before run => sub {
     Prophet::CLI->end_pager();
 };
 
+our %ACTIONS = ();
+
+our %INFO = (
+
+);
+
 after out_record => sub {
     my $self = shift;
     my $record = shift;
 
-    my $keys = $self->out_widget( $record );
+    $self->out_widget( $record );
     ASK_AGAIN:
     print "Update> ";
 
-    my $action = <>;
-    chomp $action;
-    $action =~ s/^\s+//;
-    $action =~ s/\s+$//;
+    my $do = <STDIN>;
+    chomp $do;
+    $do =~ s/^\s+//;
+    $do =~ s/\s+$//;
+    return unless length $do;
 
-    return unless length $action;
+    my @list = split /\+/, $do;
 
-    my $do = $keys->{ $action };
-    unless ( $do ) {
-        print "No action binded to '$action', try again...\n";
-        goto ASK_AGAIN;
-    }
+    my $ask_again = 0;
+    foreach my $do ( @list ) {
+        my $action = $ACTIONS{ $do };
+        unless ( $action ) {
+            print "No action binded to '$do', try again...\n";
+            $ask_again = 1; next;
+        }
+        next unless $action->{'action'};
 
-    if ( $do->{'action'} eq 'status' ) {
-        $record->set_prop( name => 'status', value => $do->{'value'} );
-        print "Done\n";
-    }
-    else {
-        print "Not implemented, patches are welcome\n";
-        goto ASK_AGAIN;
+        my $name = 'action_'. $action->{'action'};
+        unless ( $self->can($name) ) {
+            print "Not implemented, patches are welcome\n";
+            $ask_again = 1; next;
+        }
+
+        $self->$name( $record, %$action );
+        print "Done $do\n";
     }
+    goto ASK_AGAIN if $ask_again;
 };
 
 sub out_widget {
     my $self = shift;
     my $record = shift;
-    my %keys = (
-        b => { line => 0, order => 0, action => 'show', value=> 'basics', display => 'show [b]asics' },
-        d => { line => 0, order => 1, action => 'show', value=> 'details', display => '[d]etails' },
-        m => { line => 1, order => 0, action => 'milestone', display => '[m]ilestone' },
-        c => { line => 1, order => 1, action => 'component', display => '[c]omponent' },
+
+    $self->prepare_actions($record) unless keys %ACTIONS;
+    
+    print "show [b] basics or [d] details\n";
+    foreach my $property ( @{ $INFO{'properties'} } ) {
+        my $prop_shortcut = $INFO{'shortcuts'}{$property};
+        print "$property:\n";
+        print "\t";
+        my $current = $record->prop($property);
+        my $not_first = 0;
+        foreach my $value ( @{ $INFO{'values'}{$property} } ) {
+            print ", " if $not_first++;
+            print "[". $prop_shortcut . $INFO{vshortcuts}{$property}{$value} ."] $value";
+            print "*" if $value eq $current;
+        }
+        print "\n";
+    }
+}
+
+sub action_property {
+    my $self = shift;
+    my $record = shift;
+    my %args = ( name => undef, value => undef, @_ );
+    $record->set_prop( name => $args{'name'}, value => $args{'value'} );
+}
+
+sub prepare_actions {
+    my $self = shift;
+    my $record = shift;
+
+    %ACTIONS = (
+        b => { action => 'show', value => 'basics' },
+        d => { action => 'show', value => 'details' },
     );
-    {
-        my $order = 0;
-        my @statuses = @{ $record->app_handle->setting( label => 'statuses' )->get };
-        foreach my $status ( @statuses ) {
-            my $letter = ''; my $pos = 0;
-            do {
-                $letter = substr $status, $pos++, 1;
-            } while ( exists $keys{$letter} && $pos < length $status );
+
+    my @reserved = keys %ACTIONS;
+    my $app_handle = $record->app_handle;
+    my @props = @{ $app_handle->setting( label => 'common_ticket_props' )->get };
+
+    foreach my $property ( @props ) {
+        my $plural_form = $self->plural_noun( $property );
+        # XXX: dirty hack
+        next unless $app_handle->database_settings->{$plural_form};
+
+        my @values = @{ $app_handle->setting( label => $plural_form )->get };
+        next unless @values;
+
+        $INFO{'values'}{$property} = \@values;
+
+        my $shortcut = $INFO{'shortcuts'}{$property}
+            = $self->shortcut( $property, @reserved );
+        push @reserved, $shortcut;
+        $ACTIONS{ $shortcut } = {};
+    }
+
+    @props = grep $INFO{'values'}{ $_ }, @props;
+    $INFO{'properties'} = \@props;
+
+    foreach my $property ( @props ) {
+        my @reserved = ();
+        foreach my $value ( @{ $INFO{'values'}{$property} } ) {
+            my $shortcut = $self->shortcut( $value, @reserved );
+            push @reserved, $shortcut;
             
-            my $display = $status;
-            substr $display, $pos-1, 0, '[';
-            substr $display, $pos+1, 0, ']';
-            $keys{$letter} = {
-                line => 2, order => $order++,
-                action => 'status', value => $status,
-                display => $display,
+            $ACTIONS{ $INFO{'shortcuts'}{$property} . $shortcut } = {
+                action => 'property', name => $property, value => $value, 
             };
+            $INFO{'vshortcuts'}{$property}{$value} = $shortcut;
         }
     }
+}
 
-    my $status = $record->prop('status');
+sub plural_noun {
+    my $self = shift;
+    my $noun = shift;
+
+# simple plural form generation, full info on
+# http://www.csse.monash.edu.au/~damian/papers/HTML/Plurals.html
+
+    return $noun.'es' if $noun =~ /[cs]h$/;
+    return $noun.'es' if $noun =~ /ss$/;
+    return $noun      if $noun =~ s/([aeo]l|[^d]ea|ar)f$/$1ves/;
+    return $noun      if $noun =~ s/([nlw]i)fe$/$1ves/;
+    return $noun.'s'  if $noun =~ /[aeiou]y$/;
+    return $noun      if $noun =~ s/y$/ies/;
+    return $noun.'s'  if $noun =~ /[aeiou]o$/;
+    return $noun.'es' if $noun =~ /o$/;
+    return $noun.'es' if $noun =~ /s$/;
+    return $noun.'s';
+}
 
-    my $res = '';
-    my $line = 0;
-    foreach my $key ( sort {$a->{'line'} <=> $b->{'line'} || $a->{'order'} <=> $b->{'order'}} values %keys ) {
-        next if $key->{'action'} eq 'status' && $key->{'value'} eq $status;
+sub shortcut {
+    my $self = shift;
+    my $word = shift;
+    my @reserved = @_;
 
-        if ( $key->{'line'} != $line ) {
-            print $res, "\n";
-            $res = '';
-            $line = $key->{'line'};
-        }
-        
-        $res .= ', ' if $res;
-        $res .= $key->{'display'};
+    for (my $i = 0; $i < length $word; $i++ ) {
+        my $char = substr $word, $i, 1;
+        return wantarray? ($char, $i) : $char
+            unless grep $_ eq $char, @reserved; 
     }
-    print $res, "\n";
-
-    return \%keys;
+    for (my $i = 1; $i <= length $word; $i++ ) {
+        my $prefix = substr $word, 0, $i;
+        return wantarray? ($prefix, $i) : $prefix
+            unless grep $_ eq $prefix, @reserved;
+    }
+    return $word, 0;
 }
 
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
 
 1;
-

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



More information about the Bps-public-commit mailing list