[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