From f847c1b0ce7037890f74b011ab670320db170509 Mon Sep 17 00:00:00 2001 From: Andrew Chilton Date: Sat, 21 Jun 2008 12:53:05 +1200 Subject: [PATCH] Major structural updates to cil, it's data and layout. * change to save format - now like RFC822 * change to issue names - now the first 8 chars of an MD5 * added CIL.pm as a singleton class * made creation and parsing of issues easier and more generic * updated the 'cil' command line to reflect all of the above --- bin/cil | 79 ++++++++----------- issues/{i_1209992018.cil => i_02ee35bd.cil} | 0 issues/{i_1209990558.cil => i_5c88cb30.cil} | 0 issues/{i_1209991618.cil => i_6baa8555.cil} | 0 issues/{i_1209990028.cil => i_cbb43db9.cil} | 0 lib/CIL.pm | 87 +++++++++++++++++++++ lib/CIL/Issue.pm | 22 +++++- lib/CIL/Utils.pm | 22 +++++- 8 files changed, 156 insertions(+), 54 deletions(-) rename issues/{i_1209992018.cil => i_02ee35bd.cil} (100%) rename issues/{i_1209990558.cil => i_5c88cb30.cil} (100%) rename issues/{i_1209991618.cil => i_6baa8555.cil} (100%) rename issues/{i_1209990028.cil => i_cbb43db9.cil} (100%) create mode 100644 lib/CIL.pm diff --git a/bin/cil b/bin/cil index af6a9fc..d5d67e5 100755 --- a/bin/cil +++ b/bin/cil @@ -20,11 +20,14 @@ use strict; use warnings; +use Data::Dumper; + use Digest::MD5 qw(md5_hex); use File::Touch; use File::Glob ':glob'; use File::Basename; use Term::CallEditor qw(solicit); +use CIL; use CIL::Issue; use CIL::Comment; @@ -146,7 +149,7 @@ sub list { check_paths(); # find all the issues - my $issues = get_all_issues(); + my $issues = CIL->instance->get_issues(); if ( @$issues ) { separator(); foreach my $issue ( @$issues ) { @@ -163,20 +166,24 @@ sub summary { check_paths(); # find all the issues - my $issues = get_all_issues(); - separator(); - title('Summary'); - foreach my $issue ( @$issues ) { - display_issue_summary($issue); + my $issues = CIL->instance->get_issues(); + if ( @$issues ) { + separator(); + foreach my $issue ( @$issues ) { + display_issue_summary($issue); + } + separator(); + } + else { + msg('no issues found'); } - separator(); } sub show { my ($issue_name) = @_; # firstly, read the issue in - my $issue = CIL::Issue->new_load_issue($issue_name); + my $issue = CIL::Issue->load($issue_name); unless ( defined $issue ) { fatal("Couldn't load issue '$issue'"); } @@ -201,38 +208,20 @@ sub add { sub edit { my ($issue_name) = @_; - my $issue = CIL::Issue->new_load_issue($issue_name); + my $issue = CIL::Issue->load($issue_name); unless ( defined $issue ) { fatal("Couldn't load issue '$issue'"); } - my $summary = $issue->Summary; - my $status = $issue->Status; - my $created_by = $issue->CreatedBy; - my $assigned_to = $issue->AssignedTo; - my $label = $issue->Label; - my $description = $issue->Description; - # create the ini file, then edit it - my $edit_issue_text = <<"EOF"; -[Issue] - -Summary = $summary -Status = $status -CreatedBy = $created_by -AssignedTo = $assigned_to -Label = $label -Description = <as_output; # read in the new issue text - my $fh = solicit( $edit_issue_text ); + my $fh = solicit( join('', @$edit_issue_text) ); my $issue_edited; eval { - $issue_edited = CIL::Issue->new_parse_issue( $fh ); + $issue_edited = CIL::Issue->new_from_fh( $issue->name, $fh ); }; if ( $@ ) { fatal("couldn't parse issue: $@"); @@ -241,16 +230,8 @@ EOF fatal("couldn't create issue (program error)"); } - # for the fields we're interested in, set them - foreach my $field ( qw(Summary Status CreatedBy AssignedTo Labels Description) ) { - $issue->$field( $issue_edited->$field() ); - } - if ( $issue->changed ) { - $issue->save(); - } - else { - msg('Issue not changed'); - } + $issue_edited->save(); + display_issue_full( $issue_edited ); } sub comment { @@ -320,12 +301,10 @@ sub get_all_issues { sub display_issue_summary { my ($issue) = @_; - my $msg = $issue->Name; + my $msg = $issue->name; $msg .= "\t"; $msg .= $issue->Status; $msg .= "\t"; - $msg .= $issue->AssignedTo; - $msg .= "\t"; $msg .= $issue->Summary; msg($msg); @@ -334,28 +313,32 @@ sub display_issue_summary { sub display_issue_short { my ($issue) = @_; - title( "Issue " . $issue->Name ); + title( "Issue " . $issue->name ); field( 'Summary', $issue->Summary() ); - field( 'Name', $issue->Name() ); field( 'CreatedBy', $issue->CreatedBy() ); field( 'AssignedTo', $issue->AssignedTo() ); field( 'Inserted', $issue->Inserted() ); field( 'Status', $issue->Status() ); - field( 'Labels', $issue->Labels() ); + field( 'Labels', join(' ', @{$issue->Label()}) ); } sub display_issue_full { my ($issue) = @_; separator(); - title('Issue: ' . $issue->name); + title('Issue ' . $issue->name); field( 'Summary', $issue->Summary() ); field( 'Status', $issue->Status() ); field( 'CreatedBy', $issue->CreatedBy() ); field( 'AssignedTo', $issue->AssignedTo() ); field( 'Inserted', $issue->Inserted() ); field( 'Updated', $issue->Inserted() ); - field( 'Label', $issue->Label() ); + field( 'Label', $_ ) + foreach sort @{$issue->Label()}; + field( 'Comment', $_ ) + foreach sort @{$issue->Comment()}; + field( 'Attachment', $_ ) + foreach sort @{$issue->Attachment()}; separator(); text('Description', $issue->Description()); separator(); diff --git a/issues/i_1209992018.cil b/issues/i_02ee35bd.cil similarity index 100% rename from issues/i_1209992018.cil rename to issues/i_02ee35bd.cil diff --git a/issues/i_1209990558.cil b/issues/i_5c88cb30.cil similarity index 100% rename from issues/i_1209990558.cil rename to issues/i_5c88cb30.cil diff --git a/issues/i_1209991618.cil b/issues/i_6baa8555.cil similarity index 100% rename from issues/i_1209991618.cil rename to issues/i_6baa8555.cil diff --git a/issues/i_1209990028.cil b/issues/i_cbb43db9.cil similarity index 100% rename from issues/i_1209990028.cil rename to issues/i_cbb43db9.cil diff --git a/lib/CIL.pm b/lib/CIL.pm new file mode 100644 index 0000000..b697066 --- /dev/null +++ b/lib/CIL.pm @@ -0,0 +1,87 @@ +## ---------------------------------------------------------------------------- +# cil is a Command line Issue List +# Copyright (C) 2008 Andrew Chilton +# +# This file is part of 'cil'. +# +# cil is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +## ---------------------------------------------------------------------------- + +package CIL; + +use strict; +use warnings; +use File::Glob qw(:glob); + +use base qw(Class::Singleton Class::Accessor); +__PACKAGE__->mk_accessors(qw(issue_dir)); + +my $defaults = { + issue_dir => 'issues', +}; + +## ---------------------------------------------------------------------------- + +sub _new_instance { + my ($proto) = @_; + my $class = ref $proto || $proto; + my $self = bless {}, $class; + foreach my $key ( keys %$defaults ) { + $self->$key( $defaults->{$key} ); + } + return $self; +} + +sub set_config { + my ($self, $config) = @_; + + foreach my $key ( qw(issue_dir) ) { + $self->$key( $config->{$key} ) + if defined $config->{$key}; + } +} + +sub list_issues { + my ($self) = @_; + + my $globpath = $self->issue_dir . "/i_*.cil"; + my @filenames = bsd_glob($globpath); + + my @issues; + foreach my $filename ( sort @filenames ) { + my ($name) = $filename =~ m{/i_(.*)\.cil$}xms; + push @issues, { + name => $name, + filename => $filename, + }; + } + return \@issues; +} + +sub get_issues { + my ($self) = @_; + + my $issue_list = $self->list_issues(); + + my @issues; + foreach my $issue ( @$issue_list ) { + push @issues, CIL::Issue->load( $issue->{name} ); + } + return \@issues; +} + +## ---------------------------------------------------------------------------- +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Issue.pm b/lib/CIL/Issue.pm index 695210d..f19e621 100644 --- a/lib/CIL/Issue.pm +++ b/lib/CIL/Issue.pm @@ -27,12 +27,20 @@ use Carp; use Config::IniFiles; use YAML qw(LoadFile DumpFile); +use CIL; use CIL::Utils; use base qw(CIL::Base); __PACKAGE__->mk_accessors(qw(Summary Status AssignedTo Label Comment Attachment)); my @FIELDS = ( qw(Summary Status CreatedBy AssignedTo Label Comment Attachment Inserted Updated Description) ); +my $cfg = { + array => { + Label => 1, + Comment => 1, + Attachment => 1, + }, +}; ## ---------------------------------------------------------------------------- @@ -78,6 +86,11 @@ sub new_from_data { foreach my $field ( @FIELDS ) { next unless defined $data->{$field}; + # make it an array if it should be one + if ( exists $cfg->{array}{$field} and ref $data->{$field} ne 'ARRAY' ) { + $data->{$field} = [ $data->{$field} ]; + } + # modify the data directly, otherwise Updated will kick in $self->set_no_update($field, $data->{$field}); } @@ -143,7 +156,7 @@ sub load { croak 'provide an issue name to load' unless defined $name; - my $filename = "issues/$name.cil"; + my $filename = CIL->instance->issue_dir . "/i_$name.cil"; croak "filename '$filename' does no exist" unless -f $filename; @@ -153,10 +166,15 @@ sub load { return $issue; } +sub as_output { + my ($self) = @_; + return CIL::Utils->format_data_as_output( $self->{data}, @FIELDS ); +} + sub save { my ($self) = @_; my $name = $self->name; - my $filename = "issues/i_$name.cil"; + my $filename = CIL->instance->issue_dir . "/i_$name.cil"; CIL::Utils->write_cil_file( $filename, $self->{data}, @FIELDS ); } diff --git a/lib/CIL/Utils.pm b/lib/CIL/Utils.pm index c4841ae..b9cd689 100644 --- a/lib/CIL/Utils.pm +++ b/lib/CIL/Utils.pm @@ -71,17 +71,20 @@ sub parse_from_lines { return $data; } -sub write_cil_file { - my ($class, $filename, $data, @fields) = @_; +sub format_data_as_output { + my ($class, $data, @fields) = @_; + # we format the last field differently, so pop it off now my $last_field = pop @fields; my @lines; - foreach my $field ( @fields ) { next if $field eq $last_field; if ( ref $data->{$field} eq 'ARRAY' ) { + # don't output this field if there is nothing in it + next unless @{$data->{$field}}; + foreach ( sort @{$data->{$field}} ) { push @lines, "$field: $_\n"; } @@ -91,10 +94,21 @@ sub write_cil_file { } } + # finally, output the last field on it's own push @lines, "\n"; push @lines, $data->{$last_field}, "\n"; - write_file($filename, \@lines); + return \@lines; +} + +sub write_cil_file { + my ($class, $filename, $data, @fields) = @_; + + # get the output format + my $lines = $class->format_data_as_output($data, @fields); + + # ... and save + write_file($filename, $lines); } ## ---------------------------------------------------------------------------- -- 2.39.5