From 920815e5cc9d27bf25ca407026b66becf229a904 Mon Sep 17 00:00:00 2001 From: Andrew Chilton Date: Sat, 28 Jun 2008 11:51:14 +1200 Subject: [PATCH] Add the 'fsck' command along with relevant refactorings. --- bin/cil | 128 +++++++++++++++++++++++++++++++++++++++++- issues/c_81dc204c.cil | 9 +++ issues/i_c6a8d865.cil | 5 +- lib/CIL.pm | 56 +++++++++++++++--- lib/CIL/Base.pm | 6 +- lib/CIL/Issue.pm | 14 ++--- 6 files changed, 196 insertions(+), 22 deletions(-) create mode 100644 issues/c_81dc204c.cil diff --git a/bin/cil b/bin/cil index 4bc39fe..9e9604b 100755 --- a/bin/cil +++ b/bin/cil @@ -247,7 +247,7 @@ sub cmd_add { $edit = 'n'; } else { - print $issue->error(), "\n"; + msg($_) foreach @{ $issue->errors }; print 'Would you like to re-edit (y/n): '; $edit = ; chomp $edit; @@ -288,7 +288,7 @@ sub cmd_edit { $edit = 'n'; } else { - print $issue->error(), "\n"; + msg($_) foreach @{ $issue->errors }; print 'Would you like to re-edit (y/n): '; $edit = ; chomp $edit; @@ -333,7 +333,7 @@ sub cmd_comment { $edit = 'n'; } else { - print $comment->error(), "\n"; + msg($_) foreach @{ $issue->errors }; print 'Would you like to re-edit (y/n): '; $edit = ; chomp $edit; @@ -422,6 +422,128 @@ sub cmd_extract { write_file( $filename, $attachment->as_binary ); } +sub cmd_fsck { + my ($cil, $args) = @_; + + # this looks at all the issues it can find and checks for: + # * validity + # * all the comments are there + # * all the attachments are there + # then it checks each individual comment/attachment for: + # * ToDo: validity + # * it's parent exists + + check_paths($cil); + + # find all the issues, comments and attachments + my $issues = $cil->get_issues(); + my $issue = {}; + foreach my $i ( @$issues ) { + $issue->{$i->name} = $i; + } + my $comments = $cil->get_comments(); + my $comment = {}; + foreach my $c ( @$comments ) { + $comment->{$c->name} = $c; + } + my $attachments = $cil->get_attachments(); + my $attachment = {}; + foreach my $a ( @$attachments ) { + $attachment->{$a->name} = $a; + } + + my $errors = {}; + + if ( @$issues ) { + foreach my $i ( sort { $a->Inserted cmp $b->Inserted } @$issues ) { + my $name = $i->name; + + unless ( $i->is_valid($cil) ) { + foreach ( @{ $i->errors } ) { + push @{$errors->{$name}}, $_; + } + } + + # check that all it's comments are there and that they have this parent + my $comments = $i->Comments; + foreach my $c ( @$comments ) { + # see if this comment exists at all + if ( exists $comment->{$c} ) { + # check the parent is this issue + push @{$errors->{$name}}, "comment '$c' is listed under issue '" . $i->name . "' but does not reciprocate" + unless $comment->{$c}->Issue eq $i->name; + } + else { + push @{$errors->{$name}}, "comment '$c' listed in issue '" . $i->name . "' does not exist"; + } + } + + # check that all it's attachments are there and that they have this parent + my $attachments = $i->Attachments; + foreach my $a ( @$attachments ) { + # see if this attachment exists at all + if ( exists $attachment->{$a} ) { + # check the parent is this issue + push @{$errors->{$name}}, "attachment '$a' is listed under issue '" . $i->name . "' but does not reciprocate" + unless $attachment->{$a}->Issue eq $i->name; + } + else { + push @{$errors->{$name}}, "attachment '$a' listed in 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 + foreach my $c ( sort { $a->Inserted cmp $b->Inserted } @$comments ) { + # check that the parent of each comment exists + unless ( exists $issue->{$c->Issue} ) { + push @{$errors->{$c->name}}, "comment '" . $c->name . "' refers to issue '" . $c->Issue . "' but issue does not exist"; + } + } + } + + print_fsck_errors('Comment', $errors); + + # attachments + $errors = {}; + + # loop through all the attachments + if ( @$attachments ) { + # check that their parent issues exist + foreach my $a ( sort { $a->Inserted cmp $b->Inserted } @$attachments ) { + # check that the parent of each attachment exists + unless ( exists $issue->{$a->Issue} ) { + push @{$errors->{$a->name}}, "attachment '" . $a->name . "' refers to issue '" . $a->Issue . "' but issue does not exist"; + } + } + } + + print_fsck_errors('Attachment', $errors); + + # nothing more to do + separator(); +} + +sub print_fsck_errors { + my ($entity, $errors) = @_; + + separator(); + foreach my $issue_name ( keys %$errors ) { + title( "$entity $issue_name "); + foreach my $error ( @{$errors->{$issue_name}} ) { + msg("* $error"); + } + } +} + ## ---------------------------------------------------------------------------- sub check_paths { diff --git a/issues/c_81dc204c.cil b/issues/c_81dc204c.cil new file mode 100644 index 0000000..7d3b708 --- /dev/null +++ b/issues/c_81dc204c.cil @@ -0,0 +1,9 @@ +Issue: c6a8d865 +CreatedBy: Andrew Chilton +Inserted: 2008-06-27T23:39:55 +Updated: 2008-06-27T23:40:49 + +Added the command 'fsck'. Currently it works okay but it might need looking at +in the future for functionality and possible refactoring. + +Closing issue. diff --git a/issues/i_c6a8d865.cil b/issues/i_c6a8d865.cil index dfff588..9e46130 100644 --- a/issues/i_c6a8d865.cil +++ b/issues/i_c6a8d865.cil @@ -1,11 +1,12 @@ Summary: Add a 'fsck' command -Status: New +Status: Finished CreatedBy: Andrew Chilton AssignedTo: Andrew Chilton Label: Milestone-v0.3 Label: Type-Enhancement +Comment: 81dc204c Inserted: 2008-06-27T13:39:48 -Updated: 2008-06-27T23:27:54 +Updated: 2008-06-27T23:40:49 When we add issues and their comments and attachments, there is the possibility that you don't actually check in the correct files at the same time. This diff --git a/lib/CIL.pm b/lib/CIL.pm index 2a4f9d5..e2be890 100644 --- a/lib/CIL.pm +++ b/lib/CIL.pm @@ -58,21 +58,39 @@ sub new { return $self; } -sub list_issues { - my ($self) = @_; +sub list_entities { + my ($self, $prefix) = @_; - my $globpath = $self->IssueDir . "/i_*.cil"; + my $globpath = $self->IssueDir . "/${prefix}_*.cil"; my @filenames = bsd_glob($globpath); - my @issues; + my @entities; foreach my $filename ( sort @filenames ) { - my ($name) = $filename =~ m{/i_(.*)\.cil$}xms; - push @issues, { + my ($name) = $filename =~ m{/${prefix}_(.*)\.cil$}xms; + push @entities, { name => $name, filename => $filename, }; } - return \@issues; + return \@entities; +} + +sub list_issues { + my ($self) = @_; + + return $self->list_entities('i'); +} + +sub list_comments { + my ($self) = @_; + + return $self->list_entities('c'); +} + +sub list_attachments { + my ($self) = @_; + + return $self->list_entities('a'); } sub get_issues { @@ -87,6 +105,30 @@ sub get_issues { return \@issues; } +sub get_comments { + my ($self) = @_; + + my $comment_list = $self->list_comments(); + + my @comments; + foreach my $comment ( @$comment_list ) { + push @comments, CIL::Comment->new_from_name( $self, $comment->{name} ); + } + return \@comments; +} + +sub get_attachments { + my ($self) = @_; + + my $attachment_list = $self->list_attachments(); + + my @attachments; + foreach my $attachment ( @$attachment_list ) { + push @attachments, CIL::Attachment->new_from_name( $self, $attachment->{name} ); + } + return \@attachments; +} + sub get_comments_for { my ($self, $issue) = @_; diff --git a/lib/CIL/Base.pm b/lib/CIL/Base.pm index b08ebd8..f9b932f 100644 --- a/lib/CIL/Base.pm +++ b/lib/CIL/Base.pm @@ -215,12 +215,12 @@ sub name { return $self->{name}; } -sub error { +sub errors { my $self = shift; if( @_ ) { - $self->{error} = $_[0]; + $self->{errors} = $_[0]; } - return $self->{error}; + return $self->{errors}; } ## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Issue.pm b/lib/CIL/Issue.pm index 904a93b..d44626e 100644 --- a/lib/CIL/Issue.pm +++ b/lib/CIL/Issue.pm @@ -93,17 +93,17 @@ sub last_field { sub is_valid { my ($self, $cil) = @_; + my @errors; + # issues should have a Summary unless ( defined defined $self->Summary and length $self->Summary ) { - $self->error( 'You must provide a summary.' ); - return; + push @errors, 'Issue does not have a summary'; } # see if we only allow certain Statuses if ( $cil->StatusStrict ) { unless ( exists $cil->StatusAllowed()->{$self->Status} ) { - $self->error( "You have 'StatusStrict' turned on but this status (" . $self->Status . ") is not in the 'StatusAllowedList'" ); - return; + push @errors, "StatusStrict is turned on but this issue has an invalid status '" . $self->Status . "'"; } } @@ -112,13 +112,13 @@ sub is_valid { my @labels = @{$self->Labels}; foreach my $label ( @labels ) { unless ( exists $cil->LabelAllowed()->{$label} ) { - $self->error( "You have 'LabelStrict' turned on but this label ($label) is not in the 'LabelAllowedList'" ); - return; + push @errors, "LabelStrict is turned on but this issue has an invalid label '$label'"; } } } - return 1; + $self->errors( \@errors ); + return @errors ? 0 : 1; } sub add_label { -- 2.39.5