From 9fcb3bc29dfd429f521c4e40452197dc364310c3 Mon Sep 17 00:00:00 2001 From: Francois Marier Date: Thu, 5 Aug 2010 20:52:16 -0400 Subject: Imported Upstream version 0.07.00 --- .cil | 16 +- .gitignore | 2 - AUTHORS | 11 + Build.PL | 32 ++ Changes | 4 + INSTALLATION | 5 +- MANIFEST | 16 + MANIFEST.SKIP | 50 +++ Makefile | 13 + bin/cil | 1004 +++--------------------------------------- debian-etch/changelog | 69 +++ debian-etch/compat | 1 + debian-etch/control | 18 + debian-etch/copyright | 25 ++ debian-etch/docs | 1 + debian-etch/install | 3 + debian-etch/manpages | 1 + debian-etch/rules | 53 +++ debian-lenny/changelog | 69 +++ debian-lenny/compat | 1 + debian-lenny/control | 18 + debian-lenny/copyright | 25 ++ debian-lenny/docs | 1 + debian-lenny/install | 3 + debian-lenny/manpages | 1 + debian-lenny/rules | 53 +++ issues/c_02a9bb68.cil | 13 + issues/c_043f8971.cil | 6 + issues/c_06e0d28c.cil | 11 + issues/c_0ecf17ae.cil | 6 + issues/c_146b6b88.cil | 7 + issues/c_1d9e3911.cil | 12 + issues/c_2b92ef13.cil | 6 + issues/c_3da3fd2f.cil | 6 + issues/c_3f088351.cil | 6 + issues/c_45cd5e23.cil | 23 + issues/c_47223ac4.cil | 6 + issues/c_4b71d0c3.cil | 6 + issues/c_4d6c02bb.cil | 12 + issues/c_4edba98c.cil | 16 + issues/c_5fe9eaea.cil | 6 + issues/c_61aea66d.cil | 7 + issues/c_6287dc43.cil | 6 + issues/c_6f5bc459.cil | 18 + issues/c_70533ec8.cil | 7 + issues/c_792a4acf.cil | 6 + issues/c_7b75b82c.cil | 7 + issues/c_7eb313cd.cil | 11 + issues/c_7f22c24e.cil | 7 + issues/c_81dc204c.cil | 9 + issues/c_95e81a14.cil | 16 + issues/c_961f2658.cil | 6 + issues/c_a8edef8d.cil | 7 + issues/c_d49a551f.cil | 7 + issues/c_d6ee2369.cil | 22 + issues/c_d87e016d.cil | 14 + issues/c_d8dd779f.cil | 8 + issues/c_d98c9a37.cil | 6 + issues/c_da74ee18.cil | 6 + issues/c_e9cc10a9.cil | 9 + issues/c_f09a77f4.cil | 9 + issues/c_f8206d17.cil | 7 + issues/c_feb65ae7.cil | 9 + issues/i_02ee35bd.cil | 17 + issues/i_03c93e82.cil | 10 + issues/i_0e004cde.cil | 26 ++ issues/i_1111d724.cil | 10 + issues/i_1a5fb257.cil | 15 + issues/i_1bb8c18d.cil | 10 + issues/i_41b351fc.cil | 24 + issues/i_48eaec49.cil | 25 ++ issues/i_52d702df.cil | 11 + issues/i_574046f9.cil | 16 + issues/i_5c88cb30.cil | 31 ++ issues/i_5ec585b1.cil | 13 + issues/i_6b087805.cil | 13 + issues/i_6baa8555.cil | 17 + issues/i_768d9434.cil | 28 ++ issues/i_85eceee9.cil | 39 ++ issues/i_98203ce8.cil | 26 ++ issues/i_9890cf04.cil | 20 + issues/i_99d9dd74.cil | 31 ++ issues/i_9b0d3687.cil | 10 + issues/i_9b7f9096.cil | 10 + issues/i_a5b1eb37.cil | 27 ++ issues/i_a7e3b882.cil | 12 + issues/i_a90ad11f.cil | 24 + issues/i_b18c21e8.cil | 12 + issues/i_b19d5ada.cil | 24 + issues/i_b5a4ef93.cil | 38 ++ issues/i_b6033e30.cil | 15 + issues/i_b8061619.cil | 12 + issues/i_bf35f2c7.cil | 15 + issues/i_bf9badb4.cil | 23 + issues/i_c6a8d865.cil | 17 + issues/i_c77fae7c.cil | 22 + issues/i_c98515e2.cil | 33 ++ issues/i_cbb43db9.cil | 14 + issues/i_ce8053b0.cil | 17 + issues/i_d05969b6.cil | 13 + issues/i_d0b8bc09.cil | 15 + issues/i_d3ac4078.cil | 16 + issues/i_d4cd6efd.cil | 18 + issues/i_df9e14d6.cil | 11 + issues/i_f7ce705b.cil | 13 + issues/i_f8b44370.cil | 12 + issues/i_fb79b2e8.cil | 16 + lib/CIL.pm | 122 ++++- lib/CIL/Attachment.pm | 4 + lib/CIL/Base.pm | 19 +- lib/CIL/Command.pm | 17 + lib/CIL/Command/Add.pm | 65 +++ lib/CIL/Command/Am.pm | 140 ++++++ lib/CIL/Command/Attach.pm | 88 ++++ lib/CIL/Command/Comment.pm | 63 +++ lib/CIL/Command/DependsOn.pm | 61 +++ lib/CIL/Command/Edit.pm | 84 ++++ lib/CIL/Command/Extract.pm | 45 ++ lib/CIL/Command/Fsck.pm | 185 ++++++++ lib/CIL/Command/Init.pm | 108 +++++ lib/CIL/Command/Label.pm | 82 ++++ lib/CIL/Command/List.pm | 55 +++ lib/CIL/Command/Precedes.pm | 62 +++ lib/CIL/Command/Show.pm | 42 ++ lib/CIL/Command/Status.pm | 71 +++ lib/CIL/Command/Steal.pm | 59 +++ lib/CIL/Command/Summary.pm | 55 +++ lib/CIL/Command/Track.pm | 51 +++ lib/CIL/Command/Work.pm | 64 +++ lib/CIL/Comment.pm | 4 + lib/CIL/Git.pm | 139 ++++++ lib/CIL/Issue.pm | 30 +- lib/CIL/Utils.pm | 388 +++++++++++++++- ubuntu-jaunty/changelog | 69 +++ ubuntu-jaunty/compat | 1 + ubuntu-jaunty/control | 18 + ubuntu-jaunty/copyright | 25 ++ ubuntu-jaunty/docs | 1 + ubuntu-jaunty/install | 3 + ubuntu-jaunty/manpages | 1 + ubuntu-jaunty/rules | 53 +++ 141 files changed, 3939 insertions(+), 997 deletions(-) delete mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 Build.PL create mode 100644 MANIFEST create mode 100644 MANIFEST.SKIP create mode 100644 Makefile create mode 100644 debian-etch/changelog create mode 100644 debian-etch/compat create mode 100644 debian-etch/control create mode 100644 debian-etch/copyright create mode 100644 debian-etch/docs create mode 100644 debian-etch/install create mode 100644 debian-etch/manpages create mode 100755 debian-etch/rules create mode 100644 debian-lenny/changelog create mode 100644 debian-lenny/compat create mode 100644 debian-lenny/control create mode 100644 debian-lenny/copyright create mode 100644 debian-lenny/docs create mode 100644 debian-lenny/install create mode 100644 debian-lenny/manpages create mode 100755 debian-lenny/rules create mode 100644 issues/c_02a9bb68.cil create mode 100644 issues/c_043f8971.cil create mode 100644 issues/c_06e0d28c.cil create mode 100644 issues/c_0ecf17ae.cil create mode 100644 issues/c_146b6b88.cil create mode 100644 issues/c_1d9e3911.cil create mode 100644 issues/c_2b92ef13.cil create mode 100644 issues/c_3da3fd2f.cil create mode 100644 issues/c_3f088351.cil create mode 100644 issues/c_45cd5e23.cil create mode 100644 issues/c_47223ac4.cil create mode 100644 issues/c_4b71d0c3.cil create mode 100644 issues/c_4d6c02bb.cil create mode 100644 issues/c_4edba98c.cil create mode 100644 issues/c_5fe9eaea.cil create mode 100644 issues/c_61aea66d.cil create mode 100644 issues/c_6287dc43.cil create mode 100644 issues/c_6f5bc459.cil create mode 100644 issues/c_70533ec8.cil create mode 100644 issues/c_792a4acf.cil create mode 100644 issues/c_7b75b82c.cil create mode 100644 issues/c_7eb313cd.cil create mode 100644 issues/c_7f22c24e.cil create mode 100644 issues/c_81dc204c.cil create mode 100644 issues/c_95e81a14.cil create mode 100644 issues/c_961f2658.cil create mode 100644 issues/c_a8edef8d.cil create mode 100644 issues/c_d49a551f.cil create mode 100644 issues/c_d6ee2369.cil create mode 100644 issues/c_d87e016d.cil create mode 100644 issues/c_d8dd779f.cil create mode 100644 issues/c_d98c9a37.cil create mode 100644 issues/c_da74ee18.cil create mode 100644 issues/c_e9cc10a9.cil create mode 100644 issues/c_f09a77f4.cil create mode 100644 issues/c_f8206d17.cil create mode 100644 issues/c_feb65ae7.cil create mode 100644 issues/i_02ee35bd.cil create mode 100644 issues/i_03c93e82.cil create mode 100644 issues/i_0e004cde.cil create mode 100644 issues/i_1111d724.cil create mode 100644 issues/i_1a5fb257.cil create mode 100644 issues/i_1bb8c18d.cil create mode 100644 issues/i_41b351fc.cil create mode 100644 issues/i_48eaec49.cil create mode 100644 issues/i_52d702df.cil create mode 100644 issues/i_574046f9.cil create mode 100644 issues/i_5c88cb30.cil create mode 100644 issues/i_5ec585b1.cil create mode 100644 issues/i_6b087805.cil create mode 100644 issues/i_6baa8555.cil create mode 100644 issues/i_768d9434.cil create mode 100644 issues/i_85eceee9.cil create mode 100644 issues/i_98203ce8.cil create mode 100644 issues/i_9890cf04.cil create mode 100644 issues/i_99d9dd74.cil create mode 100644 issues/i_9b0d3687.cil create mode 100644 issues/i_9b7f9096.cil create mode 100644 issues/i_a5b1eb37.cil create mode 100644 issues/i_a7e3b882.cil create mode 100644 issues/i_a90ad11f.cil create mode 100644 issues/i_b18c21e8.cil create mode 100644 issues/i_b19d5ada.cil create mode 100644 issues/i_b5a4ef93.cil create mode 100644 issues/i_b6033e30.cil create mode 100644 issues/i_b8061619.cil create mode 100644 issues/i_bf35f2c7.cil create mode 100644 issues/i_bf9badb4.cil create mode 100644 issues/i_c6a8d865.cil create mode 100644 issues/i_c77fae7c.cil create mode 100644 issues/i_c98515e2.cil create mode 100644 issues/i_cbb43db9.cil create mode 100644 issues/i_ce8053b0.cil create mode 100644 issues/i_d05969b6.cil create mode 100644 issues/i_d0b8bc09.cil create mode 100644 issues/i_d3ac4078.cil create mode 100644 issues/i_d4cd6efd.cil create mode 100644 issues/i_df9e14d6.cil create mode 100644 issues/i_f7ce705b.cil create mode 100644 issues/i_f8b44370.cil create mode 100644 issues/i_fb79b2e8.cil create mode 100644 lib/CIL/Command.pm create mode 100644 lib/CIL/Command/Add.pm create mode 100644 lib/CIL/Command/Am.pm create mode 100644 lib/CIL/Command/Attach.pm create mode 100644 lib/CIL/Command/Comment.pm create mode 100644 lib/CIL/Command/DependsOn.pm create mode 100644 lib/CIL/Command/Edit.pm create mode 100644 lib/CIL/Command/Extract.pm create mode 100644 lib/CIL/Command/Fsck.pm create mode 100644 lib/CIL/Command/Init.pm create mode 100644 lib/CIL/Command/Label.pm create mode 100644 lib/CIL/Command/List.pm create mode 100644 lib/CIL/Command/Precedes.pm create mode 100644 lib/CIL/Command/Show.pm create mode 100644 lib/CIL/Command/Status.pm create mode 100644 lib/CIL/Command/Steal.pm create mode 100644 lib/CIL/Command/Summary.pm create mode 100644 lib/CIL/Command/Track.pm create mode 100644 lib/CIL/Command/Work.pm create mode 100644 lib/CIL/Git.pm create mode 100644 ubuntu-jaunty/changelog create mode 100644 ubuntu-jaunty/compat create mode 100644 ubuntu-jaunty/control create mode 100644 ubuntu-jaunty/copyright create mode 100644 ubuntu-jaunty/docs create mode 100644 ubuntu-jaunty/install create mode 100644 ubuntu-jaunty/manpages create mode 100755 ubuntu-jaunty/rules diff --git a/.cil b/.cil index 645e449..b8e42db 100644 --- a/.cil +++ b/.cil @@ -1,19 +1,14 @@ VCS: Git +UseGit: 1 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: Fixed StatusClosedList: OnHold StatusClosedList: Duplicate StatusClosedList: Finished +StatusClosedList: Cancelled LabelStrict: 1 LabelAllowedList: Release-v0.1.0 LabelAllowedList: Release-v0.2.0 @@ -22,6 +17,9 @@ LabelAllowedList: Release-v0.3.0 LabelAllowedList: Release-v0.4.0 LabelAllowedList: Release-v0.4.1 LabelAllowedList: Release-v0.4.2 +LabelAllowedList: Release-v0.5.0 +LabelAllowedList: Release-v0.5.1 +LabelAllowedList: Release-v0.06.00 LabelAllowedList: Type-Enhancement LabelAllowedList: Type-Defect LabelAllowedList: Type-Task @@ -33,6 +31,8 @@ LabelAllowedList: Milestone-v0.2 LabelAllowedList: Milestone-v0.3 LabelAllowedList: Milestone-v0.4 LabelAllowedList: Milestone-v0.5 +LabelAllowedList: Milestone-v0.06 +LabelAllowedList: Milestone-v0.07 LabelAllowedList: Milestone-Future LabelAllowedList: Priority-Critical LabelAllowedList: Priority-High diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 140fe6f..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*-stamp -cil.1 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..c048f90 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,11 @@ +Andrew Chilton +Andrew Ruthven +Brenda Wallace +Brian Smith +Francois Marier +Grant McLean +Nigel McNie +Pedro Melo +Penny Leach +Sam Vilain +Yanick Champoux diff --git a/Build.PL b/Build.PL new file mode 100644 index 0000000..7061afc --- /dev/null +++ b/Build.PL @@ -0,0 +1,32 @@ +use strict; +use warnings; +use Module::Build; + +my $builder = Module::Build->new( + module_name => 'CIL', + license => 'perl', + dist_author => 'Andrew Chilton ', + dist_version_from => 'lib/CIL.pm', + build_requires => { + 'Class::Accessor' => 0, + 'DateTime' => 0, + 'Digest::MD5' => 0, + 'Email::Date' => 0, + 'Email::Find' => 0, + 'Email::Simple' => 0, + 'Fcntl' => 0, + 'File::Basename' => 0, + 'File::Glob' => 0, + 'File::Slurp' => 0, + 'File::Spec' => 0, + 'File::Temp' => 0, + 'File::Touch' => 0, + 'Getopt::Mixed' => 0, + 'MIME::Base64' => 0, + 'Test::More' => 0, + }, + add_to_cleanup => [ 'CIL-*' ], + create_makefile_pl => 'traditional', +); + +$builder->create_build_script(); diff --git a/Changes b/Changes index beaf0a4..f22211c 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,7 @@ +0.6.0 (Unreleased) + + * New hook infrastructure, currently only 'issue_post_save' is allowed + 0.5.1 (2008-07-05) * New release minus all the cruft diff --git a/INSTALLATION b/INSTALLATION index ce3d02b..e79cd24 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -5,11 +5,11 @@ Dependencies Perl Modules: - * Term::CallEditor * File::Touch * File::Glob * File::Basename * MIME::Base64 + * Email::Find Some of these are distributed with perl itself but is left as an excercise to the reader to figure out what you need in your distribution (for Debian Etch, @@ -29,6 +29,7 @@ For Debian Etch, the following packages will need to be installed: * libfile-slurp-perl * libclass-accessor-perl * libdatetime-perl +* libfile-homedir-perl Out of the box, cil provides two debian directories depending on which version of Debian you wish to use. Currently, there isn't much difference but choose @@ -69,6 +70,6 @@ Then you can either run by: =============================================================================== -See http://kapiti.geek.nz/software/cil.html for further information. +See http://www.chilts.org/projects/cil/ for further information. =============================================================================== diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..525d8a0 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,16 @@ +bin/cil +Build.PL +Changes +COPYING +etc/bash_completion.d/cil +INSTALLATION +lib/CIL.pm +lib/CIL/Attachment.pm +lib/CIL/Base.pm +lib/CIL/Comment.pm +lib/CIL/Issue.pm +lib/CIL/Utils.pm +MANIFEST This list of files +README +t/00_files.t +t/i_cafebabe.cil diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP new file mode 100644 index 0000000..98fabec --- /dev/null +++ b/MANIFEST.SKIP @@ -0,0 +1,50 @@ +# Avoid version control files. +\bRCS\b +\bCVS\b +,v$ +\B\.svn\b +\B\.cvsignore$ + +# Avoid Makemaker generated and utility files. +\bMakefile$ +\bblib +\bMakeMaker-\d +\bpm_to_blib$ +\bblibdirs$ +^MANIFEST\.SKIP$ + +# Avoid Module::Build generated and utility files. +\bBuild$ +\bBuild.bat$ +\b_build + +# Avoid Devel::Cover generated files +\bcover_db + +# Avoid temp and backup files. +~$ +\.tmp$ +\.old$ +\.bak$ +\#$ +\.# +\.rej$ + +# Avoid OS-specific files/dirs +# Mac OSX metadata +\B\.DS_Store +# Mac OSX SMB mount metadata files +\B\._ +# Avoid archives of this distribution +\bCIL-[\d\.\_]+ + +# issues should not be part of the module +issues/ +.cil + +# exclude debian-* stuff +debian-\w+/ + +# git stuff +.git/ +.gitignore diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..27abede --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +open: + cil summary --is-open + +next-milestone: + cil summary --is-open --label=Milestone-v0.07 + +closed: + cil summary --is-closed + +clean: + find . -name '*~' -exec rm {} ';' + +.PHONY: issue-summary issue-list clean diff --git a/bin/cil b/bin/cil index 4ff4d32..a2b4131 100755 --- a/bin/cil +++ b/bin/cil @@ -21,7 +21,6 @@ use strict; use warnings; use Getopt::Mixed "nextOption"; -use Digest::MD5 qw(md5_hex); use File::Touch; use File::Glob ':glob'; use File::Basename; @@ -33,14 +32,11 @@ use CIL; use CIL::Issue; use CIL::Comment; use CIL::Attachment; +use CIL::Utils; ## ---------------------------------------------------------------------------- # constants -my $y = 'y'; - -use constant VERSION => '0.5.1'; - my @IN_OPTS = ( # strings 'p=s', # p = path @@ -55,12 +51,19 @@ my @IN_OPTS = ( 'created-by>c', # for 'summary', 'list' 'a=s', # a = assigned_to 'assigned-to>a',# for 'summary', 'list' + 'r=s', # r = revision + 'revision>s', # for all query commands # booleans 'bare', # for 'init' 'is-open', # for 'summary', 'list' 'is-closed', # for 'summary', 'list' 'is-mine', # for 'summary', 'list' + 'mine', # for 'add' + 'add', # for 'add', 'comment' + 'commit', # for 'add', 'comment' + 'batch', # for 'am' + 'remove', # for 'label' 'help', 'version', ); @@ -72,6 +75,11 @@ my %BOOLEAN_ARGS = ( 'is-open' => 1, 'is-closed' => 1, 'is-mine' => 1, + 'mine' => 1, + 'add' => 1, + 'commit' => 1, + 'batch' => 1, + 'remove' => 1, ); ## ---------------------------------------------------------------------------- @@ -82,7 +90,7 @@ my %BOOLEAN_ARGS = ( # do the version and help if ( exists $args->{version} ) { - print "cil version ".VERSION."\n"; + print "cil version " . $CIL::VERSION . "\n"; exit; } @@ -95,901 +103,31 @@ my %BOOLEAN_ARGS = ( Getopt::Mixed::abortMsg('specify a command') 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 $command_name = shift @ARGV; + my( $command ) = grep { $command_name eq $_->name } CIL->commands + or Getopt::Mixed::abortMsg("'$command_name' is not a valid cil command."); + # make a new $cil object my $cil = CIL->new(); - $cil->read_config_user(); - $cil->read_config_file(); - - &{"cmd_$command"}($cil, $args, @ARGV); -} - -## ---------------------------------------------------------------------------- -# commands - -sub cmd_init { - my ($cil, $args) = @_; - - my $path = $args->{p} || '.'; # default path is right here - - # 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 - if ( $args->{bare} ) { - unless ( touch $config ) { - rmdir $issues_dir; - fatal("couldn't create a '$config' file"); - } - } - else { - # write a default .cil file - write_file($config, <<'CONFIG'); -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 -CONFIG - } - - # add a README.txt so people know what this is about - unless ( -f "$issues_dir/README.txt" ) { - write_file("$issues_dir/README.txt", <<'README'); -This directory is used by CIL to track issues and feature requests. - -The home page for CIL is at http://kapiti.geek.nz/software/cil.html -README - } - - # $path/issues/ and $path/.cil create correctly - msg("initialised empty issue list inside '$path/'"); -} - -sub cmd_list { - my ($cil, $args) = @_; - - check_paths($cil); - - # find all the issues - my $issues = $cil->get_issues(); - $issues = filter_issues( $cil, $issues, $args ); - if ( @$issues ) { - foreach my $issue ( sort { $a->Inserted cmp $b->Inserted } @$issues ) { - separator(); - display_issue_headers($cil, $issue); - } - separator(); - } - else { - msg('no issues found'); - } -} - -sub cmd_summary { - my ($cil, $args) = @_; - - check_paths($cil); - - # find all the issues - my $issues = $cil->get_issues(); - $issues = filter_issues( $cil, $issues, $args ); - if ( @$issues ) { - separator(); - foreach my $issue ( @$issues ) { - display_issue_summary($cil, $issue); - } - separator(); - } - else { - msg('no issues found'); - } -} - -sub cmd_show { - my ($cil, undef, $issue_name) = @_; - - # firstly, read the issue in - my $issue = load_issue_fuzzy( $cil, $issue_name ); - display_issue_full($cil, $issue); -} - -sub cmd_status { - my ($cil, undef, $issue_name, $status) = @_; - - unless ( defined $status ) { - fatal("provide a status to set this issue to"); - } - - # firstly, read the issue in - my $issue = load_issue_fuzzy( $cil, $issue_name ); - - # set the status for this issue - $issue->Status( $status ); - $issue->save($cil); - - display_issue($cil, $issue); -} - -sub cmd_steal { - my ($cil, undef, $issue_name) = @_; - - # firstly, read the issue in - my $issue = load_issue_fuzzy( $cil, $issue_name ); - - # set the AssignedTo for this issue to you (because you're stealing it) - $issue->AssignedTo( user($cil) ); - $issue->save($cil); - - display_issue($cil, $issue); -} - -sub cmd_add { - my ($cil, undef, $issue_name) = @_; - - CIL::Utils->ensure_interactive(); - - my $user = user($cil); - - my $issue = CIL::Issue->new('tmpname'); - $issue->Status('New'); - $issue->CreatedBy( $user ); - $issue->Description("Description ..."); - - add_issue_loop($cil, undef, $issue); -} - -sub cmd_edit { - my ($cil, undef, $issue_name) = @_; - - my $issue = load_issue_fuzzy( $cil, $issue_name ); - - CIL::Utils->ensure_interactive(); - - 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( $issue->name, $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 ); - - # save it - $issue->save($cil); - display_issue($cil, $issue); -} - -sub cmd_comment { - my ($cil, undef, $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( user($cil) ); - $comment->Description("Description ..."); - - add_comment_loop($cil, undef, $issue, $comment); -} - -sub cmd_attach { - my ($cil, undef, $issue_name, $filename) = @_; - - my $issue = load_issue_fuzzy( $cil, $issue_name ); - - # check to see if the file exists - unless ( -r $filename ) { - fatal("couldn't read file '$filename'"); - } - - my $basename = basename( $filename ); - my $user = user($cil); - - my $add_attachment_text = <<"EOF"; -Filename : $basename -CreatedBy : $user - -File goes here ... this will be overwritten. -EOF - - # read in the new issue text - CIL::Utils->ensure_interactive(); - my $fh = CIL::Utils->solicit( $add_attachment_text ); - - my $attachment = CIL::Attachment->new_from_fh( 'tmp', $fh ); - unless ( defined $attachment ) { - fatal("could not create new attachment"); - } - - # now add the file itself - my $contents = read_file( $filename ); - $attachment->set_file_contents( $contents ); - - # set the size - my ($size) = (stat($filename))[7]; - $attachment->Size( $size ); - - # we've got the attachment, so let's name it - 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 - $attachment->Issue( $issue->name ); - $attachment->save($cil); - - # add the comment to the issue, update it's timestamp and save it out - $issue->add_attachment( $attachment ); - $issue->save($cil); - display_issue_full($cil, $issue); -} - -sub cmd_extract { - my ($cil, $args, $attachment_name) = @_; - - my $attachment = load_attachment_fuzzy($cil, $attachment_name); - - my $filename = $args->{f} || $attachment->Filename(); - write_file( $filename, $attachment->as_binary ); -} - -sub cmd_track { - my ($cil, $args, $issue_name) = @_; - - fatal("the 'VCS' option in your .cil file is not set") - unless defined $cil->VCS; - - fatal("the 'VCS' option currently only supports values of 'Git'") - unless $cil->VCS eq 'Git'; - - my $issue = load_issue_fuzzy($cil, $issue_name); - - # add the issue to Git - my $issue_dir = $cil->IssueDir(); - my @files; - push @files, "$issue_dir/i_" . $issue->name . '.cil'; - push @files, map { "$issue_dir/c_${_}.cil" } @{ $issue->CommentList }; - push @files, map { "$issue_dir/a_${_}.cil" } @{ $issue->AttachmentList }; - msg("git add @files"); -} - -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; - } - - # ------ - # issues - 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->CommentList; - 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->AttachmentList; - 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"; - } - } - - # 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 - 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 left - separator(); -} - -sub cmd_am { - my ($cil, $args, $email_filename) = @_; - - 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 ); + # for all commands (except init), we need to know we can see the proper paths + # (ie. issues/) + CIL::Utils->check_paths( $cil ) + unless $command_name eq 'init'; - # 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 = ; - 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) = @_; - - # make sure an issue directory is available - unless ( -d $cil->IssueDir ) { - fatal("couldn't find '" . $cil->IssueDir . "' directory"); - } -} - -sub filter_issues { - my ($cil, $issues, $args) = @_; - - # 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; - - # firstly, get out the Statuses we want - if ( defined $args->{s} ) { - @new_issues = grep { $_->Status eq $args->{s} } @new_issues; - } - - # then see if we want a particular label (could be a bit nicer) - if ( defined $args->{l} ) { - my @tmp; - foreach my $issue ( @new_issues ) { - push @tmp, $issue - if grep { $_ eq $args->{l} } @{$issue->LabelList}; - } - @new_issues = @tmp; - } - - # filter out dependent on open/closed - if ( defined $args->{'is-open'} ) { - # just get the open issues - @new_issues = grep { $_->is_open($cil) } @new_issues; - } - if ( defined $args->{'is-closed'} ) { - # just get the closed issues - @new_issues = grep { $_->is_closed($cil) } @new_issues; - } - - # filter out 'created by' - if ( defined $args->{c} ) { - @new_issues = grep { $args->{c} eq $_->created_by_email } @new_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; - } - - return \@new_issues; -} + $cil->read_config_user(); + $cil->read_config_file(); -sub print_fsck_errors { - my ($entity, $errors) = @_; - return unless keys %$errors; + # add any hooks we want + # none yet - separator(); - foreach my $issue_name ( keys %$errors ) { - title( "$entity $issue_name "); - foreach my $error ( @{$errors->{$issue_name}} ) { - msg("* $error"); - } - } + $command->run($cil, $args, @ARGV); } ## ---------------------------------------------------------------------------- -# input/output - -sub display_issue_summary { - my ($cil, $issue) = @_; - - my $msg = $issue->name(); - $msg .= "\t"; - $msg .= $issue->Status(); - $msg .= "\t"; - $msg .= $issue->Summary(); - - msg($msg); -} - -sub display_issue_headers { - my ($cil, $issue) = @_; - - title( 'Issue ' . $issue->name() ); - field( 'Summary', $issue->Summary() ); - field( 'CreatedBy', $issue->CreatedBy() ); - field( 'AssignedTo', $issue->AssignedTo() ); - field( 'Inserted', $issue->Inserted() ); - field( 'Status', $issue->Status() ); - field( 'Labels', join(' ', @{$issue->LabelList()}) ); - field( 'DependsOn', join(' ', @{$issue->DependsOnList()}) ); - field( 'Precedes', join(' ', @{$issue->PrecedesList()}) ); -} - -sub display_issue { - my ($cil, $issue) = @_; - - separator(); - title( 'Issue ' . $issue->name() ); - field( 'Summary', $issue->Summary() ); - field( 'Status', $issue->Status() ); - field( 'CreatedBy', $issue->CreatedBy() ); - field( 'AssignedTo', $issue->AssignedTo() ); - field( 'Label', $_ ) - foreach sort @{$issue->LabelList()}; - field( 'Comment', $_ ) - foreach sort @{$issue->CommentList()}; - field( '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()); - separator(); -} +# hooks -sub display_issue_full { - my ($cil, $issue) = @_; - - separator(); - title( 'Issue ' . $issue->name() ); - field( 'Summary', $issue->Summary() ); - field( 'Status', $issue->Status() ); - field( 'CreatedBy', $issue->CreatedBy() ); - 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 ) { - display_comment( $cil, $comment ); - } - - my $attachments = $cil->get_attachments_for( $issue ); - foreach my $attachment ( @$attachments ) { - 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 . '>'; -} +# none yet ## ---------------------------------------------------------------------------- # helper functions for this command line tool @@ -1020,48 +158,6 @@ sub get_options { return $args; } -sub msg { - print ( defined $_[0] ? $_[0] : '' ); - print "\n"; -} - -sub separator { - msg('=' x 79); -} - -sub title { - my ($title) = @_; - my $msg = "--- $title "; - $msg .= '-' x (74 - length($title)); - msg($msg); -} - -sub field { - my ($field, $value) = @_; - my $msg = "$field"; - $msg .= " " x (12 - length($field)); - msg("$msg: " . (defined $value ? $value : '') ); -} - -sub text { - my ($field, $value) = @_; - msg ""; - msg($value); - msg ""; -} - -sub err { - print STDERR ( defined $_[0] ? $_[0] : '' ); - print STDERR "\n"; -} - -sub fatal { - my ($msg) = @_; - chomp $msg; - print STDERR $msg, "\n"; - exit 2; -} - ## ---------------------------------------------------------------------------- # program info @@ -1075,13 +171,14 @@ Commands: summary [FILTERS...] list [FILTERS...] show ISSUE - status ISSUE NEW_STATUS + status NEW_STATUS [ISSUES...] + label NEW_LABEL [ISSUES...] steal ISSUE edit ISSUE comment ISSUE attach ISSUE FILENAME extract ATTACHMENT [--filename=FILENAME] - am EMAIL.TXT + am EMAIL.TXT [--batch] track ISSUE fsck @@ -1093,7 +190,7 @@ Filters: --assigned-to=? --is-mine -See for further information. +See for further information. Report bugs to . END_USAGE } @@ -1159,9 +256,13 @@ and Label fields. Shows each issue with more information. You may filter on both the Status and Label fields. -=item add +=item add [--mine] [summary] + +Adds an issues after you have edited the input. Text passed +after 'add' will be used as the bug summary line. -Adds an issues after you have edited the input. +If you use the --mine flag, the AssignedTo field is automatically set to you +(saves having to copy and paste the CreatedBy field). =item show ISSUE @@ -1256,7 +357,7 @@ C turned on. These check both C and C 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 +explicitly defined a status as being in both lists (for whatever reason you have). =item --assigned-to=EMAIL_ADDRESS, --is-mine @@ -1279,11 +380,8 @@ may be declared multiple times: The C<.cil> file is fairly simple and an example can be seen here: - VCS: Git + UseGit: 1 StatusStrict: 1 - StatusAllowedList: New - StatusAllowedList: InProgress - StatusAllowedList: Finished StatusOpenList: New StatusOpenList: InProgress StatusClosedList: Finished @@ -1296,12 +394,12 @@ The C<.cil> file is fairly simple and an example can be seen here: =over -=item VCS +=item UseGit -Default: empty, Type: Enum(Git) +Default: 0, Type: Boolean (0/1) -Currently this option only supports Git. This enables you to use the 'track' -command. +Determines whether to use Git or not. Some features require Git though Cil is +perfectly usable without. =item StatusStrict @@ -1311,13 +409,6 @@ If this is set to a true value then cil checks that the status you enter into an issue (after adding or editing) is also in the allowed list (see StatusAllowedList). -=item StatusAllowedList - -Default: empty, Type: List - -This list is checked against when adding or editing issues but only if you have -StatusStrict on. - =item StatusOpenList Default: empty, Type: List @@ -1330,6 +421,11 @@ Default: empty, Type: List This list is checked against when filtering with --is-closed. +=item StatusAllowedList + +This list is automatically generated from the StatusOpenList and the +StatusClosedList. It does not have to appear in the config file. + =item LabelStrict Default: 0, Type: Boolean (0/1) diff --git a/debian-etch/changelog b/debian-etch/changelog new file mode 100644 index 0000000..846e40d --- /dev/null +++ b/debian-etch/changelog @@ -0,0 +1,69 @@ +cil (0.5.1) unstable; urgency=low + + * New release minus all the cruft + + -- Andrew Chilton Sat, 05 Jul 2008 18:28:22 +1200 + +cil (0.5.0) unstable; urgency=low + + * Fix bug when running certain commands (inc. init) + * Added command 'steal' + * Added command 'track' + + -- Andrew Chilton Sat, 05 Jul 2008 15:36:22 +1200 + +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 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 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 Wed, 02 Jul 2008 23:12:20 +1200 + +cil (0.3.0) unstable; urgency=low + + * Added filters for the listing commands + * Added ability to read .cil config file + * Can now set which Statuses are valid + * Can set which Labels are valid + * Added 'fsck' command + * Added bash completion for options, commands and entities + * Ready for 0.3.0 release + + -- Andrew Chilton Sat, 28 Jun 2008 12:06:19 +1200 + +cil (0.2.1) unstable; urgency=low + + * Ready for 0.2.1 release + + -- Andrew Chilton Mon, 23 Jun 2008 22:32:18 +1200 + +cil (0.2.0) unstable; urgency=low + + * Ready for 0.2 release + + -- Andrew Chilton Sun, 22 Jun 2008 16:17:18 +1200 + +cil (0.1.0) unstable; urgency=low + + * Ready for 0.1 release + + -- Andrew Chilton Sun, 04 May 2008 16:17:17 +1200 diff --git a/debian-etch/compat b/debian-etch/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian-etch/compat @@ -0,0 +1 @@ +5 diff --git a/debian-etch/control b/debian-etch/control new file mode 100644 index 0000000..8042cb9 --- /dev/null +++ b/debian-etch/control @@ -0,0 +1,18 @@ +Source: cil +Section: perl +Priority: extra +Maintainer: Andrew Chilton +Uploaders: Andrew Chilton +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 5) +Build-Depends-Indep: perl + +Package: cil +Section: perl +Priority: extra +Architecture: all +Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl, libemail-date-perl, libfile-homedir-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 + be added, edited and listed easily. diff --git a/debian-etch/copyright b/debian-etch/copyright new file mode 100644 index 0000000..57ddd5f --- /dev/null +++ b/debian-etch/copyright @@ -0,0 +1,25 @@ +This package was debianized by Andrew Chilton on +Sun, 22 Jun 2008 17:48:00 +1200 + +Upstream Author: Andrew Chilton + +Copyright: (C) 2008 Andrew Chilton + +License: + + 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 . + +You are free to distribute this software under the terms of the GNU General +Public License. On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL file. diff --git a/debian-etch/docs b/debian-etch/docs new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/debian-etch/docs @@ -0,0 +1 @@ +README diff --git a/debian-etch/install b/debian-etch/install new file mode 100644 index 0000000..dc23abd --- /dev/null +++ b/debian-etch/install @@ -0,0 +1,3 @@ +lib/* usr/share/perl5 +bin/cil usr/bin +etc/bash_completion.d/cil etc/bash_completion.d diff --git a/debian-etch/manpages b/debian-etch/manpages new file mode 100644 index 0000000..866347b --- /dev/null +++ b/debian-etch/manpages @@ -0,0 +1 @@ +cil.1 diff --git a/debian-etch/rules b/debian-etch/rules new file mode 100755 index 0000000..c886698 --- /dev/null +++ b/debian-etch/rules @@ -0,0 +1,53 @@ +#!/usr/bin/make -f +## ---------------------------------------------------------------------------- + +## ---------------------------------------------------------------------------- +## uncomment this to turn on verbose mode + +# export DH_VERBOSE=1 + +## ---------------------------------------------------------------------------- + +clean: + dh_testdir + dh_testroot + rm -f build-stamp install-stamp + [ ! -f Makefile ] || $(MAKE) clean + rm -f $(CURDIR)/cil.1 + dh_clean + +build: build-stamp +build-stamp: + dh_testdir + [ ! -f Makefile ] || $(MAKE) + echo Doing MAN... + pod2man $(CURDIR)/bin/cil > $(CURDIR)/cil.1 + touch build-stamp + +binary: + dh_testdir + dh_testroot + + dh_install + dh_installdirs + dh_installdocs + dh_installdebconf + dh_installman + dh_installchangelogs Changes + dh_compress + dh_fixperms + dh_installdeb + + dh_perl + + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-arch: + +binary: binary-indep binary-arch + +.PHONY: clean install binary-indep binary-arch binary + +## ---------------------------------------------------------------------------- diff --git a/debian-lenny/changelog b/debian-lenny/changelog new file mode 100644 index 0000000..846e40d --- /dev/null +++ b/debian-lenny/changelog @@ -0,0 +1,69 @@ +cil (0.5.1) unstable; urgency=low + + * New release minus all the cruft + + -- Andrew Chilton Sat, 05 Jul 2008 18:28:22 +1200 + +cil (0.5.0) unstable; urgency=low + + * Fix bug when running certain commands (inc. init) + * Added command 'steal' + * Added command 'track' + + -- Andrew Chilton Sat, 05 Jul 2008 15:36:22 +1200 + +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 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 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 Wed, 02 Jul 2008 23:12:20 +1200 + +cil (0.3.0) unstable; urgency=low + + * Added filters for the listing commands + * Added ability to read .cil config file + * Can now set which Statuses are valid + * Can set which Labels are valid + * Added 'fsck' command + * Added bash completion for options, commands and entities + * Ready for 0.3.0 release + + -- Andrew Chilton Sat, 28 Jun 2008 12:06:19 +1200 + +cil (0.2.1) unstable; urgency=low + + * Ready for 0.2.1 release + + -- Andrew Chilton Mon, 23 Jun 2008 22:32:18 +1200 + +cil (0.2.0) unstable; urgency=low + + * Ready for 0.2 release + + -- Andrew Chilton Sun, 22 Jun 2008 16:17:18 +1200 + +cil (0.1.0) unstable; urgency=low + + * Ready for 0.1 release + + -- Andrew Chilton Sun, 04 May 2008 16:17:17 +1200 diff --git a/debian-lenny/compat b/debian-lenny/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian-lenny/compat @@ -0,0 +1 @@ +7 diff --git a/debian-lenny/control b/debian-lenny/control new file mode 100644 index 0000000..8042cb9 --- /dev/null +++ b/debian-lenny/control @@ -0,0 +1,18 @@ +Source: cil +Section: perl +Priority: extra +Maintainer: Andrew Chilton +Uploaders: Andrew Chilton +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 5) +Build-Depends-Indep: perl + +Package: cil +Section: perl +Priority: extra +Architecture: all +Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl, libemail-date-perl, libfile-homedir-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 + be added, edited and listed easily. diff --git a/debian-lenny/copyright b/debian-lenny/copyright new file mode 100644 index 0000000..57ddd5f --- /dev/null +++ b/debian-lenny/copyright @@ -0,0 +1,25 @@ +This package was debianized by Andrew Chilton on +Sun, 22 Jun 2008 17:48:00 +1200 + +Upstream Author: Andrew Chilton + +Copyright: (C) 2008 Andrew Chilton + +License: + + 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 . + +You are free to distribute this software under the terms of the GNU General +Public License. On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL file. diff --git a/debian-lenny/docs b/debian-lenny/docs new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/debian-lenny/docs @@ -0,0 +1 @@ +README diff --git a/debian-lenny/install b/debian-lenny/install new file mode 100644 index 0000000..dc23abd --- /dev/null +++ b/debian-lenny/install @@ -0,0 +1,3 @@ +lib/* usr/share/perl5 +bin/cil usr/bin +etc/bash_completion.d/cil etc/bash_completion.d diff --git a/debian-lenny/manpages b/debian-lenny/manpages new file mode 100644 index 0000000..866347b --- /dev/null +++ b/debian-lenny/manpages @@ -0,0 +1 @@ +cil.1 diff --git a/debian-lenny/rules b/debian-lenny/rules new file mode 100755 index 0000000..c886698 --- /dev/null +++ b/debian-lenny/rules @@ -0,0 +1,53 @@ +#!/usr/bin/make -f +## ---------------------------------------------------------------------------- + +## ---------------------------------------------------------------------------- +## uncomment this to turn on verbose mode + +# export DH_VERBOSE=1 + +## ---------------------------------------------------------------------------- + +clean: + dh_testdir + dh_testroot + rm -f build-stamp install-stamp + [ ! -f Makefile ] || $(MAKE) clean + rm -f $(CURDIR)/cil.1 + dh_clean + +build: build-stamp +build-stamp: + dh_testdir + [ ! -f Makefile ] || $(MAKE) + echo Doing MAN... + pod2man $(CURDIR)/bin/cil > $(CURDIR)/cil.1 + touch build-stamp + +binary: + dh_testdir + dh_testroot + + dh_install + dh_installdirs + dh_installdocs + dh_installdebconf + dh_installman + dh_installchangelogs Changes + dh_compress + dh_fixperms + dh_installdeb + + dh_perl + + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-arch: + +binary: binary-indep binary-arch + +.PHONY: clean install binary-indep binary-arch binary + +## ---------------------------------------------------------------------------- diff --git a/issues/c_02a9bb68.cil b/issues/c_02a9bb68.cil new file mode 100644 index 0000000..554d4a3 --- /dev/null +++ b/issues/c_02a9bb68.cil @@ -0,0 +1,13 @@ +Issue: 85eceee9 +CreatedBy: Andrew Chilton +Inserted: 2008-06-27T13:18:47 +Updated: 2008-06-27T13:20:01 + +Added the --created-by and --assigned-to filters. + +These work just on the email address and not the whole field. E.g. + + $ cil list --created-by=andy@example.com + $ cil list --assigned-to=andy@example.org + +The short options for these are -c and -a. diff --git a/issues/c_043f8971.cil b/issues/c_043f8971.cil new file mode 100644 index 0000000..d317428 --- /dev/null +++ b/issues/c_043f8971.cil @@ -0,0 +1,6 @@ +Issue: 5ec585b1 +CreatedBy: Andrew Chilton +Inserted: 2010-01-23T06:37:08 +Updated: 2010-01-23T06:37:20 + +Now done. Should remove the correct label specified. 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 +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_0ecf17ae.cil b/issues/c_0ecf17ae.cil new file mode 100644 index 0000000..fd0cdc7 --- /dev/null +++ b/issues/c_0ecf17ae.cil @@ -0,0 +1,6 @@ +Issue: d3ac4078 +CreatedBy: Andrew Chilton +Inserted: 2010-02-08T19:07:54 +Updated: 2010-02-08T19:07:54 + +I'll make it an option for the project .cil file. diff --git a/issues/c_146b6b88.cil b/issues/c_146b6b88.cil new file mode 100644 index 0000000..4b4c18e --- /dev/null +++ b/issues/c_146b6b88.cil @@ -0,0 +1,7 @@ +Issue: 1a5fb257 +CreatedBy: Andrew Chilton +Inserted: 2010-01-24T11:14:08 +Updated: 2010-01-24T11:14:40 + +Before even doing this issue, the 'depends-on' was being mapped to +'depends_on', so that has also been fixed. diff --git a/issues/c_1d9e3911.cil b/issues/c_1d9e3911.cil new file mode 100644 index 0000000..58cc7e1 --- /dev/null +++ b/issues/c_1d9e3911.cil @@ -0,0 +1,12 @@ +Issue: f7ce705b +CreatedBy: Andrew Chilton +Inserted: 2010-01-25T01:31:35 +Updated: 2010-01-25T01:31:35 + +Checks the DependsOn and Precedes so it checks first before adding the other +issue. + +Also, since flag_as_updated() wasn't doing the Updated time, now calls +set_updated_now(). + +Finally, set_no_update() changed to be more sane. diff --git a/issues/c_2b92ef13.cil b/issues/c_2b92ef13.cil new file mode 100644 index 0000000..ba1f86d --- /dev/null +++ b/issues/c_2b92ef13.cil @@ -0,0 +1,6 @@ +Issue: cbb43db9 +CreatedBy: Andrew Chilton +Inserted: 2008-06-22T03:54:13 +Updated: 2008-06-22T03:54:13 + +This has been now been completed and will be released in cil v0.2. diff --git a/issues/c_3da3fd2f.cil b/issues/c_3da3fd2f.cil new file mode 100644 index 0000000..323073e --- /dev/null +++ b/issues/c_3da3fd2f.cil @@ -0,0 +1,6 @@ +Issue: 6b087805 +CreatedBy: Andrew Chilton +Inserted: 2008-07-03T11:15:33 +Updated: 2008-07-03T11:16:26 + +Done. Pretty easy eh! 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 +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 +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_47223ac4.cil b/issues/c_47223ac4.cil new file mode 100644 index 0000000..991e0d4 --- /dev/null +++ b/issues/c_47223ac4.cil @@ -0,0 +1,6 @@ +Issue: 1111d724 +CreatedBy: Andrew Chilton +Inserted: 2010-01-24T20:51:47 +Updated: 2010-01-24T20:52:03 + +libfile-homedir-perl added to the relevant places. diff --git a/issues/c_4b71d0c3.cil b/issues/c_4b71d0c3.cil new file mode 100644 index 0000000..fdba844 --- /dev/null +++ b/issues/c_4b71d0c3.cil @@ -0,0 +1,6 @@ +Issue: 85eceee9 +CreatedBy: Andrew Chilton +Inserted: 2008-06-27T12:40:51 +Updated: 2008-06-27T12:40:51 + +Now added --is-open and --is-closed. 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 +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_4edba98c.cil b/issues/c_4edba98c.cil new file mode 100644 index 0000000..c58c7ed --- /dev/null +++ b/issues/c_4edba98c.cil @@ -0,0 +1,16 @@ +Issue: 6baa8555 +CreatedBy: Andrew Chilton +Inserted: 2008-06-26T12:11:09 +Updated: 2008-06-26T12:12:41 + +Added the following options: + +* StatusStrict +* StatusAllowedList +* StatusOpenList +* StatusClosedList + +* LabelStrict +* LabelAllowedList + +The lists are only checked if the strict variables are on. diff --git a/issues/c_5fe9eaea.cil b/issues/c_5fe9eaea.cil new file mode 100644 index 0000000..4f42821 --- /dev/null +++ b/issues/c_5fe9eaea.cil @@ -0,0 +1,6 @@ +Issue: d0b8bc09 +CreatedBy: Andrew Chilton +Inserted: 2010-01-23T12:42:07 +Updated: 2010-01-23T12:42:17 + +All tabs and whitespace formatting tidied-up. 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 +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 +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 +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_70533ec8.cil b/issues/c_70533ec8.cil new file mode 100644 index 0000000..bca6d44 --- /dev/null +++ b/issues/c_70533ec8.cil @@ -0,0 +1,7 @@ +Issue: 768d9434 +CreatedBy: Andrew Chilton +Inserted: 2008-07-05T03:08:49 +Updated: 2008-07-05T03:09:11 + +Done. For now it just loops through the comments and attachments, though there +is no checking done. diff --git a/issues/c_792a4acf.cil b/issues/c_792a4acf.cil new file mode 100644 index 0000000..c22f3f4 --- /dev/null +++ b/issues/c_792a4acf.cil @@ -0,0 +1,6 @@ +Issue: fb79b2e8 +CreatedBy: Andrew Chilton +Inserted: 2008-06-22T04:02:46 +Updated: 2008-06-22T04:02:46 + +This has been completed. diff --git a/issues/c_7b75b82c.cil b/issues/c_7b75b82c.cil new file mode 100644 index 0000000..a95c0ed --- /dev/null +++ b/issues/c_7b75b82c.cil @@ -0,0 +1,7 @@ +Issue: 41b351fc +CreatedBy: Andrew Chilton +Inserted: 2008-07-13T10:29:22 +Updated: 2008-07-13T10:30:58 + +Added the initial go at the hook system. It seems to work but until we actually +do some, it'll just be a framework for the time being. diff --git a/issues/c_7eb313cd.cil b/issues/c_7eb313cd.cil new file mode 100644 index 0000000..8d97144 --- /dev/null +++ b/issues/c_7eb313cd.cil @@ -0,0 +1,11 @@ +Issue: 85eceee9 +CreatedBy: Andrew Chilton +Inserted: 2008-06-23T12:07:44 +Updated: 2008-06-23T12:07:44 + +Added both --status and --label. + +In the case of Status, it tests for equality. + +In the case of Label, it tests that the issue has at least one label of the one +specified. 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 +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_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/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 +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_961f2658.cil b/issues/c_961f2658.cil new file mode 100644 index 0000000..a7a2f35 --- /dev/null +++ b/issues/c_961f2658.cil @@ -0,0 +1,6 @@ +Issue: df9e14d6 +CreatedBy: Andrew Chilton +Inserted: 2010-01-23T06:44:34 +Updated: 2010-01-23T06:44:49 + +This whole area is a bit of a mess and needs a little clearing up. diff --git a/issues/c_a8edef8d.cil b/issues/c_a8edef8d.cil new file mode 100644 index 0000000..d395555 --- /dev/null +++ b/issues/c_a8edef8d.cil @@ -0,0 +1,7 @@ +Issue: a90ad11f +CreatedBy: Andrew Chilton +Inserted: 2008-07-03T10:48:45 +Updated: 2008-07-03T10:49:42 + +Added a default .cil file when creating a repo. Also allows the '--bare' option +so that advanced users can do what they like. diff --git a/issues/c_d49a551f.cil b/issues/c_d49a551f.cil new file mode 100644 index 0000000..35f2232 --- /dev/null +++ b/issues/c_d49a551f.cil @@ -0,0 +1,7 @@ +Issue: 52d702df +CreatedBy: Andrew Chilton +Inserted: 2010-01-24T10:55:41 +Updated: 2010-01-24T10:56:09 + +Hopefully I got everything. Removed from a number of places and changed in the +main cil manpage. 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 +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 +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_d8dd779f.cil b/issues/c_d8dd779f.cil new file mode 100644 index 0000000..f18b4e9 --- /dev/null +++ b/issues/c_d8dd779f.cil @@ -0,0 +1,8 @@ +Issue: 5c88cb30 +CreatedBy: Andrew Chilton +Inserted: 2008-06-23T12:36:04 +Updated: 2008-06-23T12:36:04 + +Closing this issue as WontFix since the current solution is good (ie. the 8 +char hex number). Will reopen if demand says so and I'll try and get a patch +off whoever wants it :-) diff --git a/issues/c_d98c9a37.cil b/issues/c_d98c9a37.cil new file mode 100644 index 0000000..6893a10 --- /dev/null +++ b/issues/c_d98c9a37.cil @@ -0,0 +1,6 @@ +Issue: b5a4ef93 +CreatedBy: Andrew Chilton +Inserted: 2010-01-22T02:11:30 +Updated: 2010-01-22T02:11:48 + +Added the code for --add and --commit for 'comment'. diff --git a/issues/c_da74ee18.cil b/issues/c_da74ee18.cil new file mode 100644 index 0000000..00d3fa7 --- /dev/null +++ b/issues/c_da74ee18.cil @@ -0,0 +1,6 @@ +Issue: b5a4ef93 +CreatedBy: Andrew Chilton +Inserted: 2010-01-22T02:07:31 +Updated: 2010-01-22T02:07:47 + +Added the code for --commit and --add for 'add'. diff --git a/issues/c_e9cc10a9.cil b/issues/c_e9cc10a9.cil new file mode 100644 index 0000000..b6d8839 --- /dev/null +++ b/issues/c_e9cc10a9.cil @@ -0,0 +1,9 @@ +Issue: 85eceee9 +CreatedBy: Andrew Chilton +Inserted: 2008-06-27T13:30:08 +Updated: 2008-06-27T13:30:45 + +Not going to do --has-comments or --has-attachments until someone says that +it's actually useful. + +Closing this but as finished. 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 +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/c_f8206d17.cil b/issues/c_f8206d17.cil new file mode 100644 index 0000000..669c425 --- /dev/null +++ b/issues/c_f8206d17.cil @@ -0,0 +1,7 @@ +Issue: b18c21e8 +CreatedBy: Andrew Chilton +Inserted: 2010-01-23T12:36:20 +Updated: 2010-01-23T12:36:40 + +This issue needs to be cancelled since it's just sitting there and doing +nothing. diff --git a/issues/c_feb65ae7.cil b/issues/c_feb65ae7.cil new file mode 100644 index 0000000..d4e89f3 --- /dev/null +++ b/issues/c_feb65ae7.cil @@ -0,0 +1,9 @@ +Issue: 5c88cb30 +CreatedBy: Andrew Chilton +Inserted: 2008-06-21T10:57:47 +Updated: 2008-06-21T10:57:47 + +Currently I'm adding the ability for each issue name, comment etc to start with +the first 8 hex chars of an MD5 string from the data itself. Therefore, the +main problem with having the epoch and possible duplication goes away. This +issue can then be given a low priority. diff --git a/issues/i_02ee35bd.cil b/issues/i_02ee35bd.cil new file mode 100644 index 0000000..298e0fa --- /dev/null +++ b/issues/i_02ee35bd.cil @@ -0,0 +1,17 @@ +Summary: Labels should be allowed to have a 'required' set +Status: Duplicate +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Priority-Medium +Label: Release-v0.1.0 +Label: Type-Enhancement +Comment: 61aea66d +Inserted: 2008-05-05T12:53:38 +Updated: 2008-06-28T11:31:35 + +In the .cil config file, there should a field which determines a +'required' set of labels. + +e.g. + +required_labels=against type priority diff --git a/issues/i_03c93e82.cil b/issues/i_03c93e82.cil new file mode 100644 index 0000000..c81a4da --- /dev/null +++ b/issues/i_03c93e82.cil @@ -0,0 +1,10 @@ +Summary: Remove the whole VCS.pm stuff, just have a Git.pm at the top level +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Inserted: 2010-01-24T10:17:18 +Updated: 2010-01-25T09:55:05 + +No-one is going to use cil with anything other than Git (well, maybe not using +Git at all) so remove all the abstract stuff that isn't needed. diff --git a/issues/i_0e004cde.cil b/issues/i_0e004cde.cil new file mode 100644 index 0000000..096c74d --- /dev/null +++ b/issues/i_0e004cde.cil @@ -0,0 +1,26 @@ +Summary: cil idea: poor man's cilweb +Status: New +CreatedBy: Francois Marier +AssignedTo: Andrew Chilton +Inserted: 2008-07-06T20:08:52 +Updated: 2008-07-13T05:13:33 + +Hey Andy, + +I was gonna refer to one of my issues using Gitorious' gitweb-like interface +and then I thought: wait, cil could easily generate an index.html! + +So how about this: in addition to a README.txt file, the issues directory +could also have an index.html file which you'd update: + +1- whenever you add/edit an issue using the cil command +2- whenever you ask for it explicitely (kinda like git-update-server-info) + or a hook does it before pushing the underlying git repo + +The index file would contain the output of "cil summary", with relative +links to the issues themselves. + +That way, you can link to that file in your gitweb install and call it your +issue tracker! + +Francois diff --git a/issues/i_1111d724.cil b/issues/i_1111d724.cil new file mode 100644 index 0000000..258cb3b --- /dev/null +++ b/issues/i_1111d724.cil @@ -0,0 +1,10 @@ +Summary: Make sure libfile-homedir-perl is in Debian packaging +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Comment: 47223ac4 +Inserted: 2010-01-23T13:17:50 +Updated: 2010-01-24T20:52:13 + +This also needs to be added to the INSTALLATION file. diff --git a/issues/i_1a5fb257.cil b/issues/i_1a5fb257.cil new file mode 100644 index 0000000..7792876 --- /dev/null +++ b/issues/i_1a5fb257.cil @@ -0,0 +1,15 @@ +Summary: Make sure depends-on and precedes can --add and --commit +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Comment: 146b6b88 +Inserted: 2010-01-24T10:36:07 +Updated: 2010-01-24T11:14:40 + +We need to support the following: + + $ cil depends-on --add cafebab1 cafebab2 + $ cil depends-on --commit cafebab1 cafebab2 + $ cil precedes --add cafebab1 cafebab2 + $ cil precedes --commit cafebab1 cafebab2 diff --git a/issues/i_1bb8c18d.cil b/issues/i_1bb8c18d.cil new file mode 100644 index 0000000..5e9044a --- /dev/null +++ b/issues/i_1bb8c18d.cil @@ -0,0 +1,10 @@ +Summary: 'cil init' uses 'git' instead of 'Git' +Status: Fixed +CreatedBy: Yanick Champoux +AssignedTo: Yanick Champoux +Inserted: 2008-10-06T23:27:34 +Updated: 2008-10-06T23:32:32 + +When 'cil init' detects that Git is present, it +set the VCS to 'git' in the .cil file, while it +should be set to 'Git' instead. diff --git a/issues/i_41b351fc.cil b/issues/i_41b351fc.cil new file mode 100644 index 0000000..9e96c08 --- /dev/null +++ b/issues/i_41b351fc.cil @@ -0,0 +1,24 @@ +Summary: Add some sort of hook system +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.5 +Label: Type-Enhancement +Comment: 7b75b82c +Inserted: 2008-07-13T05:08:27 +Updated: 2008-07-13T10:34:43 + +For example, when you add an issue, you might want to do the following things: + +* reindex all the issues (for faster search - #98203ce8) +* generate an issues/index.html file (for poor man's cilweb - #0e004cde) +* make sure Git is tracking things + +This could be used for all kinds of events, such as: + +* new issue +* change of status +* status -> closed +* new comment +* new attachments +* etc 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 +AssignedTo: Andrew Chilton +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_52d702df.cil b/issues/i_52d702df.cil new file mode 100644 index 0000000..2a1119d --- /dev/null +++ b/issues/i_52d702df.cil @@ -0,0 +1,11 @@ +Summary: The StatusOpenList and StatusClosedList should fully describe what is allowed +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Comment: d49a551f +Inserted: 2010-01-23T13:14:45 +Updated: 2010-01-24T10:56:40 + +If we make those two lists fully describe what status can be had, then we can +remove the StatusAllowedList from the .cil config file. 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 +AssignedTo: Andrew Chilton +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_5c88cb30.cil b/issues/i_5c88cb30.cil new file mode 100644 index 0000000..51cb0f4 --- /dev/null +++ b/issues/i_5c88cb30.cil @@ -0,0 +1,31 @@ +Summary: Options for issues names needs to be added +Status: OnHold +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-Future +Label: Priority-Low +Label: Type-Enhancement +Comment: d8dd779f +Comment: feb65ae7 +Inserted: 2008-05-05T12:33:19 +Updated: 2008-06-26T12:10:32 + +When issues are created, they are given the epoch as it's name. +Instead of just using the epoch, the user should be able to configure +the .cil file to use the format of their choice. + +e.g. issue_name_format=[ epoch | inc | iso-8601 ] + +Possible name formats include: + +* an incrementing number + * but if cil goes distributed (which was originally planned), will + this work? + +* ISO 8601 - YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) + * do we need to have TZD on the end (though obviously this wouldn't + then be ISO 8601) + +* GUID/UUID like 9e28b50a-cba1-4b20-9276-d30ee727b14a + +(and maybe others) diff --git a/issues/i_5ec585b1.cil b/issues/i_5ec585b1.cil new file mode 100644 index 0000000..caab419 --- /dev/null +++ b/issues/i_5ec585b1.cil @@ -0,0 +1,13 @@ +Summary: Add a cil label --remove command +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Comment: 043f8971 +Inserted: 2010-01-22T01:41:59 +Updated: 2010-01-23T06:37:44 + +Currently you can 'cil label MyLabel cafebabe' but you can't remove it. Add the +following option: + + $ cil label --remove MyLabel cafebabe diff --git a/issues/i_6b087805.cil b/issues/i_6b087805.cil new file mode 100644 index 0000000..186f86d --- /dev/null +++ b/issues/i_6b087805.cil @@ -0,0 +1,13 @@ +Summary: Add a 'steal' command +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.5 +Label: Type-Enhancement +Comment: 3da3fd2f +Inserted: 2008-07-03T10:10:50 +Updated: 2008-07-03T11:23:03 + +A 'cil steal ' command would be helpful to assign issues to yourself. +This is just shorthabe for editing an issue and putting your "UserName +" into the 'AssignedTo' field. diff --git a/issues/i_6baa8555.cil b/issues/i_6baa8555.cil new file mode 100644 index 0000000..f70d6ac --- /dev/null +++ b/issues/i_6baa8555.cil @@ -0,0 +1,17 @@ +Summary: Do checking on input fields after adding or editing issue +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Priority-Medium +Label: Release-v0.1.0 +Label: Type-Enhancement +Comment: 3f088351 +Comment: 4edba98c +Inserted: 2008-05-05T12:46:58 +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 +checked against it. + +This could also be done for Labels too. diff --git a/issues/i_768d9434.cil b/issues/i_768d9434.cil new file mode 100644 index 0000000..16d9919 --- /dev/null +++ b/issues/i_768d9434.cil @@ -0,0 +1,28 @@ +Summary: Add a command 'track' +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.5 +Label: Type-Enhancement +Comment: 70533ec8 +Inserted: 2008-07-05T02:58:20 +Updated: 2008-07-05T03:09:11 + +A new command called 'track' would be good so that you can tell 'cil' to tell +your CVS which files to track. This means you don't have to keep adding all +those issues and/or comments to your repo manually and all the dependecies are +done. + +e.g. + + $ cil track cafebabe + git add issues/i_cafebabe.cil + git add issues/c_decaf7ea.cil + git add issues/a_deadbeaf.cil + +Maybe for now it should just print those lines out, but in the future a command +line option means to actually do it. In the this state, you could always do: + + $ cil track cafebabe | sh + +which would then do it for you. diff --git a/issues/i_85eceee9.cil b/issues/i_85eceee9.cil new file mode 100644 index 0000000..59707ce --- /dev/null +++ b/issues/i_85eceee9.cil @@ -0,0 +1,39 @@ +Summary: Ability to filter the issues lists (summary and list) +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.3 +Label: Release-v0.2.0 +Label: Type-Enhancement +Comment: 02a9bb68 +Comment: 4b71d0c3 +Comment: 7eb313cd +Comment: e9cc10a9 +Inserted: 2008-06-23T12:05:33 +Updated: 2008-06-27T13:32:59 + +The ability to filter on various things would be nice. For example using these +list commands, though summary should work the same way: + + $ cil list --status=New + $ cil list --status=Assigned + $ cil list --status=Finished + + $ cil list --label=Release-v0.1 + $ cil list --label=Type-Enhancement + +And combining them should be easy: + + $ cil list --status=Assigned --label=Type-Defect + +Other options include: + + $ cil list --assigned-to=andychilton@gmail.com + $ cil list --has-attachments --has-comments + $ cil list --is-open/closed + +There may be other options so this issue will be closed when we think we've had +enough. + +Note: whilst filtering on lists is good, actual searching is still better for a +lot of things you'd like to do. This will be added as a separate issue. diff --git a/issues/i_98203ce8.cil b/issues/i_98203ce8.cil new file mode 100644 index 0000000..f913c1f --- /dev/null +++ b/issues/i_98203ce8.cil @@ -0,0 +1,26 @@ +Summary: Search and indexing should be added to help aid finding issues +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-Future +Label: Release-v0.2.1 +Label: Type-Enhancement +Inserted: 2008-06-23T12:20:45 +Updated: 2008-06-26T11:54:39 + +Some sort of indexing and search should be added to cil so that it is easier to +find issues in amongst a long list of them. + +There have been some suggestions in the past but we want something that is +local, doesn't have to be set up and will just create a file right there. + +Using it should be a matter of just searching (and the re-indexing will happen +automatically). Here are some example commands which might be good: + + # shouldn't be necessary but there should be a way to do it + $ cil reindex + + $ cil search 'Project Blah refactoring' + $ cil search 'screenshot table formatting' + +The search should list results in either the 'summary' or 'list' view. diff --git a/issues/i_9890cf04.cil b/issues/i_9890cf04.cil new file mode 100644 index 0000000..b5a9bdf --- /dev/null +++ b/issues/i_9890cf04.cil @@ -0,0 +1,20 @@ +Summary: Add a field for 'Interested' other users +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Inserted: 2010-02-11T02:50:13 +Updated: 2010-02-11T02:50:13 + +We'll keep it so that there is only ever one assignee (AssignedTo) but other +people can become interested in a bug by adding themselfes to that list. + +Some useful commands would be: + + $ cil interested cafebabe... + $ cil interested --remove cafebabe... + +Also some filters such as: + + $ cil summary --is-interested + +... and so on. diff --git a/issues/i_99d9dd74.cil b/issues/i_99d9dd74.cil new file mode 100644 index 0000000..208d1b9 --- /dev/null +++ b/issues/i_99d9dd74.cil @@ -0,0 +1,31 @@ +Summary: Add a filter '--grep=regex' +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-Future +Label: Release-v0.2.1 +Label: Type-Enhancement +Inserted: 2008-06-24T12:16:57 +Updated: 2008-06-27T23:59:48 + +Having a 'grep' filter would be quite powerful. It could be used in the 'list' +and 'summary' commands. It would be good if it accepts Perl regexes and might +work a little something like this: + +Find all issues with 'screenshot' in them: + + $ cil list --grep=screenshot + +Find any issue that mentions one of the following: + + $ cil list --grep=css|html|javascript + +This one would be directed at the 'CreatedBy' and 'AssignedTo' fields: + + $ cil list --grep=andychilton@ + +This one would probably be targeted at the 'Label' field: + + $ cil list --grep=^Release-v0.2 + +So accepting Perl regexes would be excellent. diff --git a/issues/i_9b0d3687.cil b/issues/i_9b0d3687.cil new file mode 100644 index 0000000..1e39717 --- /dev/null +++ b/issues/i_9b0d3687.cil @@ -0,0 +1,10 @@ +Summary: Add ability to run some Git commands from some hooks +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Inserted: 2008-07-13T10:35:52 +Updated: 2008-07-13T10:39:37 + +When we add/edit an issue, a comment or an attachment it would be good to be able to +run some Git commands to make sure those files are tracked by Git (or the VCS +of your choosing). diff --git a/issues/i_9b7f9096.cil b/issues/i_9b7f9096.cil new file mode 100644 index 0000000..4167358 --- /dev/null +++ b/issues/i_9b7f9096.cil @@ -0,0 +1,10 @@ +Summary: When doing 'cil add', should read ~/.cilrc for AutoAssignSelf option +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Inserted: 2010-01-23T11:48:21 +Updated: 2010-01-23T12:11:43 + +Now that cil reads ~/.cilrc, you can now add 'AutoAssignSelf' to the config and +it'll automatically assign any new issues to yourself. 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 +AssignedTo: Nigel McNie +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 +AssignedTo: Andrew Chilton +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..ae4c429 --- /dev/null +++ b/issues/i_a90ad11f.cil @@ -0,0 +1,24 @@ +Summary: Write a default .cil file so --commands work +Status: Finished +CreatedBy: Nigel McNie +AssignedTo: Andrew Chilton +Comment: a8edef8d +Comment: d6ee2369 +Inserted: 2008-07-02T12:22:45 +Updated: 2008-07-03T10:52:32 + +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..1e7db6b --- /dev/null +++ b/issues/i_b18c21e8.cil @@ -0,0 +1,12 @@ +Summary: Ongoing maintenance and refactorings +Status: Cancelled +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Type-Refactoring +Comment: f8206d17 +Inserted: 2008-06-29T10:16:39 +Updated: 2010-01-23T12:36:49 + +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_b19d5ada.cil b/issues/i_b19d5ada.cil new file mode 100644 index 0000000..7eb3b56 --- /dev/null +++ b/issues/i_b19d5ada.cil @@ -0,0 +1,24 @@ +Summary: Add a 'cil check-in-git' command +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-Future +Label: Release-v0.2.1 +Label: Type-Enhancement +Inserted: 2008-06-24T03:24:14 +Updated: 2008-06-27T13:29:00 + +The ability to check whether issues/comments/attachments are tracked by Git is +important. Or indeed any VCS system. + +My thoughts are that this command would do something like the following: + +* internally, it runs "git ls-files issues/" and makes a list of files in that + directory +* makes a list of issues that are currently contained in the directory +* complains if it finds something Git doesn't know about + +Also, when it runs through each issue, it should do the same for all comments +and attachments. It could either output something which tells you you have +untracked files or it could give you example git commands which add them to +those being tracked. diff --git a/issues/i_b5a4ef93.cil b/issues/i_b5a4ef93.cil new file mode 100644 index 0000000..692f5fb --- /dev/null +++ b/issues/i_b5a4ef93.cil @@ -0,0 +1,38 @@ +Summary: Add a '--commit' to 'cil add' (plus some others) +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Comment: d98c9a37 +Comment: da74ee18 +Inserted: 2009-12-23T06:27:27 +Updated: 2010-01-22T02:15:23 + +When adding a new issue, I usually do: + + $ cil add + ... + $ git add issues/i_cafebabe.cil + $ git commit -m 'cil-cafebabe: New Issue' issues/i_cafebabe.cil + +To shortcut this, having the following would be nice: + + $ cil add --commit + +Also, having the following would also be nice: + + $ cil comment --add cafebabe + +to do: + + $ cil comment cafebabe + ... + $ cil add issues/i_cafebabe.cil issues/c_deadbeef.cil + +Maybe review some other commands. e.g: + + $ cil status --commit InProgress cafebabe + $ cil status --add InProgress cafebabe + $ cil label --add/commit Milestone-v0.3 cafebabe baadf00d effic0de + +Should be nice :) diff --git a/issues/i_b6033e30.cil b/issues/i_b6033e30.cil new file mode 100644 index 0000000..ca4a4b9 --- /dev/null +++ b/issues/i_b6033e30.cil @@ -0,0 +1,15 @@ +Summary: can't find issues folder +Status: Cancelled +CreatedBy: Name +AssignedTo: +Label: Milestone-v0.06 +Inserted: 2009-06-06T09:39:09 +Updated: 2010-01-21T23:12:50 + +Description ... +I created an issue, while in the issues folder.. it doesn't write it +would be nice if it echoed the issue just entered to allow the user to copypaste it it once they were in the right folder agin. + +brenda@Toshi:~/projects/birdcage/issues$ cil add +write_file 'issues/i_1659e495.cil' - sysopen: No such file or directory at /usr/share/perl5/CIL/Utils.pm line 124 + diff --git a/issues/i_b8061619.cil b/issues/i_b8061619.cil new file mode 100644 index 0000000..d34711b --- /dev/null +++ b/issues/i_b8061619.cil @@ -0,0 +1,12 @@ +Summary: cil add should detect early on if cil init hasn't been run +Status: Finished +CreatedBy: Andrew Ruthven +AssignedTo: +Label: Milestone-v0.06 +Inserted: 2008-09-22T03:26:21 +Updated: 2010-01-21T23:11:51 + +Currently if you run cil add you can start to create a bug report, hit save +and then cil bombs out not being able to create a file inside issues. + +cil add should detect if issues doesn't exist and complain early on. diff --git a/issues/i_bf35f2c7.cil b/issues/i_bf35f2c7.cil new file mode 100644 index 0000000..a61a59f --- /dev/null +++ b/issues/i_bf35f2c7.cil @@ -0,0 +1,15 @@ +Summary: Adding a label twice actually does it +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Inserted: 2009-12-05T00:38:49 +Updated: 2010-01-22T01:39:51 + +Take an issue with no labels: + + $ cil label cafebabe Milestone-v0.1 + $ cil label cafebabe Milestone-v0.1 + $ cil show cafebabe + +The label appears twice. This shouldn't happen. 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 +AssignedTo: Andrew Chilton +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_c6a8d865.cil b/issues/i_c6a8d865.cil new file mode 100644 index 0000000..9e46130 --- /dev/null +++ b/issues/i_c6a8d865.cil @@ -0,0 +1,17 @@ +Summary: Add a 'fsck' command +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: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 +command will help to figure out whether you have all the files around. + +This command will also check each command for validity. For example, if you +change the 'StatusAllowedList' in your '.cil' file, then this will help +determine if there are any issues set to now invalid statuses. diff --git a/issues/i_c77fae7c.cil b/issues/i_c77fae7c.cil new file mode 100644 index 0000000..cc55b9f --- /dev/null +++ b/issues/i_c77fae7c.cil @@ -0,0 +1,22 @@ +Summary: Make commit messages nicer when multiple issues are updated +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Inserted: 2010-01-27T23:59:52 +Updated: 2010-01-29T05:40:37 + +When updating the status, label, depends on or precedes (and other things which +can happen to multiple issues at any one time), the commit message doesn't say +which issues were affected. + +Since we don't want them all on the same line, we could have a commit message +much like the following: + +Added label 'Milestone-v0.07' + +* cafebabe +* blahblah +* issue102 + +etc 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 +AssignedTo: Andrew Chilton +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_cbb43db9.cil b/issues/i_cbb43db9.cil new file mode 100644 index 0000000..61123ef --- /dev/null +++ b/issues/i_cbb43db9.cil @@ -0,0 +1,14 @@ +Summary: Addition of a 'attach' command +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Priority-Medium +Label: Release-v0.1.0 +Label: Type-Enhancement +Comment: 2b92ef13 +Inserted: 2008-05-05T12:20:28 +Updated: 2008-06-26T11:55:42 + +'cil' currently has no way of adding attachments to issues. + +This should be added so that the actual data cil stores is complete. 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 +AssignedTo: Andrew Chilton +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/issues/i_d05969b6.cil b/issues/i_d05969b6.cil new file mode 100644 index 0000000..34186d9 --- /dev/null +++ b/issues/i_d05969b6.cil @@ -0,0 +1,13 @@ +Summary: Make cil read from a ~/.cilrc file for local settings +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Inserted: 2010-01-23T11:22:40 +Updated: 2010-01-23T11:46:20 + +To do things like auto-assigning to yourself, and to override CreatedBy fields, +cil should read from a ~/.cilrc file, rather than trying to figure it out from +all kinds of places. + +Doing this would make a lot of other things easier. diff --git a/issues/i_d0b8bc09.cil b/issues/i_d0b8bc09.cil new file mode 100644 index 0000000..d428594 --- /dev/null +++ b/issues/i_d0b8bc09.cil @@ -0,0 +1,15 @@ +Summary: Tidy up CIL.pm (and others) of formatting +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Comment: 5fe9eaea +Inserted: 2010-01-23T11:40:50 +Updated: 2010-01-23T12:42:28 + +This includes: + +* whitespace at end of lines +* comment separator lines +* stupid tabs -> spaces +* and other questionable practices diff --git a/issues/i_d3ac4078.cil b/issues/i_d3ac4078.cil new file mode 100644 index 0000000..b8d76bb --- /dev/null +++ b/issues/i_d3ac4078.cil @@ -0,0 +1,16 @@ +Summary: Obfuscating (a little bit) email in issues +Status: New +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Comment: 0ecf17ae +Inserted: 2010-02-08T19:07:02 +Updated: 2010-02-08T19:08:07 + +Issue #1 on GitHub ... + +Hi, +First of all, thanks for this nice piece of code :) +My idea, is to mess with email addreses a bit. Presenting them in a form like "user at domain dot com" or just "user at domain.com" isn't really less readable than the standard form, yet it might save our spamfilters some work. + +Kind regards, +Ted diff --git a/issues/i_d4cd6efd.cil b/issues/i_d4cd6efd.cil new file mode 100644 index 0000000..a3bdb79 --- /dev/null +++ b/issues/i_d4cd6efd.cil @@ -0,0 +1,18 @@ +Summary: Add some personal config options +Status: Cancelled +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Inserted: 2009-12-02T04:11:04 +Updated: 2010-01-23T13:08:20 + +Add the following options: + +* DefaultAssignedTo +* AssignToMe + +In the first case, if set, this shows who this bug should be assigned to. If +this isn't set, it isn't set to anything. + +If the second is set, AssignedTo is set to the current user. + +Each of these options may be added to ./.cil or to ~/.cilrc. diff --git a/issues/i_df9e14d6.cil b/issues/i_df9e14d6.cil new file mode 100644 index 0000000..0e6ec40 --- /dev/null +++ b/issues/i_df9e14d6.cil @@ -0,0 +1,11 @@ +Summary: The CreatedBy field should be autopopulated +Status: Finished +CreatedBy: Andrew Ruthven +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Comment: 961f2658 +Inserted: 2008-09-22T03:28:32 +Updated: 2010-01-23T12:29:50 + +The users fullname and username@hostname is probably a reasonable first +guess. (DEBNAME and DEBEMAIL environment variables are also good.) diff --git a/issues/i_f7ce705b.cil b/issues/i_f7ce705b.cil new file mode 100644 index 0000000..87d03c4 --- /dev/null +++ b/issues/i_f7ce705b.cil @@ -0,0 +1,13 @@ +Summary: Check for duplicate DependsOn and Precedes +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.07 +Comment: 1d9e3911 +Inserted: 2010-01-24T11:08:48 +Updated: 2010-01-25T01:33:36 + +Cil allows the addition of duplicate precedes. This shouldn't be allowed. + +It should automatically just not do anything if this combination already +exists. diff --git a/issues/i_f8b44370.cil b/issues/i_f8b44370.cil new file mode 100644 index 0000000..6367286 --- /dev/null +++ b/issues/i_f8b44370.cil @@ -0,0 +1,12 @@ +Summary: When adding new issues, the Git comment is 'New Comment' +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.06 +Inserted: 2010-01-23T11:52:10 +Updated: 2010-01-23T11:56:58 + +Instead, the message should say 'New '. + +For this, we'll need the entities to return a user readable string of what it +is. diff --git a/issues/i_fb79b2e8.cil b/issues/i_fb79b2e8.cil new file mode 100644 index 0000000..e865d07 --- /dev/null +++ b/issues/i_fb79b2e8.cil @@ -0,0 +1,16 @@ +Summary: Ability to set Issue Status' from the command line +Status: Finished +CreatedBy: Andrew Chilton +AssignedTo: Andrew Chilton +Label: Milestone-v0.2 +Label: Release-v0.1.0 +Label: Type-Enhancement +Comment: 792a4acf +Inserted: 2008-06-22T04:00:20 +Updated: 2008-06-26T11:56:03 + +The ability to do something like the following would be good. + + $ cil status cafebabe Finished + +would be rather cool. diff --git a/lib/CIL.pm b/lib/CIL.pm index 9a87bf9..548ada3 100644 --- a/lib/CIL.pm +++ b/lib/CIL.pm @@ -23,28 +23,51 @@ package CIL; use strict; use warnings; +use Carp qw(croak confess); use File::Glob qw(:glob); +use File::HomeDir; +use CIL::Git; + +use vars qw( $VERSION ); +$VERSION = '0.07.00'; + +use Module::Pluggable + sub_name => 'commands', + search_path => [ 'CIL::Command' ], + require => 1; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw( IssueDir StatusStrict StatusAllowed StatusOpen StatusClosed LabelStrict LabelAllowed - VCS + DefaultNewStatus + UseGit UserName UserEmail + AutoAssignSelf + git hook )); my $defaults = { - IssueDir => 'issues', # the dir to save the issues in - StatusStrict => 0, # whether to complain if a status is invalid - LabelStrict => 0, # whether to complain if a label is invalid + IssueDir => 'issues', # the dir to save the issues in + StatusStrict => 0, # whether to complain if a status is invalid + LabelStrict => 0, # whether to complain if a label is invalid + DefaultNewStatus => 'New', # What Status to use for new issues by default + UseGit => 0, # don't do anything with Git }; -my @config_hashes = qw(StatusAllowed StatusOpen StatusClosed LabelAllowed); +my @config_hashes = qw(StatusOpen StatusClosed LabelAllowed); my $defaults_user = { - UserName => 'Name', - UserEmail => 'me@example.com', + UserName => eval { Git->repository->config( 'user.name' ) } || 'UserName', + UserEmail => eval { Git->repository->config( 'user.email' ) } || 'username@example.org', + AutoAssignSelf => 0, +}; + +my $allowed = { + hook => { + 'issue_post_save' => 1, + }, }; ## ---------------------------------------------------------------------------- @@ -60,11 +83,15 @@ sub new { # save the settings for various bits of info foreach my $key ( keys %$defaults ) { # if we have been passed it in, use it, else use the default - $self->$key( $cfg->{$key} || $defaults->{$key} ); + $self->$key( $cfg->{$key} || $defaults->{$key} ); } return $self; } +sub command_names { + return map { $_->name } $_[0]->commands; +} + sub list_entities { my ($self, $prefix, $base) = @_; @@ -189,15 +216,23 @@ sub get_attachments_for { sub read_config_user { my ($self) = @_; - my $filename = "$ENV{HOME}/.cilrc"; + my $filename = File::HomeDir->my_home() . '/.cilrc'; + # firstly, set the default config my $cfg; + %$cfg = %$defaults_user; + + # then read the ~/.cilrc file 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) ) { + # for some settings, see if we can get it from Git + $cfg->{UserName} = eval { Git->repository->config( 'user.name' ) } || $cfg->{UserName}; + $cfg->{UserEmail} = eval { Git->repository->config( 'user.email' ) } || $cfg->{UserEmail}; + + # save them all internally + foreach ( qw(UserName UserEmail AutoAssignSelf) ) { $self->$_( $cfg->{$_} || $defaults_user->{$_} ); } } @@ -212,14 +247,13 @@ sub read_config_file { my $cfg; if ( -f $filename ) { $cfg = CIL::Utils->parse_cil_file( $filename ); + %$cfg = (%$defaults, %$cfg); } else { + # set some defaults if we don't have a .cil file $cfg = $defaults; } - # set some defaults if we don't have any of these - %$cfg = (%$defaults, %$cfg); - # for some things, make a hash out of them foreach my $hash_name ( @config_hashes ) { # if we have nothing in the cfg hash already, set it to empty and move on @@ -242,16 +276,72 @@ sub read_config_file { # set each config item $self->IssueDir( $cfg->{IssueDir} ); + $self->UseGit( $cfg->{UseGit} ); + # Status info $self->StatusStrict( $cfg->{StatusStrict} ); - $self->StatusAllowed( $cfg->{StatusAllowed} ); $self->StatusOpen( $cfg->{StatusOpen} ); $self->StatusClosed( $cfg->{StatusClosed} ); + # make the StatusAllowed list the sum of StatusOpen and StatusClosed + $self->StatusAllowed( { %{$cfg->{StatusOpen}}, %{$cfg->{StatusClosed}} } ); + + # Label Info $self->LabelStrict( $cfg->{LabelStrict} ); $self->LabelAllowed( $cfg->{LabelAllowed} ); - $self->VCS( $cfg->{VCS} ); + $self->DefaultNewStatus( $cfg->{DefaultNewStatus} ); + + # create the git instance if we want it + $self->UseGit( $cfg->{UseGit} || 0 ); + if ( $self->UseGit ) { + $self->git( CIL::Git->new() ); + } +} + +sub register_hook { + my ($self, $hook_name, $code) = @_; + + unless ( defined $allowed->{hook}{$hook_name} ) { + croak "hook '$hook_name' not allowed"; + } + + push @{$self->{hook}{$hook_name}}, $code; +} + +sub run_hook { + my ($self, $hook_name, @rest) = @_; + + unless ( defined $allowed->{hook}{$hook_name} ) { + croak "hook '$hook_name' not allowed"; + } + + # call all the hooks with all the args + if ( ref $self->hook eq 'HASH' ) { + foreach my $code ( @{$self->hook->{$hook_name}} ) { + &$code( $self, @rest ); + } + } +} + +sub file_exists { + my ($self, $filename) = @_; + return -f $filename; +} + +sub dir_exists { + my ($self, $dir) = @_; + return -d $dir; +} + +sub parse_cil_file { + my ($self, $filename, $last_field) = @_; + return CIL::Utils->parse_cil_file($filename, $last_field); +} + +sub save { + my ($self, $filename, $data, @fields) = @_; + return CIL::Utils->write_cil_file( $filename, $data, @fields ); } ## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Attachment.pm b/lib/CIL/Attachment.pm index 337ed1a..ee2a73a 100644 --- a/lib/CIL/Attachment.pm +++ b/lib/CIL/Attachment.pm @@ -81,6 +81,10 @@ sub prefix { return 'a'; } +sub type { + return 'Attachment'; +} + sub fields { return \@FIELDS; } diff --git a/lib/CIL/Base.pm b/lib/CIL/Base.pm index f9b932f..34fba60 100644 --- a/lib/CIL/Base.pm +++ b/lib/CIL/Base.pm @@ -38,11 +38,11 @@ sub new_from_name { croak 'provide a name' unless defined $name; - my $filename = $class->create_filename($cil, $name); + my $filename = $class->filename($cil, $name); croak "filename '$filename' does no exist" - unless -f $filename; + unless $cil->file_exists($filename); - my $data = CIL::Utils->parse_cil_file($filename, $class->last_field); + my $data = $cil->parse_cil_file($filename, $class->last_field); my $issue = $class->new_from_data( $name, $data ); return $issue; } @@ -74,6 +74,7 @@ sub new_from_data { $self->set_no_update($field, $data->{$field}); } $self->set_no_update('Changed', 0); + $self->set_no_update('Updated', $data->{Updated}); return $self; } @@ -115,10 +116,11 @@ sub set_data { sub save { my ($self, $cil) = @_; - my $filename = $self->create_filename($cil, $self->name); + my $filename = $self->filename($cil, $self->name); my $fields = $self->fields(); - CIL::Utils->write_cil_file( $filename, $self->{data}, @$fields ); + + $cil->save( $filename, $self->{data}, @$fields ); } sub as_output { @@ -127,7 +129,7 @@ sub as_output { return CIL::Utils->format_data_as_output( $self->{data}, @$fields ); } -sub create_filename { +sub filename { my ($class, $cil, $name) = @_; # create the filename from it's parts @@ -170,10 +172,7 @@ sub set { # so that we can update fields without 'Updated' being changed sub set_no_update { my ($self, $field, $value) = @_; - - my $saved_update_time = $self->Updated; - $self->set( $field, $value ); - $self->Updated( $saved_update_time ); + $self->{data}{$field} = $value; } sub set_inserted_now { diff --git a/lib/CIL/Command.pm b/lib/CIL/Command.pm new file mode 100644 index 0000000..194047b --- /dev/null +++ b/lib/CIL/Command.pm @@ -0,0 +1,17 @@ +package CIL::Command; + +use strict; +use warnings; + +sub name { + my $self = shift; + + my $name = lc( ref $self || $self ); + + $name =~ s/^CIL::Command:://i; + + return $name; +} + + +'end of package CIL::Command'; diff --git a/lib/CIL/Command/Add.pm b/lib/CIL/Command/Add.pm new file mode 100644 index 0000000..76b1785 --- /dev/null +++ b/lib/CIL/Command/Add.pm @@ -0,0 +1,65 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Add; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'add' } + +sub run { + my ($self, $cil, $args, @argv) = @_; + + CIL::Utils->ensure_interactive(); + + my $user = CIL::Utils->user($cil); + + my $issue = CIL::Issue->new('tmpname'); + $issue->Summary( join ' ', @argv ); + $issue->Status($cil->DefaultNewStatus); + $issue->CreatedBy( $user ); + $issue->AssignedTo( $user ) + if ( $args->{mine} or $cil->AutoAssignSelf ); + $issue->Description("Description ..."); + + $issue = CIL::Utils->add_issue_loop($cil, undef, $issue); + + if ( $cil->UseGit ) { + # if we want to add or commit this issue + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + } + + # if we want to commit this issue + if ( $args->{commit} ) { + $cil->git->commit( $cil, 'New Issue', $issue ); + } + } +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Am.pm b/lib/CIL/Command/Am.pm new file mode 100644 index 0000000..5b763ea --- /dev/null +++ b/lib/CIL/Command/Am.pm @@ -0,0 +1,140 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Am; + +use strict; +use warnings; + +use File::Slurp qw(read_file write_file); +use Email::Date qw(find_date); +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'am' } + +sub run { + my ($self, $cil, $args, $email_filename) = @_; + + unless ( -r $email_filename ) { + CIL::Utils::fatal("couldn't load email '$email_filename'"); + } + + my $msg_text = read_file($email_filename); + + my $email = Email::Simple->new($msg_text); + unless ( defined $email ) { + CIL::Utils::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; + } + + CIL::Utils->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 ) { + CIL::Utils->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 + CIL::Utils->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 { + if ( $args->{batch} ) { + CIL::Utils->fatal('Cannot add to an existing message (in batch mode) when there are multiple matched messages!'); + } + my $ans = CIL::Utils::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 ); + + CIL::Utils->add_comment_loop($cil, undef, $issue, $comment); + } + else { + CIL::Utils->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($cil->DefaultNewStatus); + $issue->CreatedBy( $from ); + $issue->AssignedTo( CIL::Utils->user($cil) ); + $issue->Inserted( $date ); + $issue->Updated( $date ); + $issue->Description( $body ); + + # display + CIL::Utils->display_issue_full($cil, $issue); + + # then ask if the user would like to add it + CIL::Utils->msg("Couldn't find any likely issues, so this might be a new one."); + if ( $args->{batch} ) { + CIL::Utils->msg('Running in batch mode, so just adding mail as a new issue'); + } else { + my $ans = CIL::Utils::ans('Would you like to add this message as an issue shown above (y/n): '); + return unless $ans eq 'y'; + } + + CIL::Utils->add_issue_loop($cil, undef, $issue); + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Attach.pm b/lib/CIL/Command/Attach.pm new file mode 100644 index 0000000..f114614 --- /dev/null +++ b/lib/CIL/Command/Attach.pm @@ -0,0 +1,88 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Attach; + +use strict; +use warnings; + +use base qw(CIL::Command); +use File::Basename; +use File::Slurp; +use Digest::MD5 qw(md5_hex); + +## ---------------------------------------------------------------------------- + +sub name { 'attach' } + +sub run { + my ($self, $cil, undef, $issue_name, $filename) = @_; + + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + # check to see if the file exists + unless ( -r $filename ) { + $cil->fatal("couldn't read file '$filename'"); + } + + my $basename = basename( $filename ); + my $user = CIL::Utils->user($cil); + + my $add_attachment_text = <<"EOF"; +Filename : $basename +CreatedBy : $user + +File goes here ... this will be overwritten. +EOF + + # read in the new issue text + CIL::Utils->ensure_interactive(); + my $fh = CIL::Utils->solicit( $add_attachment_text ); + + my $attachment = CIL::Attachment->new_from_fh( 'tmp', $fh ); + unless ( defined $attachment ) { + $cil->fatal("could not create new attachment"); + } + + # now add the file itself + my $contents = read_file( $filename ); + $attachment->set_file_contents( $contents ); + + # set the size + my ($size) = (stat($filename))[7]; + $attachment->Size( $size ); + + # we've got the attachment, so let's name it + 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 + $attachment->Issue( $issue->name ); + $attachment->save($cil); + + # add the comment to the issue, update it's timestamp and save it out + $issue->add_attachment( $attachment ); + $issue->save($cil); + CIL::Utils->display_issue_full($cil, $issue); +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Comment.pm b/lib/CIL/Command/Comment.pm new file mode 100644 index 0000000..0942982 --- /dev/null +++ b/lib/CIL/Command/Comment.pm @@ -0,0 +1,63 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Comment; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'comment' } + +sub run { + my ($self, $cil, $args, $issue_name) = @_; + + my $issue = CIL::Utils->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( CIL::Utils->user($cil) ); + $comment->Description("Description ..."); + + $comment = CIL::Utils->add_comment_loop($cil, undef, $issue, $comment); + + if ( $cil->UseGit ) { + # if we want to add or commit this comment + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + $cil->git->add( $cil, $comment ); + } + + # if we want to commit this comment + if ( $args->{commit} ) { + $cil->git->commit( $cil, 'New Comment', $issue, $comment ); + } + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/DependsOn.pm b/lib/CIL/Command/DependsOn.pm new file mode 100644 index 0000000..1df5f19 --- /dev/null +++ b/lib/CIL/Command/DependsOn.pm @@ -0,0 +1,61 @@ +## ---------------------------------------------------------------------------- +# 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::Command::DependsOn; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'depends-on' } + +sub run { + my ($self, $cil, $args, $issue_name, $depends_name) = @_; + + my $issue = CIL::Utils->load_issue_fuzzy($cil, $issue_name); + my $depends = CIL::Utils->load_issue_fuzzy($cil, $depends_name); + + $issue->add_depends_on( $depends->name ); + $depends->add_precedes( $issue->name ); + + $issue->save($cil); + $depends->save($cil); + + if ( $cil->UseGit ) { + # if we want to add or commit this change + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + $cil->git->add( $cil, $depends ); + } + + # if we want to commit this change + if ( $args->{commit} ) { + my $message = 'Issue ' . $issue->name . ' has a new dependent ' . $depends->name; + $cil->git->commit_multiple( $cil, $message, $issue, $depends ); + } + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Edit.pm b/lib/CIL/Command/Edit.pm new file mode 100644 index 0000000..2f7a7e0 --- /dev/null +++ b/lib/CIL/Command/Edit.pm @@ -0,0 +1,84 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Edit; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +my $y = 'y'; + +## ---------------------------------------------------------------------------- + +sub name { 'edit' } + +sub run { + my ($self, $cil, $args, $issue_name) = @_; + + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + CIL::Utils->ensure_interactive(); + + 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( $issue->name, $fh ); + + # check if the issue is valid + if ( $issue->is_valid($cil) ) { + $edit = 'n'; + } + else { + CIL::Utils->msg($_) foreach @{ $issue->errors }; + $edit = CIL::Utils::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 ); + + # save it + $issue->save($cil); + + if ( $cil->UseGit ) { + # if we want to add or commit this issue + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + } + + # if we want to commit this issue + if ( $args->{commit} ) { + $cil->git->commit( $cil, 'Issue Edited', $issue ); + } + } + + CIL::Utils->display_issue($cil, $issue); +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Extract.pm b/lib/CIL/Command/Extract.pm new file mode 100644 index 0000000..03df451 --- /dev/null +++ b/lib/CIL/Command/Extract.pm @@ -0,0 +1,45 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Extract; + +use strict; +use warnings; + +use base qw(CIL::Command); +use File::Slurp qw(write_file); + +## ---------------------------------------------------------------------------- + +sub name { 'extract' } + +sub run { + my ($self, $cil, $args, $attachment_name) = @_; + + my $attachment = CIL::Utils->load_attachment_fuzzy($cil, $attachment_name); + + my $filename = $args->{f} || $attachment->Filename(); + write_file( $filename, $attachment->as_binary ); +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Fsck.pm b/lib/CIL/Command/Fsck.pm new file mode 100644 index 0000000..2c48b36 --- /dev/null +++ b/lib/CIL/Command/Fsck.pm @@ -0,0 +1,185 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Fsck; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'fsck' } + +sub run { + my ($self, $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 + + # 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; + } + + # ------ + # issues + 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->CommentList; + 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->AttachmentList; + 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"; + } + } + + # 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 + 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 left + CIL::Utils->separator(); +} + +sub print_fsck_errors { + my ($entity, $errors) = @_; + return unless keys %$errors; + + CIL::Utils->separator(); + foreach my $issue_name ( keys %$errors ) { + CIL::Utils->title( "$entity $issue_name "); + foreach my $error ( @{$errors->{$issue_name}} ) { + CIL::Utils->msg("* $error"); + } + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Init.pm b/lib/CIL/Command/Init.pm new file mode 100644 index 0000000..1bf92d5 --- /dev/null +++ b/lib/CIL/Command/Init.pm @@ -0,0 +1,108 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Init; + +use strict; +use warnings; +use File::Slurp qw(read_file write_file); + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'init' } + +sub run { + my ($self, $cil, $args) = @_; + + my $path = $args->{p} || '.'; # default path is right here + + # error if $path doesn't exist + unless ( -d $path ) { + CIL::Utils->fatal("path '$path' doesn't exist"); + } + + # error if issues/ already exists + my $issues_dir = "$path/issues"; + if ( -d $issues_dir ) { + CIL::Utils->fatal("issues directory '$issues_dir' already exists, not initialising issues"); + } + + # error if .cil already exists + my $config = "$path/.cil"; + if ( -f $config ) { + CIL::Utils->fatal("config file '$config' already exists, not initialising issues"); + } + + # try to create the issues/ dir + unless ( mkdir $issues_dir ) { + CIL::Utils->fatal("Couldn't create '$issues_dir' directory: $!"); + } + + # are we in a Git repository? + my $use_git = 0; + if ( -d '.git' ) { + CIL::Utils->msg( 'git repository detected, setting to use it' ); + $use_git = 1; + } + + # create a .cil file here also + if ( $args->{bare} ) { + unless ( touch $config ) { + rmdir $issues_dir; + CIL::Utils->fatal("couldn't create a '$config' file"); + } + } + else { + # write a default .cil file + write_file($config, <<"CONFIG"); +UseGit: $use_git +StatusStrict: 1 +StatusOpenList: New +StatusOpenList: InProgress +StatusClosedList: Finished +DefaultNewStatus: New +LabelStrict: 1 +LabelAllowedList: Type-Enhancement +LabelAllowedList: Type-Defect +LabelAllowedList: Priority-High +LabelAllowedList: Priority-Medium +LabelAllowedList: Priority-Low +CONFIG + } + + # add a README.txt so people know what this is about + unless ( -f "$issues_dir/README.txt" ) { + write_file("$issues_dir/README.txt", <<'README'); +This directory is used by CIL to track issues and feature requests. + +The home page for CIL is at http://www.chilts.org/projects/cil/ +README + } + + # $path/issues/ and $path/.cil create correctly + CIL::Utils->msg("initialised empty issue list inside '$path/'"); +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Label.pm b/lib/CIL/Command/Label.pm new file mode 100644 index 0000000..d8da2c8 --- /dev/null +++ b/lib/CIL/Command/Label.pm @@ -0,0 +1,82 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Label; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'label' } + +sub run { + my ($self, $cil, $args, $label, @issue_names) = @_; + + unless ( defined $label ) { + CIL::Utils->fatal("provide a valid label to add to this issue"); + } + + my @issues; + + # for every issue + foreach my $issue_name ( @issue_names ) { + # firstly, read the issue in + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + # decide whether we are adding or removing this label + if ( $args->{remove} ) { + $issue->remove_label( $label ); + } + else { + $issue->add_label( $label ); + } + + # save + $issue->save($cil); + + if ( $cil->UseGit ) { + # if we want to add or commit this issue + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + } + } + + push @issues, $issue; + } + + if ( $cil->UseGit ) { + # if we want to commit these issues + if ( $args->{commit} ) { + if ( $args->{remove} ) { + $cil->git->commit_multiple( $cil, "Removed label '$label'", @issues ); + } + else { + $cil->git->commit_multiple( $cil, "Added label '$label'", @issues ); + } + } + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/List.pm b/lib/CIL/Command/List.pm new file mode 100644 index 0000000..cdb5b03 --- /dev/null +++ b/lib/CIL/Command/List.pm @@ -0,0 +1,55 @@ +## ---------------------------------------------------------------------------- +# 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::Command::List; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'list' } + +sub run { + my ($self, $cil, $args) = @_; + + CIL::Utils->check_paths($cil); + + # find all the issues + my $issues = $cil->get_issues(); + $issues = CIL::Utils->filter_issues( $cil, $issues, $args ); + if ( @$issues ) { + foreach my $issue ( sort { $a->Inserted cmp $b->Inserted } @$issues ) { + CIL::Utils->separator(); + CIL::Utils->display_issue_headers($issue); + } + CIL::Utils->separator(); + } + else { + CIL::Utils->msg('no issues found'); + } +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Precedes.pm b/lib/CIL/Command/Precedes.pm new file mode 100644 index 0000000..0fdf12e --- /dev/null +++ b/lib/CIL/Command/Precedes.pm @@ -0,0 +1,62 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Precedes; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'precedes' } + +sub run { + my ($self, $cil, $args, $issue_name, $precedes_name) = @_; + + my $issue = CIL::Utils->load_issue_fuzzy($cil, $issue_name); + my $precedes = CIL::Utils->load_issue_fuzzy($cil, $precedes_name); + + $issue->add_precedes( $precedes->name ); + $precedes->add_depends_on( $issue->name ); + + $issue->save($cil); + $precedes->save($cil); + + if ( $cil->UseGit ) { + # if we want to add or commit this change + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + $cil->git->add( $cil, $precedes ); + } + + # if we want to commit this change + if ( $args->{commit} ) { + my $message = 'Issue ' . $issue->name . ' precedes ' . $precedes->name; + $cil->git->commit_multiple( $cil, $message, $issue, $precedes ); + } + } +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Show.pm b/lib/CIL/Command/Show.pm new file mode 100644 index 0000000..865fa3a --- /dev/null +++ b/lib/CIL/Command/Show.pm @@ -0,0 +1,42 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Show; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'show' } + +sub run { + my ($self, $cil, undef, $issue_name) = @_; + + # firstly, read the issue in + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + CIL::Utils->display_issue_full($cil, $issue); +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Status.pm b/lib/CIL/Command/Status.pm new file mode 100644 index 0000000..b74f2ae --- /dev/null +++ b/lib/CIL/Command/Status.pm @@ -0,0 +1,71 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Status; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'status' } + +sub run { + my ($self, $cil, $args, $status, @issue_names) = @_; + + unless ( defined $status ) { + CIL::Utils->fatal("provide a valid status to set this issue to"); + } + + my @issues; + + # for every issue, read it it and set the Status + foreach my $issue_name ( @issue_names ) { + # firstly, read the issue in + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + # set the label for this issue + $issue->Status( $status ); + $issue->save($cil); + + # if we want to add or commit this issue + if ( $cil->UseGit ) { + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + } + } + + push @issues, $issue; + } + + if ( $cil->UseGit ) { + # if we want to commit these issues + if ( $args->{commit} ) { + my $message = "Status changed to '$status'"; + $cil->git->commit_multiple( $cil, $message, @issues ); + } + } +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Steal.pm b/lib/CIL/Command/Steal.pm new file mode 100644 index 0000000..641c5ae --- /dev/null +++ b/lib/CIL/Command/Steal.pm @@ -0,0 +1,59 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Steal; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'steal' } + +sub run { + my ($self, $cil, $args, $issue_name) = @_; + + # firstly, read the issue in + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + # set the AssignedTo for this issue to you (because you're stealing it) + $issue->AssignedTo( CIL::Utils->user($cil) ); + $issue->save($cil); + + if ( $cil->UseGit ) { + # if we want to add or commit this issue + if ( $args->{add} or $args->{commit} ) { + $cil->git->add( $cil, $issue ); + } + + # if we want to commit this issue + if ( $args->{commit} ) { + $cil->git->commit( $cil, 'Issue Stolen', $issue ); + } + } + + CIL::Utils->display_issue_full($cil, $issue); +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Summary.pm b/lib/CIL/Command/Summary.pm new file mode 100644 index 0000000..f5a3ab6 --- /dev/null +++ b/lib/CIL/Command/Summary.pm @@ -0,0 +1,55 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Summary; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'summary' } + +sub run { + my ($self, $cil, $args) = @_; + + CIL::Utils->check_paths($cil); + + # find all the issues + my $issues = $cil->get_issues(); + $issues = CIL::Utils->filter_issues( $cil, $issues, $args ); + if ( @$issues ) { + CIL::Utils->separator(); + foreach my $issue ( @$issues ) { + CIL::Utils->display_issue_summary($issue); + } + CIL::Utils->separator(); + } + else { + CIL::Utils->msg('no issues found'); + } +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Track.pm b/lib/CIL/Command/Track.pm new file mode 100644 index 0000000..ce2f879 --- /dev/null +++ b/lib/CIL/Command/Track.pm @@ -0,0 +1,51 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Track; + +use strict; +use warnings; + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'track' } + +sub run { + my ($self, $cil, undef, $issue_name) = @_; + + CIL::Utils->fatal("to use this feature the 'UseGit' option in your .cil file should be set") + unless $cil->UseGit; + + my $issue = CIL::Utils->load_issue_fuzzy($cil, $issue_name); + + # add the issue to Git + my $issue_dir = $cil->IssueDir(); + my @files; + push @files, "$issue_dir/i_" . $issue->name . '.cil'; + push @files, map { "$issue_dir/c_${_}.cil" } @{ $issue->CommentList }; + push @files, map { "$issue_dir/a_${_}.cil" } @{ $issue->AttachmentList }; + CIL::Utils->msg("git add @files"); +} + +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Command/Work.pm b/lib/CIL/Command/Work.pm new file mode 100644 index 0000000..83f8d7c --- /dev/null +++ b/lib/CIL/Command/Work.pm @@ -0,0 +1,64 @@ +## ---------------------------------------------------------------------------- +# 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::Command::Work; + +use strict; +use warnings; +use File::Slurp qw(read_file write_file); + +use base qw(CIL::Command); + +## ---------------------------------------------------------------------------- + +sub name { 'work' } + +sub run { + my ($self, $cil, $args, $issue_name) = @_; + + CIL::Utils->fatal("to use this feature the 'UseGit' option in your .cil file should be set") + unless $cil->UseGit; + + # firstly, read the issue in + my $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + + # right, got it's name, let's see if there is a branch for it + my @branches = $cil->git->branches(); + my $branch = {}; + foreach ( @branches ) { + $branch->{substr $_, 2} = 1; + } + if ( exists $branch->{$issue->name} ) { + $cil->git->switch_to_branch( $issue->name ); + } + else { + $cil->git->create_branch( $issue->name ); + } + + # now that we've switched branches, load the issue in again (just in case) + $issue = CIL::Utils->load_issue_fuzzy( $cil, $issue_name ); + $issue->Status( 'InProgress' ); + $issue->save($cil); +} + +1; + +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Comment.pm b/lib/CIL/Comment.pm index 362f094..5fa572b 100644 --- a/lib/CIL/Comment.pm +++ b/lib/CIL/Comment.pm @@ -63,6 +63,10 @@ sub prefix { return 'c'; } +sub type { + return 'Comment'; +} + sub fields { return \@FIELDS; } diff --git a/lib/CIL/Git.pm b/lib/CIL/Git.pm new file mode 100644 index 0000000..a38323c --- /dev/null +++ b/lib/CIL/Git.pm @@ -0,0 +1,139 @@ +## ---------------------------------------------------------------------------- +# 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::Git; + +use strict; +use warnings; +use Carp; +use List::Util qw(reduce); +use Git; + +use base qw(Class::Accessor); + +sub git { + my $self = shift; + $self->{git} ||= Git->repository; +} + +sub glob_rev { + my ($self, $rev, $path) = @_; + + # only support globbing the last element + my ($dir, $pattern) = $path =~ m{^([^\*]*/)([^/]*)$} + or croak "unsupported pattern '$path'"; + $pattern =~ s{([\\\.])}{\\$1}g; + $pattern =~ s{\*}{.*}g; + my @match; + $DB::single = 1; + for ( $self->git->command("ls-tree", $rev, $dir) ) { + chomp; + my ($blobid, $path) = m{([0-9a-f]{40})\s+(.*)} or die; + if ( $path =~ m{^\Q$dir\E$pattern$} ) { + push @match, $path; + } + } + @match; +} + +sub file_exists { + my ($self, $rev, $path) = @_; + + my $output = eval { $self->git->command("cat-file", "-t", "$rev:$path") }; + return ( $output && $output =~ /blob/ ); +} + +sub dir_exists { + my ($self, $rev, $path) = @_; + + my $output = eval { $self->git->command("cat-file", "-t", "$rev:$path") }; + return ( $output && $output =~ /tree/ ); +} + +sub get_fh { + my ($self, $rev, $path) = @_; + $self->git->command_output_pipe("cat-file", "blob", "$rev:$path"); +} + +sub UserName { + return $_[0]->git->config( 'user.name' ); +} + +sub UserEmail { + return $_[0]->git->config( 'user.email' ); +} + +sub branches { + my ($self) = @_; + return $self->git->command('branch'); +} + +sub switch_to_branch { + my ($self, $branch_name) = @_; + $self->git->command('checkout', $branch_name); +} + +sub create_branch { + my ($self, $branch_name) = @_; + $self->git->command('checkout', '-b', $branch_name); +} + +sub add { + my ($self, $cil, @entities) = @_; + + my @filenames; + foreach my $entity ( @entities ) { + my $filename = $entity->filename($cil, $entity->name()); + push @filenames, $filename; + } + return $self->git->command('add', @filenames); +} + +sub commit { + my ($self, $cil, $message, @entities) = @_; + + my @filenames; + foreach my $entity ( @entities ) { + my $filename = $entity->filename($cil, $entity->name()); + push @filenames, $filename; + } + + $message = 'cil-' . $entities[0]->name . ": $message"; + return $self->git->command('commit', '-m', $message, @filenames); +} + +sub commit_multiple { + my ($self, $cil, $message, @entities) = @_; + + my @filenames; + foreach my $entity ( @entities ) { + my $filename = $entity->filename($cil, $entity->name()); + push @filenames, $filename; + } + + my $commit_list_string = reduce { $a . $b } map { "* cil-" . $_->name . "\n" } @entities; + + return $self->git->command('commit', '-m', "$message\n\n$commit_list_string", @filenames); +} + +## ---------------------------------------------------------------------------- +1; +## ---------------------------------------------------------------------------- diff --git a/lib/CIL/Issue.pm b/lib/CIL/Issue.pm index eff317f..c1360d0 100644 --- a/lib/CIL/Issue.pm +++ b/lib/CIL/Issue.pm @@ -82,6 +82,10 @@ sub prefix { return 'i'; } +sub type { + return 'Issue'; +} + sub fields { return \@FIELDS; } @@ -131,8 +135,22 @@ sub add_label { croak 'provide a label when adding one' unless defined $label; + # return if we already have this label + return if grep { $_ eq $label } @{$self->{data}{Label}}; + push @{$self->{data}{Label}}, $label; - $self->flag_as_updated(); + $self->set_updated_now(); +} + +sub remove_label { + my ($self, $label) = @_; + + croak 'provide a label when removing one' + unless defined $label; + + # remove this label + @{$self->{data}{Label}} = grep { $_ ne $label } @{$self->{data}{Label}}; + $self->set_updated_now(); } sub add_comment { @@ -165,8 +183,11 @@ sub add_depends_on { croak 'provide an issue name when adding a depends' unless defined $depends; + # return if we already have this depends + return if grep { $_ eq $depends } @{$self->{data}{DependsOn}}; + push @{$self->{data}{DependsOn}}, $depends; - $self->flag_as_updated(); + $self->set_updated_now(); } sub add_precedes { @@ -175,8 +196,11 @@ sub add_precedes { croak 'provide an issue name when adding a precedes' unless defined $precedes; + # return if we already have this precedes + return if grep { $_ eq $precedes } @{$self->{data}{Precedes}}; + push @{$self->{data}{Precedes}}, $precedes; - $self->flag_as_updated(); + $self->set_updated_now(); } sub LabelList { diff --git a/lib/CIL/Utils.pm b/lib/CIL/Utils.pm index 47f7ada..cad802f 100644 --- a/lib/CIL/Utils.pm +++ b/lib/CIL/Utils.pm @@ -29,11 +29,13 @@ use File::Temp qw(tempfile); use Email::Find; use POSIX qw(getpgrp tcgetpgrp); use Fcntl qw(:DEFAULT :flock); +use Digest::MD5 qw(md5_hex); ## ---------------------------------------------------------------------------- # setup some globals my $editor = $ENV{EDITOR} || 'vi'; +my $y = 'y'; ## ---------------------------------------------------------------------------- @@ -76,7 +78,7 @@ sub parse_from_lines { $data->{$key} = $value; } } - + # now read everything that's left into the $last_field field (if there is one) $data->{$last_field} = join("\n", @lines) if defined $last_field; @@ -124,6 +126,9 @@ sub write_cil_file { write_file($filename, $lines); } +## ---------------------------------------------------------------------------- +# input + # this method based on Term::CallEditor(v0.11)'s solicit method # original: Copyright 2004 by Jeremy Mates # copied under the terms of the GPL @@ -149,7 +154,8 @@ sub solicit { flock $fh, LOCK_UN; # run the editor - my $status = system($editor, $filename); + my @editor_args = split(/\s+/, $editor); + my $status = system(@editor_args, $filename); # check its return value if ( $status != 0 ) { @@ -183,6 +189,379 @@ sub ensure_interactive { return; } +sub add_issue_loop { + my ($class, $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 = $class->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 { + $class->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); + + # should probably be run from with $cil + $cil->run_hook('issue_post_save', $issue); + + $class->display_issue($cil, $issue); + + return $issue; +} + +sub add_comment_loop { + my ($class, $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 { + $class->msg($_) foreach @{ $issue->errors }; + $edit = $class->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); + $class->display_issue_full($cil, $issue); + + return $comment; +} + +## ---------------------------------------------------------------------------- +# loading + +sub load_issue_fuzzy { + my ($class, $cil, $partial_name) = @_; + + my $issues = $cil->list_issues_fuzzy( $partial_name ); + unless ( defined $issues ) { + $class->fatal("Couldn't find any issues using '$partial_name'"); + } + + if ( @$issues > 1 ) { + $class->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 ) { + $class->fatal("Couldn't load issue '$issue_name'"); + } + + return $issue; +} + +sub load_comment_fuzzy { + my ($class, $cil, $partial_name) = @_; + + my $comments = $cil->list_comments_fuzzy( $partial_name ); + unless ( defined $comments ) { + $class->fatal("Couldn't find any comments using '$partial_name'"); + } + + if ( @$comments > 1 ) { + $class->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 ) { + $class->fatal("Couldn't load comment '$comment_name'"); + } + + return $comment; +} + +sub load_attachment_fuzzy { + my ($class, $cil, $partial_name) = @_; + + my $attachments = $cil->list_attachments_fuzzy( $partial_name ); + unless ( defined $attachments ) { + $class->fatal("Couldn't find any attachments using '$partial_name'"); + } + + if ( @$attachments > 1 ) { + $class->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 ) { + $class->fatal("Couldn't load attachment '$partial_name'"); + } + + return $attachment; +} + +## ---------------------------------------------------------------------------- +# display + +sub display_issue { + my ($class, $cil, $issue) = @_; + + $class->separator(); + $class->title( 'Issue ' . $issue->name() ); + $class->field( 'Summary', $issue->Summary() ); + $class->field( 'Status', $issue->Status() ); + $class->field( 'CreatedBy', $issue->CreatedBy() ); + $class->field( 'AssignedTo', $issue->AssignedTo() ); + $class->field( 'Label', $_ ) + foreach sort @{$issue->LabelList()}; + $class->field( 'Comment', $_ ) + foreach sort @{$issue->CommentList()}; + $class->field( 'Attachment', $_ ) + foreach sort @{$issue->AttachmentList()}; + $class->field( 'DependsOn', $_ ) + foreach sort @{$issue->DependsOnList()}; + $class->field( 'Precedes', $_ ) + foreach sort @{$issue->PrecedesList()}; + $class->field( 'Inserted', $issue->Inserted() ); + $class->field( 'Updated', $issue->Inserted() ); + $class->text('Description', $issue->Description()); + $class->separator(); +} + +sub display_issue_full { + my ($class, $cil, $issue) = @_; + + $class->separator(); + $class->title( 'Issue ' . $issue->name() ); + $class->field( 'Summary', $issue->Summary() ); + $class->field( 'Status', $issue->Status() ); + $class->field( 'CreatedBy', $issue->CreatedBy() ); + $class->field( 'AssignedTo', $issue->AssignedTo() ); + $class->field( 'Label', $_ ) + foreach sort @{$issue->Label()}; + $class->field( 'DependsOn', $_ ) + foreach sort @{$issue->DependsOnList()}; + $class->field( 'Precedes', $_ ) + foreach sort @{$issue->PrecedesList()}; + $class->field( 'Inserted', $issue->Inserted() ); + $class->field( 'Updated', $issue->Updated() ); + $class->text('Description', $issue->Description()); + + my $comments = $cil->get_comments_for( $issue ); + foreach my $comment ( @$comments ) { + $class->display_comment( $cil, $comment ); + } + + my $attachments = $cil->get_attachments_for( $issue ); + foreach my $attachment ( @$attachments ) { + $class->display_attachment( $cil, $attachment ); + $class->msg(); + } + + $class->separator(); +} + +sub display_comment { + my ($class, $cil, $comment) = @_; + + $class->title( 'Comment ' . $comment->name() ); + $class->field( 'CreatedBy', $comment->CreatedBy() ); + $class->field( 'Inserted', $comment->Inserted() ); + $class->field( 'Updated', $comment->Inserted() ); + $class->text('Description', $comment->Description()); +} + +sub display_attachment { + my ($class, $cil, $attachment) = @_; + + $class->title( 'Attachment ' . $attachment->name() ); + $class->field( 'Filename', $attachment->Filename() ); + $class->field( 'CreatedBy', $attachment->CreatedBy() ); + $class->field( 'Inserted', $attachment->Inserted() ); + $class->field( 'Updated', $attachment->Inserted() ); +} + +sub filter_issues { + my ($class, $cil, $issues, $args) = @_; + + # don't filter if we haven't been given anything + return $issues unless defined $args; + 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'} ) { + $class->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; + + # firstly, get out the Statuses we want + if ( defined $args->{s} ) { + @new_issues = grep { $_->Status eq $args->{s} } @new_issues; + } + + # then see if we want a particular label (could be a bit nicer) + if ( defined $args->{l} ) { + my @tmp; + foreach my $issue ( @new_issues ) { + push @tmp, $issue + if grep { $_ eq $args->{l} } @{$issue->LabelList}; + } + @new_issues = @tmp; + } + + # filter out dependent on open/closed + if ( defined $args->{'is-open'} ) { + # just get the open issues + @new_issues = grep { $_->is_open($cil) } @new_issues; + } + if ( defined $args->{'is-closed'} ) { + # just get the closed issues + @new_issues = grep { $_->is_closed($cil) } @new_issues; + } + + # filter out 'created by' + if ( defined $args->{c} ) { + @new_issues = grep { $args->{c} eq $_->created_by_email } @new_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; + } + + return \@new_issues; +} + +sub separator { + my ($class) = @_; + $class->msg('=' x 79); +} + +sub msg { + my ($class, $msg) = @_; + print ( defined $msg ? $msg : '' ); + print "\n"; +} + +sub display_issue_summary { + my ($class, $issue) = @_; + + my $msg = $issue->name(); + $msg .= " "; + $msg .= $issue->Status(); + $msg .= (' ' x ( 13 - length $issue->Status() )); + $msg .= $issue->Summary(); + + $class->msg($msg); +} + +sub display_issue_headers { + my ($class, $issue) = @_; + + $class->title( 'Issue ' . $issue->name() ); + $class->field( 'Summary', $issue->Summary() ); + $class->field( 'CreatedBy', $issue->CreatedBy() ); + $class->field( 'AssignedTo', $issue->AssignedTo() ); + $class->field( 'Inserted', $issue->Inserted() ); + $class->field( 'Status', $issue->Status() ); + $class->field( 'Labels', join(' ', @{$issue->LabelList()}) ); + $class->field( 'DependsOn', join(' ', @{$issue->DependsOnList()}) ); + $class->field( 'Precedes', join(' ', @{$issue->PrecedesList()}) ); +} + +sub title { + my ($class, $title) = @_; + my $msg = "--- $title "; + $msg .= '-' x (74 - length($title)); + $class->msg($msg); +} + +sub field { + my ($class, $field, $value) = @_; + my $msg = "$field"; + $msg .= " " x (12 - length($field)); + $class->msg("$msg: " . (defined $value ? $value : '') ); +} + +sub text { + my ($class, $field, $value) = @_; + $class->msg(); + $class->msg($value); + $class->msg(); +} + +## ---------------------------------------------------------------------------- +# system + +sub check_paths { + my ($class, $cil) = @_; + + # make sure an issue directory is available + unless ( $cil->dir_exists($cil->IssueDir) ) { + $class->fatal("couldn't find '" . $cil->IssueDir . "' directory"); + } +} + +sub ans { + my ($msg) = @_; + print $msg; + my $ans = ; + chomp $ans; + print "\n"; + return $ans; +} + +sub err { + my ($class, $msg) = @_; + print STDERR ( defined $msg ? $msg : '' ); + print STDERR "\n"; +} + +sub fatal { + my ($class, $msg) = @_; + chomp $msg; + print STDERR $msg, "\n"; + exit 2; +} + +## ---------------------------------------------------------------------------- +# helpers + sub extract_email_address { my ($class, $text) = @_; @@ -198,6 +577,11 @@ sub extract_email_address { return $email_address; } +sub user { + my ($class, $cil) = @_; + return $cil->UserName . ' <' . $cil->UserEmail . '>'; +} + ## ---------------------------------------------------------------------------- 1; ## ---------------------------------------------------------------------------- diff --git a/ubuntu-jaunty/changelog b/ubuntu-jaunty/changelog new file mode 100644 index 0000000..846e40d --- /dev/null +++ b/ubuntu-jaunty/changelog @@ -0,0 +1,69 @@ +cil (0.5.1) unstable; urgency=low + + * New release minus all the cruft + + -- Andrew Chilton Sat, 05 Jul 2008 18:28:22 +1200 + +cil (0.5.0) unstable; urgency=low + + * Fix bug when running certain commands (inc. init) + * Added command 'steal' + * Added command 'track' + + -- Andrew Chilton Sat, 05 Jul 2008 15:36:22 +1200 + +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 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 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 Wed, 02 Jul 2008 23:12:20 +1200 + +cil (0.3.0) unstable; urgency=low + + * Added filters for the listing commands + * Added ability to read .cil config file + * Can now set which Statuses are valid + * Can set which Labels are valid + * Added 'fsck' command + * Added bash completion for options, commands and entities + * Ready for 0.3.0 release + + -- Andrew Chilton Sat, 28 Jun 2008 12:06:19 +1200 + +cil (0.2.1) unstable; urgency=low + + * Ready for 0.2.1 release + + -- Andrew Chilton Mon, 23 Jun 2008 22:32:18 +1200 + +cil (0.2.0) unstable; urgency=low + + * Ready for 0.2 release + + -- Andrew Chilton Sun, 22 Jun 2008 16:17:18 +1200 + +cil (0.1.0) unstable; urgency=low + + * Ready for 0.1 release + + -- Andrew Chilton Sun, 04 May 2008 16:17:17 +1200 diff --git a/ubuntu-jaunty/compat b/ubuntu-jaunty/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/ubuntu-jaunty/compat @@ -0,0 +1 @@ +7 diff --git a/ubuntu-jaunty/control b/ubuntu-jaunty/control new file mode 100644 index 0000000..8042cb9 --- /dev/null +++ b/ubuntu-jaunty/control @@ -0,0 +1,18 @@ +Source: cil +Section: perl +Priority: extra +Maintainer: Andrew Chilton +Uploaders: Andrew Chilton +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 5) +Build-Depends-Indep: perl + +Package: cil +Section: perl +Priority: extra +Architecture: all +Depends: ${perl:Depends}, libgetopt-mixed-perl, libfile-touch-perl, libfile-slurp-perl, libclass-accessor-perl, libdatetime-perl, libemail-find-perl, libemail-date-perl, libfile-homedir-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 + be added, edited and listed easily. diff --git a/ubuntu-jaunty/copyright b/ubuntu-jaunty/copyright new file mode 100644 index 0000000..57ddd5f --- /dev/null +++ b/ubuntu-jaunty/copyright @@ -0,0 +1,25 @@ +This package was debianized by Andrew Chilton on +Sun, 22 Jun 2008 17:48:00 +1200 + +Upstream Author: Andrew Chilton + +Copyright: (C) 2008 Andrew Chilton + +License: + + 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 . + +You are free to distribute this software under the terms of the GNU General +Public License. On Debian systems, the complete text of the GNU General Public +License can be found in /usr/share/common-licenses/GPL file. diff --git a/ubuntu-jaunty/docs b/ubuntu-jaunty/docs new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/ubuntu-jaunty/docs @@ -0,0 +1 @@ +README diff --git a/ubuntu-jaunty/install b/ubuntu-jaunty/install new file mode 100644 index 0000000..dc23abd --- /dev/null +++ b/ubuntu-jaunty/install @@ -0,0 +1,3 @@ +lib/* usr/share/perl5 +bin/cil usr/bin +etc/bash_completion.d/cil etc/bash_completion.d diff --git a/ubuntu-jaunty/manpages b/ubuntu-jaunty/manpages new file mode 100644 index 0000000..866347b --- /dev/null +++ b/ubuntu-jaunty/manpages @@ -0,0 +1 @@ +cil.1 diff --git a/ubuntu-jaunty/rules b/ubuntu-jaunty/rules new file mode 100755 index 0000000..c886698 --- /dev/null +++ b/ubuntu-jaunty/rules @@ -0,0 +1,53 @@ +#!/usr/bin/make -f +## ---------------------------------------------------------------------------- + +## ---------------------------------------------------------------------------- +## uncomment this to turn on verbose mode + +# export DH_VERBOSE=1 + +## ---------------------------------------------------------------------------- + +clean: + dh_testdir + dh_testroot + rm -f build-stamp install-stamp + [ ! -f Makefile ] || $(MAKE) clean + rm -f $(CURDIR)/cil.1 + dh_clean + +build: build-stamp +build-stamp: + dh_testdir + [ ! -f Makefile ] || $(MAKE) + echo Doing MAN... + pod2man $(CURDIR)/bin/cil > $(CURDIR)/cil.1 + touch build-stamp + +binary: + dh_testdir + dh_testroot + + dh_install + dh_installdirs + dh_installdocs + dh_installdebconf + dh_installman + dh_installchangelogs Changes + dh_compress + dh_fixperms + dh_installdeb + + dh_perl + + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-arch: + +binary: binary-indep binary-arch + +.PHONY: clean install binary-indep binary-arch binary + +## ---------------------------------------------------------------------------- -- cgit v1.2.3