summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chilton <andychilton@gmail.com>2008-07-04 16:17:33 +1200
committerAndrew Chilton <andychilton@gmail.com>2008-07-04 16:17:33 +1200
commitf6649a52ff5610af925818cddd720fa5945bd6b3 (patch)
treeaed0ee63e5d460343749789a1ebe2836bcf00470
parent03a60521d41962fb3d36e8e8002e9bba51796ff6 (diff)
Imported Upstream version v0.4.2upstream/v0.4.2
-rw-r--r--.cil9
-rw-r--r--INSTALLATION2
-rw-r--r--README10
-rwxr-xr-xbin/cil630
-rw-r--r--debian-etch/changelog26
-rw-r--r--debian-etch/control2
-rw-r--r--debian-lenny/changelog26
-rw-r--r--debian-lenny/control2
-rw-r--r--etc/bash_completion.d/cil2
-rw-r--r--issues/c_06e0d28c.cil11
-rw-r--r--issues/c_3f088351.cil6
-rw-r--r--issues/c_45cd5e23.cil23
-rw-r--r--issues/c_4d6c02bb.cil12
-rw-r--r--issues/c_61aea66d.cil7
-rw-r--r--issues/c_6287dc43.cil6
-rw-r--r--issues/c_6f5bc459.cil18
-rw-r--r--issues/c_7f22c24e.cil7
-rw-r--r--issues/c_95e81a14.cil16
-rw-r--r--issues/c_d6ee2369.cil22
-rw-r--r--issues/c_d87e016d.cil14
-rw-r--r--issues/c_f09a77f4.cil9
-rw-r--r--issues/i_02ee35bd.cil5
-rw-r--r--issues/i_48eaec49.cil25
-rw-r--r--issues/i_574046f9.cil16
-rw-r--r--issues/i_6baa8555.cil5
-rw-r--r--issues/i_a5b1eb37.cil27
-rw-r--r--issues/i_a7e3b882.cil12
-rw-r--r--issues/i_a90ad11f.cil23
-rw-r--r--issues/i_b18c21e8.cil11
-rw-r--r--issues/i_bf9badb4.cil23
-rw-r--r--issues/i_c98515e2.cil33
-rw-r--r--issues/i_ce8053b0.cil17
-rw-r--r--lib/CIL.pm67
-rw-r--r--lib/CIL/Issue.pm46
34 files changed, 1011 insertions, 159 deletions
diff --git a/.cil b/.cil
index c1fef1f..0225961 100644
--- a/.cil
+++ b/.cil
@@ -1,12 +1,14 @@
StatusStrict: 1
StatusAllowedList: New
StatusAllowedList: InProgress
+StatusAllowedList: Ongoing
StatusAllowedList: Fixed
StatusAllowedList: OnHold
StatusAllowedList: Duplicate
StatusAllowedList: Finished
StatusOpenList: New
StatusOpenList: InProgress
+StatusOpenList: Ongoing
StatusOpenList: Fixed
StatusClosedList: OnHold
StatusClosedList: Duplicate
@@ -15,14 +17,21 @@ LabelStrict: 1
LabelAllowedList: Release-v0.1.0
LabelAllowedList: Release-v0.2.0
LabelAllowedList: Release-v0.2.1
+LabelAllowedList: Release-v0.3.0
+LabelAllowedList: Release-v0.4.0
+LabelAllowedList: Release-v0.4.1
+LabelAllowedList: Release-v0.4.2
LabelAllowedList: Type-Enhancement
LabelAllowedList: Type-Defect
LabelAllowedList: Type-Task
LabelAllowedList: Type-Patch
+LabelAllowedList: Type-Refactoring
LabelAllowedList: Type-Other
LabelAllowedList: Milestone-v0.1
LabelAllowedList: Milestone-v0.2
LabelAllowedList: Milestone-v0.3
+LabelAllowedList: Milestone-v0.4
+LabelAllowedList: Milestone-v0.5
LabelAllowedList: Milestone-Future
LabelAllowedList: Priority-Critical
LabelAllowedList: Priority-High
diff --git a/INSTALLATION b/INSTALLATION
index cf172ab..e46413c 100644
--- a/INSTALLATION
+++ b/INSTALLATION
@@ -43,7 +43,7 @@ Debian paackage:
which can then be installed with:
- $ sudo dpkg -i ../cil_0.3.0_all.deb
+ $ sudo dpkg -i ../cil_0.4.2_all.deb
or added to a repository you are using for easier installation with apt-get or
aptitude.
diff --git a/README b/README
index c0f3d5e..bceb623 100644
--- a/README
+++ b/README
@@ -38,6 +38,7 @@ When listing the issues, they can also be filtered:
$ cil list --label=Type-Enhancement
$ cil list --is-open
$ cil list --label=Milestone-v0.3 --is-open
+ $ cil list --is-mine
You can see what the issue name is by looking at the 'Issue' title. Imagine it
is 'cafebabe' (which by default is the time from epoch). To see your issue
@@ -81,6 +82,15 @@ it from the issue:
$ cil extract decaf7ea --filename=mycore
+If someone sends you a bug report or a comment via email and you wish to import
+it into your issues list, you can use the 'am' command to do it's best to
+import it. It will try and figure out if an issue is already mentioned and if
+so, will try and import the email as a comment for that particular issue. In
+the case where an existing issue is not found, it will import the email as a
+new issue:
+
+ $ cil am email.txt
+
Finally, because the cil issue files reside on the filesystem in flat files,
there needs to be a way to check the integrity of the issues, therefore you can
run this to do checks regarding the whole issue list:
diff --git a/bin/cil b/bin/cil
index b8bcd20..5aaa020 100755
--- a/bin/cil
+++ b/bin/cil
@@ -26,6 +26,9 @@ use File::Touch;
use File::Glob ':glob';
use File::Basename;
use File::Slurp qw(read_file write_file);
+use Email::Simple;
+use Email::Date qw(find_date);
+
use CIL;
use CIL::Issue;
use CIL::Comment;
@@ -36,7 +39,7 @@ use CIL::Attachment;
my $y = 'y';
-use constant VERSION => '0.3.0';
+use constant VERSION => '0.4.2';
my @IN_OPTS = (
# strings
@@ -56,6 +59,7 @@ my @IN_OPTS = (
# booleans
'is-open', # for 'summary', 'list'
'is-closed', # for 'summary', 'list'
+ 'is-mine', # for 'summary', 'list'
'help',
'version',
);
@@ -65,11 +69,9 @@ my %BOOLEAN_ARGS = (
'version' => 1,
'is-open' => 1,
'is-closed' => 1,
+ 'is-mine' => 1,
);
-my $gan = $ENV{GIT_AUTHOR_NAME} || 'Your Name';
-my $gae = $ENV{GIT_AUTHOR_EMAIL} || 'you@example.org';
-
## ----------------------------------------------------------------------------
# main program
@@ -92,13 +94,15 @@ my $gae = $ENV{GIT_AUTHOR_EMAIL} || 'you@example.org';
if @ARGV == 0;
my $command = shift @ARGV;
+ $command =~ s{-}{_}gxms;
no strict 'refs';
if ( not defined &{"cmd_$command"} ) {
Getopt::Mixed::abortMsg("'$command' is not a valid cil command.");
}
my $cil = CIL->new();
- $cil->read_config_file( '.cil' );
+ $cil->read_config_user();
+ $cil->read_config_file();
&{"cmd_$command"}($cil, $args, @ARGV);
}
@@ -196,10 +200,7 @@ sub cmd_show {
my ($cil, undef, $issue_name) = @_;
# firstly, read the issue in
- my $issue = CIL::Issue->new_from_name($cil, $issue_name);
- unless ( defined $issue ) {
- fatal("Couldn't load issue '$issue_name'");
- }
+ my $issue = load_issue_fuzzy( $cil, $issue_name );
display_issue_full($cil, $issue);
}
@@ -211,10 +212,7 @@ sub cmd_status {
}
# firstly, read the issue in
- my $issue = CIL::Issue->new_from_name($cil, $issue_name);
- unless ( defined $issue ) {
- fatal("Couldn't load issue '$issue_name'");
- }
+ my $issue = load_issue_fuzzy( $cil, $issue_name );
# set the status for this issue
$issue->Status( $status );
@@ -228,50 +226,20 @@ sub cmd_add {
CIL::Utils->ensure_interactive();
+ my $user = user($cil);
+
my $issue = CIL::Issue->new('tmpname');
$issue->Status('New');
- $issue->CreatedBy("$gan <$gae>");
- $issue->AssignedTo("$gan <$gae>");
+ $issue->CreatedBy( $user );
$issue->Description("Description ...");
- my $edit = $y;
-
- # keep going until we get a valid issue or we want to quit
- while ( $edit eq $y ) {
- # read in the new issue text
- my $fh = CIL::Utils->solicit( $issue->as_output );
- $issue = CIL::Issue->new_from_fh( 'tmp', $fh );
-
- # check if the issue is valid
- if ( $issue->is_valid($cil) ) {
- $edit = 'n';
- }
- else {
- msg($_) foreach @{ $issue->errors };
- print 'Would you like to re-edit (y/n): ';
- $edit = <STDIN>;
- chomp $edit;
- print "\n";
- }
- }
-
- # if the issue is still invalid, they quit without correcting it
- return unless $issue->is_valid( $cil );
-
- # we've got the issue, so let's name it
- my $unique_str = $issue->Inserted . $issue->Summary . $issue->Description;
- $issue->set_name( substr(md5_hex($unique_str), 0, 8) );
- $issue->save($cil);
- display_issue($cil, $issue);
+ add_issue_loop($cil, undef, $issue);
}
sub cmd_edit {
my ($cil, undef, $issue_name) = @_;
- my $issue = CIL::Issue->new_from_name($cil, $issue_name);
- unless ( defined $issue ) {
- fatal("Couldn't load issue '$issue_name'");
- }
+ my $issue = load_issue_fuzzy( $cil, $issue_name );
CIL::Utils->ensure_interactive();
@@ -289,10 +257,7 @@ sub cmd_edit {
}
else {
msg($_) foreach @{ $issue->errors };
- print 'Would you like to re-edit (y/n): ';
- $edit = <STDIN>;
- chomp $edit;
- print "\n";
+ $edit = ans('Would you like to re-edit (y/n): ');
}
}
@@ -307,63 +272,23 @@ sub cmd_edit {
sub cmd_comment {
my ($cil, undef, $issue_name) = @_;
- my $issue = CIL::Issue->new_from_name($cil, $issue_name);
- unless ( defined $issue ) {
- fatal("couldn't load issue '$issue_name'");
- }
+ my $issue = load_issue_fuzzy( $cil, $issue_name );
CIL::Utils->ensure_interactive();
# create the new comment
my $comment = CIL::Comment->new('tmpname');
$comment->Issue( $issue->name );
- $comment->CreatedBy("$gan <$gae>");
+ $comment->CreatedBy( user($cil) );
$comment->Description("Description ...");
- my $edit = $y;
-
- # keep going until we get a valid issue or we want to quit
- while ( $edit eq $y ) {
- # read in the new comment text
- my $fh = CIL::Utils->solicit( $comment->as_output );
- $comment = CIL::Comment->new_from_fh( 'tmp', $fh );
-
- # check if the comment is valid
- if ( $comment->is_valid($cil) ) {
- $edit = 'n';
- }
- else {
- msg($_) foreach @{ $issue->errors };
- print 'Would you like to re-edit (y/n): ';
- $edit = <STDIN>;
- chomp $edit;
- print "\n";
- }
- }
-
- # if the comment is still invalid, they quit without correcting it
- return unless $comment->is_valid( $cil );
-
- # we've got the comment, so let's name it
- my $unique_str = $comment->Inserted . $issue->Description;
- $comment->set_name( substr(md5_hex($unique_str), 0, 8) );
-
- # finally, save it
- $comment->save($cil);
-
- # add the comment to the issue, update it's timestamp and save it out
- $issue->add_comment( $comment );
- $issue->save($cil);
- display_issue_full($cil, $issue);
+ add_comment_loop($cil, undef, $issue, $comment);
}
sub cmd_attach {
my ($cil, undef, $issue_name, $filename) = @_;
- my $issue = CIL::Issue->new_from_name($cil, $issue_name);
- unless ( defined $issue ) {
- fatal("couldn't load issue '$issue_name'");
- }
+ my $issue = load_issue_fuzzy( $cil, $issue_name );
# check to see if the file exists
unless ( -r $filename ) {
@@ -371,10 +296,11 @@ sub cmd_attach {
}
my $basename = basename( $filename );
+ my $user = user($cil);
my $add_attachment_text = <<"EOF";
Filename : $basename
-CreatedBy : $gan <$gae>
+CreatedBy : $user
File goes here ... this will be overwritten.
EOF
@@ -397,7 +323,7 @@ EOF
$attachment->Size( $size );
# we've got the attachment, so let's name it
- my $unique_str = $attachment->Inserted . $attachment->File;
+ my $unique_str = time . $attachment->Inserted . $attachment->File;
$attachment->set_name( substr(md5_hex($unique_str), 0, 8) );
# finally, tell it who it's parent is and then save
@@ -413,10 +339,7 @@ EOF
sub cmd_extract {
my ($cil, $args, $attachment_name) = @_;
- my $attachment = CIL::Attachment->new_from_name($cil, $attachment_name);
- unless ( defined $attachment ) {
- fatal("Couldn't load attachment '$attachment_name'");
- }
+ my $attachment = load_attachment_fuzzy($cil, $attachment_name);
my $filename = $args->{f} || $attachment->Filename();
write_file( $filename, $attachment->as_binary );
@@ -452,8 +375,9 @@ sub cmd_fsck {
$attachment->{$a->name} = $a;
}
+ # ------
+ # issues
my $errors = {};
-
if ( @$issues ) {
foreach my $i ( sort { $a->Inserted cmp $b->Inserted } @$issues ) {
my $name = $i->name;
@@ -465,7 +389,7 @@ sub cmd_fsck {
}
# check that all it's comments are there and that they have this parent
- my $comments = $i->Comments;
+ my $comments = $i->CommentList;
foreach my $c ( @$comments ) {
# see if this comment exists at all
if ( exists $comment->{$c} ) {
@@ -479,7 +403,7 @@ sub cmd_fsck {
}
# check that all it's attachments are there and that they have this parent
- my $attachments = $i->Attachments;
+ my $attachments = $i->AttachmentList;
foreach my $a ( @$attachments ) {
# see if this attachment exists at all
if ( exists $attachment->{$a} ) {
@@ -491,14 +415,43 @@ sub cmd_fsck {
push @{$errors->{$name}}, "attachment '$a' listed in issue '" . $i->name . "' does not exist";
}
}
+
+ # check that all it's 'DependsOn' are there and that they have this under 'Precedes'
+ my $depends_on = $i->DependsOnList;
+ foreach my $d ( @$depends_on ) {
+ # see if this issue exists at all
+ if ( exists $issue->{$d} ) {
+ # check the 'Precedes' is this issue
+ my %precedes = map { $_ => 1 } @{$issue->{$d}->PrecedesList};
+ push @{$errors->{$name}}, "issue '$d' should precede '" . $i->name . "' but doesn't"
+ unless exists $precedes{$i->name};
+ }
+ else {
+ push @{$errors->{$name}}, "issue '$d' listed as a dependency of issue '" . $i->name . "' does not exist";
+ }
+ }
+
+ # check that all it's 'Precedes' are there and that they have this under 'DependsOn'
+ my $precedes = $i->PrecedesList;
+ foreach my $p ( @$precedes ) {
+ # see if this issue exists at all
+ if ( exists $issue->{$p} ) {
+ # check the 'DependsOn' is this issue
+ my %depends_on = map { $_ => 1 } @{$issue->{$p}->DependsOnList};
+ push @{$errors->{$name}}, "issue '$p' should depend on '" . $i->name . "' but doesn't"
+ unless exists $depends_on{$i->name};
+ }
+ else {
+ push @{$errors->{$name}}, "issue '$p' listed as preceding issue '" . $i->name . "' does not exist";
+ }
+ }
}
}
-
print_fsck_errors('Issue', $errors);
+ # --------
# comments
$errors = {};
-
# loop through all the comments
if ( @$comments ) {
# check that their parent issues exist
@@ -509,12 +462,11 @@ sub cmd_fsck {
}
}
}
-
print_fsck_errors('Comment', $errors);
+ # -----------
# attachments
$errors = {};
-
# loop through all the attachments
if ( @$attachments ) {
# check that their parent issues exist
@@ -525,26 +477,276 @@ sub cmd_fsck {
}
}
}
-
print_fsck_errors('Attachment', $errors);
- # nothing more to do
+ # ------------
+ # nothing left
separator();
}
-sub print_fsck_errors {
- my ($entity, $errors) = @_;
+sub cmd_am {
+ my ($cil, $args, $email_filename) = @_;
- separator();
- foreach my $issue_name ( keys %$errors ) {
- title( "$entity $issue_name ");
- foreach my $error ( @{$errors->{$issue_name}} ) {
- msg("* $error");
+ unless ( -f $email_filename ) {
+ fatal("couldn't load email '$email_filename'");
+ }
+
+ my $msg_text = read_file($email_filename);
+
+ my $email = Email::Simple->new($msg_text);
+ unless ( defined $email ) {
+ fatal("email file '$email_filename' didn't look like an email");
+ }
+
+ # extract some fields
+ my $subject = $email->header('Subject');
+ my $from = $email->header('From');
+ my $date = find_date($email)->datetime;
+ my $body = $email->body;
+
+ # see if we can find any issue names in either the subject or the body
+ my @issue_names;
+ foreach my $text ( $subject, $body ) {
+ my @new = ( $text =~ /\b\#?([0-9a-f]{8})\b/gxms );
+ push @issue_names, @new;
+ }
+
+ msg("Found possible issue names in email: ", ( join(' ', @issue_names) || '[none]' ));
+
+ my %issue;
+ foreach ( @issue_names ) {
+ my $i = eval { CIL::Issue->new_from_name($cil, $_) };
+ next unless defined $i;
+
+ $issue{$i->name} = $i;
+ }
+
+ if ( keys %issue ) {
+ msg( "Found actual issues: " . (join(' ', keys %issue)) );
+
+ # create the new comment
+ my $comment = CIL::Comment->new('tmpname');
+ $comment->Issue( '...' );
+ $comment->CreatedBy( $from );
+ $comment->Inserted( $date );
+ # $comment->Updated( $date );
+ $comment->Description( $body );
+
+ # display
+ display_comment($cil, $comment);
+
+ # found at least one issue, so this might be a comment
+ my $issue;
+ if ( keys %issue == 1 ) {
+ $issue = (values %issue)[0];
+ }
+ else {
+ my $ans = ans('To which issue would you like to add this comment: ');
+
+ # ToDo: decide whether we let them choose an arbitrary issue, for
+ # now quit unless they choose one from the list
+ return unless exists $issue{$ans};
+
+ # got a valid issue_name, so set the parent name
+ $issue = $issue{$ans};
}
+
+ # set the parent issue
+ $comment->Issue( $issue->name );
+
+ add_comment_loop($cil, undef, $issue, $comment);
+ }
+ else {
+ msg("Couldn't find reference to any issues in the email.");
+
+ # no issue found so make up the issue first
+ my $issue = CIL::Issue->new('tmpname');
+ $issue->Summary( $subject );
+ $issue->Status( 'New' );
+ $issue->CreatedBy( $from );
+ $issue->AssignedTo( user($cil) );
+ $issue->Inserted( $date );
+ $issue->Updated( $date );
+ $issue->Description( $body );
+
+ # display
+ display_issue_full($cil, $issue);
+
+ # then ask if the user would like to add it
+ msg("Couldn't find any likely issues, so this might be a new one.");
+ my $ans = ans('Would you like to add this message as an issue shown above (y/n): ');
+ return unless $ans eq 'y';
+
+ add_issue_loop($cil, undef, $issue);
}
}
+sub cmd_depends_on {
+ my ($cil, undef, $issue_name, $depends_name) = @_;
+
+ my $issue = load_issue_fuzzy($cil, $issue_name);
+ my $depends = load_issue_fuzzy($cil, $depends_name);
+
+ $issue->add_depends_on( $depends->name );
+ $depends->add_precedes( $issue->name );
+
+ $issue->save($cil);
+ $depends->save($cil);
+}
+
+sub cmd_precedes {
+ my ($cil, undef, $issue_name, $depends_name) = @_;
+
+ # switch them round and call 'DependsOn'
+ cmd_depends_on($cil, undef, $depends_name, $issue_name);
+}
+
## ----------------------------------------------------------------------------
+# helpers
+
+sub load_issue_fuzzy {
+ my ($cil, $partial_name) = @_;
+
+ my $issues = $cil->list_issues_fuzzy( $partial_name );
+ unless ( defined $issues ) {
+ fatal("Couldn't find any issues using '$partial_name'");
+ }
+
+ if ( @$issues > 1 ) {
+ fatal('found multiple issues which match that name: ' . join(' ', map { $_->{name} } @$issues));
+ }
+
+ my $issue_name = $issues->[0]->{name};
+ my $issue = CIL::Issue->new_from_name($cil, $issue_name);
+ unless ( defined $issue ) {
+ fatal("Couldn't load issue '$issue_name'");
+ }
+
+ return $issue;
+}
+
+sub load_comment_fuzzy {
+ my ($cil, $partial_name) = @_;
+
+ my $comments = $cil->list_comments_fuzzy( $partial_name );
+ unless ( defined $comments ) {
+ fatal("Couldn't find any comments using '$partial_name'");
+ }
+
+ if ( @$comments > 1 ) {
+ fatal('found multiple comments which match that name: ' . join(' ', map { $_->{name} } @$comments));
+ }
+
+ my $comment_name = $comments->[0]->{name};
+ my $comment = CIL::comment->new_from_name($cil, $comment_name);
+ unless ( defined $comment ) {
+ fatal("Couldn't load comment '$comment_name'");
+ }
+
+ return $comment;
+}
+
+sub load_attachment_fuzzy {
+ my ($cil, $partial_name) = @_;
+
+ my $attachments = $cil->list_attachments_fuzzy( $partial_name );
+ unless ( defined $attachments ) {
+ fatal("Couldn't find any attachments using '$partial_name'");
+ }
+
+ if ( @$attachments > 1 ) {
+ fatal('found multiple attachments which match that name: ' . join(' ', map { $_->{name} } @$attachments));
+ }
+
+ my $attachment_name = $attachments->[0]->{name};
+ my $attachment = CIL::Attachment->new_from_name($cil, $attachment_name);
+ unless ( defined $attachment ) {
+ fatal("Couldn't load attachment '$partial_name'");
+ }
+
+ return $attachment;
+}
+
+sub ans {
+ my ($msg) = @_;
+ print $msg;
+ my $ans = <STDIN>;
+ chomp $ans;
+ print "\n";
+ return $ans;
+}
+
+sub add_issue_loop {
+ my ($cil, undef, $issue) = @_;
+
+ my $edit = $y;
+
+ # keep going until we get a valid issue or we want to quit
+ while ( $edit eq $y ) {
+ # read in the new issue text
+ my $fh = CIL::Utils->solicit( $issue->as_output );
+ $issue = CIL::Issue->new_from_fh( 'tmp', $fh );
+
+ # check if the issue is valid
+ if ( $issue->is_valid($cil) ) {
+ $edit = 'n';
+ }
+ else {
+ msg($_) foreach @{ $issue->errors };
+ $edit = ans('Would you like to re-edit (y/n): ');
+ }
+ }
+
+ # if the issue is still invalid, they quit without correcting it
+ return unless $issue->is_valid( $cil );
+
+ # we've got the issue, so let's name it
+ my $unique_str = time . $issue->Inserted . $issue->Summary . $issue->Description;
+ $issue->set_name( substr(md5_hex($unique_str), 0, 8) );
+ $issue->save($cil);
+ display_issue($cil, $issue);
+
+ return $issue;
+}
+
+sub add_comment_loop {
+ my ($cil, undef, $issue, $comment) = @_;
+
+ my $edit = $y;
+
+ # keep going until we get a valid issue or we want to quit
+ while ( $edit eq $y ) {
+ # read in the new comment text
+ my $fh = CIL::Utils->solicit( $comment->as_output );
+ $comment = CIL::Comment->new_from_fh( 'tmp', $fh );
+
+ # check if the comment is valid
+ if ( $comment->is_valid($cil) ) {
+ $edit = 'n';
+ }
+ else {
+ msg($_) foreach @{ $issue->errors };
+ $edit = ans('Would you like to re-edit (y/n): ');
+ }
+ }
+
+ # if the comment is still invalid, they quit without correcting it
+ return unless $comment->is_valid( $cil );
+
+ # we've got the comment, so let's name it
+ my $unique_str = time . $comment->Inserted . $issue->Description;
+ $comment->set_name( substr(md5_hex($unique_str), 0, 8) );
+
+ # finally, save it
+ $comment->save($cil);
+
+ # add the comment to the issue, update it's timestamp and save it out
+ $issue->add_comment( $comment );
+ $issue->save($cil);
+ display_issue_full($cil, $issue);
+
+ return $comment;
+}
sub check_paths {
my ($cil) = @_;
@@ -561,6 +763,11 @@ sub filter_issues {
# don't filter if we haven't been given anything
return $issues unless %$args;
+ # check that they aren't filtering on both --assigned-to and --is-mine
+ if ( defined $args->{a} and defined $args->{'is-mine'} ) {
+ fatal("the --assigned-to and --is-mine filters are mutually exclusive");
+ }
+
# take a copy of the whole lot first (so we don't destroy the input list)
my @new_issues = @$issues;
@@ -574,7 +781,7 @@ sub filter_issues {
my @tmp;
foreach my $issue ( @new_issues ) {
push @tmp, $issue
- if grep { $_ eq $args->{l} } @{$issue->Labels};
+ if grep { $_ eq $args->{l} } @{$issue->LabelList};
}
@new_issues = @tmp;
}
@@ -595,6 +802,8 @@ sub filter_issues {
}
# filter out 'assigned to'
+ $args->{a} = $cil->UserEmail
+ if defined $args->{'is-mine'};
if ( defined $args->{a} ) {
@new_issues = grep { $args->{a} eq $_->assigned_to_email } @new_issues;
}
@@ -602,6 +811,19 @@ sub filter_issues {
return \@new_issues;
}
+sub print_fsck_errors {
+ my ($entity, $errors) = @_;
+ return unless keys %$errors;
+
+ separator();
+ foreach my $issue_name ( keys %$errors ) {
+ title( "$entity $issue_name ");
+ foreach my $error ( @{$errors->{$issue_name}} ) {
+ msg("* $error");
+ }
+ }
+}
+
## ----------------------------------------------------------------------------
# input/output
@@ -626,7 +848,9 @@ sub display_issue_headers {
field( 'AssignedTo', $issue->AssignedTo() );
field( 'Inserted', $issue->Inserted() );
field( 'Status', $issue->Status() );
- field( 'Labels', join(' ', @{$issue->Label()}) );
+ field( 'Labels', join(' ', @{$issue->LabelList()}) );
+ field( 'DependsOn', join(' ', @{$issue->DependsOnList()}) );
+ field( 'Precedes', join(' ', @{$issue->PrecedesList()}) );
}
sub display_issue {
@@ -639,11 +863,15 @@ sub display_issue {
field( 'CreatedBy', $issue->CreatedBy() );
field( 'AssignedTo', $issue->AssignedTo() );
field( 'Label', $_ )
- foreach sort @{$issue->Label()};
+ foreach sort @{$issue->LabelList()};
field( 'Comment', $_ )
- foreach sort @{$issue->Comment()};
+ foreach sort @{$issue->CommentList()};
field( 'Attachment', $_ )
- foreach sort @{$issue->Attachment()};
+ foreach sort @{$issue->AttachmentList()};
+ field( 'DependsOn', $_ )
+ foreach sort @{$issue->DependsOnList()};
+ field( 'Precedes', $_ )
+ foreach sort @{$issue->PrecedesList()};
field( 'Inserted', $issue->Inserted() );
field( 'Updated', $issue->Inserted() );
text('Description', $issue->Description());
@@ -661,32 +889,53 @@ sub display_issue_full {
field( 'AssignedTo', $issue->AssignedTo() );
field( 'Label', $_ )
foreach sort @{$issue->Label()};
+ field( 'DependsOn', $_ )
+ foreach sort @{$issue->DependsOnList()};
+ field( 'Precedes', $_ )
+ foreach sort @{$issue->PrecedesList()};
field( 'Inserted', $issue->Inserted() );
field( 'Updated', $issue->Inserted() );
text('Description', $issue->Description());
my $comments = $cil->get_comments_for( $issue );
foreach my $comment ( @$comments ) {
- title( 'Comment ' . $comment->name() );
- field( 'CreatedBy', $comment->CreatedBy() );
- field( 'Inserted', $comment->Inserted() );
- field( 'Updated', $comment->Inserted() );
- text('Description', $comment->Description());
+ display_comment( $cil, $comment );
}
my $attachments = $cil->get_attachments_for( $issue );
foreach my $attachment ( @$attachments ) {
- title( 'Attachment ' . $attachment->name() );
- field( 'Filename', $attachment->Filename() );
- field( 'CreatedBy', $attachment->CreatedBy() );
- field( 'Inserted', $attachment->Inserted() );
- field( 'Updated', $attachment->Inserted() );
+ display_attachment( $cil, $attachment );
msg();
}
separator();
}
+sub display_comment {
+ my ($cil, $comment) = @_;
+
+ title( 'Comment ' . $comment->name() );
+ field( 'CreatedBy', $comment->CreatedBy() );
+ field( 'Inserted', $comment->Inserted() );
+ field( 'Updated', $comment->Inserted() );
+ text('Description', $comment->Description());
+}
+
+sub display_attachment {
+ my ($cil, $attachment) = @_;
+
+ title( 'Attachment ' . $attachment->name() );
+ field( 'Filename', $attachment->Filename() );
+ field( 'CreatedBy', $attachment->CreatedBy() );
+ field( 'Inserted', $attachment->Inserted() );
+ field( 'Updated', $attachment->Inserted() );
+}
+
+sub user {
+ my ($cil) = @_;
+ return $cil->UserName . ' <' . $cil->UserEmail . '>';
+}
+
## ----------------------------------------------------------------------------
# helper functions for this command line tool
@@ -768,8 +1017,8 @@ Usage: $0 COMMAND [options]
Commands:
init [--path=PATH]
add
- summary [--status=STATUS] [--label=LABEL] [--is-open] [--is-closed]
- list [--status=STATUS] [--label=LABEL] [--is-open] [--is-closed]
+ summary [FILTERS...]
+ list [FILTERS...]
show ISSUE
status ISSUE NEW_STATUS
edit ISSUE
@@ -778,8 +1027,16 @@ Commands:
extract ATTACHMENT [--filename=FILENAME]
fsck
+Filters:
+ --status=?
+ --is-open
+ --is-closed
+ --label=?
+ --assigned-to=?
+ --is-mine
+
See <http://kapiti.geek.nz/software/cil.html> for further information.
-Report bugs to <andychilton -at- gmail -dot- com>.
+Report bugs to <andychilton\@gmail.com>.
END_USAGE
}
@@ -813,6 +1070,8 @@ cil - the command-line issue list
$ cil extract decaf7ea
$ cil extract decaf7ea --filename=other_filename.txt
+ $ cil am email.txt
+
$ cil fsck
=head1 DESCRIPTION
@@ -827,12 +1086,12 @@ and attachments as local files which you can check in to your repository.
Creates a local '.cil' file and an 'issues' directory. If PATH is specified,
the config file and directory will be created in the destination directory.
-=item summary [--status=STATUS] [--label=LABEL] [--is-open] [--is-closed]
+=item summary [filters]
Displays a one line summary for each issue. You may filter on both the Status
and Label fields.
-=item list [--status=STATUS] [--label=LABEL] [--is-open] [--is-closed]
+=item list [filters]
Shows each issue with more information. You may filter on both the Status and
Label fields.
@@ -850,6 +1109,21 @@ Shows the issue name with more detail.
Shortcut so that you can set a new status on an issue without having to edit
it.
+=item depends-on ISSUE1 ISSUE2
+
+Shortcut so that cil will add a 'DependsOn' from issue 1 to issue
+2. Conversley, issue 2 will also then contain a 'Precedes' pointer to issue 1.
+
+=item precedes ISSUE1 ISSUE2
+
+This is the exact opposite of C<depends-on> and is here for convenience and
+completeness. ie. issue 1 has to be completed before issue 2.
+
+=item status ISSUE NEW_STATUS
+
+Shortcut so that you can set a new status on an issue without having to edit
+it.
+
=item edit ISSUE
Edits the issue. If it changes, set the updates time to now.
@@ -867,6 +1141,59 @@ Adds that particular filename to an existing issue.
Extracts the file from the attachment number. If filename if given uses that,
otherwise it will use the original one saved along with the attachment.
+=item fsck
+
+Tries to help you organise your issues if any aren't valid or have broken
+relationships.
+
+=item am
+
+Applies an email message to the issue list. It tries to figure out the type of
+email it is, whether it is a new issue or a comment on an already existing
+issue. For example, if it can find valid issue names in the subject or body of
+the message, it adds it as a comment to that issue. If it can't find any valid
+issue names, it presumes it's a new issue and adds that.
+
+Note: this command will deal with Mailbox format files later on.
+
+=back
+
+=head1 FILTERS
+
+Filters can be used on both the C<summary> and C<list> commands. Most can be
+combined. See each individual filter for details.
+
+=over
+
+=item --status=STATUS
+
+You can choose any of the Statuses which might appear in your issues. This
+status does not have to be defined in your C<.cil> file, even if you have
+C<StatusStrict> turned on.
+
+=item --label=LABEL
+
+You can choose any of the Labels which might appear in your issues. This
+label does not have to be defined in your C<.cil> file, even if you have
+C<LabelStrict> turned on.
+
+=item --is-open, --is-closed
+
+These check both C<StatusOpenList> and C<StatusClosedList> from your C<.cil>
+file. If both are specified, you're likely to get no issues unless you
+explicitely defined a status as being in both lists (for whatever reason you
+have).
+
+=item --assigned-to=EMAIL_ADDRESS, --is-mine
+
+These items are mutually exclusive. The C<--assigned-to> just checks the email
+address in the AssignedTo field. It does not match anything else in that field,
+including any preceding name or any angle brackets.
+
+The C<--is-mine> filter is a shortcut to asking if AssignedTo is you. Cil knows
+your email address if you define it in your user's C<~/.cilrc> file as
+C<UserEmail>.
+
=back
=head1 .cil
@@ -935,6 +1262,33 @@ This determines which labels are allowed if you have turned on LabelStrict.
=back
+=head1 ~/.cilrc
+
+The C<~/.cilrc> file is read to configure the user's preferences for all cil
+lists they're using. It is of the same format as the C<.cil> file and contains
+the following options:
+
+ UserName: Andrew Chilton
+ UserEmail: andychilton@gmail.com
+
+=over
+
+=item UserName
+
+Default: 'Name', Type: String
+
+This is used as a default in the C<CreatedBy> and C<AssignedTo> fields in any
+issues/comments/attachments you add.
+
+=item UserEmail
+
+Default: 'Email', Type: String
+
+This is used as a default in the C<CreatedBy> and C<AssignedTo> fields in any
+issues/comments/attachments you add.
+
+=back
+
=head1 BUGS
Probably. Let me know :-)
diff --git a/debian-etch/changelog b/debian-etch/changelog
index 16920ad..6218950 100644
--- a/debian-etch/changelog
+++ b/debian-etch/changelog
@@ -1,3 +1,29 @@
+cil (0.4.2) unstable; urgency=low
+
+ * Fix bug where new issues are assigned to the reporter
+ * Fix bug where only one item in a config list breaks listings
+ * Ready for 0.4.2 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Thu, 03 Jul 2008 00:09:21 +1200
+
+cil (0.4.1) unstable; urgency=low
+
+ * Fix dependency on libemail-date-perl
+ * Ready for 0.4.1 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Thu, 03 Jul 2008 00:09:21 +1200
+
+cil (0.4.0) unstable; urgency=low
+
+ * Can now read a ~/.cilrc file for user defined options
+ * Added command 'am' which applies a mailbox
+ * Can now use shortened hash names to the commands
+ * Allows dependencies between issues
+ * New filter called --is-mine
+ * Ready for 0.4.0 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Wed, 02 Jul 2008 23:12:20 +1200
+
cil (0.3.0) unstable; urgency=low
* Added filters for the listing commands
diff --git a/debian-etch/control b/debian-etch/control
index ded0c34..9a6ca1d 100644
--- a/debian-etch/control
+++ b/debian-etch/control
@@ -11,7 +11,7 @@ Package: cil
Section: perl
Priority: optional
Architecture: all
-Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl
+Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl, libemail-filter-perl, libemail-date-perl
Description: command line issue tracker
'cil' allows easy command-line creation of an issue tracker. It saves each
issue locally and in plain text. Commands are given such that these issues can
diff --git a/debian-lenny/changelog b/debian-lenny/changelog
index 16920ad..fa918b5 100644
--- a/debian-lenny/changelog
+++ b/debian-lenny/changelog
@@ -1,3 +1,29 @@
+cil (0.4.2) unstable; urgency=low
+
+ * Fix bug where new issues are assigned to the reporter
+ * Fix bug where only one item in a config list breaks listings
+ * Ready for 0.4.2 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Thu, 03 Jul 2008 22:22:22 +1200
+
+cil (0.4.1) unstable; urgency=low
+
+ * Fix dependency on libemail-date-perl
+ * Ready for 0.4.1 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Thu, 03 Jul 2008 00:09:21 +1200
+
+cil (0.4.0) unstable; urgency=low
+
+ * Can now read a ~/.cilrc file for user defined options
+ * Added command 'am' which applies a mailbox
+ * Can now use shortened hash names to the commands
+ * Allows dependencies between issues
+ * New filter called --is-mine
+ * Ready for 0.4.0 release
+
+ -- Andrew Chilton <andychilton@gmail.com> Wed, 02 Jul 2008 23:12:20 +1200
+
cil (0.3.0) unstable; urgency=low
* Added filters for the listing commands
diff --git a/debian-lenny/control b/debian-lenny/control
index ded0c34..9a6ca1d 100644
--- a/debian-lenny/control
+++ b/debian-lenny/control
@@ -11,7 +11,7 @@ Package: cil
Section: perl
Priority: optional
Architecture: all
-Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl
+Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl, libemail-filter-perl, libemail-date-perl
Description: command line issue tracker
'cil' allows easy command-line creation of an issue tracker. It saves each
issue locally and in plain text. Commands are given such that these issues can
diff --git a/etc/bash_completion.d/cil b/etc/bash_completion.d/cil
index 3a57087..9c86338 100644
--- a/etc/bash_completion.d/cil
+++ b/etc/bash_completion.d/cil
@@ -38,7 +38,7 @@ _cil()
# constants
opts="--help --version --path --status --label --filename --is-open --is-closed --assigned-to --created-by"
- commands="init add summary list show status edit comment attach extract"
+ commands="init add summary list show status depends-on precedes edit comment attach extract"
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
diff --git a/issues/c_06e0d28c.cil b/issues/c_06e0d28c.cil
new file mode 100644
index 0000000..63f2608
--- /dev/null
+++ b/issues/c_06e0d28c.cil
@@ -0,0 +1,11 @@
+Issue: 574046f9
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-02T10:51:45
+Updated: 2008-07-02T10:53:10
+
+Added the ability to use --is-mine. Also, when adding the documnentation, I
+moved the filters to their own section.
+
+Basically, --is-mine takes the email defined in ~/.cilrc and applies it by just
+overwriting --assigned-by, internally. This is okay since these two options are
+mutually exclusive.
diff --git a/issues/c_3f088351.cil b/issues/c_3f088351.cil
new file mode 100644
index 0000000..8bc3c4b
--- /dev/null
+++ b/issues/c_3f088351.cil
@@ -0,0 +1,6 @@
+Issue: 6baa8555
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-06-28T11:36:19
+Updated: 2008-06-28T11:36:42
+
+Work done as part of #85eceee9.
diff --git a/issues/c_45cd5e23.cil b/issues/c_45cd5e23.cil
new file mode 100644
index 0000000..7614c36
--- /dev/null
+++ b/issues/c_45cd5e23.cil
@@ -0,0 +1,23 @@
+Issue: 48eaec49
+CreatedBy: Francois Marier <francois@debian.org>
+Inserted: 2008-06-29T00:20:11
+Updated: 2008-06-29T12:05:50
+
+On 2008-06-29 at 12:13:49, Andrew Chilton wrote:
+> Any other thoughts about how it would work? Maybe that enough for now
+> and we see what happens.
+
+Thinking about the use case where I'd want to add a comment on an issue
+(like what I am doing now about the cil-am command), I think it would be
+neat if cil-am could detect that.
+
+So for example, if you find a cil hash in the body of an email (or the
+subject line), then it could be added as a comment. The timestamp of the
+email determining the order.
+
+That would be a way to add a comment to an issue without depending on a web
+interface.
+
+[snip]
+
+Francois
diff --git a/issues/c_4d6c02bb.cil b/issues/c_4d6c02bb.cil
new file mode 100644
index 0000000..3702f53
--- /dev/null
+++ b/issues/c_4d6c02bb.cil
@@ -0,0 +1,12 @@
+Issue: ce8053b0
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-01T11:33:55
+Updated: 2008-07-01T11:34:38
+
+Added the ability to read the ~/.cilrc config file. The only things it can
+contain for now are:
+
+* UserName
+* UserEmail
+
+but we can easily add more as time goes on.
diff --git a/issues/c_61aea66d.cil b/issues/c_61aea66d.cil
new file mode 100644
index 0000000..c2daa55
--- /dev/null
+++ b/issues/c_61aea66d.cil
@@ -0,0 +1,7 @@
+Issue: 02ee35bd
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-06-28T11:28:46
+Updated: 2008-06-28T11:29:03
+
+This was added as part of Milestone-v0.3. See issue #85eceee9 for further
+details.
diff --git a/issues/c_6287dc43.cil b/issues/c_6287dc43.cil
new file mode 100644
index 0000000..041e3f7
--- /dev/null
+++ b/issues/c_6287dc43.cil
@@ -0,0 +1,6 @@
+Issue: a7e3b882
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-03T10:17:39
+Updated: 2008-07-03T10:18:01
+
+Made sure that nothing is put into the 'AssignedTo' field on new issues.
diff --git a/issues/c_6f5bc459.cil b/issues/c_6f5bc459.cil
new file mode 100644
index 0000000..b23a530
--- /dev/null
+++ b/issues/c_6f5bc459.cil
@@ -0,0 +1,18 @@
+Issue: 48eaec49
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-06-29T12:08:32
+Updated: 2008-06-29T12:11:14
+
+Added ability to process an email message. It will either be added as a new
+issue or as a comment to an existing issue. The process for determining what
+happens is as follows:
+
+* a list of possible issue names is compiled from the subject and body of the
+ email
+* of those, it checks if any are valid in the current list
+
+If any are valid, it will add the email as a comment to that one (if there is
+only one) or will ask you which to add it to if there are more than one).
+
+In the case where there is no valid issues, it will add the email as a new
+issue.
diff --git a/issues/c_7f22c24e.cil b/issues/c_7f22c24e.cil
new file mode 100644
index 0000000..ec8c84e
--- /dev/null
+++ b/issues/c_7f22c24e.cil
@@ -0,0 +1,7 @@
+Issue: c98515e2
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-02T10:02:11
+Updated: 2008-07-02T10:02:38
+
+Added checks in 'fsck' so that it looks at the 'Precedes' and the 'DependsOn'
+fields.
diff --git a/issues/c_95e81a14.cil b/issues/c_95e81a14.cil
new file mode 100644
index 0000000..27bdf26
--- /dev/null
+++ b/issues/c_95e81a14.cil
@@ -0,0 +1,16 @@
+Issue: bf9badb4
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-01T10:59:42
+Updated: 2008-07-01T11:00:46
+
+Now allows you to put in issue names as shortened versions of their full names.
+Also attachment names too. Provisions have already been added in case we want
+to do comment names too.
+
+e.g.
+
+ cil show cafe
+ cil edit cafe
+ cil extract dead
+
+and the like.
diff --git a/issues/c_d6ee2369.cil b/issues/c_d6ee2369.cil
new file mode 100644
index 0000000..f1deb9a
--- /dev/null
+++ b/issues/c_d6ee2369.cil
@@ -0,0 +1,22 @@
+Issue: a90ad11f
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-02T12:40:07
+Updated: 2008-07-02T12:42:18
+
+Nigel suggested on IRC of using the example .cil file in the manpage if wanting a default file:
+
+ StatusStrict: 1
+ StatusAllowedList: New
+ StatusAllowedList: InProgress
+ StatusAllowedList: Finished
+ StatusOpenList: New
+ StatusOpenList: InProgress
+ StatusClosedList: Finished
+ LabelStrict: 1
+ LabelAllowedList: Type-Enhancement
+ LabelAllowedList: Type-Defect
+ LabelAllowedList: Priority-High
+ LabelAllowedList: Priority-Medium
+ LabelAllowedList: Priority-Low
+
+Maybe a 'DefaultAssignedTo' in the .cil file might help.
diff --git a/issues/c_d87e016d.cil b/issues/c_d87e016d.cil
new file mode 100644
index 0000000..e9bf8b1
--- /dev/null
+++ b/issues/c_d87e016d.cil
@@ -0,0 +1,14 @@
+Issue: c98515e2
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-01T12:16:51
+Updated: 2008-07-01T12:29:32
+
+Added the 'DependsOn' and 'Precedes' fields. These are automatically added when
+using the command line such as:
+
+ cil depends-on cafebabe feedface
+ cil precedes feedface cafebabe
+
+Both of these commands do the same thing.
+
+ToDo: add checks for this functionality into 'fsck'.
diff --git a/issues/c_f09a77f4.cil b/issues/c_f09a77f4.cil
new file mode 100644
index 0000000..bf26521
--- /dev/null
+++ b/issues/c_f09a77f4.cil
@@ -0,0 +1,9 @@
+Issue: a5b1eb37
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+Inserted: 2008-07-02T12:51:27
+Updated: 2008-07-02T12:52:08
+
+This was happening because there was only one line for the StatusClosedList.
+This would happen with some of the other List items too.
+
+Should be fixed now.
diff --git a/issues/i_02ee35bd.cil b/issues/i_02ee35bd.cil
index 85596e3..298e0fa 100644
--- a/issues/i_02ee35bd.cil
+++ b/issues/i_02ee35bd.cil
@@ -1,12 +1,13 @@
Summary: Labels should be allowed to have a 'required' set
-Status: New
+Status: Duplicate
CreatedBy: Andrew Chilton <andychilton@gmail.com>
AssignedTo: Andrew Chilton <andychilton@gmail.com>
Label: Priority-Medium
Label: Release-v0.1.0
Label: Type-Enhancement
+Comment: 61aea66d
Inserted: 2008-05-05T12:53:38
-Updated: 2008-06-26T11:53:27
+Updated: 2008-06-28T11:31:35
In the .cil config file, there should a field which determines a
'required' set of labels.
diff --git a/issues/i_48eaec49.cil b/issues/i_48eaec49.cil
new file mode 100644
index 0000000..ad0a5b5
--- /dev/null
+++ b/issues/i_48eaec49.cil
@@ -0,0 +1,25 @@
+Summary: Add command 'am'
+Status: Finished
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Milestone-v0.4
+Label: Type-Enhancement
+Comment: 45cd5e23
+Comment: 6f5bc459
+Inserted: 2008-06-28T23:57:56
+Updated: 2008-06-29T12:11:14
+
+This command would take a mailbox and apply it as a new bug. It would take the
+first subject as the summary and the body as the issue decription. Then, each
+subsequent email would be added as a comment.
+
+The Status would be set to 'New' pending another way of doing it.
+
+I guess attachments throughout the email thread could also be imported.
+Depending on how hard this is, we might syphon it off to another issue for
+another release.
+
+There may be other smart things we can do further down the line. For example,
+maybe we could try and read the Status from the subject line somehow but I
+think we just implement it straightforward for now and see what suggestions
+other people have.
diff --git a/issues/i_574046f9.cil b/issues/i_574046f9.cil
new file mode 100644
index 0000000..753bb26
--- /dev/null
+++ b/issues/i_574046f9.cil
@@ -0,0 +1,16 @@
+Summary: Have a filter called '--is-mine'
+Status: Finished
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Milestone-v0.4
+Label: Type-Enhancement
+Comment: 06e0d28c
+Inserted: 2008-07-02T10:16:59
+Updated: 2008-07-02T11:11:44
+
+By having a filter '--is-mine', means it's much easier to type than
+'--assigned-to=andychilton-at-gmail-dot-com'.
+
+ cil list --is-open --is-mine
+
+That would be pretty nice.
diff --git a/issues/i_6baa8555.cil b/issues/i_6baa8555.cil
index 701e18e..f70d6ac 100644
--- a/issues/i_6baa8555.cil
+++ b/issues/i_6baa8555.cil
@@ -1,13 +1,14 @@
Summary: Do checking on input fields after adding or editing issue
-Status: InProgress
+Status: Finished
CreatedBy: Andrew Chilton <andychilton@gmail.com>
AssignedTo: Andrew Chilton <andychilton@gmail.com>
Label: Priority-Medium
Label: Release-v0.1.0
Label: Type-Enhancement
+Comment: 3f088351
Comment: 4edba98c
Inserted: 2008-05-05T12:46:58
-Updated: 2008-06-26T12:12:41
+Updated: 2008-06-28T11:36:42
For example, if there is a config item in .cil called
'allowed_statuses', all input values in the 'Status' field should be
diff --git a/issues/i_a5b1eb37.cil b/issues/i_a5b1eb37.cil
new file mode 100644
index 0000000..6f41d03
--- /dev/null
+++ b/issues/i_a5b1eb37.cil
@@ -0,0 +1,27 @@
+Summary: Can't use string ("Finished") as an ARRAY ref while "strict refs" in use at /usr/share/perl5/CIL.pm line 227.
+Status: Finished
+CreatedBy: Nigel McNie <nigel@mcnie.name>
+AssignedTo: Nigel McNie <nigel@mcnie.name>
+Comment: f09a77f4
+Inserted: 2008-07-02T12:27:39
+Updated: 2008-07-02T12:52:26
+
+I get this error when running 'cil list --is-open' on my repo.
+
+My .cil:
+
+StatusStrict: 1
+StatusAllowedList: New
+StatusAllowedList: InProgress
+StatusAllowedList: Finished
+StatusOpenList: New
+StatusOpenList: InProgress
+StatusClosedList: Finished
+LabelStrict: 1
+LabelAllowedList: Type-Enhancement
+LabelAllowedList: Type-Defect
+LabelAllowedList: Priority-High
+LabelAllowedList: Priority-Medium
+LabelAllowedList: Priority-Low
+
+Do you need more info? How does more info work in cil anyways :)
diff --git a/issues/i_a7e3b882.cil b/issues/i_a7e3b882.cil
new file mode 100644
index 0000000..ded2434
--- /dev/null
+++ b/issues/i_a7e3b882.cil
@@ -0,0 +1,12 @@
+Summary: New issues shouldn't be assigned to anyone
+Status: Finished
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Release-v0.4.0
+Label: Type-Defect
+Comment: 6287dc43
+Inserted: 2008-07-03T09:59:59
+Updated: 2008-07-03T10:18:36
+
+This came about because a bug submitted by Nigel was AssignedTo him. I think it
+should be blank to start off with.
diff --git a/issues/i_a90ad11f.cil b/issues/i_a90ad11f.cil
new file mode 100644
index 0000000..e02b869
--- /dev/null
+++ b/issues/i_a90ad11f.cil
@@ -0,0 +1,23 @@
+Summary: Write a default .cil file so --commands work
+Status: New
+CreatedBy: Nigel McNie <nigel@mcnie.name>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Comment: d6ee2369
+Inserted: 2008-07-02T12:22:45
+Updated: 2008-07-02T12:42:18
+
+When I tried to use cil for the first time, I did:
+
+cil init
+[fix debian packaging :)]
+cil init
+cil add
+cil list --is-open
+
+And got no results. Because cil didn't know at that point what statuses counted
+as 'open'.
+
+It would be nice if a default .cil was written out, with just enough statuses
+etc. in it to make those common --command flags work.
+
+You could also add cil init --bare to not write this out.
diff --git a/issues/i_b18c21e8.cil b/issues/i_b18c21e8.cil
new file mode 100644
index 0000000..cede95c
--- /dev/null
+++ b/issues/i_b18c21e8.cil
@@ -0,0 +1,11 @@
+Summary: Ongoing maintenance and refactorings
+Status: Ongoing
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Type-Refactoring
+Inserted: 2008-06-29T10:16:39
+Updated: 2008-06-29T10:23:51
+
+This issue is so that refactorings can be checked in against a particular
+issue. This makes it easier to track and see a high level change of what was
+done.
diff --git a/issues/i_bf9badb4.cil b/issues/i_bf9badb4.cil
new file mode 100644
index 0000000..065c8d0
--- /dev/null
+++ b/issues/i_bf9badb4.cil
@@ -0,0 +1,23 @@
+Summary: Allow shortened hash names
+Status: Finished
+CreatedBy: Francois Marier <francois@debian.org>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Milestone-v0.4
+Label: Type-Enhancement
+Comment: 95e81a14
+Inserted: 2008-06-29T13:20:11
+Updated: 2008-07-01T11:15:35
+
+How about doing the same thing that git is doing for commit hashes: if you
+only type the first few characters of the hash, then as long as it's not
+ambiguous, git will accept that.
+
+So instead of typing
+
+ cil show 28fb3258
+
+I could just do
+
+ cil show 28f
+
+Francois
diff --git a/issues/i_c98515e2.cil b/issues/i_c98515e2.cil
new file mode 100644
index 0000000..98dc5a7
--- /dev/null
+++ b/issues/i_c98515e2.cil
@@ -0,0 +1,33 @@
+Summary: Allow dependencies between issues
+Status: Finished
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Milestone-v0.4
+Label: Type-Enhancement
+Comment: 7f22c24e
+Comment: d87e016d
+Inserted: 2008-07-01T03:23:39
+Updated: 2008-07-02T10:03:09
+
+Francois suggested that allowing dependencies between issues would be
+good. ie. this one here is dependent on that one over there (ie. the
+other needs to be fixed first).
+
+I'd prefer to keep it generic, ie. you set the status to 'DependsOn'
+and then you refer to the other issue in the description or a comment.
+
+If that were the case, then no code changes would be required.
+
+But...
+
+It sounds like people would want this as a separate field though, so
+maybe we add it as follows. The top section of each issue would have a
+new field (if applicable), called "DependsOn" and would refer to the
+other issue number:
+
+ DependsOn: cafebabe
+
+If we do this, do we need to add a 'Precedes' field to the other
+issue?
+
+I'll ask the others for input.
diff --git a/issues/i_ce8053b0.cil b/issues/i_ce8053b0.cil
new file mode 100644
index 0000000..7669a1e
--- /dev/null
+++ b/issues/i_ce8053b0.cil
@@ -0,0 +1,17 @@
+Summary: Ability to have a ~/.cilrc file
+Status: Finished
+CreatedBy: Andrew Chilton <andychilton@gmail.com>
+AssignedTo: Andrew Chilton <andychilton@gmail.com>
+Label: Milestone-v0.4
+Label: Type-Enhancement
+Comment: 4d6c02bb
+Inserted: 2008-06-28T23:44:50
+Updated: 2008-07-01T11:34:38
+
+The ability to have a ~/.cilrc file can help with the following:
+
+* UserName: An Other
+* UserEmail me@example.com
+
+There are probably other uses too but for now, just getting it used is what's
+important.
diff --git a/lib/CIL.pm b/lib/CIL.pm
index e2be890..ee85064 100644
--- a/lib/CIL.pm
+++ b/lib/CIL.pm
@@ -30,6 +30,7 @@ __PACKAGE__->mk_accessors(qw(
IssueDir
StatusStrict StatusAllowed StatusOpen StatusClosed
LabelStrict LabelAllowed
+ UserName UserEmail
));
my $defaults = {
@@ -40,6 +41,11 @@ my $defaults = {
my @config_hashes = qw(StatusAllowed StatusOpen StatusClosed LabelAllowed);
+my $defaults_user = {
+ UserName => 'Name',
+ UserEmail => 'me@example.com',
+};
+
## ----------------------------------------------------------------------------
sub new {
@@ -59,9 +65,11 @@ sub new {
}
sub list_entities {
- my ($self, $prefix) = @_;
+ my ($self, $prefix, $base) = @_;
+
+ $base = '' unless defined $base;
- my $globpath = $self->IssueDir . "/${prefix}_*.cil";
+ my $globpath = $self->IssueDir . "/${prefix}_${base}*.cil";
my @filenames = bsd_glob($globpath);
my @entities;
@@ -93,6 +101,24 @@ sub list_attachments {
return $self->list_entities('a');
}
+sub list_issues_fuzzy {
+ my ($self, $partial_name) = @_;
+
+ return $self->list_entities('i', $partial_name);
+}
+
+sub list_comments_fuzzy {
+ my ($self, $partial_name) = @_;
+
+ return $self->list_entities('c', $partial_name);
+}
+
+sub list_attachments_fuzzy {
+ my ($self, $partial_name) = @_;
+
+ return $self->list_entities('a', $partial_name);
+}
+
sub get_issues {
my ($self) = @_;
@@ -133,7 +159,7 @@ sub get_comments_for {
my ($self, $issue) = @_;
my @comments;
- foreach my $comment_name ( @{$issue->Comments} ) {
+ foreach my $comment_name ( @{$issue->CommentList} ) {
my $comment = CIL::Comment->new_from_name( $self, $comment_name );
push @comments, $comment;
}
@@ -148,7 +174,7 @@ sub get_attachments_for {
my ($self, $issue) = @_;
my @attachments;
- foreach my $attachment_name ( @{$issue->Attachments} ) {
+ foreach my $attachment_name ( @{$issue->AttachmentList} ) {
my $attachment = CIL::Attachment->new_from_name( $self, $attachment_name );
push @attachments, $attachment;
}
@@ -159,10 +185,36 @@ sub get_attachments_for {
return \@attachments;
}
+sub read_config_user {
+ my ($self) = @_;
+
+ my $filename = "$ENV{HOME}/.cilrc";
+
+ my $cfg;
+ if ( -f $filename ) {
+ $cfg = CIL::Utils->parse_cil_file( $filename );
+ }
+
+ # set each config to be either the user defined one or the default
+ foreach ( qw(UserName UserEmail) ) {
+ $self->$_( $cfg->{$_} || $defaults_user->{$_} );
+ }
+}
+
sub read_config_file {
- my ( $self, $filename ) = @_;
+ my ( $self ) = @_;
+
+ my $filename = '.cil';
- my $cfg = CIL::Utils->parse_cil_file( $filename );
+ # since we might not have a '.cil' file yet (in the case where we're calling 'init',
+ # then we should just return whatever the defaults are
+ my $cfg;
+ if ( -f $filename ) {
+ $cfg = CIL::Utils->parse_cil_file( $filename );
+ }
+ else {
+ $cfg = $defaults;
+ }
# set some defaults if we don't have any of these
foreach my $key ( keys %$defaults ) {
@@ -172,7 +224,8 @@ sub read_config_file {
# for some things, make a hash out of them
foreach my $hash_name ( @config_hashes ) {
my $h = {};
- foreach my $thing ( @{$cfg->{"${hash_name}List"}} ) {
+ my @list = ref $cfg->{"${hash_name}List"} eq 'ARRAY' ? @{$cfg->{"${hash_name}List"}} : $cfg->{"${hash_name}List"};
+ foreach my $thing ( @list ) {
$h->{$thing} = 1;
}
$cfg->{$hash_name} = $h;
diff --git a/lib/CIL/Issue.pm b/lib/CIL/Issue.pm
index d44626e..eff317f 100644
--- a/lib/CIL/Issue.pm
+++ b/lib/CIL/Issue.pm
@@ -31,14 +31,16 @@ use CIL::Utils;
use base qw(CIL::Base);
# fields specific to Issue
-__PACKAGE__->mk_accessors(qw(Summary Status AssignedTo Label Comment Attachment Description));
+__PACKAGE__->mk_accessors(qw(Summary Status AssignedTo DependsOn Precedes Label Comment Attachment Description));
-my @FIELDS = ( qw(Summary Status CreatedBy AssignedTo Label Comment Attachment Inserted Updated Description) );
+my @FIELDS = ( qw(Summary Status CreatedBy AssignedTo DependsOn Precedes Label Comment Attachment Inserted Updated Description) );
my $cfg = {
array => {
Label => 1,
Comment => 1,
Attachment => 1,
+ DependsOn => 1,
+ Precedes => 1,
},
};
@@ -65,6 +67,8 @@ sub new {
Label => [],
Comment => [],
Attachment => [],
+ DependsOn => [],
+ Precedes => [],
Description => '',
};
$self->{Changed} = 0;
@@ -109,7 +113,7 @@ sub is_valid {
# see if we only allow certain Labels
if ( $cil->LabelStrict ) {
- my @labels = @{$self->Labels};
+ my @labels = @{$self->LabelList};
foreach my $label ( @labels ) {
unless ( exists $cil->LabelAllowed()->{$label} ) {
push @errors, "LabelStrict is turned on but this issue has an invalid label '$label'";
@@ -155,21 +159,51 @@ sub add_attachment {
$self->flag_as_updated();
}
-sub Labels {
+sub add_depends_on {
+ my ($self, $depends) = @_;
+
+ croak 'provide an issue name when adding a depends'
+ unless defined $depends;
+
+ push @{$self->{data}{DependsOn}}, $depends;
+ $self->flag_as_updated();
+}
+
+sub add_precedes {
+ my ($self, $precedes) = @_;
+
+ croak 'provide an issue name when adding a precedes'
+ unless defined $precedes;
+
+ push @{$self->{data}{Precedes}}, $precedes;
+ $self->flag_as_updated();
+}
+
+sub LabelList {
my ($self) = @_;
return $self->{data}{Label};
}
-sub Comments {
+sub CommentList {
my ($self) = @_;
return $self->{data}{Comment};
}
-sub Attachments {
+sub AttachmentList {
my ($self) = @_;
return $self->{data}{Attachment};
}
+sub DependsOnList {
+ my ($self) = @_;
+ return $self->{data}{DependsOn};
+}
+
+sub PrecedesList {
+ my ($self) = @_;
+ return $self->{data}{Precedes};
+}
+
sub is_open {
my ($self, $cil) = @_;