]> git.mjollnir.org Git - cil.git/commitdiff
Added the commands init, add and list
authorAndrew Chilton <andychilton@gmail.com>
Sat, 19 Apr 2008 09:57:45 +0000 (21:57 +1200)
committerAndrew Chilton <andychilton@gmail.com>
Sat, 19 Apr 2008 09:57:45 +0000 (21:57 +1200)
bin/cil
lib/CIL/Base.pm
lib/CIL/Issue.pm

diff --git a/bin/cil b/bin/cil
index 860efe92200d4f7b93aac10f64e9d2d940637e51..bc6c9dd36a961c941925c1153540f87c9a896de4 100755 (executable)
--- a/bin/cil
+++ b/bin/cil
@@ -6,24 +6,50 @@ use warnings;
 use Data::Dumper;
 use CIL::Issue;
 use Term::CallEditor;
+use File::Touch;
+use YAML;
+use File::Glob ':glob';
+use File::Basename;
 
 my $COMMANDS = {
+    init    => 1,
+    list    => 1,
     add     => 1,
     show    => 1,
-    comment => 1,
-    update  => 1
 };
 
+my $new_issue_text = <<"EOF";
+[Issue]
+
+Summary     =
+Status      =New
+CreatedBy   =$ENV{GIT_AUTHOR_NAME} <$ENV{GIT_AUTHOR_EMAIL}>
+Labels      =
+Description = <<END_OF_DESCRIPTION
+
+END_OF_DESCRIPTION
+EOF
+
 ## ----------------------------------------------------------------------------
 
 {
     my ($command) = shift;
     unless ( defined $command and exists $COMMANDS->{$command} ) {
         usage();
-        exit 2;
+        exit 1;
     }
 
-    if ( $command eq 'show' ) {
+    if ( $command eq 'init' ) {
+        my ($path) = @ARGV;
+        $path ||= '.';
+        init($path);
+    }
+    elsif ( $command eq 'list' ) {
+        my ($issue_name) = @ARGV;
+        list();
+
+    }
+    elsif ( $command eq 'show' ) {
         my ($issue_name) = @ARGV;
         show($issue_name);
 
@@ -34,24 +60,132 @@ my $COMMANDS = {
 
 }
 
+## ----------------------------------------------------------------------------
+# commands
+
+sub init {
+    my ($path) = @_;
+
+    # error if $path doesn't exist
+    unless ( -d $path ) {
+        fatal("path '$path' doesn't exist");
+    }
+
+    # error if issues/ already exists
+    my $issues_dir = "$path/issues";
+    if ( -d $issues_dir ) {
+        fatal("issues directory '$issues_dir' already exists, not initialising issues");
+    }
+
+    # error if .cil already exists
+    my $config = "$path/.cil";
+    if ( -f $config ) {
+        fatal("config file '$config' already exists, not initialising issues");
+    }
+
+    # try to create the issues/ dir
+    unless ( mkdir $issues_dir ) {
+        fatal("Couldn't create '$issues_dir' directory: $!");
+    }
+
+    # create a .cil file here also
+    unless ( touch $config ) {
+        rmdir $issues_dir;
+        fatal("couldn't create a '$config' file");
+    }
+
+    # $path/issues/ and $path/.cil create correctly
+    msg("initialised empty issue list inside '$path/'");
+}
+
+sub list {
+    check_paths();
+
+    my @issues;
+
+    # find all the issues
+    my @filenames = <issues/*.yaml>;
+    foreach my $filename ( sort @filenames ) {
+        push @issues, CIL::Issue->new_load_issue( basename($filename, '.yaml') );
+    }
+    @issues = sort { $a->Inserted cmp $b->Inserted } @issues;
+    separator();
+    foreach my $issue ( @issues ) {
+        display_issue_short($issue);
+    }
+    separator();
+}
+
 sub show {
     my ($issue_name) = @_;
 
     # firstly, read the issue in
-    my $issue = CIL::Issue->load_issue('2008-04-17T22:05:02.000Z');
-
+    my $issue = CIL::Issue->new_load_issue($issue_name);
     unless ( defined $issue ) {
         print STDERR "Couldn't load issue '$issue'\n";
         return;
     }
+    display_issue_full( $issue );
+}
+
+sub add {
+    my ($issue_name) = @_;
+
+    # read in the new issue text
+    my $fh = solicit( $new_issue_text );
+
+    my $issue;
+    eval {
+        $issue = CIL::Issue->new_parse_issue( $fh );
+    };
+    if ( $@ ) {
+        fatal("couldn't parse issue: $@");
+    }
+    unless ( defined $issue ) {
+        fatal("couldn't parse issue (program error)");
+    }
+
+    $issue->inserted;
+    $issue->set_no_update( 'Name', $issue->Inserted );
+    $issue->save();
+    display_issue_full( $issue );
+}
+
+## ----------------------------------------------------------------------------
+
+sub check_paths {
+    # make sure an issue directory is available
+    unless ( -d 'issues' ) {
+        fatal("couldn't find 'issues' directory");
+    }
+}
+
+## ----------------------------------------------------------------------------
+# input/output
+
+sub display_issue_short {
+    my ($issue) = @_;
+
+    title( "Issue " . $issue->Name );
+    field( 'Summary', $issue->Summary() );
+    field( 'Name', $issue->Name() );
+    field( 'CreatedBy', $issue->CreatedBy() );
+    field( 'Inserted', $issue->Inserted() );
+    field( 'Status', $issue->Status() );
+    field( 'Labels', $issue->Labels() );
+}
+
+sub display_issue_full {
+    my ($issue) = @_;
 
     separator();
     title('Details');
     field( 'Summary', $issue->Summary() );
     field( 'Name', $issue->Name() );
+    field( 'Status', $issue->Status() );
     field( 'CreatedBy', $issue->CreatedBy() );
     field( 'Inserted', $issue->Inserted() );
-    field( 'Status', $issue->Status() );
+    field( 'Updated', $issue->Inserted() );
     field( 'Labels', $issue->Labels() );
     separator();
     text('Description', $issue->Description());
@@ -60,62 +194,60 @@ sub show {
     separator();
 }
 
-sub add {
-    my ($issue_name) = @_;
-    my $fh = solicit('FOO: please replace this text');
-    die "$Term::CallEditor::errstr\n" unless $fh;
-    my $text;
-    $text .= $_ while <$fh>;
-    separator();
-    text('You said:', $text);
-    separator();
-}
-
-## ----------------------------------------------------------------------------
-
-sub usage {
-   print <<"END_USAGE";
-Usage: $0 <command> [options]
-
-Commands:
-   add
-   show    <issue>
-   comment <issue>
-   update  <issue>
-
-See <http://github.com/andychilton/cil/> for further information.
-Report bugs to <andychilton -at- gmail -dot- com>.
-END_USAGE
-}
-
-sub say {
-    print $_[0], "\n";
+sub msg {
+    print ( defined $_[0] ? $_[0] : '' );
+    print "\n";
 }
 
 sub separator {
-    say('=' x 79);
+    msg('=' x 79);
 }
 
 sub title {
     my ($title) = @_;
     my $msg = "--- $title ";
     $msg .= '-' x (74 - length($title));
-    say($msg);
+    msg($msg);
 }
 
 sub field {
     my ($field, $value) = @_;
     my $msg = "$field";
     $msg .= " " x (12 - length($field));
-    say("$msg: " . (defined $value ? $value : '') );
+    msg("$msg: " . (defined $value ? $value : '') );
 }
 
 sub text {
     my ($field, $value) = @_;
     title($field);
-    say "";
-    say($value);
-    say "";
+    msg "";
+    msg($value);
+    msg "";
+}
+
+sub fatal {
+    my ($msg) = @_;
+    chomp $msg;
+    print STDERR $msg, "\n";
+    exit 2;
+}
+
+## ----------------------------------------------------------------------------
+# program info
+
+sub usage {
+   print <<"END_USAGE";
+Usage: $0 <command> [options]
+
+Commands:
+   init    <path>
+   add
+   list
+   show    <issue>
+
+See <http://kapiti.geek.nz/software/cil.html> for further information.
+Report bugs to <andychilton -at- gmail -dot- com>.
+END_USAGE
 }
 
 ## ----------------------------------------------------------------------------
index a061d199f3f6d95fb48d3f5fc5dcd582201d8207..121d372ac0a0d124dcca151c1beacb58de14709c 100644 (file)
@@ -3,19 +3,59 @@ package CIL::Base;
 
 use strict;
 use warnings;
+use Carp;
 use DateTime;
 
 use base qw(Class::Accessor);
 __PACKAGE__->mk_accessors(qw(Description CreatedBy Inserted Updated));
 
+# override Class::Accessor's set
+sub set {
+    my ($self, $key, $value) = @_;
+    croak "provide a key name" unless defined $key;
+
+    my $orig = $self->get($key);
+
+    # get out if both are defined and they're the same
+    if ( defined $orig and defined $value ) {
+        return if $orig eq $value
+    }
+
+    # get out if neither are defined
+    if ( !defined $orig and !defined $value ) {
+        return;
+    }
+
+    # since we're actually changing the key, say we updated something
+    $self->{data}{$key} = $value;
+    $self->updated;
+}
+
+sub set_no_update {
+    my ($self, $key, $value) = @_;
+    croak "provide a key name" unless defined $key;
+    $self->{data}{$key} = $value;
+}
+
+# override Class::Accessor's get
+sub get {
+    my ($self, $key) = @_;
+    $self->{data}{$key};
+}
+
 sub inserted {
     my ($self) = @_;
-    $self->{Inserted} = DateTime->new()->iso8601;
+    my $time = time;
+    $self->{data}{Inserted} = $time;
+    $self->{data}{Updated} = $time;
+    $self->{Changed} = '1';
 }
 
 sub updated {
     my ($self) = @_;
-    $self->{Updated} = DateTime->new()->iso8601;
+    my $time = time;
+    $self->{data}{Updated} = $time;
+    $self->{Changed} = '1';
 }
 
 ## ----------------------------------------------------------------------------
index 6475983a556c887ea162d6bea55c3ff6c27ebf59..0fe4c8b51a30d9618ff7333cf5aa01b7f40159b9 100644 (file)
@@ -3,54 +3,93 @@ package CIL::Issue;
 
 use strict;
 use warnings;
+use Carp;
 use Data::Dumper;
 use Config::IniFiles;
+use YAML qw(LoadFile DumpFile);
 
 use base qw(CIL::Base);
 __PACKAGE__->mk_accessors(qw(Name Summary Status Labels Comments));
 
+my @ATTRS = ( qw(Name Summary Description CreatedBy Status Labels Comments) );
+
 ## ----------------------------------------------------------------------------
 
-sub load_issue {
-    my ($self, $name) = @_;
-    return unless defined $name;
+sub new {
+    my ($proto) = @_;
+    my $class = ref $proto || $proto;
+    my $self = {};
+    bless $self, $class;
+    $self->inserted;
+    return $self;
+}
+
+sub new_load_issue {
+    my ($class, $name) = @_;
 
-    my $filename = "issues/$name.ini";
+    unless ( defined $name ) {
+        croak "provide an issue name to load";
+    }
+
+    my $filename = "issues/$name.yaml";
+    unless ( -f $filename ) {
+        croak "filename '$filename' does no exist";
+    }
 
-    return unless -f $filename;
     my $issue = CIL::Issue->new();
-    $issue->read_issue( $filename );
-    $issue->Name( $name );
+    $issue->{data} = LoadFile( $filename );
     return $issue;
-}
-
-sub read_issue {
-    my ($self, $filename) = @_;
 
     my $cfg = Config::IniFiles->new( -file => $filename );
+    unless ( defined $cfg ) {
+        croak("not a valid inifile");
+    }
 
-    foreach my $attr ( qw(Summary Description) ) {
-         $self->{$attr} = $cfg->val( 'Issue', $attr );
+    # my $issue = CIL::Issue->new();
+    foreach my $attr ( qw(Summary Name Description CreatedBy Status Labels Inserted Updated) ) {
+        # modify the data directly, otherwise Updated will kick in
+        $issue->{data}{$attr} = $cfg->val( 'Issue', $attr );
     }
+    $issue->{data}{Comments}    = [];
+
+    # set the issue Name
+    $issue->{data}{Name} = $name;
+
+    return $issue;
 }
 
-sub reset {
-    my ($self) = @_;
+sub new_parse_issue {
+    my ($class, $file) = @_;
 
-    foreach my $attr ( qw(changed) ) {
-        delete $self->{$attr};
+    # $file may be a string ($filename) or a file handle ($fh)
+    my $cfg = Config::IniFiles->new( -file => $file );
+
+    unless ( defined $cfg ) {
+        croak("not a valid inifile");
+    }
+
+    my $issue = CIL::Issue->new();
+    foreach my $attr ( qw(Summary Name Description CreatedBy Status Labels Inserted Updated) ) {
+        # modify the data directly, otherwise Updated will kick in
+        $issue->set_no_update($attr, $cfg->val( 'Issue', $attr ));
     }
+    $issue->set_no_update('Comments', []);
+    return $issue;
 }
 
-sub inserted {
+sub save {
     my ($self) = @_;
-    $self->{data}{inserted} = time;
+    my $name = $self->Name;
+    my $filename = "issues/$name.yaml";
+    DumpFile($filename, $self->{data});
 }
 
-sub updated {
+sub reset {
     my ($self) = @_;
-    $self->{changed} = '1';
-    $self->{data}{updated} = time;
+
+    foreach my $attr ( @ATTRS ) {
+        delete $self->{$attr};
+    }
 }
 
 sub add_comment {