[Bps-public-commit] UNNAMED PROJECT branch, master, updated. 28f9b4dfddb4d8ac719ec6a7779ba0aa24908f7a
spang at bestpractical.com
spang at bestpractical.com
Fri Jan 16 06:56:04 EST 2009
The branch, master has been updated
via 28f9b4dfddb4d8ac719ec6a7779ba0aa24908f7a (commit)
via c391ab716a9e7d338ffe7f011d6dc31e58589510 (commit)
via b7f236a375f1ca7412ec70eeaa3657dd2b5ae2c2 (commit)
via d7878e886adaf1898d3333ecf958fabe96c603a6 (commit)
via d895a42828fca26b94a7a092c67d8eb8047deea1 (commit)
via 2669a2f4048ad424d78ab79b36ef6c01e3a84f33 (commit)
via cfaea3ed7bd7ec12c7b31ebc41f1cb585a111061 (commit)
via 4a6978e1983fb26b1aaadd961166d0629e20c971 (commit)
via bfd9bbe7a30a89901612c2f69a6ddeb1a56adff7 (commit)
via 52fc5a8399654b51d197b672516af5d452a06d7d (commit)
via 76e9fb05f66d247564ffff32832c485bd0b49a72 (commit)
via ab2e2334c3694b343252b073e5b48cce740431bd (commit)
via 99825a89b2394636679d2a8dfd1f23e6e43a9c33 (commit)
via 1f1640e7a48b5f40d32793da0bd3bec6c610dbf9 (commit)
via be7c43fc78f85ca5755e593a15c0ce0d3e94a592 (commit)
from 8d11921df6790e28d6e63162740bd1ad38a42372 (commit)
Summary of changes:
.gitignore | 2 +-
lib/App/SD.pm | 11 ++
lib/App/SD/CLI/Command/Help/Search.pm | 4 +
lib/App/SD/CLI/Command/Help/Tickets.pm | 28 +++++-
lib/App/SD/CLI/Command/Ticket/Show.pm | 7 ++
lib/App/SD/CLI/Command/Ticket/Update.pm | 9 +-
lib/App/SD/CLI/Dispatcher.pm | 2 +-
lib/App/SD/CLI/Model/Ticket.pm | 36 ++++++--
lib/App/SD/Model/Ticket.pm | 54 ++++++++++-
lib/App/SD/Test.pm | 18 +++-
t/02-create-with-editor.t | 87 +++++++++++-------
t/03-update-ticket-with-editor.t | 120 ++++++++++++++++++++++--
t/data/sd-ticket-create-verbose.tmpl | 23 +++++
t/data/sd-ticket-create.tmpl | 16 +++
t/data/sd-ticket-update-all-props.tmpl | 18 ++++
t/data/sd-ticket-update-verbose-all-props.tmpl | 25 +++++
t/data/sd-ticket-update-verbose.tmpl | 23 +++++
t/data/sd-ticket-update.tmpl | 17 ++++
t/scripts/ticket-comment-update-editor.pl | 2 +
t/scripts/ticket-create-editor.pl | 42 ++++++++-
t/scripts/ticket-update-editor.pl | 58 +++++++++++-
21 files changed, 524 insertions(+), 78 deletions(-)
create mode 100644 t/data/sd-ticket-create-verbose.tmpl
create mode 100644 t/data/sd-ticket-create.tmpl
create mode 100644 t/data/sd-ticket-update-all-props.tmpl
create mode 100644 t/data/sd-ticket-update-verbose-all-props.tmpl
create mode 100644 t/data/sd-ticket-update-verbose.tmpl
create mode 100644 t/data/sd-ticket-update.tmpl
- Log -----------------------------------------------------------------
commit be7c43fc78f85ca5755e593a15c0ce0d3e94a592
Author: Christine Spang <spang at mit.edu>
Date: Wed Jan 14 10:54:25 2009 +0200
add verbose mode for ticket create command
diff --git a/lib/App/SD.pm b/lib/App/SD.pm
index dfb53fb..949d315 100644
--- a/lib/App/SD.pm
+++ b/lib/App/SD.pm
@@ -24,6 +24,17 @@ sub database_settings {
project_name => ['3B4B297C-906F-4018-9829-F7CC672274C9' => 'Your SD Project'],
default_props_to_show => ['3f0a074f-af13-406f-bf7b-d69bbf360720' => qw/id summary status milestone component owner created due creator reporter original_replica/],
+ prop_descriptions => ['c1bced3a-ad2c-42c4-a502-4149205060f1',
+ { summary =>
+ "a one-line summary of what this ticket is about",
+ owner =>
+ "the email address of the person who is responsible for this ticket",
+ due =>
+ "when this ticket must be finished by (ISO 8601 format)",
+ reporter =>
+ "the email address of the person who reported this ticket"
+ },
+ ],
};
}
diff --git a/lib/App/SD/CLI/Model/Ticket.pm b/lib/App/SD/CLI/Model/Ticket.pm
index cfbcde8..4ae7653 100644
--- a/lib/App/SD/CLI/Model/Ticket.pm
+++ b/lib/App/SD/CLI/Model/Ticket.pm
@@ -72,7 +72,7 @@ sub _build_separator {
}
-=head2 create_record_template RECORD
+=head2 create_record_template [ RECORD ]
Creates a string representing a new record, prefilling default props
and props specified on the command line. Intended to be presented to
@@ -108,8 +108,7 @@ sub create_record_template {
#
# filter out props we don't want to present for editing
my %do_not_edit = map { $_ => 1 } @do_not_edit;
-
-
+
for my $prop ( $record->props_to_show ) {
if ( $do_not_edit{$prop}) {
if ( $prop eq 'id' && $update ) {
@@ -151,11 +150,16 @@ sub create_record_template {
my $immutable_props_string = $self->_build_kv_pairs(
order => \@metadata_order,
- data => \%immutable_props
+ data => \%immutable_props,
+ verbose => $self->has_arg('verbose'),
+ record => $record,
);
+
my $editable_props_string = $self->_build_kv_pairs(
order => \@editable_order,
- data => \%editable_props
+ data => \%editable_props,
+ verbose => $self->has_arg('verbose'),
+ record => $record,
);
# glue all the parts together
@@ -187,10 +191,24 @@ sub _build_template_section {
sub _build_kv_pairs {
my $self = shift;
- my %args = validate (@_, { order => 1, data => 1 });
+ my %args = validate (@_, { order => 1, data => 1,
+ verbose => 1, record => 1 });
my $string = '';
for my $prop ( @{$args{order}}) {
+ # if called with --verbose, we print descriptions and valid values for
+ # props (if they exist)
+ if ( $args{verbose} ) {
+ if ( my $desc = $self->app_handle->setting( label => 'prop_descriptions' )->get()->[0]->{$prop} ) {
+ $string .= '# '.$desc."\n";
+ }
+ if ( ($args{record}->recommended_values_for_prop($prop))[0] ) {
+ my @valid_values =
+ $args{record}->recommended_values_for_prop($prop);
+ $string .= "# valid values for $prop: ".
+ join(', ', @valid_values)."\n";
+ }
+ }
$string .= "$prop: ".($args{data}->{$prop} ||'') ."\n";
}
return $string;
commit 1f1640e7a48b5f40d32793da0bd3bec6c610dbf9
Author: Christine Spang <spang at mit.edu>
Date: Wed Jan 14 13:47:48 2009 +0200
untangle the mess of having multiple args called --verbose with different meanings. now --all-props means show all the props of a ticket (e.g. in an update) and --verbose means show descriptions/valid values
diff --git a/lib/App/SD/CLI/Model/Ticket.pm b/lib/App/SD/CLI/Model/Ticket.pm
index 4ae7653..a736c61 100644
--- a/lib/App/SD/CLI/Model/Ticket.pm
+++ b/lib/App/SD/CLI/Model/Ticket.pm
@@ -109,7 +109,10 @@ sub create_record_template {
# filter out props we don't want to present for editing
my %do_not_edit = map { $_ => 1 } @do_not_edit;
- for my $prop ( $record->props_to_show ) {
+ for my $prop ( $record->props_to_show(
+ # only call props_to_show with --all-props if we're in an update
+ # because new tickets have no declared props
+ { 'all-props' => ($self->has_arg('all-props') && $update) } ) ) {
if ( $do_not_edit{$prop}) {
if ( $prop eq 'id' && $update ) {
diff --git a/lib/App/SD/Model/Ticket.pm b/lib/App/SD/Model/Ticket.pm
index d46fc1e..3f7559e 100644
--- a/lib/App/SD/Model/Ticket.pm
+++ b/lib/App/SD/Model/Ticket.pm
@@ -153,20 +153,56 @@ sub color_prop_due {
return $due;
}
-=head2 props_to_show
+=head2 props_to_show { 'all-props' => 1 }
A list of which properties to display for the C<show> command (in order
from first to last).
+If called with 'all-props' as a true value, will return all the
+declared props of a ticket rather than the predefined list of ones
+to show. (Should not be called this way during a ticket create as
+new tickets have no declared properties.)
+
=cut
sub props_to_show {
my $self = shift;
my $args = shift || {};
- return @{ $self->app_handle->setting(label => 'default_props_to_show')->get() }
- unless $args->{'verbose'};
+ my $props_list = $self->app_handle->setting(label =>
+ 'default_props_to_show')->get();
+
+ return @{$props_list} unless $args->{'all-props'};
+
+ return _create_prop_ordering( hash_to_order => $self->get_props,
+ order => $props_list);
+}
+
+=head2 _create_prop_ordering hash_to_order => $hashref, order => $arrayref
+
+Given references to a hash and an array, return an array of the keys of the
+hash in the order specified by the array, with any extra keys at the end of the
+ordering.
+
+=cut
+
+sub _create_prop_ordering {
+ my %args = @_;
+ my %props = %{$args{hash_to_order}};
+ my @order = @{$args{order}};
+ my @new_props_list;
+
+ # if props in the ordering are in the hash, add them to
+ # the new ordering
+ for my $prop (@order) {
+ if ( $props{$prop} || $prop eq 'id' ) {
+ push @new_props_list, $prop;
+ delete $props{$prop};
+ }
+ }
+ # add hash keys not in the ordering to the end of the new ordering
+ push @new_props_list, keys %props;
- return $self->declared_props;
+ return @new_props_list;
}
=head2 immutable_props
commit 99825a89b2394636679d2a8dfd1f23e6e43a9c33
Author: Christine Spang <spang at mit.edu>
Date: Wed Jan 14 13:49:11 2009 +0200
document args of create and update
diff --git a/lib/App/SD/CLI/Command/Help/Tickets.pm b/lib/App/SD/CLI/Command/Help/Tickets.pm
index 46c4695..192db0f 100644
--- a/lib/App/SD/CLI/Command/Help/Tickets.pm
+++ b/lib/App/SD/CLI/Command/Help/Tickets.pm
@@ -10,12 +10,36 @@ sub run {
print <<EOF
$cmd ticket create
Invokes a text editor with a ticket creation template.
+ Note that 'new' is an alias for 'create'.
+
+ $cmd ticket create --verbose
+ Invokes a text editor with a ticket creation template
+ and also shows descriptions and valid values for
+ properties.
$cmd ticket create -- summary="This is a summary" status=open
Create a new ticket non-interactively.
$cmd ticket update 123 -- status=closed
Sets the status of the ticket with local id 123 to closed.
+ Note that 'edit' is an alias for 'update'.
+
+ $cmd ticket update 123
+ Interactively update the ticket with local id 123 in a text
+ editor.
+
+ $cmd ticket update 123 --verbose
+ Interactively update the ticket with local id 123 in a text
+ editor and show descriptions and valid values for props.
+
+ $cmd ticket update 123 --all-props
+ Interactively update the ticket with local id 123 in a text
+ editor, presenting all the props of the record for editing instead of
+ just those specified by the database setting 'default_props_to_show'.
+
+ $cmd ticket update fad5849a-67f1-11dd-bde1-5b33d3ff2799 -- status=closed
+ Sets the status of the ticket with uuid
+ fad5849a-67f1-11dd-bde1-5b33d3ff2799 to closed.
$cmd ticket resolve 123
Sets the status of the ticket with local id 123 to closed.
@@ -24,10 +48,6 @@ print <<EOF
Sets the status of the ticket with local id 123 to closed,
allowing you to edit any properties in an editor and
optionally add a comment in the process.
-
- $cmd ticket update fad5849a-67f1-11dd-bde1-5b33d3ff2799 -- status=closed
- Sets the status of the ticket with uuid
- fad5849a-67f1-11dd-bde1-5b33d3ff2799 to closed.
EOF
}
commit ab2e2334c3694b343252b073e5b48cce740431bd
Author: Christine Spang <spang at mit.edu>
Date: Wed Jan 14 19:10:29 2009 +0200
redirect help init/clone to help intro
diff --git a/lib/App/SD/CLI/Dispatcher.pm b/lib/App/SD/CLI/Dispatcher.pm
index fa80b06..0540eb7 100644
--- a/lib/App/SD/CLI/Dispatcher.pm
+++ b/lib/App/SD/CLI/Dispatcher.pm
@@ -13,7 +13,7 @@ rewrite [ ['about', 'copying'] ] => sub { "help $1" };
under help => sub {
- on intro => run_command('Help::Intro');
+ on [ [ 'intro', 'init', 'clone' ] ] => run_command('Help::Intro');
on about => run_command('Help::About');
on config => run_command('Help::Config');
on copying => run_command('Help::Copying');
commit 76e9fb05f66d247564ffff32832c485bd0b49a72
Author: Christine Spang <spang at mit.edu>
Date: Thu Jan 15 00:03:08 2009 +0200
test script regexes can be cooler with lookbehinds
diff --git a/t/scripts/ticket-create-editor.pl b/t/scripts/ticket-create-editor.pl
index 98121a1..cf42a84 100755
--- a/t/scripts/ticket-create-editor.pl
+++ b/t/scripts/ticket-create-editor.pl
@@ -3,8 +3,7 @@
# perl script to trick Proc::InvokeEditor with for the ticket create command
while (<>) {
- s/^summary:.*$/summary: creating tickets with an editor is totally awesome/;
+ s/(?<=^summary: ).*$/creating tickets with an editor is totally awesome/;
print;
print "We can create a comment at the same time.\n" if /^===/;
}
-
diff --git a/t/scripts/ticket-update-editor.pl b/t/scripts/ticket-update-editor.pl
index 3432881..f4afd3a 100755
--- a/t/scripts/ticket-update-editor.pl
+++ b/t/scripts/ticket-update-editor.pl
@@ -3,7 +3,7 @@
# perl script to trick Proc::InvokeEditor with for the ticket update command
while (<>) {
- s/^summary:.*$/summary: summary changed/;
+ s/(?<=^summary: ).*$/summary changed/;
s/^owner:.*//;
print;
print "We can create a comment at the same time.\n" if /^===/;
commit 52fc5a8399654b51d197b672516af5d452a06d7d
Author: Christine Spang <spang at mit.edu>
Date: Thu Jan 15 14:46:59 2009 +0200
git should ignore Makefile.old too
diff --git a/.gitignore b/.gitignore
index 6b02c8d..f97dba5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
blib/
pm_to_blib
-Makefile
+Makefile*
*~
commit bfd9bbe7a30a89901612c2f69a6ddeb1a56adff7
Author: Christine Spang <spang at mit.edu>
Date: Thu Jan 15 14:52:10 2009 +0200
tests for interactive sd ticket create options
diff --git a/lib/App/SD/Test.pm b/lib/App/SD/Test.pm
index c222298..962c2ad 100644
--- a/lib/App/SD/Test.pm
+++ b/lib/App/SD/Test.pm
@@ -115,11 +115,12 @@ sub get_luid_for_uuid {
return undef;
}
-=head2 create_ticket_with_editor_ok
+=head2 create_ticket_with_editor_ok [ '--verbose' ... ]
Creates a ticket and comment at the same time using a spawned editor. It's
expected that C<$ENV{VISUAL}> has been frobbed into something non-interactive,
-or this test will just hang forever.
+or this test will just hang forever. Any extra arguments passed in will be
+passed on to sd ticket create.
Returns a list of the ticket luid, ticket uuid, comment luid, and comment uuid.
@@ -127,8 +128,10 @@ Returns a list of the ticket luid, ticket uuid, comment luid, and comment uuid.
sub create_ticket_with_editor_ok {
+ my @extra_args = @_;
+
local $Test::Builder::Level = $Test::Builder::Level + 1;
- Prophet::Test::run_output_matches( 'sd', [ 'ticket', 'create' ],
+ Prophet::Test::run_output_matches( 'sd', [ 'ticket', 'create', @extra_args ],
[qr/Created ticket (.*?)(?{ $A = $1})\s+\((.*)(?{ $B = $2 })\)/,
qr/Created comment (.*?)(?{ $C = $1})\s+\((.*)(?{ $D = $2 })\)/]
);
diff --git a/t/02-create-with-editor.t b/t/02-create-with-editor.t
index aed3ee1..e9b4351 100644
--- a/t/02-create-with-editor.t
+++ b/t/02-create-with-editor.t
@@ -1,46 +1,67 @@
#!/usr/bin/perl -w
use strict;
-use Prophet::Test tests => 4;
+use Prophet::Test tests => 13;
use App::SD::Test;
BEGIN {
require File::Temp;
$ENV{'PROPHET_REPO'} = $ENV{'SD_REPO'} = File::Temp::tempdir( CLEANUP => 0 ) . '/_svb';
diag 'export SD_REPO=' . $ENV{'PROPHET_REPO'} . "\n";
- App::SD::Test->set_editor('ticket-create-editor.pl');
}
run_script( 'sd', [ 'init']);
my $replica_uuid = replica_uuid;
-my ($ticket_id, $ticket_uuid, $comment_id, $comment_uuid) = create_ticket_with_editor_ok();
-
-run_output_matches( 'sd', [ 'ticket',
- 'list', '--regex', '.' ],
- [ qr/(\d+) creating tickets with an editor is totally awesome new/]
-);
-
-run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
- [
- "id: $ticket_id ($ticket_uuid)",
- 'summary: creating tickets with an editor is totally awesome',
- 'status: new',
- 'milestone: alpha',
- 'component: core',
- qr/^created: \d{4}-\d{2}-\d{2}.+$/,
- qr/^creator: /,
- 'reporter: ' . $ENV{EMAIL},
- "original_replica: $replica_uuid",
- ]
-);
-
-run_output_matches( 'sd', [ 'ticket', 'comment', 'show', '--batch', '--id', $comment_id ],
- [
- "id: $comment_id ($comment_uuid)",
- 'content: We can create a comment at the same time.',
- qr/^created: \d{4}-\d{2}-\d{2}.+$/,
- qr/^creator: /,
- "original_replica: $replica_uuid",
- qr/^ticket: $ticket_uuid$/,
- ]
-);
+
+sub create_ticket_and_check {
+ my %args = @_;
+
+ my ($ticket_id, $ticket_uuid, $comment_id, $comment_uuid) = create_ticket_with_editor_ok(@{$args{extra_args}});
+
+ run_output_matches( 'sd', [ 'ticket',
+ 'list', '--regex', '.' ],
+ [ qr/(\d+) we are testing sd ticket create new/]
+ ) if $args{check_sd_list};
+
+ run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
+ [
+ "id: $ticket_id ($ticket_uuid)",
+ 'summary: we are testing sd ticket create',
+ 'status: new',
+ 'milestone: alpha',
+ 'component: core',
+ qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ qr/^creator: /,
+ 'reporter: ' . $ENV{EMAIL},
+ "original_replica: $replica_uuid",
+ ]
+ );
+
+ run_output_matches( 'sd', [ 'ticket', 'comment', 'show', '--batch', '--id', $comment_id ],
+ [
+ "id: $comment_id ($comment_uuid)",
+ 'content: template ok!',
+ qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ qr/^creator: /,
+ "original_replica: $replica_uuid",
+ qr/^ticket: $ticket_uuid$/,
+ ]
+ );
+}
+
+# test template for sd ticket create
+App::SD::Test->set_editor("ticket-create-editor.pl --no-args $replica_uuid");
+create_ticket_and_check(check_sd_list => 1);
+
+# test template for sd ticket create --all-props
+App::SD::Test->set_editor("ticket-create-editor.pl --all-props $replica_uuid");
+create_ticket_and_check(extra_args => ['--all-props']);
+
+# test template for sd ticket create --verbose
+App::SD::Test->set_editor("ticket-create-editor.pl --verbose $replica_uuid");
+create_ticket_and_check(extra_args => ['--verbose']);
+
+# test template for sd ticket create --verbose --all-props
+App::SD::Test->set_editor("ticket-create-editor.pl --verbose-and-all $replica_uuid");
+create_ticket_and_check(extra_args => ['--all-props', '--verbose']);
+
diff --git a/t/data/sd-ticket-create-verbose.tmpl b/t/data/sd-ticket-create-verbose.tmpl
new file mode 100644
index 0000000..c0c3683
--- /dev/null
+++ b/t/data/sd-ticket-create-verbose.tmpl
@@ -0,0 +1,23 @@
+=== required ticket metadata (changes here will not be saved) ===
+
+creator: USER
+original_replica: REPLICA
+
+=== edit ticket details below ===
+
+# a one-line summary of what the ticket is about
+summary:
+# valid values for status: new, open, stalled, closed, rejected
+status: new
+# valid values for milestone: alpha, beta, 1.0
+milestone: alpha
+# valid values for component: core, ui, docs, tests
+component: core
+# the email address of the person who is responsible for this ticket
+owner:
+# when this ticket must be finished by (ISO 8601 format)
+due:
+# the email address of the person who reported this ticket
+reporter: EMAIL
+
+=== add new ticket comment below ===
diff --git a/t/data/sd-ticket-create.tmpl b/t/data/sd-ticket-create.tmpl
new file mode 100644
index 0000000..2ab8e53
--- /dev/null
+++ b/t/data/sd-ticket-create.tmpl
@@ -0,0 +1,16 @@
+=== required ticket metadata (changes here will not be saved) ===
+
+creator: USER
+original_replica: REPLICA
+
+=== edit ticket details below ===
+
+summary:
+status: new
+milestone: alpha
+component: core
+owner:
+due:
+reporter: EMAIL
+
+=== add new ticket comment below ===
diff --git a/t/scripts/ticket-create-editor.pl b/t/scripts/ticket-create-editor.pl
index cf42a84..67a4187 100755
--- a/t/scripts/ticket-create-editor.pl
+++ b/t/scripts/ticket-create-editor.pl
@@ -1,9 +1,38 @@
#!/usr/bin/perl -i
+use Prophet::Util;
+use File::Spec;
# perl script to trick Proc::InvokeEditor with for the ticket create command
+my $template = '';
+
+my %tmpl_files = ( '--no-args' => 'sd-ticket-create.tmpl',
+ '--all-props' => 'sd-ticket-create.tmpl',
+ '--verbose' => 'sd-ticket-create-verbose.tmpl',
+ '--verbose-and-all' => 'sd-ticket-create-verbose.tmpl',
+ );
+
+my $tmpl_file = $tmpl_files{shift @ARGV};
+
+my $valid_template =
+ Prophet::Util->slurp("t/data/$tmpl_file");
+
+my $replica_uuid = shift @ARGV;
+
+$valid_template =~ s/USER/$ENV{USER}/g;
+$valid_template =~ s/REPLICA/$replica_uuid/g;
+$valid_template =~ s/EMAIL/$ENV{EMAIL}/g;
+
while (<>) {
- s/(?<=^summary: ).*$/creating tickets with an editor is totally awesome/;
+ $template .= $_;
+
+ s/(?<=^summary: ).*$/we are testing sd ticket create/;
print;
- print "We can create a comment at the same time.\n" if /^===/;
+
+ if ( /^=== add new ticket comment below ===$/ &&
+ $template eq $valid_template ) {
+ print "template ok!\n";
+ } elsif ( /^=== add new ticket comment below ===$/ ) {
+ print "template not ok!\n";
+ }
}
commit 4a6978e1983fb26b1aaadd961166d0629e20c971
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 11:42:49 2009 +0200
make update_ticket_with_editor_ok accept extra args to pass to 'sd ticket update'
diff --git a/lib/App/SD/Test.pm b/lib/App/SD/Test.pm
index 962c2ad..f681fd5 100644
--- a/lib/App/SD/Test.pm
+++ b/lib/App/SD/Test.pm
@@ -140,11 +140,12 @@ sub create_ticket_with_editor_ok {
return ( $ticket_luid, $ticket_uuid, $comment_luid, $comment_uuid );
}
-=head2 update_ticket_with_editor_ok TICKET_LUID, TICKET_UUID
+=head2 update_ticket_with_editor_ok TICKET_LUID, TICKET_UUID [ '--verbose' ]
Updates the ticket given by TICKET_UUID using a spawned editor. It's
expected that C<$ENV{VISUAL}> has been frobbed into something non-interactive,
-or this test will just hang forever.
+or this test will just hang forever. Any extra arguments passed in will
+be passed on to sd ticket update.
Returns the luid and uuid of the comment created during the update (both will
be undef if none is created).
@@ -155,9 +156,11 @@ sub update_ticket_with_editor_ok {
my $self = shift;
my $ticket_luid = shift;
my $ticket_uuid = shift;
+ my @extra_args = @_;
local $Test::Builder::Level = $Test::Builder::Level + 1;
- Prophet::Test::run_output_matches( 'sd', [ 'ticket', 'update', $ticket_uuid ],
+ Prophet::Test::run_output_matches( 'sd', [ 'ticket', 'update', $ticket_uuid,
+ @extra_args ],
[ qr/Updated ticket (.*?)\s+\((.*)\)/,
qr/Created comment (.*?)(?{ $A = $1 })\s+\((.*)(?{ $B = $2 })\)/ ]
);
commit cfaea3ed7bd7ec12c7b31ebc41f1cb585a111061
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 12:38:23 2009 +0200
tests for ticket update
diff --git a/t/03-update-ticket-with-editor.t b/t/03-update-ticket-with-editor.t
index 1d73982..a73fc83 100644
--- a/t/03-update-ticket-with-editor.t
+++ b/t/03-update-ticket-with-editor.t
@@ -1,31 +1,38 @@
#!/usr/bin/perl -w
use strict;
-use Prophet::Test tests => 5;
+use Prophet::Test tests => 16;
use App::SD::Test;
BEGIN {
require File::Temp;
$ENV{'PROPHET_REPO'} = $ENV{'SD_REPO'} = File::Temp::tempdir( CLEANUP => 0 ) . '/_svb';
diag 'export SD_REPO=' . $ENV{'PROPHET_REPO'} . "\n";
- App::SD::Test->set_editor('ticket-update-editor.pl');
}
run_script( 'sd', [ 'init']);
my $replica_uuid = replica_uuid;
+diag('changing settings to enable different behaviour with --verbose arg');
+run_output_matches( 'sd', [ 'settings', '--set', '--', 'default_props_to_show',
+ '["id","summary","status","milestone","owner","created","due","creator","reporter","original_replica"]' ],
+ [
+ 'Trying to change default_props_to_show from ["id","summary","status","milestone","component","owner","created","due","creator","reporter","original_replica"] to ["id","summary","status","milestone","owner","created","due","creator","reporter","original_replica"].',
+ 'Changed default_props_to_show from ["id","summary","status","milestone","component","owner","created","due","creator","reporter","original_replica"] to ["id","summary","status","milestone","owner","created","due","creator","reporter","original_replica"].',
+ ]
+);
+
# create ticket
my ($ticket_id, $ticket_uuid) = create_ticket_ok( '--summary', 'zomg!',
'--owner', 'foo at bar.com');
-# verify that it's correct (test prop won't be shown)
+# verify that it's correct
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
[
"id: $ticket_id ($ticket_uuid)",
'summary: zomg!',
'status: new',
'milestone: alpha',
- 'component: core',
'owner: foo at bar.com',
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
@@ -34,31 +41,124 @@ run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
]
);
+App::SD::Test->set_editor("ticket-update-editor.pl --no-args $replica_uuid $ticket_uuid");
+
# update it
my ($comment_id, $comment_uuid) = App::SD::Test->update_ticket_with_editor_ok($ticket_id, $ticket_uuid);
-# check output
+# check output -- component prop should be hidden by default_props_to_show
run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
[
"id: $ticket_id ($ticket_uuid)",
'summary: summary changed',
'status: new',
'milestone: alpha',
- 'component: core',
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ 'due: 2050-01-25 23:11:42',
qr/^creator: /,
'reporter: ' . $ENV{EMAIL},
"original_replica: $replica_uuid",
]
);
-run_output_matches( 'sd', [ 'ticket', 'comment', 'show', '--batch', '--id', $comment_id ],
+sub check_comment_ok {
+ # comment output verifies that the template presented to the user for
+ # editing was correct
+ run_output_matches( 'sd',
+ [ 'ticket', 'comment', 'show', '--batch', '--id', $comment_id ],
+ [
+ "id: $comment_id ($comment_uuid)",
+ 'content: template ok!',
+ qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ qr/^creator: /,
+ "original_replica: $replica_uuid",
+ qr/^ticket: $ticket_uuid$/,
+ ]
+ );
+}
+
+check_comment_ok();
+
+# sd ticket edit 20 --all-props
+App::SD::Test->set_editor("ticket-update-editor.pl --all-props $replica_uuid $ticket_uuid");
+
+# update it
+# template should show the hidden component prop
+($comment_id, $comment_uuid) = App::SD::Test->update_ticket_with_editor_ok($ticket_id, $ticket_uuid, '--all-props');
+
+# check output -- component prop should be hidden by default_props_to_show
+run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
[
- "id: $comment_id ($comment_uuid)",
- 'content: We can create a comment at the same time.',
+ "id: $ticket_id ($ticket_uuid)",
+ 'summary: now we are checking --all-props',
+ 'status: new',
+ 'milestone: alpha',
+ "owner: $ENV{EMAIL}",
qr/^created: \d{4}-\d{2}-\d{2}.+$/,
qr/^creator: /,
+ 'reporter: ' . $ENV{EMAIL},
"original_replica: $replica_uuid",
- qr/^ticket: $ticket_uuid$/,
]
);
+
+check_comment_ok();
+
+# sd ticket edit 20 --verbose
+App::SD::Test->set_editor("ticket-update-editor.pl --verbose $replica_uuid $ticket_uuid");
+
+# update it
+($comment_id, $comment_uuid) = App::SD::Test->update_ticket_with_editor_ok($ticket_id, $ticket_uuid, '--verbose');
+
+# check output -- component prop should be hidden by default_props_to_show
+run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id ],
+ [
+ "id: $ticket_id ($ticket_uuid)",
+ 'summary: now we are checking --verbose',
+ 'status: new',
+ 'milestone: alpha',
+ qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ 'due: 2050-01-31 19:14:09',
+ qr/^creator: /,
+ 'reporter: ' . $ENV{EMAIL},
+ "original_replica: $replica_uuid",
+ ]
+);
+
+check_comment_ok();
+
+# sd ticket edit 20 --verbose --all-props
+App::SD::Test->set_editor("ticket-update-editor.pl --verbose-and-all $replica_uuid $ticket_uuid");
+
+diag('changing settings for regression test: make sure props aren\'t deleted');
+diag('if they weren\'t presented for editing in the first place');
+
+run_output_matches( 'sd', [ 'settings', '--set', '--', 'default_props_to_show',
+ '["id","summary","status","milestone","owner","created","due","creator","original_replica"]' ],
+ [
+ 'Trying to change default_props_to_show from ["id","summary","status","milestone","owner","created","due","creator","reporter","original_replica"] to ["id","summary","status","milestone","owner","created","due","creator","original_replica"].',
+ 'Changed default_props_to_show from ["id","summary","status","milestone","owner","created","due","creator","reporter","original_replica"] to ["id","summary","status","milestone","owner","created","due","creator","original_replica"].',
+ ]
+);
+
+# update it
+($comment_id, $comment_uuid) = App::SD::Test->update_ticket_with_editor_ok($ticket_id, $ticket_uuid, '--verbose', '--all-props');
+
+# check output -- reporter prop should not have been deleted
+# (need --verbose arg to check this)
+run_output_matches( 'sd', [ 'ticket', 'basics', '--batch', '--id', $ticket_id, '--verbose' ],
+ [
+ "id: $ticket_id ($ticket_uuid)",
+ 'summary: now we are checking --verbose --all-props',
+ 'status: new',
+ 'milestone: alpha',
+ "owner: $ENV{EMAIL}",
+ qr/^created: \d{4}-\d{2}-\d{2}.+$/,
+ qr/^creator: /,
+ "original_replica: $replica_uuid",
+ # no ordering is imposed on props not in default_props_to_show
+ qr/(?:reporter: $ENV{EMAIL}|component: core)/,
+ qr/(?:reporter: $ENV{EMAIL}|component: core)/,
+ ]
+);
+
+check_comment_ok();
diff --git a/t/data/sd-ticket-create-verbose.tmpl b/t/data/sd-ticket-create-verbose.tmpl
index c0c3683..3839a29 100644
--- a/t/data/sd-ticket-create-verbose.tmpl
+++ b/t/data/sd-ticket-create-verbose.tmpl
@@ -5,7 +5,7 @@ original_replica: REPLICA
=== edit ticket details below ===
-# a one-line summary of what the ticket is about
+# a one-line summary of what this ticket is about
summary:
# valid values for status: new, open, stalled, closed, rejected
status: new
diff --git a/t/data/sd-ticket-update-all-props.tmpl b/t/data/sd-ticket-update-all-props.tmpl
new file mode 100644
index 0000000..7e9173d
--- /dev/null
+++ b/t/data/sd-ticket-update-all-props.tmpl
@@ -0,0 +1,18 @@
+qr/=== required ticket metadata \(changes here will not be saved\) ===
+
+id: \d+ \($ticket_uuid\)
+created: \d{4}-\d{2}-\d{2}.+
+creator: $ENV{USER}
+original_replica: $replica_uuid
+
+=== edit ticket details below ===
+
+summary: summary changed
+status: new
+milestone: alpha
+owner:
+due: 2050-01-25 23:11:42
+reporter: $ENV{EMAIL}
+component: core
+
+=== add new ticket comment below ===/
diff --git a/t/data/sd-ticket-update-verbose-all-props.tmpl b/t/data/sd-ticket-update-verbose-all-props.tmpl
new file mode 100644
index 0000000..1e9bd46
--- /dev/null
+++ b/t/data/sd-ticket-update-verbose-all-props.tmpl
@@ -0,0 +1,25 @@
+qr/=== required ticket metadata \(changes here will not be saved\) ===
+
+id: \d+ \($ticket_uuid\)
+created: \d{4}-\d{2}-\d{2}.+
+creator: $ENV{USER}
+original_replica: $replica_uuid
+
+=== edit ticket details below ===
+
+# a one-line summary of what this ticket is about
+summary: now we are checking --verbose
+# valid values for status: new, open, stalled, closed, rejected
+status: new
+# valid values for milestone: alpha, beta, 1.0
+milestone: alpha
+# the email address of the person who is responsible for this ticket
+owner:
+# when this ticket must be finished by \(ISO 8601 format\)
+due: 2050-01-31 19:14:09
+# the email address of the person who reported this ticket
+reporter: $ENV{EMAIL}
+# valid values for component: core, ui, docs, tests
+component: core
+
+=== add new ticket comment below ===/
diff --git a/t/data/sd-ticket-update-verbose.tmpl b/t/data/sd-ticket-update-verbose.tmpl
new file mode 100644
index 0000000..ae8ed39
--- /dev/null
+++ b/t/data/sd-ticket-update-verbose.tmpl
@@ -0,0 +1,23 @@
+qr/=== required ticket metadata \(changes here will not be saved\) ===
+
+id: \d+ \($ticket_uuid\)
+created: \d{4}-\d{2}-\d{2}.+
+creator: $ENV{USER}
+original_replica: $replica_uuid
+
+=== edit ticket details below ===
+
+# a one-line summary of what this ticket is about
+summary: now we are checking --all-props
+# valid values for status: new, open, stalled, closed, rejected
+status: new
+# valid values for milestone: alpha, beta, 1.0
+milestone: alpha
+# the email address of the person who is responsible for this ticket
+owner: $ENV{EMAIL}
+# when this ticket must be finished by \(ISO 8601 format\)
+due:
+# the email address of the person who reported this ticket
+reporter: $ENV{EMAIL}
+
+=== add new ticket comment below ===/
diff --git a/t/data/sd-ticket-update.tmpl b/t/data/sd-ticket-update.tmpl
new file mode 100644
index 0000000..6dc3bfd
--- /dev/null
+++ b/t/data/sd-ticket-update.tmpl
@@ -0,0 +1,17 @@
+qr/=== required ticket metadata \(changes here will not be saved\) ===
+
+id: \d+ \($ticket_uuid\)
+created: \d{4}-\d{2}-\d{2}.+
+creator: $ENV{USER}
+original_replica: $replica_uuid
+
+=== edit ticket details below ===
+
+summary: zomg!
+status: new
+milestone: alpha
+owner: foo\@bar.com
+due:
+reporter: $ENV{EMAIL}
+
+=== add new ticket comment below ===/
diff --git a/t/scripts/ticket-create-editor.pl b/t/scripts/ticket-create-editor.pl
index 67a4187..481ea61 100755
--- a/t/scripts/ticket-create-editor.pl
+++ b/t/scripts/ticket-create-editor.pl
@@ -23,6 +23,9 @@ $valid_template =~ s/USER/$ENV{USER}/g;
$valid_template =~ s/REPLICA/$replica_uuid/g;
$valid_template =~ s/EMAIL/$ENV{EMAIL}/g;
+# open DEBUG, '>', '/home/spang/tmp/got.txt';
+# open DEBUG2, '>', '/home/spang/tmp/wanted.txt';
+
while (<>) {
$template .= $_;
@@ -34,5 +37,7 @@ while (<>) {
print "template ok!\n";
} elsif ( /^=== add new ticket comment below ===$/ ) {
print "template not ok!\n";
+ # print DEBUG $template;
+ # print DEBUG2 $valid_template;
}
}
diff --git a/t/scripts/ticket-update-editor.pl b/t/scripts/ticket-update-editor.pl
index f4afd3a..7f02e72 100755
--- a/t/scripts/ticket-update-editor.pl
+++ b/t/scripts/ticket-update-editor.pl
@@ -1,11 +1,59 @@
#!/usr/bin/perl -i
+use strict;
+use warnings;
+
+use Prophet::Util;
# perl script to trick Proc::InvokeEditor with for the ticket update command
+my $template = '';
+
+my %tmpl_files = ( '--no-args' => 'sd-ticket-update.tmpl',
+ '--all-props' => 'sd-ticket-update-all-props.tmpl',
+ '--verbose' => 'sd-ticket-update-verbose.tmpl',
+ '--verbose-and-all' => 'sd-ticket-update-verbose-all-props.tmpl',
+ );
+
+my $option = shift @ARGV;
+my $tmpl_file = $tmpl_files{$option};
+
+my $valid_template =
+ Prophet::Util->slurp("t/data/$tmpl_file");
+
+my $replica_uuid = shift @ARGV;
+my $ticket_uuid = shift @ARGV;
+
+# open DEBUG, '>', '/home/spang/tmp/got.txt';
+# open DEBUG2, '>', '/home/spang/tmp/wanted.txt';
+
while (<>) {
- s/(?<=^summary: ).*$/summary changed/;
- s/^owner:.*//;
- print;
- print "We can create a comment at the same time.\n" if /^===/;
-}
+ $template .= $_;
+ if ($option eq '--no-args') {
+ s/(?<=^summary: ).*$/summary changed/;
+ s/^owner:.*$//; # deleting a prop
+ s/(?<=^due: ).*$/2050-01-25 23:11:42/; # adding a prop
+ } elsif ($option eq '--all-props') {
+ s/(?<=summary: ).*$/now we are checking --all-props/;
+ s/^due:.*//; # deleting a prop
+ s/(?<=^owner: ).*$/$ENV{EMAIL}/; # adding a prop
+ } elsif ($option eq '--verbose') {
+ s/(?<=^summary: ).*$/now we are checking --verbose/;
+ s/^owner:.*//; # deleting a prop
+ s/(?<=^due: ).*$/2050-01-31 19:14:09/; # adding a prop
+ } elsif ($option eq '--verbose-and-all') {
+ s/(?<=^summary: ).*$/now we are checking --verbose --all-props/;
+ s/^due.*//; # deleting a prop
+ s/(?<=^owner: ).*$/$ENV{EMAIL}/; # adding a prop
+ }
+ print;
+
+ if ( /^=== add new ticket comment below ===$/ &&
+ $template =~ eval($valid_template) ) {
+ print "template ok!\n";
+ } elsif ( /^=== add new ticket comment below ===$/ ) {
+ print "template not ok!\n";
+ # print DEBUG $template;
+ # print DEBUG2 eval($valid_template);
+ }
+}
commit 2669a2f4048ad424d78ab79b36ef6c01e3a84f33
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 12:38:53 2009 +0200
always use strict/warnings oy
diff --git a/t/scripts/ticket-comment-update-editor.pl b/t/scripts/ticket-comment-update-editor.pl
index 10db960..a670d9a 100755
--- a/t/scripts/ticket-comment-update-editor.pl
+++ b/t/scripts/ticket-comment-update-editor.pl
@@ -1,4 +1,6 @@
#!/usr/bin/perl -i
+use strict;
+use warnings;
# perl script to trick Proc::InvokeEditor with for the ticket comment update
# command
diff --git a/t/scripts/ticket-create-editor.pl b/t/scripts/ticket-create-editor.pl
index 481ea61..70e6933 100755
--- a/t/scripts/ticket-create-editor.pl
+++ b/t/scripts/ticket-create-editor.pl
@@ -1,4 +1,7 @@
#!/usr/bin/perl -i
+use strict;
+use warnings;
+
use Prophet::Util;
use File::Spec;
commit d895a42828fca26b94a7a092c67d8eb8047deea1
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 12:41:21 2009 +0200
allow for props_to_show to have different behaviours when returning props
for update/show commands and go back to using the verbose arg here so we
don't have to change the prophet api
diff --git a/lib/App/SD/CLI/Model/Ticket.pm b/lib/App/SD/CLI/Model/Ticket.pm
index a736c61..24d4186 100644
--- a/lib/App/SD/CLI/Model/Ticket.pm
+++ b/lib/App/SD/CLI/Model/Ticket.pm
@@ -110,9 +110,10 @@ sub create_record_template {
my %do_not_edit = map { $_ => 1 } @do_not_edit;
for my $prop ( $record->props_to_show(
- # only call props_to_show with --all-props if we're in an update
+ # only call props_to_show with --verbose if we're in an update
# because new tickets have no declared props
- { 'all-props' => ($self->has_arg('all-props') && $update) } ) ) {
+ { 'verbose' => ($self->has_arg('all-props') && $update),
+ update => $update } ) ) {
if ( $do_not_edit{$prop}) {
if ( $prop eq 'id' && $update ) {
diff --git a/lib/App/SD/Model/Ticket.pm b/lib/App/SD/Model/Ticket.pm
index 3f7559e..3eb83ee 100644
--- a/lib/App/SD/Model/Ticket.pm
+++ b/lib/App/SD/Model/Ticket.pm
@@ -153,16 +153,22 @@ sub color_prop_due {
return $due;
}
-=head2 props_to_show { 'all-props' => 1 }
+=head2 props_to_show { 'verbose' => 1, update => 0 }
A list of which properties to display for the C<show> command (in order
from first to last).
-If called with 'all-props' as a true value, will return all the
+If called with 'verbose' as a true value, will return all the
declared props of a ticket rather than the predefined list of ones
to show. (Should not be called this way during a ticket create as
new tickets have no declared properties.)
+If called with 'update' as a true value, props in the prop ordering
+setting will still be returned in the list even if the record
+doesn't have that property. (Because we often want to not show
+blank properties, but still have the option of adding them in
+an update.)
+
=cut
sub props_to_show {
@@ -171,18 +177,22 @@ sub props_to_show {
my $props_list = $self->app_handle->setting(label =>
'default_props_to_show')->get();
- return @{$props_list} unless $args->{'all-props'};
+ return @{$props_list} unless $args->{'verbose'};
return _create_prop_ordering( hash_to_order => $self->get_props,
- order => $props_list);
+ order => $props_list,
+ update => $args->{update});
}
-=head2 _create_prop_ordering hash_to_order => $hashref, order => $arrayref
+=head2 _create_prop_ordering hash_to_order => $hashref, order => $arrayref [, update => 1 ]
Given references to a hash and an array, return an array of the keys of the
hash in the order specified by the array, with any extra keys at the end of the
ordering.
+If called with update as a true value, will add keys in the ordering to the
+returned order even if they're not in the hash.
+
=cut
sub _create_prop_ordering {
@@ -194,7 +204,7 @@ sub _create_prop_ordering {
# if props in the ordering are in the hash, add them to
# the new ordering
for my $prop (@order) {
- if ( $props{$prop} || $prop eq 'id' ) {
+ if ( $props{$prop} || $prop eq 'id' || $args{update} ) {
push @new_props_list, $prop;
delete $props{$prop};
}
commit d7878e886adaf1898d3333ecf958fabe96c603a6
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 12:43:26 2009 +0200
bugfix: only delete props after an update if they were actually presented for editing in the first place
diff --git a/lib/App/SD/CLI/Command/Ticket/Update.pm b/lib/App/SD/CLI/Command/Ticket/Update.pm
index 108dcfa..0b7ddd3 100644
--- a/lib/App/SD/CLI/Command/Ticket/Update.pm
+++ b/lib/App/SD/CLI/Command/Ticket/Update.pm
@@ -40,10 +40,11 @@ sub process_template {
# we want to do this all in one changeset)
for my $prop ( keys %{ $record->get_props } ) {
next if ( grep { $_ eq $prop } $record->immutable_props );
-
-
- $props_ref->{$prop} = '' if !exists $props_ref->{$prop};
-
+ $props_ref->{$prop} = ''
+ if (!exists $props_ref->{$prop} &&
+ # only delete props if they were actually presented
+ # for editing in the first place
+ grep { $_ eq $prop } $record->props_to_show( { update => 1 } ) );
}
# don't add props that didn't change to the changeset
commit b7f236a375f1ca7412ec70eeaa3657dd2b5ae2c2
Author: Christine Spang <spang at mit.edu>
Date: Fri Jan 16 12:44:26 2009 +0200
make --all-props work the same as --verbose in ticket show command (for consistency with create/update)
diff --git a/lib/App/SD/CLI/Command/Ticket/Show.pm b/lib/App/SD/CLI/Command/Ticket/Show.pm
index ab4e47c..aed8a4c 100644
--- a/lib/App/SD/CLI/Command/Ticket/Show.pm
+++ b/lib/App/SD/CLI/Command/Ticket/Show.pm
@@ -13,6 +13,13 @@ override run => sub {
$self->require_uuid;
my $record = $self->_load_record;
+ # prophet uses --verbose to decide whether to show all declared props
+ # or not (rather than just the ones returned by props_to_show),
+ # but --all-props is more consistent with sd's behaviour in update/create
+ if ($self->has_arg('all-props')) {
+ $self->set_arg('verbose' => 1);
+ }
+
print "\n= METADATA\n\n";
super();
commit c391ab716a9e7d338ffe7f011d6dc31e58589510
Author: Christine Spang <spang at bestpractical.com>
Date: Fri Jan 16 12:51:17 2009 +0200
document show --all-props
diff --git a/lib/App/SD/CLI/Command/Help/Search.pm b/lib/App/SD/CLI/Command/Help/Search.pm
index 54bee19..b90dea4 100644
--- a/lib/App/SD/CLI/Command/Help/Search.pm
+++ b/lib/App/SD/CLI/Command/Help/Search.pm
@@ -32,6 +32,10 @@ print <<EOF
Show basic information, comments, and history for the ticket with local
id 1234. ('details' is an alias for 'show')
+ $cmd ticket show 1234 --all-props
+ Show all properties of the given ticket, even if they aren't in
+ the database setting default_props_to_show.
+
$cmd ticket show 1234 --skip-history
Show only metadata and comments for the ticket 1234 (but not
history).
commit 28f9b4dfddb4d8ac719ec6a7779ba0aa24908f7a
Merge: c391ab7... 8d11921...
Author: Christine Spang <spang at bestpractical.com>
Date: Fri Jan 16 13:51:01 2009 +0200
Merge branch 'master' of code.bestpractical.com:/git/sd
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list