[Bps-public-commit] r15217 - in Prophet/trunk: . lib/Prophet/CLI lib/Prophet/CLI/Command t
spang at bestpractical.com
spang at bestpractical.com
Mon Aug 18 10:15:41 EDT 2008
Author: spang
Date: Mon Aug 18 10:15:29 2008
New Revision: 15217
Modified:
Prophet/trunk/ (props changed)
Prophet/trunk/lib/Prophet/CLI.pm
Prophet/trunk/lib/Prophet/CLI/Command.pm
Prophet/trunk/lib/Prophet/CLI/Command/Update.pm
Prophet/trunk/lib/Prophet/CLI/RecordCommand.pm
Prophet/trunk/t/edit.t
Log:
r48271 at loki: spang | 2008-08-14 21:47:49 +0100
make editing key/value pairs with --edit much nicer and more flexible
r48274 at loki: spang | 2008-08-15 00:47:27 +0100
print the type instead of 'record' in the error message when a record can't be found
r48275 at loki: spang | 2008-08-15 15:31:30 +0100
fixes and cleanups to the update command
r48276 at loki: spang | 2008-08-15 15:42:26 +0100
--edit's behaviour changed
r48282 at loki: spang | 2008-08-15 17:25:43 +0100
add a test that props with no value are not set in edit.t
r48418 at loki: spang | 2008-08-18 10:19:14 +0100
cmp_regex is used with props, not args
Modified: Prophet/trunk/lib/Prophet/CLI.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/CLI.pm (original)
+++ Prophet/trunk/lib/Prophet/CLI.pm Mon Aug 18 10:15:29 2008
@@ -220,7 +220,7 @@
=head2 cmp_regex
-Returns the regex to use for matching argument key/value separators.
+Returns the regex to use for matching property key/value separators.
=cut
Modified: Prophet/trunk/lib/Prophet/CLI/Command.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/CLI/Command.pm (original)
+++ Prophet/trunk/lib/Prophet/CLI/Command.pm Mon Aug 18 10:15:29 2008
@@ -1,6 +1,8 @@
package Prophet::CLI::Command;
use Moose;
+use Params::Validate qw(validate);
+
has cli => (
is => 'rw',
isa => 'Prophet::CLI',
@@ -55,50 +57,100 @@
return scalar Proc::InvokeEditor->edit($text);
}
-=head2 edit_hash hashref -> hashref
+=head2 edit_hash hash => hashref, ordering => arrayref
Filters the hash through the user's C<$EDITOR> using L<Proc::InvokeEditor>.
No validation is done on the input or output.
+If the optional ordering argument is specified, hash keys will be presented
+in that order (with unspecified elements following) for edit.
+
+If the record class for the current type defines a C<props_not_to_edit>
+routine, those props will not be presented for editing.
+
+False values are not returned unless a prop is removed from the output.
+
=cut
sub edit_hash {
my $self = shift;
- my $hash = shift;
+ validate( @_, { hash => 1, ordering => 0 } );
+ my %args = @_;
+ my $hash = $args{'hash'};
+ my @ordering = @{ $args{'ordering'} || [] };
+ my $do_not_edit = $record->can('props_not_to_edit') ? $record->props_not_to_edit : '';
+ my $record = $self->_get_record_class;
+
+ if (@ordering) {
+ # add any keys not in @ordering to the end of it
+ my %keys_in_ordering;
+ map { $keys_in_ordering{$_} = 1 if exists($hash->{$_}) } @ordering;
+ map { push @ordering, $_ if !exists($keys_in_ordering{$_}) } keys %$hash;
+ } else {
+ @ordering = sort keys %$hash;
+ }
+
+ # filter out props we don't want to present for editing
+ @ordering = grep { !/$do_not_edit/ } @ordering;
+
+ my $input = join "\n", map { "$_: $hash->{$_}" } @ordering;
- my $input = join "\n", map { "$_: $hash->{$_}\n" } keys %$hash;
my $output = $self->edit_text($input);
+ die "Aborted.\n" if $input eq $output;
+
+ # parse the output
my $filtered = {};
- while ($output =~ m{^(\S+?):\s*(.*)$}mg) {
- $filtered->{$1} = $2;
+ foreach my $line (split "\n", $output) {
+ if ($line =~ m/^([^:]+):\s*(.*)$/) {
+ my $prop = $1;
+ my $val = $2;
+ # don't return empty values
+ $filtered->{$prop} = $val unless !($val);
+ }
+ }
+
+ # if a key is deleted intentionally, set its value to ''
+ foreach my $prop (keys %$hash) {
+ if (!exists $filtered->{$prop} and $prop =~ !/$do_not_edit/) {
+ $filtered->{$prop} = '';
+ }
}
+ no warnings 'uninitialized';
+ # filter out unchanged keys as they clutter changesets if they're set again
+ map { delete $filtered->{$_} if $hash->{$_} eq $filtered->{$_} } keys %$filtered;
+
return $filtered;
}
-=head2 edit_props [arg], defaults -> hashref
+=head2 edit_props arg => str, defaults => hashref, ordering => arrayref
Returns a hashref of the command's props mixed in with any default props.
-If the "arg" argument is specified, (default "edit", use C<undef> if you only want default arguments), then L</edit_hash> is invoked on the property list.
+If the "arg" argument is specified, (default "edit", use C<undef> if you only
+want default arguments), then L</edit_hash> is invoked on the property list.
+
+If the C<ordering> argument is specified, properties will be presented in that
+order (with unspecified props following) if filtered through L</edit_hash>.
=cut
sub edit_props {
my $self = shift;
- my $arg = shift || 'edit';
+ my %args = @_;
+ my $arg = $args{'arg'} || 'edit';
+ my $defaults = $args{'defaults'};
my %props;
- if (@_ == 1) {
- %props = (%{ $_[0] }, %{ $self->props });
- }
- else {
- %props = (@_, %{ $self->props });
+ if ($defaults) {
+ %props = (%{ $defaults }, %{ $self->props });
+ } else {
+ %props = %{$self->props};
}
if ($self->has_arg($arg)) {
- return $self->edit_hash(\%props);
+ return $self->edit_hash(hash => \%props, ordering => $args{'ordering'});
}
return \%props;
Modified: Prophet/trunk/lib/Prophet/CLI/Command/Update.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/CLI/Command/Update.pm (original)
+++ Prophet/trunk/lib/Prophet/CLI/Command/Update.pm Mon Aug 18 10:15:29 2008
@@ -7,7 +7,20 @@
my $self = shift;
my $record = shift;
- return $self->edit_props('edit');
+ my $props = $record->get_props;
+ # don't feed in existing values if we're not interactively editing
+ my $defaults = $self->has_arg('edit') ? $props : undef;
+
+ my @ordering = ( );
+ # we want props in $record->props_to_show to show up in the editor if --edit
+ # is supplied too
+ if ($record->can('props_to_show') && $self->has_arg('edit')) {
+ @ordering = $record->props_to_show;
+ map { $props->{$_} = '' if !exists($props->{$_}) } @ordering;
+ }
+
+ return $self->edit_props(arg => 'edit', defaults => $defaults,
+ ordering => \@ordering);
}
sub run {
@@ -16,7 +29,9 @@
$self->require_uuid;
my $record = $self->_load_record;
- my $result = $record->set_props( props => $self->edit_record($record) );
+ my $new_props = $self->edit_record($record);
+ my $result = $record->set_props( props => $new_props );
+
if ($result) {
print $record->type . " " . $record->luid . " (".$record->uuid.")"." updated.\n";
@@ -26,7 +41,6 @@
. $record->luid . " ("
. $record->uuid
. ") not updated.\n";
-
}
}
Modified: Prophet/trunk/lib/Prophet/CLI/RecordCommand.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/CLI/RecordCommand.pm (original)
+++ Prophet/trunk/lib/Prophet/CLI/RecordCommand.pm Mon Aug 18 10:15:29 2008
@@ -69,7 +69,7 @@
my $self = shift;
my $record = $self->_get_record_class;
$record->load( uuid => $self->uuid )
- || $self->fatal_error("I couldn't find the record " . $self->uuid);
+ || $self->fatal_error("I couldn't find the " . $self->type . ' ' . $self->uuid);
return $record;
}
Modified: Prophet/trunk/t/edit.t
==============================================================================
--- Prophet/trunk/t/edit.t (original)
+++ Prophet/trunk/t/edit.t Mon Aug 18 10:15:29 2008
@@ -22,9 +22,9 @@
# ------------
$out = run_command('create', '--type=Robot Master', '--edit');
-like($out, $created_re);
+# $out only captures STDOUT, not STDERR
+is($out, '', 'Create aborted on no editor input');
is($invoked_editor, 1, "Editor invoked once");
-ok($uuid, "got a uuid");
cleanup();
# ------------
@@ -34,6 +34,7 @@
name: Shadow Man
weapon: Shadow Blade
weakness: Top Spin
+strength:
TEXT
});
@@ -46,6 +47,7 @@
is($shadow_man->prop('name'), 'Shadow Man', 'correct name');
is($shadow_man->prop('weapon'), 'Shadow Blade', 'correct weapon');
is($shadow_man->prop('weakness'), 'Top Spin', 'correct weakness');
+is($shadow_man->prop('strength'), undef, 'strength not set');
cleanup();
# ------------
@@ -97,7 +99,7 @@
is($crash_man2->uuid, $uuid, "correct uuid");
is($crash_man2->prop('name'), 'Clash Man', 'corrected name');
is($crash_man2->prop('weapon'), 'Clash Bomb', 'corrected weapon');
-is($crash_man2->prop('weakness'), 'Air Shooter', 'same weakness');
+is($crash_man2->prop('weakness'), undef, 'weakness deleted');
cleanup();
# ------------
More information about the Bps-public-commit
mailing list