Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f243f0ed44 | ||
|
|
b305cc0a60 | ||
|
|
53609b2837 | ||
|
|
bdaa0f89d9 | ||
|
|
2fd8d8aa83 | ||
|
|
e69fb81b2b | ||
|
|
d2aa0f31b0 | ||
|
|
05f67db429 | ||
|
|
62be3f8acb | ||
|
|
cc5c99c0a1 | ||
|
|
35792e7874 | ||
|
|
083407f789 | ||
|
|
e1146cdd20 | ||
|
|
f04205be4c | ||
|
|
07da2396fc | ||
|
|
ec7f7cc939 | ||
|
|
1b28d8714b | ||
|
|
79f59f12ae | ||
|
|
f595bc4731 | ||
|
|
972efc58f4 | ||
|
|
dc9ba6d6b8 | ||
|
|
a7196ca181 | ||
|
|
1355571876 | ||
|
|
d3fcd40279 | ||
|
|
c4dcdbff0f | ||
|
|
d39e45841d | ||
|
|
b28575625e | ||
|
|
fc8f8957c4 | ||
|
|
0499bfff49 | ||
|
|
af49ccf508 | ||
|
|
7b0edfdeba | ||
|
|
e5d56e3075 | ||
|
|
ede746ba16 | ||
|
|
0bad0277fe | ||
|
|
8488cbd1a6 | ||
|
|
6f9356da64 | ||
|
|
90d53245c3 | ||
|
|
1422a15cbc | ||
|
|
9c15457d7f | ||
|
|
20d8124a1d | ||
|
|
db6de54ccc | ||
|
|
eb864820cf | ||
|
|
0291e4c72e | ||
|
|
6e27feb8a3 | ||
|
|
1dcba4619e | ||
|
|
7538b43c68 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,5 +15,4 @@ www.xls
|
|||||||
src/tests/all.log
|
src/tests/all.log
|
||||||
src/tests/*.data
|
src/tests/*.data
|
||||||
*~
|
*~
|
||||||
movie*
|
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|||||||
4
AUTHORS
4
AUTHORS
@@ -17,6 +17,7 @@ The following submitted code, packages or analysis, and deserve special thanks:
|
|||||||
P.C. Shyamshankar
|
P.C. Shyamshankar
|
||||||
Johan Friis
|
Johan Friis
|
||||||
Steven de Brouwer
|
Steven de Brouwer
|
||||||
|
Pietro Cerutti
|
||||||
|
|
||||||
Thanks to the following, who submitted detailed bug reports and excellent suggestions:
|
Thanks to the following, who submitted detailed bug reports and excellent suggestions:
|
||||||
Eugene Kramer
|
Eugene Kramer
|
||||||
@@ -34,6 +35,7 @@ Thanks to the following, who submitted detailed bug reports and excellent sugges
|
|||||||
Eric Farris
|
Eric Farris
|
||||||
Bruce Dillahunty
|
Bruce Dillahunty
|
||||||
Askme Too
|
Askme Too
|
||||||
|
Mike Adonay
|
||||||
Thomas@BIC
|
Thomas@BIC
|
||||||
Ian Mortimer
|
Ian Mortimer
|
||||||
|
Zach Frazier
|
||||||
|
|||||||
54
ChangeLog
54
ChangeLog
@@ -1,7 +1,55 @@
|
|||||||
|
|
||||||
------ current release ---------------------------
|
------ current release ---------------------------
|
||||||
|
|
||||||
1.8.0 (7/21/2009)
|
1.8.2 (9/7/2009)
|
||||||
|
+ Added feature #282 that returns useful exit codes to the shell. Now a
|
||||||
|
script can detect whether no tasks were returned by a report (thanks to
|
||||||
|
Pietro Cerutti).
|
||||||
|
+ Fixed bug #287 that causes color control codes to be written to shadow
|
||||||
|
files (thanks to Richard Querin).
|
||||||
|
+ Fixed bug #289 which imported task from todo.sh without valid uuids
|
||||||
|
(thanks to Ben Jackson).
|
||||||
|
+ Fixed bug #291 which generated a false warning about an unrecognized
|
||||||
|
variable when enabling default.projects in .taskrc (thanks to Thomas@BIC).
|
||||||
|
+ Fixed bug #288 which failed to propagate rc file overrides on the command
|
||||||
|
line to the default command (thanks to Zach Frazier).
|
||||||
|
|
||||||
|
------ old releases ------------------------------
|
||||||
|
|
||||||
|
1.8.1 (8/20/2009) 35792e7874d2bb664abb1a0a67960b7fe7e0fccf
|
||||||
|
+ Fixed bug #231 that broke the build on OpenBSD 32-bit due to a time_t
|
||||||
|
and int collision (thanks to Pietro Cerutti).
|
||||||
|
+ Fixed bug #241 that prevented bash's tab-completion of projects in Fedora
|
||||||
|
11 and likely anything using bash-4 (thanks to John Florian).
|
||||||
|
+ Fixed bug #242 that sometimes causes the ID echoed after a task is added
|
||||||
|
to be incorrect (thanks to John Florian).
|
||||||
|
+ Fixed bug #245 that quoted date fields on export, that were subsequently
|
||||||
|
improperly parsed on import (thanks to John Florian).
|
||||||
|
+ Fixed bug #248 where single and double quotes are both stored as
|
||||||
|
ampersand-quot-semi (thanks to John Florian).
|
||||||
|
+ Fixed bug #249 that caused annotations with the same date to be lost after
|
||||||
|
a "task edit" command (thanks to Federico Hernandez).
|
||||||
|
+ Fixed bug #250 whereby rc.dateformat was not observed when parsing the
|
||||||
|
creation date of an annotation (thanks to Federico Hernandez).
|
||||||
|
+ Fixed bug #251 whereby the presence of annotations cause the .hasnt attribute
|
||||||
|
modifier to not work (thanks to John Florian).
|
||||||
|
+ Fixed bug #252 that prevented use of attribute modifiers on dates to effect
|
||||||
|
a range, such as "task ls due.after:eom due.before:eoy" (thanks to John
|
||||||
|
Florian).
|
||||||
|
+ Fixed bug #256 that allowed a recurring task with no due date.
|
||||||
|
+ Fixed bug #257 where an extant ~/.taskrc file prevented the override and
|
||||||
|
automatic creation of an alternate rc file (thanks to Zach Frazier).
|
||||||
|
+ Fixed bug #259 that cause a build failure on Snow Leopard 10a432.
|
||||||
|
+ Fixed bug #260 whereby the start, stop and delete commands did not complain
|
||||||
|
when filter arguments were specified, even though they were ignored
|
||||||
|
(thanks to T. Charles Yun).
|
||||||
|
+ Fixed bug that allowed a recurring task to be added without a due date.
|
||||||
|
+ Fixed bug that displays the wrong .taskrc file name on override (thanks to
|
||||||
|
Federico Hernandez).
|
||||||
|
+ Fixed bug that failed to suppress color control code in the header and footnote
|
||||||
|
when redirecting output to a file (thanks to John Florian).
|
||||||
|
|
||||||
|
1.8.0 (7/21/2009) 14977ef317bd004dae2f2c313e806af9f2a2140c
|
||||||
+ Added zsh tab completion script (thanks to P.C. Shyamshankar).
|
+ Added zsh tab completion script (thanks to P.C. Shyamshankar).
|
||||||
+ Fixed bug that cause the _forcecolor configuration variable to be
|
+ Fixed bug that cause the _forcecolor configuration variable to be
|
||||||
considered obsolete (thank to Bruce Dillahunty).
|
considered obsolete (thank to Bruce Dillahunty).
|
||||||
@@ -70,9 +118,7 @@
|
|||||||
and completed tasks.
|
and completed tasks.
|
||||||
+ Now over 1,600 unit tests, helping to maintain code quality.
|
+ Now over 1,600 unit tests, helping to maintain code quality.
|
||||||
|
|
||||||
------ old releases ------------------------------
|
1.7.1 (6/8/2009) 1422a15cbc470cff590bf06daad20d01fe1b05ef
|
||||||
|
|
||||||
1.7.1 (6/8/2009)
|
|
||||||
+ Fixed build failure on OpenBSD (thanks to Mike Adonay).
|
+ Fixed build failure on OpenBSD (thanks to Mike Adonay).
|
||||||
+ Took the opportunity of a patch release to update the various email
|
+ Took the opportunity of a patch release to update the various email
|
||||||
addresses and URLs in the various documents.
|
addresses and URLs in the various documents.
|
||||||
|
|||||||
19
NEWS
19
NEWS
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
New Features in task 1.8.0
|
New Features in task 1.8
|
||||||
|
|
||||||
- Attribute modifiers, for precise queries
|
- Attribute modifiers, for precise queries
|
||||||
- Improved calendar feature
|
- Improved calendar feature
|
||||||
@@ -9,26 +9,23 @@ New Features in task 1.8.0
|
|||||||
- In addition to being a standard part of Fedora 10 and 11 (yum install task),
|
- In addition to being a standard part of Fedora 10 and 11 (yum install task),
|
||||||
task is now also a standard part of Cygwin 1.5
|
task is now also a standard part of Cygwin 1.5
|
||||||
- There are new demo movies on taskwarrior.org
|
- There are new demo movies on taskwarrior.org
|
||||||
|
- Shell-friendly exit codes
|
||||||
|
|
||||||
Please refer to the ChangeLog file for full details. There are too many to
|
Please refer to the ChangeLog file for full details. There are too many to
|
||||||
list here.
|
list here.
|
||||||
|
|
||||||
Task has been built and tested on the following configurations:
|
Task has been built and tested on the following configurations:
|
||||||
|
|
||||||
- OS X 10.5 Leopard
|
- OS X 10.6 Snow Leopard and 10.5 Leopard
|
||||||
- OS X 10.4 Tiger
|
- Fedora 11 Leonidas and 10 Cambridge
|
||||||
- Fedora Core 11 Leonidas
|
- Ubuntu 9.04 Jaunty Jackalope and 8.10 Intrepid Ibex
|
||||||
- Fedora Core 10 Cambridge
|
|
||||||
- Ubuntu 9.04 Jaunty Jackalope
|
|
||||||
- Ubuntu 8.10 Intrepid Ibex
|
|
||||||
- Ubuntu 8.04 Hardy Heron
|
|
||||||
- Slackware 12.2
|
- Slackware 12.2
|
||||||
- Arch Linux
|
- Arch Linux
|
||||||
- Solaris 10
|
- Gentoo Linux
|
||||||
- Solaris 8
|
- Solaris 10 and 8
|
||||||
- OpenBSD 4.5
|
- OpenBSD 4.5
|
||||||
- FreeBSD
|
- FreeBSD
|
||||||
- Cygwin 1.5.25-14
|
- Cygwin 1.5
|
||||||
|
|
||||||
While Task has undergone testing, bugs are sure to remain. If you encounter a
|
While Task has undergone testing, bugs are sure to remain. If you encounter a
|
||||||
bug, please enter a new issue at:
|
bug, please enter a new issue at:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT(task, 1.8.0, support@taskwarrior.org)
|
AC_INIT(task, 1.8.2, support@taskwarrior.org)
|
||||||
|
|
||||||
CFLAGS="${CFLAGS=}"
|
CFLAGS="${CFLAGS=}"
|
||||||
CXXFLAGS="${CXXFLAGS=}"
|
CXXFLAGS="${CXXFLAGS=}"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task-tutorial 5 2009-07-14 "Task 1.8.0" "User Manuals"
|
.TH task-tutorial 5 2009-09-07 "task 1.8.2" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task 1 2009-07-14 "Task 1.8.0" "User Manuals"
|
.TH task 1 2009-09-07 "task 1.8.2" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task \- A command line todo manager.
|
task \- A command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH taskrc 5 2009-07-14 "Task 1.8.0" "User Manuals"
|
.TH taskrc 5 2009-09-07 "task 1.8.2" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
taskrc \- Configuration file for the task(1) command
|
taskrc \- Configuration file for the task(1) command
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# setup.hint for task 1.7.1-1
|
# setup.hint for task 1.8.1-1
|
||||||
category: Utils
|
category: Utils
|
||||||
requires: libncurses9 cygwin
|
requires: libncurses9 cygwin
|
||||||
sdesc: A command-line to do list manager
|
sdesc: A command-line to do list manager
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
task 1.7.1-1
|
task 1.8.1-1
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
A command-line to do list manager that can be used
|
A command-line to do list manager that can be used
|
||||||
@@ -28,10 +28,10 @@ Language:
|
|||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
Build instructions:
|
Build instructions:
|
||||||
unpack task-1.7.1-1-src.tar.bz2
|
unpack task-1.8.1-1-src.tar.bz2
|
||||||
if you use setup to install this src package,
|
if you use setup to install this src package,
|
||||||
it will be unpacked under /usr/src automatically
|
it will be unpacked under /usr/src automatically
|
||||||
cd /usr/src/task-1.7.1-1
|
cd /usr/src/task-1.8.1-1
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
@@ -42,4 +42,4 @@ task was packaged for cygwin by
|
|||||||
Federico Hernandez <ultrafredde@gmail.com> and
|
Federico Hernandez <ultrafredde@gmail.com> and
|
||||||
is licensed under the GPL
|
is licensed under the GPL
|
||||||
|
|
||||||
---- task-1.7.1-1 -- 2009-06-17 ----
|
---- task-1.8.1-1 -- 2009-08-20 ----
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/setup.hint task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint
|
diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/setup.hint task-1.8.1-1.cygwin/CYGWIN-PATCHES/setup.hint
|
||||||
--- task-1.7.1-1/CYGWIN-PATCHES/setup.hint 1970-01-01 01:00:00.000000000 +0100
|
--- task-1.8.1-1/CYGWIN-PATCHES/setup.hint 1970-01-01 01:00:00.000000000 +0100
|
||||||
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint 2009-06-17 15:47:56.304750000 +0200
|
+++ task-1.8.1-1.cygwin/CYGWIN-PATCHES/setup.hint 2009-08-20 15:47:56.304750000 +0200
|
||||||
@@ -0,0 +1,10 @@
|
@@ -0,0 +1,10 @@
|
||||||
+# setup.hint for task 1.7.1-1
|
+# setup.hint for task 1.8.1-1
|
||||||
+category: Utils
|
+category: Utils
|
||||||
+requires: libncurses9 cygwin
|
+requires: libncurses9 cygwin
|
||||||
+sdesc: A command-line to do list manager
|
+sdesc: A command-line to do list manager
|
||||||
@@ -12,11 +12,11 @@ diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/setup.hint task-1.7.1-1.cygwin/CYGWIN-PAT
|
|||||||
+reports and graphs, lots of manipulation commands,
|
+reports and graphs, lots of manipulation commands,
|
||||||
+low-level API, abbreviations for all commands and
|
+low-level API, abbreviations for all commands and
|
||||||
+options, multiuser file locking, recurring tasks."
|
+options, multiuser file locking, recurring tasks."
|
||||||
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README
|
diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README task-1.8.1-1.cygwin/CYGWIN-PATCHES/task-1.8.1-1.README
|
||||||
--- task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README 1970-01-01 01:00:00.000000000 +0100
|
--- task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README 1970-01-01 01:00:00.000000000 +0100
|
||||||
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README 2009-06-17 15:47:44.320375000 +0200
|
+++ task-1.8.1-1.cygwin/CYGWIN-PATCHES/task-1.8.1-1.README 2009-08-20 15:47:44.320375000 +0200
|
||||||
@@ -0,0 +1,45 @@
|
@@ -0,0 +1,45 @@
|
||||||
+task 1.7.1-1
|
+task 1.8.1-1
|
||||||
+------------------------------------------
|
+------------------------------------------
|
||||||
+
|
+
|
||||||
+A command-line to do list manager that can be used
|
+A command-line to do list manager that can be used
|
||||||
@@ -46,10 +46,10 @@ diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README task-1.7.1-1.cygwin/C
|
|||||||
+------------------------------------
|
+------------------------------------
|
||||||
+
|
+
|
||||||
+Build instructions:
|
+Build instructions:
|
||||||
+ unpack task-1.7.1-1-src.tar.bz2
|
+ unpack task-1.8.1-1-src.tar.bz2
|
||||||
+ if you use setup to install this src package,
|
+ if you use setup to install this src package,
|
||||||
+ it will be unpacked under /usr/src automatically
|
+ it will be unpacked under /usr/src automatically
|
||||||
+ cd /usr/src/task-1.7.1-1
|
+ cd /usr/src/task-1.8.1-1
|
||||||
+ ./configure --prefix=/usr
|
+ ./configure --prefix=/usr
|
||||||
+ make
|
+ make
|
||||||
+ make install
|
+ make install
|
||||||
@@ -60,4 +60,4 @@ diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README task-1.7.1-1.cygwin/C
|
|||||||
+Federico Hernandez <ultrafredde@gmail.com> and
|
+Federico Hernandez <ultrafredde@gmail.com> and
|
||||||
+is licensed under the GPL
|
+is licensed under the GPL
|
||||||
+
|
+
|
||||||
+---- task-1.7.1-1 -- 2009-06-17 ----
|
+---- task-1.8.1-1 -- 2009-08-20 ----
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
task 1.7.1-1
|
task 1.8.1-1
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
A command-line to do list manager that can be used
|
A command-line to do list manager that can be used
|
||||||
@@ -28,10 +28,10 @@ Language:
|
|||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
Build instructions:
|
Build instructions:
|
||||||
unpack task-1.7.1-1-src.tar.bz2
|
unpack task-1.8.1-1-src.tar.bz2
|
||||||
if you use setup to install this src package,
|
if you use setup to install this src package,
|
||||||
it will be unpacked under /usr/src automatically
|
it will be unpacked under /usr/src automatically
|
||||||
cd /usr/src/task-1.7.1-1
|
cd /usr/src/task-1.8.1-1
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
@@ -42,4 +42,4 @@ task was packaged for cygwin by
|
|||||||
Federico Hernandez <ultrafredde@gmail.com> and
|
Federico Hernandez <ultrafredde@gmail.com> and
|
||||||
is licensed under the GPL
|
is licensed under the GPL
|
||||||
|
|
||||||
---- task-1.7.1-1 -- 2009-06-17 ----
|
---- task-1.8.1-1 -- 2009-08-20 ----
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Name: task
|
Name: task
|
||||||
Version: 1.8.0
|
Version: 1.8.1
|
||||||
Release: 0%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A command-line to do list manager
|
Summary: A command-line to do list manager
|
||||||
|
|
||||||
Group: Applications/Productivity
|
Group: Applications/Productivity
|
||||||
@@ -40,18 +40,25 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%doc AUTHORS ChangeLog COPYING NEWS README scripts
|
%doc AUTHORS ChangeLog COPYING NEWS README scripts i18n
|
||||||
%{_bindir}/task
|
%{_bindir}/task
|
||||||
%{_mandir}/man1/task.1.gz
|
%{_mandir}/man1/task.1.gz
|
||||||
%{_mandir}/man5/taskrc.5.gz
|
%{_mandir}/man5/taskrc.5.gz
|
||||||
%{_mandir}/man5/task-tutorial.5.gz
|
%{_mandir}/man5/task-tutorial.5.gz
|
||||||
%{_sysconfdir}/bash_completion.d
|
%config(noreplace) %{_sysconfdir}/bash_completion.d
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Mon Jun 15 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0-0
|
* Thu Aug 20 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.1-1
|
||||||
|
Intial RPM for task bugfix release 1.8.1
|
||||||
|
* Tue Jul 21 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0-1
|
||||||
Intial RPM for task release 1.8.0
|
Intial RPM for task release 1.8.0
|
||||||
Installs now bash_completion file
|
* Mon Jul 13 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta3-1
|
||||||
|
Intial RPM for task beta release 1.8.0.beta3
|
||||||
|
* Wed Jul 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta2-1
|
||||||
|
Intial RPM for task beta release 1.8.0.beta2
|
||||||
|
* Tue Jul 07 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta1-1
|
||||||
|
Intial RPM for task beta release 1.8.0.beta1
|
||||||
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-2
|
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-2
|
||||||
- Fixed inclusion of manpages.
|
- Fixed inclusion of manpages.
|
||||||
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-1
|
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-1
|
||||||
|
|||||||
@@ -1,8 +1,32 @@
|
|||||||
|
task (1.8.1-0ubuntu1) jaunty; urgency=low
|
||||||
|
|
||||||
|
* Initial deb package for task bugfix release 1.8.1
|
||||||
|
|
||||||
|
-- Federico Hernandez <ultrafredde@gmail.com> Thu, 20 Aug 2009 20:26:33 +0200
|
||||||
|
|
||||||
task (1.8.0-0ubuntu1) jaunty; urgency=low
|
task (1.8.0-0ubuntu1) jaunty; urgency=low
|
||||||
|
|
||||||
* Initial deb package for task release 1.8.0
|
* Initial deb package for task release 1.8.0
|
||||||
|
|
||||||
-- Federico Hernandez <ultrafredde@gmail.com> Thu, 11 Jun 2009 23:02:28 +0200
|
-- Federico Hernandez <ultrafredde@gmail.com> Tue, 21 Jul 2009 15:26:33 +0200
|
||||||
|
|
||||||
|
task (1.8.0-0ubuntu1~beta3) jaunty; urgency=low
|
||||||
|
|
||||||
|
* Initial deb package for task beta release 1.8.0.beta3
|
||||||
|
|
||||||
|
-- Federico Hernandez <ultrafredde@gmail.com> Mon, 13 Jul 2009 15:09:38 +0200
|
||||||
|
|
||||||
|
task (1.8.0-0ubuntu1~beta2) jaunty; urgency=low
|
||||||
|
|
||||||
|
* Initial deb package for task beta release 1.8.0.beta2
|
||||||
|
|
||||||
|
-- Federico Hernandez <ultrafredde@gmail.com> Wed, 08 Jul 2009 15:40:50 +0200
|
||||||
|
|
||||||
|
task (1.8.0-0ubuntu1~beta1) jaunty; urgency=low
|
||||||
|
|
||||||
|
* Initial deb package for task beta release 1.8.0.beta1
|
||||||
|
|
||||||
|
-- Federico Hernandez <ultrafredde@gmail.com> Tue, 07 Jul 2009 01:35:28 +0200
|
||||||
|
|
||||||
task (1.7.1-0ubuntu1) jaunty; urgency=low
|
task (1.7.1-0ubuntu1) jaunty; urgency=low
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
This package was debianized by:
|
This package was debianized by:
|
||||||
|
|
||||||
Federico Hernandez <ultrafredde@gmail.com> on Thu, 11 Jun 2009 23:02:28 +0200
|
Federico Hernandez <ultrafredde@gmail.com> on Thu, 20 Aug 2009 20:26:33 +0200
|
||||||
|
|
||||||
It was downloaded from:
|
It was downloaded from:
|
||||||
|
|
||||||
@@ -9,6 +9,9 @@ It was downloaded from:
|
|||||||
Upstream Authors:
|
Upstream Authors:
|
||||||
|
|
||||||
Paul Beckingham <paul@beckingham.net>
|
Paul Beckingham <paul@beckingham.net>
|
||||||
|
Federico Hernandez
|
||||||
|
David J Patrick
|
||||||
|
John Florian
|
||||||
Damian Glenny
|
Damian Glenny
|
||||||
Andy Lester
|
Andy Lester
|
||||||
H. İbrahim Güngör
|
H. İbrahim Güngör
|
||||||
@@ -17,18 +20,18 @@ Upstream Authors:
|
|||||||
Benjamin Tegarden
|
Benjamin Tegarden
|
||||||
Chris Pride
|
Chris Pride
|
||||||
Richard Querin
|
Richard Querin
|
||||||
Federico Hernandez
|
|
||||||
T. Charles Yun
|
T. Charles Yun
|
||||||
David J Patrick
|
|
||||||
P.C. Shyamshankar
|
P.C. Shyamshankar
|
||||||
Johan Friis
|
Johan Friis
|
||||||
Steven de Brouwer
|
Steven de Brouwer
|
||||||
|
Pietro Cerutti
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
||||||
Copyright 2006 - 2009, Paul Beckingham
|
Copyright 2006 - 2009, Paul Beckingham
|
||||||
Copyright 2009 Federico Hernandez
|
Copyright 2009 Federico Hernandez
|
||||||
Copyright 2009 P.C. Shyamshankar
|
Copyright 2009 P.C. Shyamshankar
|
||||||
|
Copyright 2009 John Florian
|
||||||
|
|
||||||
License:
|
License:
|
||||||
|
|
||||||
|
|||||||
2
package-config/ubuntu/debian/examples
Normal file
2
package-config/ubuntu/debian/examples
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
scripts
|
||||||
|
i18n
|
||||||
@@ -31,8 +31,9 @@ binary-arch: install
|
|||||||
dh_installchangelogs
|
dh_installchangelogs
|
||||||
dh_installdocs
|
dh_installdocs
|
||||||
dh_installman
|
dh_installman
|
||||||
install -D -m644 task_completion.sh $(CURDIR)/debian/task/etc/bash_completion.d/task
|
dh_installexamples
|
||||||
rm -rf $(CURDIR)/debian/task/usr/share/doc/task-1.7.1
|
install -D -m644 scripts/bash/task_completion.sh $(CURDIR)/debian/task/etc/bash_completion.d/task
|
||||||
|
rm -rf $(CURDIR)/debian/task/usr/share/doc/task-1.8.1
|
||||||
dh_strip
|
dh_strip
|
||||||
dh_compress
|
dh_compress
|
||||||
dh_fixperms
|
dh_fixperms
|
||||||
|
|||||||
@@ -48,10 +48,6 @@
|
|||||||
# http://taskwarrior.org
|
# http://taskwarrior.org
|
||||||
#
|
#
|
||||||
|
|
||||||
_task_get_projects() {
|
|
||||||
task _projects
|
|
||||||
}
|
|
||||||
|
|
||||||
_task_get_tags() {
|
_task_get_tags() {
|
||||||
task _tags
|
task _tags
|
||||||
}
|
}
|
||||||
@@ -60,6 +56,10 @@ _task_get_config() {
|
|||||||
task _config
|
task _config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_task_offer_projects() {
|
||||||
|
COMPREPLY=( $(compgen -W "$(task _projects)" -- ${cur/*:/}) )
|
||||||
|
}
|
||||||
|
|
||||||
_task()
|
_task()
|
||||||
{
|
{
|
||||||
local cur prev opts base
|
local cur prev opts base
|
||||||
@@ -67,34 +67,61 @@ _task()
|
|||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
if [ ${#COMP_WORDS[*]} -gt 2 ]
|
||||||
|
then
|
||||||
|
prev2="${COMP_WORDS[COMP_CWORD-2]}"
|
||||||
|
else
|
||||||
|
prev2=""
|
||||||
|
fi
|
||||||
|
# echo -e "\ncur='$cur'"
|
||||||
|
# echo "prev='$prev'"
|
||||||
|
# echo "prev2='$prev2'"
|
||||||
|
|
||||||
opts="$(task _commands) $(task _ids)"
|
opts="$(task _commands) $(task _ids)"
|
||||||
|
|
||||||
case "${cur}" in
|
case "${prev}" in
|
||||||
pro*:*)
|
:)
|
||||||
local projects=$(_task_get_projects)
|
case "${prev2}" in
|
||||||
local partial_project="${cur/*:/}"
|
pro*)
|
||||||
COMPREPLY=( $(compgen -W "${projects}" -- ${partial_project}) )
|
_task_offer_projects
|
||||||
return 0
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
+*)
|
*)
|
||||||
local tags=$(_task_get_tags | sed 's/^/+/')
|
case "${cur}" in
|
||||||
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
pro*:*)
|
||||||
return 0
|
_task_offer_projects
|
||||||
;;
|
return 0
|
||||||
-*)
|
;;
|
||||||
local tags=$(_task_get_tags | sed 's/^/-/')
|
:)
|
||||||
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
case "${prev}" in
|
||||||
return 0
|
pro*)
|
||||||
;;
|
_task_offer_projects
|
||||||
rc.*)
|
return 0
|
||||||
local config=$(_task_get_config | sed 's/^/rc\./')
|
;;
|
||||||
COMPREPLY=( $(compgen -W "${config}" -- ${cur}) )
|
esac
|
||||||
return 0
|
;;
|
||||||
|
+*)
|
||||||
|
local tags=$(_task_get_tags | sed 's/^/+/')
|
||||||
|
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
local tags=$(_task_get_tags | sed 's/^/-/')
|
||||||
|
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
rc.*)
|
||||||
|
local config=$(_task_get_config | sed -e 's/^/rc\./' -e 's/$/:/')
|
||||||
|
COMPREPLY=( $(compgen -W "${config}" -- ${cur}) )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
complete -F _task task
|
complete -o nospace -F _task task
|
||||||
|
|||||||
27
src/Att.cpp
27
src/Att.cpp
@@ -407,6 +407,17 @@ std::string Att::type (const std::string& name) const
|
|||||||
return "text";
|
return "text";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The type of an attribute is useful for modifier evaluation.
|
||||||
|
std::string Att::modType (const std::string& name) const
|
||||||
|
{
|
||||||
|
if (name == "hasnt" ||
|
||||||
|
name == "isnt")
|
||||||
|
return "negative";
|
||||||
|
|
||||||
|
return "positive";
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// start --> name --> . --> mod --> : --> " --> value --> " --> end
|
// start --> name --> . --> mod --> : --> " --> value --> " --> end
|
||||||
@@ -461,7 +472,7 @@ void Att::parse (Nibbler& n)
|
|||||||
else
|
else
|
||||||
throw std::string ("Missing : after attribute name"); // TODO i18n
|
throw std::string ("Missing : after attribute name"); // TODO i18n
|
||||||
|
|
||||||
/* TODO This might be too slow to include. Test.
|
/* TODO This might be too slow to include. Test this assumption.
|
||||||
validNameValue (mName, mMod, mValue);
|
validNameValue (mName, mMod, mValue);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@@ -711,8 +722,11 @@ void Att::encode (std::string& value) const
|
|||||||
while ((i = value.find ('\t')) != std::string::npos)
|
while ((i = value.find ('\t')) != std::string::npos)
|
||||||
value.replace (i, 1, "&tab;"); // no i18n
|
value.replace (i, 1, "&tab;"); // no i18n
|
||||||
|
|
||||||
|
while ((i = value.find ('\'')) != std::string::npos)
|
||||||
|
value.replace (i, 1, "&squot;"); // no i18n
|
||||||
|
|
||||||
while ((i = value.find ('"')) != std::string::npos)
|
while ((i = value.find ('"')) != std::string::npos)
|
||||||
value.replace (i, 1, """); // no i18n
|
value.replace (i, 1, "&dquot;"); // no i18n
|
||||||
|
|
||||||
while ((i = value.find (',')) != std::string::npos)
|
while ((i = value.find (',')) != std::string::npos)
|
||||||
value.replace (i, 1, ","); // no i18n
|
value.replace (i, 1, ","); // no i18n
|
||||||
@@ -730,7 +744,8 @@ void Att::encode (std::string& value) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Decode values after parse.
|
// Decode values after parse.
|
||||||
// \t <- &tab;
|
// \t <- &tab;
|
||||||
// " <- "
|
// " <- " or &dquot;
|
||||||
|
// ' <- &squot;
|
||||||
// , <- ,
|
// , <- ,
|
||||||
// [ <- &open;
|
// [ <- &open;
|
||||||
// ] <- &close;
|
// ] <- &close;
|
||||||
@@ -742,6 +757,12 @@ void Att::decode (std::string& value) const
|
|||||||
while ((i = value.find ("&tab;")) != std::string::npos) // no i18n
|
while ((i = value.find ("&tab;")) != std::string::npos) // no i18n
|
||||||
value.replace (i, 5, "\t");
|
value.replace (i, 5, "\t");
|
||||||
|
|
||||||
|
while ((i = value.find ("&dquot;")) != std::string::npos) // no i18n
|
||||||
|
value.replace (i, 7, "\"");
|
||||||
|
|
||||||
|
while ((i = value.find ("&squot;")) != std::string::npos) // no i18n
|
||||||
|
value.replace (i, 7, "'");
|
||||||
|
|
||||||
while ((i = value.find (""")) != std::string::npos) // no i18n
|
while ((i = value.find (""")) != std::string::npos) // no i18n
|
||||||
value.replace (i, 6, "\"");
|
value.replace (i, 6, "\"");
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
static bool validNameValue (std::string&, std::string&, std::string&);
|
static bool validNameValue (std::string&, std::string&, std::string&);
|
||||||
static bool validMod (const std::string&);
|
static bool validMod (const std::string&);
|
||||||
std::string type (const std::string&) const;
|
std::string type (const std::string&) const;
|
||||||
|
std::string modType (const std::string&) const;
|
||||||
void parse (const std::string&);
|
void parse (const std::string&);
|
||||||
void parse (Nibbler&);
|
void parse (Nibbler&);
|
||||||
bool match (const Att&) const;
|
bool match (const Att&) const;
|
||||||
|
|||||||
178
src/Context.cpp
178
src/Context.cpp
@@ -49,6 +49,7 @@ Context::Context ()
|
|||||||
, tdb ()
|
, tdb ()
|
||||||
, stringtable ()
|
, stringtable ()
|
||||||
, program ("")
|
, program ("")
|
||||||
|
, overrides ("")
|
||||||
, cmd ()
|
, cmd ()
|
||||||
, inShadow (false)
|
, inShadow (false)
|
||||||
{
|
{
|
||||||
@@ -126,98 +127,110 @@ void Context::initialize ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Context::run ()
|
int Context::run ()
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
Timer t ("Context::run");
|
Timer t ("Context::run");
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parse (); // Parse command line.
|
parse (); // Parse command line.
|
||||||
output = dispatch (); // Dispatch to command handlers.
|
rc = dispatch (output); // Dispatch to command handlers.
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (const std::string& error)
|
catch (const std::string& error)
|
||||||
{
|
{
|
||||||
footnote (error);
|
footnote (error);
|
||||||
|
rc = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
footnote (stringtable.get (100, "Unknown error."));
|
footnote (stringtable.get (100, "Unknown error."));
|
||||||
|
rc = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all debug messages.
|
// Dump all debug messages.
|
||||||
if (config.get (std::string ("debug"), false))
|
if (config.get (std::string ("debug"), false))
|
||||||
foreach (d, debugMessages)
|
foreach (d, debugMessages)
|
||||||
std::cout << colorizeDebug (*d) << std::endl;
|
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
|
||||||
|
std::cout << colorizeDebug (*d) << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << *d << std::endl;
|
||||||
|
|
||||||
// Dump all headers.
|
// Dump all headers.
|
||||||
foreach (h, headers)
|
foreach (h, headers)
|
||||||
std::cout << colorizeHeader (*h) << std::endl;
|
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
|
||||||
|
std::cout << colorizeHeader (*h) << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << *h << std::endl;
|
||||||
|
|
||||||
// Dump the report output.
|
// Dump the report output.
|
||||||
std::cout << output;
|
std::cout << output;
|
||||||
|
|
||||||
// Dump all footnotes.
|
// Dump all footnotes.
|
||||||
foreach (f, footnotes)
|
foreach (f, footnotes)
|
||||||
std::cout << colorizeFootnote (*f) << std::endl;
|
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
|
||||||
|
std::cout << colorizeFootnote (*f) << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << *f << std::endl;
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string Context::dispatch ()
|
int Context::dispatch (std::string &out)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
Timer t ("Context::dispatch");
|
Timer t ("Context::dispatch");
|
||||||
|
|
||||||
// TODO Just look at this thing. It cries out for a dispatch table.
|
// TODO Just look at this thing. It cries out for a dispatch table.
|
||||||
std::string out;
|
if (cmd.command == "projects") { rc = handleProjects (out); }
|
||||||
if (cmd.command == "projects") { out = handleProjects (); }
|
else if (cmd.command == "tags") { rc = handleTags (out); }
|
||||||
else if (cmd.command == "tags") { out = handleTags (); }
|
else if (cmd.command == "colors") { rc = handleColor (out); }
|
||||||
else if (cmd.command == "colors") { out = handleColor (); }
|
else if (cmd.command == "version") { rc = handleVersion (out); }
|
||||||
else if (cmd.command == "version") { out = handleVersion (); }
|
else if (cmd.command == "help") { rc = longUsage (out); }
|
||||||
else if (cmd.command == "help") { out = longUsage (); }
|
else if (cmd.command == "stats") { rc = handleReportStats (out); }
|
||||||
else if (cmd.command == "stats") { out = handleReportStats (); }
|
else if (cmd.command == "info") { rc = handleInfo (out); }
|
||||||
else if (cmd.command == "info") { out = handleInfo (); }
|
else if (cmd.command == "history") { rc = handleReportHistory (out); }
|
||||||
else if (cmd.command == "history") { out = handleReportHistory (); }
|
else if (cmd.command == "ghistory") { rc = handleReportGHistory (out); }
|
||||||
else if (cmd.command == "ghistory") { out = handleReportGHistory (); }
|
else if (cmd.command == "summary") { rc = handleReportSummary (out); }
|
||||||
else if (cmd.command == "summary") { out = handleReportSummary (); }
|
else if (cmd.command == "calendar") { rc = handleReportCalendar (out); }
|
||||||
else if (cmd.command == "calendar") { out = handleReportCalendar (); }
|
else if (cmd.command == "timesheet") { rc = handleReportTimesheet (out); }
|
||||||
else if (cmd.command == "timesheet") { out = handleReportTimesheet (); }
|
else if (cmd.command == "add") { rc = handleAdd (out); }
|
||||||
else if (cmd.command == "add") { out = handleAdd (); }
|
else if (cmd.command == "append") { rc = handleAppend (out); }
|
||||||
else if (cmd.command == "append") { out = handleAppend (); }
|
else if (cmd.command == "annotate") { rc = handleAnnotate (out); }
|
||||||
else if (cmd.command == "annotate") { out = handleAnnotate (); }
|
else if (cmd.command == "done") { rc = handleDone (out); }
|
||||||
else if (cmd.command == "done") { out = handleDone (); }
|
else if (cmd.command == "delete") { rc = handleDelete (out); }
|
||||||
else if (cmd.command == "delete") { out = handleDelete (); }
|
else if (cmd.command == "start") { rc = handleStart (out); }
|
||||||
else if (cmd.command == "start") { out = handleStart (); }
|
else if (cmd.command == "stop") { rc = handleStop (out); }
|
||||||
else if (cmd.command == "stop") { out = handleStop (); }
|
else if (cmd.command == "export") { rc = handleExport (out); }
|
||||||
else if (cmd.command == "export") { out = handleExport (); }
|
else if (cmd.command == "import") { rc = handleImport (out); }
|
||||||
else if (cmd.command == "import") { out = handleImport (); }
|
else if (cmd.command == "duplicate") { rc = handleDuplicate (out); }
|
||||||
else if (cmd.command == "duplicate") { out = handleDuplicate (); }
|
else if (cmd.command == "edit") { rc = handleEdit (out); }
|
||||||
else if (cmd.command == "edit") { out = handleEdit (); }
|
|
||||||
#ifdef FEATURE_SHELL
|
#ifdef FEATURE_SHELL
|
||||||
else if (cmd.command == "shell") { handleShell (); }
|
else if (cmd.command == "shell") { handleShell ( ); }
|
||||||
#endif
|
#endif
|
||||||
else if (cmd.command == "undo") { handleUndo (); }
|
else if (cmd.command == "undo") { handleUndo ( ); }
|
||||||
else if (cmd.command == "_projects") { out = handleCompletionProjects (); }
|
else if (cmd.command == "_projects") { rc = handleCompletionProjects (out); }
|
||||||
else if (cmd.command == "_tags") { out = handleCompletionTags (); }
|
else if (cmd.command == "_tags") { rc = handleCompletionTags (out); }
|
||||||
else if (cmd.command == "_commands") { out = handleCompletionCommands (); }
|
else if (cmd.command == "_commands") { rc = handleCompletionCommands (out); }
|
||||||
else if (cmd.command == "_ids") { out = handleCompletionIDs (); }
|
else if (cmd.command == "_ids") { rc = handleCompletionIDs (out); }
|
||||||
else if (cmd.command == "_config") { out = handleCompletionConfig (); }
|
else if (cmd.command == "_config") { rc = handleCompletionConfig (out); }
|
||||||
else if (cmd.command == "" &&
|
else if (cmd.command == "" &&
|
||||||
sequence.size ()) { out = handleModify (); }
|
sequence.size ()) { rc = handleModify (out); }
|
||||||
|
|
||||||
// Command that display IDs and therefore need TDB::gc first.
|
// Command that display IDs and therefore need TDB::gc first.
|
||||||
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); out = handleReportNext (); }
|
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); rc = handleReportNext (out); }
|
||||||
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); out = handleCustomReport (cmd.command); }
|
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); rc = handleCustomReport (cmd.command, out); }
|
||||||
|
|
||||||
// If the command is not recognized, display usage.
|
// If the command is not recognized, display usage.
|
||||||
else { out = shortUsage (); }
|
else { rc = shortUsage (out); }
|
||||||
|
|
||||||
// Only update the shadow file if such an update was not suppressed (shadow),
|
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||||
if (cmd.isWriteCommand () && !inShadow)
|
if (cmd.isWriteCommand () && !inShadow)
|
||||||
shadow ();
|
shadow ();
|
||||||
|
|
||||||
return out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -243,8 +256,6 @@ void Context::shadow ()
|
|||||||
|
|
||||||
std::string oldCurses = config.get ("curses");
|
std::string oldCurses = config.get ("curses");
|
||||||
std::string oldColor = config.get ("color");
|
std::string oldColor = config.get ("color");
|
||||||
config.set ("curses", "off");
|
|
||||||
config.set ("color", "off");
|
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
@@ -255,8 +266,12 @@ void Context::shadow ()
|
|||||||
split (args, command, ' ');
|
split (args, command, ' ');
|
||||||
|
|
||||||
initialize ();
|
initialize ();
|
||||||
|
config.set ("curses", "off");
|
||||||
|
config.set ("color", "off");
|
||||||
|
|
||||||
parse ();
|
parse ();
|
||||||
std::string result = dispatch ();
|
std::string result;
|
||||||
|
(void)dispatch (result);
|
||||||
std::ofstream out (shadowFile.c_str ());
|
std::ofstream out (shadowFile.c_str ());
|
||||||
if (out.good ())
|
if (out.good ())
|
||||||
{
|
{
|
||||||
@@ -307,6 +322,18 @@ std::string Context::canonicalize (const std::string& input) const
|
|||||||
return canonical;
|
return canonical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Context::disallowModification () const
|
||||||
|
{
|
||||||
|
if (task.size () ||
|
||||||
|
subst.mFrom != "" ||
|
||||||
|
tagAdditions.size () ||
|
||||||
|
tagRemovals.size ())
|
||||||
|
throw std::string ("The '")
|
||||||
|
+ cmd.command
|
||||||
|
+ "' command does not allow further modification of a task.";
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Context::loadCorrectConfigFile ()
|
void Context::loadCorrectConfigFile ()
|
||||||
{
|
{
|
||||||
@@ -330,6 +357,14 @@ void Context::loadCorrectConfigFile ()
|
|||||||
else if (arg->substr (0, 3) == "rc:")
|
else if (arg->substr (0, 3) == "rc:")
|
||||||
{
|
{
|
||||||
rc = arg->substr (3, std::string::npos);
|
rc = arg->substr (3, std::string::npos);
|
||||||
|
|
||||||
|
home = rc;
|
||||||
|
std::string::size_type last_slash = rc.rfind ("/");
|
||||||
|
if (last_slash != std::string::npos)
|
||||||
|
home = rc.substr (0, last_slash);
|
||||||
|
else
|
||||||
|
home = ".";
|
||||||
|
|
||||||
args.erase (arg);
|
args.erase (arg);
|
||||||
header ("Using alternate .taskrc file " + rc); // TODO i18n
|
header ("Using alternate .taskrc file " + rc); // TODO i18n
|
||||||
break;
|
break;
|
||||||
@@ -358,13 +393,19 @@ void Context::loadCorrectConfigFile ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do we need to create a default rc?
|
// Do we need to create a default rc?
|
||||||
if (access (rc.c_str (), F_OK) &&
|
if (access (rc.c_str (), F_OK))
|
||||||
confirm ("A configuration file could not be found in " // TODO i18n
|
|
||||||
+ home
|
|
||||||
+ "\n\n"
|
|
||||||
+ "Would you like a sample .taskrc created, so task can proceed?"))
|
|
||||||
{
|
{
|
||||||
config.createDefaultRC (rc, data);
|
if (confirm ("A configuration file could not be found in " // TODO i18n
|
||||||
|
+ home
|
||||||
|
+ "\n\n"
|
||||||
|
+ "Would you like a sample "
|
||||||
|
+ rc
|
||||||
|
+ " created, so task can proceed?"))
|
||||||
|
{
|
||||||
|
config.createDefaultRC (rc, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Cannot proceed without rc file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create data location, if necessary.
|
// Create data location, if necessary.
|
||||||
@@ -398,6 +439,7 @@ void Context::loadCorrectConfigFile ()
|
|||||||
n.getUntilEOS (value))
|
n.getUntilEOS (value))
|
||||||
{
|
{
|
||||||
config.set (name, value);
|
config.set (name, value);
|
||||||
|
overrides += " " + *arg;
|
||||||
footnote (std::string ("Configuration override ") + // TODO i18n
|
footnote (std::string ("Configuration override ") + // TODO i18n
|
||||||
arg->substr (3, std::string::npos));
|
arg->substr (3, std::string::npos));
|
||||||
}
|
}
|
||||||
@@ -528,7 +570,12 @@ void Context::parse (
|
|||||||
attribute.mod (mod);
|
attribute.mod (mod);
|
||||||
attribute.value (value);
|
attribute.value (value);
|
||||||
|
|
||||||
parseTask[attribute.name ()] = attribute;
|
// Preserve modifier in the key, to allow multiple modifiers on the
|
||||||
|
// same attribute. Bug #252.
|
||||||
|
if (name != "" && mod != "")
|
||||||
|
parseTask[name + "." + mod] = attribute;
|
||||||
|
else
|
||||||
|
parseTask[name] = attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
// *arg has the appearance of an attribute (foo:bar), but isn't
|
// *arg has the appearance of an attribute (foo:bar), but isn't
|
||||||
@@ -609,12 +656,13 @@ void Context::parse (
|
|||||||
// then invoke the default command.
|
// then invoke the default command.
|
||||||
if (parseCmd.command == "" && parseArgs.size () == 0)
|
if (parseCmd.command == "" && parseArgs.size () == 0)
|
||||||
{
|
{
|
||||||
std::string defaultCommand = config.get ("default.command");
|
// Apply overrides, if any.
|
||||||
|
std::string defaultCommand = config.get ("default.command") + overrides;
|
||||||
if (defaultCommand != "")
|
if (defaultCommand != "")
|
||||||
{
|
{
|
||||||
// Stuff the command line.
|
// Stuff the command line.
|
||||||
parseArgs.clear ();
|
args.clear ();
|
||||||
split (parseArgs, defaultCommand, ' ');
|
split (args, defaultCommand, ' ');
|
||||||
header ("[task " + defaultCommand + "]");
|
header ("[task " + defaultCommand + "]");
|
||||||
|
|
||||||
// Reinitialize the context and recurse.
|
// Reinitialize the context and recurse.
|
||||||
@@ -657,46 +705,46 @@ void Context::autoFilter (Task& t, Filter& f)
|
|||||||
foreach (att, t)
|
foreach (att, t)
|
||||||
{
|
{
|
||||||
// Words are found in the description using the .has modifier.
|
// Words are found in the description using the .has modifier.
|
||||||
if (att->first == "description" && att->second.mod () == "")
|
if (att->second.name () == "description" && att->second.mod () == "")
|
||||||
{
|
{
|
||||||
std::vector <std::string> words;
|
std::vector <std::string> words;
|
||||||
split (words, att->second.value (), ' ');
|
split (words, att->second.value (), ' ');
|
||||||
foreach (word, words)
|
foreach (word, words)
|
||||||
{
|
{
|
||||||
f.push_back (Att ("description", "has", *word));
|
f.push_back (Att ("description", "has", *word));
|
||||||
debug ("auto filter: " + att->first + ".has:" + *word);
|
debug ("auto filter: " + att->second.name () + ".has:" + *word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projects are matched left-most.
|
// Projects are matched left-most.
|
||||||
else if (att->first == "project" && att->second.mod () == "")
|
else if (att->second.name () == "project" && att->second.mod () == "")
|
||||||
{
|
{
|
||||||
if (att->second.value () != "")
|
if (att->second.value () != "")
|
||||||
{
|
{
|
||||||
f.push_back (Att ("project", "startswith", att->second.value ()));
|
f.push_back (Att ("project", "startswith", att->second.value ()));
|
||||||
debug ("auto filter: " + att->first + ".startswith:" + att->second.value ());
|
debug ("auto filter: " + att->second.name () + ".startswith:" + att->second.value ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f.push_back (Att ("project", "is", att->second.value ()));
|
f.push_back (Att ("project", "is", att->second.value ()));
|
||||||
debug ("auto filter: " + att->first + ".is:" + att->second.value ());
|
debug ("auto filter: " + att->second.name () + ".is:" + att->second.value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The limit attribute does not participate in filtering, and needs to be
|
// The limit attribute does not participate in filtering, and needs to be
|
||||||
// specifically handled in handleCustomReport.
|
// specifically handled in handleCustomReport.
|
||||||
else if (att->first == "limit")
|
else if (att->second.name () == "limit")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every task has a unique uuid by default, and it shouldn't be included,
|
// Every task has a unique uuid by default, and it shouldn't be included,
|
||||||
// because it is guaranteed to not match.
|
// because it is guaranteed to not match.
|
||||||
else if (att->first == "uuid")
|
else if (att->second.name () == "uuid")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// The mechanism for filtering on tags is +/-<tag>.
|
// The mechanism for filtering on tags is +/-<tag>.
|
||||||
else if (att->first == "tags")
|
else if (att->second.name () == "tags")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,7 +753,7 @@ void Context::autoFilter (Task& t, Filter& f)
|
|||||||
{
|
{
|
||||||
f.push_back (att->second);
|
f.push_back (att->second);
|
||||||
debug ("auto filter: " +
|
debug ("auto filter: " +
|
||||||
att->first +
|
att->second.name () +
|
||||||
(att->second.mod () != "" ?
|
(att->second.mod () != "" ?
|
||||||
("." + att->second.mod () + ":") :
|
("." + att->second.mod () + ":") :
|
||||||
":") +
|
":") +
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
void initialize (); // for reinitializing
|
void initialize (); // for reinitializing
|
||||||
int run (); // task classic
|
int run (); // task classic
|
||||||
int interactive (); // task interactive (not implemented)
|
int interactive (); // task interactive (not implemented)
|
||||||
std::string dispatch (); // command handler dispatch
|
int dispatch (std::string&); // command handler dispatch
|
||||||
void shadow (); // shadow file update
|
void shadow (); // shadow file update
|
||||||
|
|
||||||
int getWidth (); // determine terminal width
|
int getWidth (); // determine terminal width
|
||||||
@@ -65,6 +65,7 @@ public:
|
|||||||
void clear ();
|
void clear ();
|
||||||
|
|
||||||
std::string canonicalize (const std::string&) const;
|
std::string canonicalize (const std::string&) const;
|
||||||
|
void disallowModification () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadCorrectConfigFile ();
|
void loadCorrectConfigFile ();
|
||||||
@@ -82,6 +83,7 @@ public:
|
|||||||
StringTable stringtable;
|
StringTable stringtable;
|
||||||
std::string program;
|
std::string program;
|
||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
|
std::string overrides;
|
||||||
Cmd cmd;
|
Cmd cmd;
|
||||||
std::map <std::string, std::string> aliases;
|
std::map <std::string, std::string> aliases;
|
||||||
std::vector <std::string> tagAdditions;
|
std::vector <std::string> tagAdditions;
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ Duration::Duration (const std::string& input)
|
|||||||
parse (input);
|
parse (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Duration::operator int ()
|
|
||||||
{
|
|
||||||
return (int) mDays;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Duration::operator time_t ()
|
Duration::operator time_t ()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public:
|
|||||||
bool operator> (const Duration&);
|
bool operator> (const Duration&);
|
||||||
~Duration (); // Destructor
|
~Duration (); // Destructor
|
||||||
|
|
||||||
operator int ();
|
|
||||||
operator time_t ();
|
operator time_t ();
|
||||||
operator std::string ();
|
operator std::string ();
|
||||||
|
|
||||||
|
|||||||
@@ -40,37 +40,51 @@ bool Filter::pass (const Record& record) const
|
|||||||
// First do description/annotation matches.
|
// First do description/annotation matches.
|
||||||
foreach (att, (*this))
|
foreach (att, (*this))
|
||||||
{
|
{
|
||||||
// Descriptions have special handling.
|
// Descriptions have special handling such that they are linked to
|
||||||
|
// annotations, and filtering on description implies identical filtering
|
||||||
|
// on annotations, and that both filter matches must succeed for the filter
|
||||||
|
// to succeed overall.
|
||||||
if (att->name () == "description")
|
if (att->name () == "description")
|
||||||
{
|
{
|
||||||
|
bool description_result = true;
|
||||||
|
int annotation_pass_count = 0;
|
||||||
|
int annotation_fail_count = 0;
|
||||||
|
|
||||||
if ((r = record.find (att->name ())) != record.end ())
|
if ((r = record.find (att->name ())) != record.end ())
|
||||||
{
|
{
|
||||||
// A description match failure can be salvaged by an annotation match.
|
description_result = att->match (r->second);
|
||||||
if (! att->match (r->second))
|
|
||||||
{
|
|
||||||
bool annoMatch = false;
|
|
||||||
foreach (ra, record)
|
|
||||||
{
|
|
||||||
if (ra->first.length () > 11 &&
|
|
||||||
ra->first.substr (0, 11) == "annotation_")
|
|
||||||
{
|
|
||||||
if (att->match (ra->second))
|
|
||||||
{
|
|
||||||
annoMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!annoMatch)
|
foreach (ra, record)
|
||||||
return false;
|
{
|
||||||
|
if (ra->first.length () > 11 &&
|
||||||
|
ra->first.substr (0, 11) == "annotation_")
|
||||||
|
{
|
||||||
|
if (att->match (ra->second))
|
||||||
|
++annotation_pass_count;
|
||||||
|
else
|
||||||
|
++annotation_fail_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (! att->match (Att ()))
|
else if (! att->match (Att ()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// This innocuous little if-else took significantly more thinking and
|
||||||
|
// debugging than anything else in task. Only change this code if you
|
||||||
|
// are willing to invest a week understanding and testing it.
|
||||||
|
if (att->modType (att->mod ()) == "positive")
|
||||||
|
{
|
||||||
|
if (! (description_result || annotation_pass_count > 0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!description_result || annotation_fail_count > 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotations are skipped.
|
// Annotations are skipped, because they are handled above.
|
||||||
else if (att->name ().length () > 11 &&
|
else if (att->name ().length () > 11 &&
|
||||||
att->name ().substr (0, 11) == "annotation_")
|
att->name ().substr (0, 11) == "annotation_")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ bool Task::operator== (const Task& other)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (att, *this)
|
foreach (att, *this)
|
||||||
if (att->first != "uuid")
|
if (att->second.name () != "uuid")
|
||||||
if (att->second.value () != other.get (att->first))
|
if (att->second.value () != other.get (att->second.name ()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -363,12 +363,12 @@ std::string Task::composeCSV () const
|
|||||||
out << get ("start") << ","; // No i18n
|
out << get ("start") << ","; // No i18n
|
||||||
|
|
||||||
if (has ("due"))
|
if (has ("due"))
|
||||||
out << "'" << get ("due") << "',"; // No i18n
|
out << get ("due") << ","; // No i18n
|
||||||
else
|
else
|
||||||
out << ","; // No i18n
|
out << ","; // No i18n
|
||||||
|
|
||||||
if (has ("recur"))
|
if (has ("recur"))
|
||||||
out << "'" << get ("recur") << "',"; // No i18n
|
out << get ("recur") << ","; // No i18n
|
||||||
else
|
else
|
||||||
out << ","; // No i18n
|
out << ","; // No i18n
|
||||||
|
|
||||||
|
|||||||
169
src/command.cpp
169
src/command.cpp
@@ -49,7 +49,7 @@
|
|||||||
extern Context context;
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAdd ()
|
int handleAdd (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -84,6 +84,15 @@ std::string handleAdd ()
|
|||||||
foreach (tag, context.tagAdditions)
|
foreach (tag, context.tagAdditions)
|
||||||
context.task.addTag (*tag);
|
context.task.addTag (*tag);
|
||||||
|
|
||||||
|
// Perform some logical consistency checks.
|
||||||
|
if (context.task.has ("recur") &&
|
||||||
|
!context.task.has ("due"))
|
||||||
|
throw std::string ("You cannot specify a recurring task without a due date.");
|
||||||
|
|
||||||
|
if (context.task.has ("until") &&
|
||||||
|
!context.task.has ("recur"))
|
||||||
|
throw std::string ("You cannot specify an until date for a non-recurring task.");
|
||||||
|
|
||||||
// Only valid tasks can be added.
|
// Only valid tasks can be added.
|
||||||
context.task.validate ();
|
context.task.validate ();
|
||||||
|
|
||||||
@@ -101,19 +110,20 @@ std::string handleAdd ()
|
|||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleProjects ()
|
int handleProjects (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
context.filter.push_back (Att ("status", "pending"));
|
context.filter.push_back (Att ("status", "pending"));
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
int quantity = context.tdb.loadPending (tasks, context.filter);
|
int quantity = context.tdb.loadPending (tasks, context.filter);
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
@@ -187,19 +197,21 @@ std::string handleProjects ()
|
|||||||
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
out << "No projects."
|
out << "No projects."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleCompletionProjects ()
|
int handleCompletionProjects (std::string &outs)
|
||||||
{
|
{
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
if (context.config.get (std::string ("complete.all.projects"), false))
|
if (context.config.get (std::string ("complete.all.projects"), false))
|
||||||
@@ -221,19 +233,20 @@ std::string handleCompletionProjects ()
|
|||||||
if (project->first.length ())
|
if (project->first.length ())
|
||||||
out << project->first << std::endl;
|
out << project->first << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleTags ()
|
int handleTags (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
context.filter.push_back (Att ("status", "pending"));
|
context.filter.push_back (Att ("status", "pending"));
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
int quantity = context.tdb.loadPending (tasks, context.filter);
|
int quantity = context.tdb.loadPending (tasks, context.filter);
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
@@ -284,19 +297,22 @@ std::string handleTags ()
|
|||||||
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
out << "No tags."
|
out << "No tags."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleCompletionTags ()
|
int handleCompletionTags (std::string &outs)
|
||||||
{
|
{
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
if (context.config.get (std::string ("complete.all.tags"), false))
|
if (context.config.get (std::string ("complete.all.tags"), false))
|
||||||
@@ -323,11 +339,12 @@ std::string handleCompletionTags ()
|
|||||||
foreach (tag, unique)
|
foreach (tag, unique)
|
||||||
out << tag->first << std::endl;
|
out << tag->first << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleCompletionCommands ()
|
int handleCompletionCommands (std::string &outs)
|
||||||
{
|
{
|
||||||
std::vector <std::string> commands;
|
std::vector <std::string> commands;
|
||||||
context.cmd.allCommands (commands);
|
context.cmd.allCommands (commands);
|
||||||
@@ -337,11 +354,12 @@ std::string handleCompletionCommands ()
|
|||||||
foreach (command, commands)
|
foreach (command, commands)
|
||||||
out << *command << std::endl;
|
out << *command << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleCompletionConfig ()
|
int handleCompletionConfig (std::string &outs)
|
||||||
{
|
{
|
||||||
std::vector <std::string> configs;
|
std::vector <std::string> configs;
|
||||||
context.config.all (configs);
|
context.config.all (configs);
|
||||||
@@ -351,15 +369,15 @@ std::string handleCompletionConfig ()
|
|||||||
foreach (config, configs)
|
foreach (config, configs)
|
||||||
out << *config << std::endl;
|
out << *config << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleCompletionIDs ()
|
int handleCompletionIDs (std::string &outs)
|
||||||
{
|
{
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
@@ -377,20 +395,24 @@ std::string handleCompletionIDs ()
|
|||||||
foreach (id, ids)
|
foreach (id, ids)
|
||||||
out << *id << std::endl;
|
out << *id << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleUndo ()
|
void handleUndo ()
|
||||||
{
|
{
|
||||||
|
context.disallowModification ();
|
||||||
|
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
context.tdb.undo ();
|
context.tdb.undo ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleVersion ()
|
int handleVersion (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
// Create a table for the disclaimer.
|
// Create a table for the disclaimer.
|
||||||
@@ -477,8 +499,8 @@ std::string handleVersion ()
|
|||||||
" blanklines bulk color color.active color.due color.overdue color.pri.H "
|
" blanklines bulk color color.active color.due color.overdue color.pri.H "
|
||||||
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
||||||
"color.footnote color.header color.debug confirmation curses data.location "
|
"color.footnote color.header color.debug confirmation curses data.location "
|
||||||
"dateformat debug default.command default.priority defaultwidth due locale "
|
"dateformat debug default.command default.priority default.project defaultwidth "
|
||||||
"displayweeknumber echo.command locking monthsperline nag next project "
|
"due locale displayweeknumber echo.command locking monthsperline nag next project "
|
||||||
"shadow.command shadow.file shadow.notify weekstart editor import.synonym.id "
|
"shadow.command shadow.file shadow.notify weekstart editor import.synonym.id "
|
||||||
"import.synonym.uuid longversion complete.all.projects complete.all.tags "
|
"import.synonym.uuid longversion complete.all.projects complete.all.tags "
|
||||||
#ifdef FEATURE_SHELL
|
#ifdef FEATURE_SHELL
|
||||||
@@ -518,7 +540,7 @@ std::string handleVersion ()
|
|||||||
if (unrecognized.size ())
|
if (unrecognized.size ())
|
||||||
{
|
{
|
||||||
out << "Your .taskrc file contains these unrecognized variables:"
|
out << "Your .taskrc file contains these unrecognized variables:"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
foreach (i, unrecognized)
|
foreach (i, unrecognized)
|
||||||
out << " " << *i << std::endl;
|
out << " " << *i << std::endl;
|
||||||
@@ -529,9 +551,11 @@ std::string handleVersion ()
|
|||||||
// Verify installation. This is mentioned in the documentation as the way to
|
// Verify installation. This is mentioned in the documentation as the way to
|
||||||
// ensure everything is properly installed.
|
// ensure everything is properly installed.
|
||||||
|
|
||||||
if (all.size () == 0)
|
if (all.size () == 0) {
|
||||||
out << "Configuration error: .taskrc contains no entries"
|
out << "Configuration error: .taskrc contains no entries"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (context.config.get ("data.location") == "")
|
if (context.config.get ("data.location") == "")
|
||||||
@@ -545,17 +569,20 @@ std::string handleVersion ()
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDelete ()
|
int handleDelete (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
|
context.disallowModification ();
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -638,24 +665,29 @@ std::string handleDelete ()
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
out << "Task not deleted." << std::endl;
|
out << "Task not deleted." << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleStart ()
|
int handleStart (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
|
context.disallowModification ();
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -691,23 +723,27 @@ std::string handleStart ()
|
|||||||
<< task->get ("description")
|
<< task->get ("description")
|
||||||
<< "' already started."
|
<< "' already started."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleStop ()
|
int handleStop (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
|
context.disallowModification ();
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -737,24 +773,26 @@ std::string handleStop ()
|
|||||||
<< task->get ("description")
|
<< task->get ("description")
|
||||||
<< "' not started."
|
<< "' not started."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDone ()
|
int handleDone (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -818,6 +856,7 @@ std::string handleDone ()
|
|||||||
<< task->get ("description")
|
<< task->get ("description")
|
||||||
<< "' is not pending"
|
<< "' is not pending"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
@@ -831,11 +870,12 @@ std::string handleDone ()
|
|||||||
<< " as done"
|
<< " as done"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleExport ()
|
int handleExport (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -874,18 +914,18 @@ std::string handleExport ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleModify ()
|
int handleModify (std::string &outs)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -952,18 +992,18 @@ std::string handleModify ()
|
|||||||
if (context.config.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAppend ()
|
int handleAppend (std::string &outs)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
handleRecurrence ();
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
context.tdb.loadPending (tasks, filter);
|
context.tdb.loadPending (tasks, filter);
|
||||||
|
|
||||||
@@ -1020,11 +1060,12 @@ std::string handleAppend ()
|
|||||||
if (context.config.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDuplicate ()
|
int handleDuplicate (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -1089,7 +1130,8 @@ std::string handleDuplicate ()
|
|||||||
if (context.config.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1168,8 +1210,9 @@ void handleShell ()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleColor ()
|
int handleColor (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||||
{
|
{
|
||||||
@@ -1251,13 +1294,15 @@ std::string handleColor ()
|
|||||||
out << "Color is currently turned off in your .taskrc file. "
|
out << "Color is currently turned off in your .taskrc file. "
|
||||||
"To enable color, create the entry 'color=on'."
|
"To enable color, create the entry 'color=on'."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAnnotate ()
|
int handleAnnotate (std::string &outs)
|
||||||
{
|
{
|
||||||
if (!context.task.has ("description"))
|
if (!context.task.has ("description"))
|
||||||
throw std::string ("Cannot apply a blank annotation.");
|
throw std::string ("Cannot apply a blank annotation.");
|
||||||
@@ -1301,7 +1346,8 @@ std::string handleAnnotate ()
|
|||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1359,12 +1405,12 @@ int deltaAttributes (Task& task)
|
|||||||
|
|
||||||
foreach (att, context.task)
|
foreach (att, context.task)
|
||||||
{
|
{
|
||||||
if (att->first != "uuid" &&
|
if (att->second.name () != "uuid" &&
|
||||||
att->first != "description" &&
|
att->second.name () != "description" &&
|
||||||
att->first != "tags")
|
att->second.name () != "tags")
|
||||||
{
|
{
|
||||||
// Modifying "wait" changes status.
|
// Modifying "wait" changes status.
|
||||||
if (att->first == "wait")
|
if (att->second.name () == "wait")
|
||||||
{
|
{
|
||||||
if (att->second.value () == "")
|
if (att->second.value () == "")
|
||||||
task.setStatus (Task::pending);
|
task.setStatus (Task::pending);
|
||||||
@@ -1373,8 +1419,9 @@ int deltaAttributes (Task& task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (att->second.value () == "")
|
if (att->second.value () == "")
|
||||||
task.remove (att->first);
|
task.remove (att->second.name ());
|
||||||
else
|
else
|
||||||
|
// One of the few places where the compound attribute name is used.
|
||||||
task.set (att->first, att->second.value ());
|
task.set (att->first, att->second.value ());
|
||||||
|
|
||||||
++changes;
|
++changes;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static std::vector <std::string> customReports;
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// This report will eventually become the one report that many others morph into
|
// This report will eventually become the one report that many others morph into
|
||||||
// via the .taskrc file.
|
// via the .taskrc file.
|
||||||
std::string handleCustomReport (const std::string& report)
|
int handleCustomReport (const std::string& report, std::string &outs)
|
||||||
{
|
{
|
||||||
// Load report configuration.
|
// Load report configuration.
|
||||||
std::string columnList = context.config.get ("report." + report + ".columns");
|
std::string columnList = context.config.get ("report." + report + ".columns");
|
||||||
@@ -94,21 +94,24 @@ std::string handleCustomReport (const std::string& report)
|
|||||||
labelList,
|
labelList,
|
||||||
sortList,
|
sortList,
|
||||||
filterList,
|
filterList,
|
||||||
tasks);
|
tasks,
|
||||||
|
outs);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// This report will eventually become the one report that many others morph into
|
// This report will eventually become the one report that many others morph into
|
||||||
// via the .taskrc file.
|
// via the .taskrc file.
|
||||||
|
|
||||||
std::string runCustomReport (
|
int runCustomReport (
|
||||||
const std::string& report,
|
const std::string& report,
|
||||||
const std::string& columnList,
|
const std::string& columnList,
|
||||||
const std::string& labelList,
|
const std::string& labelList,
|
||||||
const std::string& sortList,
|
const std::string& sortList,
|
||||||
const std::string& filterList,
|
const std::string& filterList,
|
||||||
std::vector <Task>& tasks)
|
std::vector <Task>& tasks,
|
||||||
|
std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
// Load report configuration.
|
// Load report configuration.
|
||||||
std::vector <std::string> columns;
|
std::vector <std::string> columns;
|
||||||
split (columns, columnList, ',');
|
split (columns, columnList, ',');
|
||||||
@@ -547,11 +550,14 @@ std::string runCustomReport (
|
|||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else {
|
||||||
out << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
13
src/edit.cpp
13
src/edit.cpp
@@ -499,7 +499,13 @@ static void parseTask (Task& task, const std::string& after)
|
|||||||
std::string::size_type gap = value.find (" ");
|
std::string::size_type gap = value.find (" ");
|
||||||
if (gap != std::string::npos)
|
if (gap != std::string::npos)
|
||||||
{
|
{
|
||||||
Date when (value.substr (0, gap));
|
Date when (value.substr (0, gap), context.config.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
|
// This guarantees that if more than one annotation has the same date,
|
||||||
|
// that the seconds will be different, thus unique, thus not squashed.
|
||||||
|
// Bug #249
|
||||||
|
when += (const int) annotations.size ();
|
||||||
|
|
||||||
std::stringstream name;
|
std::stringstream name;
|
||||||
name << "annotation_" << when.toEpoch ();
|
name << "annotation_" << when.toEpoch ();
|
||||||
std::string text = trim (value.substr (gap, std::string::npos), "\t ");
|
std::string text = trim (value.substr (gap, std::string::npos), "\t ");
|
||||||
@@ -593,7 +599,7 @@ ARE_THESE_REALLY_HARMFUL:
|
|||||||
// Introducing the Silver Bullet. This feature is the catch-all fixative for
|
// Introducing the Silver Bullet. This feature is the catch-all fixative for
|
||||||
// various other ills. This is like opening up the hood and going in with a
|
// various other ills. This is like opening up the hood and going in with a
|
||||||
// wrench. To be used sparingly.
|
// wrench. To be used sparingly.
|
||||||
std::string handleEdit ()
|
int handleEdit (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -637,7 +643,8 @@ std::string handleEdit ()
|
|||||||
context.tdb.commit ();
|
context.tdb.commit ();
|
||||||
context.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -666,6 +666,7 @@ static std::string importTask_1_6_0 (const std::vector <std::string>& lines)
|
|||||||
static std::string importTaskCmdLine (const std::vector <std::string>& lines)
|
static std::string importTaskCmdLine (const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
|
std::string unused;
|
||||||
|
|
||||||
std::vector <std::string>::const_iterator it;
|
std::vector <std::string>::const_iterator it;
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
for (it = lines.begin (); it != lines.end (); ++it)
|
||||||
@@ -680,7 +681,7 @@ static std::string importTaskCmdLine (const std::vector <std::string>& lines)
|
|||||||
context.task.clear ();
|
context.task.clear ();
|
||||||
context.cmd.command = "";
|
context.cmd.command = "";
|
||||||
context.parse ();
|
context.parse ();
|
||||||
handleAdd ();
|
(void)handleAdd (unused);
|
||||||
context.clearMessages ();
|
context.clearMessages ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,6 +790,8 @@ static std::string importTodoSh_2_0 (const std::vector <std::string>& lines)
|
|||||||
context.parse ();
|
context.parse ();
|
||||||
decorateTask (context.task);
|
decorateTask (context.task);
|
||||||
|
|
||||||
|
context.task.set ("uuid", uuid ());
|
||||||
|
|
||||||
if (isPending)
|
if (isPending)
|
||||||
{
|
{
|
||||||
context.task.setStatus (Task::pending);
|
context.task.setStatus (Task::pending);
|
||||||
@@ -1144,7 +1147,7 @@ static std::string importCSV (const std::vector <std::string>& lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleImport ()
|
int handleImport (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -1212,7 +1215,8 @@ std::string handleImport ()
|
|||||||
else
|
else
|
||||||
throw std::string ("You must specify a file to import.");
|
throw std::string ("You must specify a file to import.");
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
//#include "text.h"
|
//#include "text.h"
|
||||||
//#include "util.h"
|
//#include "util.h"
|
||||||
//#include "main.h"
|
#include "main.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "../auto.h"
|
#include "../auto.h"
|
||||||
|
|
||||||
|
|||||||
71
src/main.h
71
src/main.h
@@ -55,25 +55,25 @@ int getDueState (const std::string&);
|
|||||||
bool nag (Task&);
|
bool nag (Task&);
|
||||||
|
|
||||||
// command.cpp
|
// command.cpp
|
||||||
std::string handleAdd ();
|
int handleAdd (std::string &);
|
||||||
std::string handleAppend ();
|
int handleAppend (std::string &);
|
||||||
std::string handleExport ();
|
int handleExport (std::string &);
|
||||||
std::string handleDone ();
|
int handleDone (std::string &);
|
||||||
std::string handleModify ();
|
int handleModify (std::string &);
|
||||||
std::string handleProjects ();
|
int handleProjects (std::string &);
|
||||||
std::string handleCompletionProjects ();
|
int handleCompletionProjects (std::string &);
|
||||||
std::string handleTags ();
|
int handleTags (std::string &);
|
||||||
std::string handleCompletionTags ();
|
int handleCompletionTags (std::string &);
|
||||||
std::string handleCompletionCommands ();
|
int handleCompletionCommands (std::string &);
|
||||||
std::string handleCompletionIDs ();
|
int handleCompletionIDs (std::string &);
|
||||||
std::string handleCompletionConfig ();
|
int handleCompletionConfig (std::string &);
|
||||||
std::string handleVersion ();
|
int handleVersion (std::string &);
|
||||||
std::string handleDelete ();
|
int handleDelete (std::string &);
|
||||||
std::string handleStart ();
|
int handleStart (std::string &);
|
||||||
std::string handleStop ();
|
int handleStop (std::string &);
|
||||||
std::string handleColor ();
|
int handleColor (std::string &);
|
||||||
std::string handleAnnotate ();
|
int handleAnnotate (std::string &);
|
||||||
std::string handleDuplicate ();
|
int handleDuplicate (std::string &);
|
||||||
void handleUndo ();
|
void handleUndo ();
|
||||||
#ifdef FEATURE_SHELL
|
#ifdef FEATURE_SHELL
|
||||||
void handleShell ();
|
void handleShell ();
|
||||||
@@ -85,27 +85,28 @@ int deltaAttributes (Task&);
|
|||||||
int deltaSubstitutions (Task&);
|
int deltaSubstitutions (Task&);
|
||||||
|
|
||||||
// edit.cpp
|
// edit.cpp
|
||||||
std::string handleEdit ();
|
int handleEdit (std::string &);
|
||||||
|
|
||||||
// report.cpp
|
// report.cpp
|
||||||
std::string shortUsage ();
|
int shortUsage (std::string &);
|
||||||
std::string longUsage ();
|
int longUsage (std::string &);
|
||||||
std::string handleInfo ();
|
int handleInfo (std::string &);
|
||||||
std::string handleReportSummary ();
|
int handleReportSummary (std::string &);
|
||||||
std::string handleReportNext ();
|
int handleReportNext (std::string &);
|
||||||
std::string handleReportHistory ();
|
int handleReportHistory (std::string &);
|
||||||
std::string handleReportGHistory ();
|
int handleReportGHistory (std::string &);
|
||||||
std::string handleReportCalendar ();
|
int handleReportCalendar (std::string &);
|
||||||
std::string handleReportStats ();
|
int handleReportStats (std::string &);
|
||||||
std::string handleReportTimesheet ();
|
int handleReportTimesheet (std::string &);
|
||||||
std::string getFullDescription (Task&);
|
std::string getFullDescription (Task&);
|
||||||
std::string getDueDate (Task&);
|
std::string getDueDate (Task&);
|
||||||
|
|
||||||
// custom.cpp
|
// custom.cpp
|
||||||
std::string handleCustomReport (const std::string&);
|
int handleCustomReport (const std::string&, std::string &);
|
||||||
std::string runCustomReport (const std::string&, const std::string&,
|
int runCustomReport (const std::string&, const std::string&,
|
||||||
const std::string&, const std::string&,
|
const std::string&, const std::string&,
|
||||||
const std::string&, std::vector <Task>&);
|
const std::string&, std::vector <Task>&,
|
||||||
|
std::string&);
|
||||||
void validReportColumns (const std::vector <std::string>&);
|
void validReportColumns (const std::vector <std::string>&);
|
||||||
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ std::string colorizeFootnote (const std::string&);
|
|||||||
std::string colorizeDebug (const std::string&);
|
std::string colorizeDebug (const std::string&);
|
||||||
|
|
||||||
// import.cpp
|
// import.cpp
|
||||||
std::string handleImport ();
|
int handleImport (std::string&);
|
||||||
|
|
||||||
// list template
|
// list template
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
extern Context context;
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string shortUsage ()
|
int shortUsage (std::string &outs)
|
||||||
{
|
{
|
||||||
Table table;
|
Table table;
|
||||||
|
|
||||||
@@ -209,14 +209,19 @@ std::string shortUsage ()
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string longUsage ()
|
int longUsage (std::string &outs)
|
||||||
{
|
{
|
||||||
|
std::string shortUsageString;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
out << shortUsage ()
|
|
||||||
|
(void)shortUsage(shortUsageString);
|
||||||
|
|
||||||
|
out << shortUsageString
|
||||||
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
||||||
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
||||||
<< "will be affected. To specify multiple IDs make sure you use one "
|
<< "will be affected. To specify multiple IDs make sure you use one "
|
||||||
@@ -276,13 +281,15 @@ std::string longUsage ()
|
|||||||
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
|
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Display all information for the given task.
|
// Display all information for the given task.
|
||||||
std::string handleInfo ()
|
int handleInfo (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
@@ -497,18 +504,22 @@ std::string handleInfo ()
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! tasks.size ())
|
if (! tasks.size ()) {
|
||||||
out << "No matches." << std::endl;
|
out << "No matches." << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Project Remaining Avg Age Complete 0% 100%
|
// Project Remaining Avg Age Complete 0% 100%
|
||||||
// A 12 13d 55% XXXXXXXXXXXXX-----------
|
// A 12 13d 55% XXXXXXXXXXXXX-----------
|
||||||
// B 109 3d 12h 10% XXX---------------------
|
// B 109 3d 12h 10% XXX---------------------
|
||||||
std::string handleReportSummary ()
|
int handleReportSummary (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
context.tdb.lock (context.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
@@ -648,10 +659,13 @@ std::string handleReportSummary ()
|
|||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " project" : " projects")
|
<< (table.rowCount () == 1 ? " project" : " projects")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else {
|
||||||
out << "No projects." << std::endl;
|
out << "No projects." << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -673,7 +687,7 @@ std::string handleReportSummary ()
|
|||||||
//
|
//
|
||||||
// Make the "three" tasks a configurable number
|
// Make the "three" tasks a configurable number
|
||||||
//
|
//
|
||||||
std::string handleReportNext ()
|
int handleReportNext (std::string &outs)
|
||||||
{
|
{
|
||||||
// Load report configuration.
|
// Load report configuration.
|
||||||
std::string columnList = context.config.get ("report.next.columns");
|
std::string columnList = context.config.get ("report.next.columns");
|
||||||
@@ -718,7 +732,8 @@ std::string handleReportNext ()
|
|||||||
labelList,
|
labelList,
|
||||||
sortList,
|
sortList,
|
||||||
filterList,
|
filterList,
|
||||||
tasks);
|
tasks,
|
||||||
|
outs);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -744,8 +759,9 @@ time_t monthlyEpoch (const std::string& date)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string handleReportHistory ()
|
int handleReportHistory (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::map <time_t, int> groups; // Represents any month with data
|
std::map <time_t, int> groups; // Represents any month with data
|
||||||
std::map <time_t, int> addedGroup; // Additions by month
|
std::map <time_t, int> addedGroup; // Additions by month
|
||||||
std::map <time_t, int> completedGroup; // Completions by month
|
std::map <time_t, int> completedGroup; // Completions by month
|
||||||
@@ -891,15 +907,19 @@ std::string handleReportHistory ()
|
|||||||
out << optionalBlankLine ()
|
out << optionalBlankLine ()
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else {
|
||||||
out << "No tasks." << std::endl;
|
out << "No tasks." << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleReportGHistory ()
|
int handleReportGHistory (std::string &outs)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
std::map <time_t, int> groups; // Represents any month with data
|
std::map <time_t, int> groups; // Represents any month with data
|
||||||
std::map <time_t, int> addedGroup; // Additions by month
|
std::map <time_t, int> addedGroup; // Additions by month
|
||||||
std::map <time_t, int> completedGroup; // Completions by month
|
std::map <time_t, int> completedGroup; // Completions by month
|
||||||
@@ -1087,14 +1107,17 @@ std::string handleReportGHistory ()
|
|||||||
else
|
else
|
||||||
out << "Legend: + added, X completed, - deleted" << std::endl;
|
out << "Legend: + added, X completed, - deleted" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
out << "No tasks." << std::endl;
|
out << "No tasks." << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleReportTimesheet ()
|
int handleReportTimesheet (std::string &outs)
|
||||||
{
|
{
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
std::vector <Task> tasks;
|
std::vector <Task> tasks;
|
||||||
@@ -1264,7 +1287,8 @@ std::string handleReportTimesheet ()
|
|||||||
end -= 7 * 86400;
|
end -= 7 * 86400;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1432,7 +1456,7 @@ std::string renderMonths (
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleReportCalendar ()
|
int handleReportCalendar (std::string &outs)
|
||||||
{
|
{
|
||||||
// Each month requires 28 text columns width. See how many will actually
|
// Each month requires 28 text columns width. See how many will actually
|
||||||
// fit. But if a preference is specified, and it fits, use it.
|
// fit. But if a preference is specified, and it fits, use it.
|
||||||
@@ -1604,11 +1628,12 @@ std::string handleReportCalendar ()
|
|||||||
<< optionalBlankLine ()
|
<< optionalBlankLine ()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleReportStats ()
|
int handleReportStats (std::string &outs)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -1836,7 +1861,8 @@ std::string handleReportStats ()
|
|||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine ();
|
<< optionalBlankLine ();
|
||||||
|
|
||||||
return out.str ();
|
outs = out.str ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
83
src/task.h
Normal file
83
src/task.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// task - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program 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 2 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, write to the
|
||||||
|
//
|
||||||
|
// Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor,
|
||||||
|
// Boston, MA
|
||||||
|
// 02110-1301
|
||||||
|
// USA
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef INCLUDED_TASK
|
||||||
|
#define INCLUDED_TASK
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Record.h"
|
||||||
|
#include "Subst.h"
|
||||||
|
#include "Sequence.h"
|
||||||
|
|
||||||
|
class Task : public Record
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Task (); // Default constructor
|
||||||
|
Task (const Task&); // Copy constructor
|
||||||
|
Task& operator= (const Task&); // Assignment operator
|
||||||
|
bool operator== (const Task&); // Comparison operator
|
||||||
|
Task (const std::string&); // Parse
|
||||||
|
~Task (); // Destructor
|
||||||
|
|
||||||
|
void parse (const std::string&);
|
||||||
|
std::string composeCSV () const;
|
||||||
|
|
||||||
|
// Status values.
|
||||||
|
enum status {pending, completed, deleted, recurring, waiting};
|
||||||
|
|
||||||
|
// Public data.
|
||||||
|
int id;
|
||||||
|
|
||||||
|
// Series of helper functions.
|
||||||
|
static status textToStatus (const std::string&);
|
||||||
|
static std::string statusToText (status);
|
||||||
|
|
||||||
|
void setEntry ();
|
||||||
|
|
||||||
|
status getStatus ();
|
||||||
|
void setStatus (status);
|
||||||
|
|
||||||
|
int getTagCount ();
|
||||||
|
bool hasTag (const std::string&);
|
||||||
|
void addTag (const std::string&);
|
||||||
|
void addTags (const std::vector <std::string>&);
|
||||||
|
void getTags (std::vector<std::string>&) const;
|
||||||
|
void removeTag (const std::string&);
|
||||||
|
|
||||||
|
void getAnnotations (std::vector <Att>&) const;
|
||||||
|
void setAnnotations (const std::vector <Att>&);
|
||||||
|
void addAnnotation (const std::string&);
|
||||||
|
void removeAnnotations ();
|
||||||
|
|
||||||
|
void validate () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int determineVersion (const std::string&);
|
||||||
|
void legacyParse (const std::string&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -75,9 +75,9 @@ int main (int argc, char** argv)
|
|||||||
Att a5 ("name", "value");
|
Att a5 ("name", "value");
|
||||||
t.is (a5.composeF4 (), "name:\"value\"", "Att::composeF4 simple");
|
t.is (a5.composeF4 (), "name:\"value\"", "Att::composeF4 simple");
|
||||||
a5.value ("\"");
|
a5.value ("\"");
|
||||||
t.is (a5.composeF4 (), "name:\""\"", "Att::composeF4 encoded \"");
|
t.is (a5.composeF4 (), "name:\"&dquot;\"", "Att::composeF4 encoded \"");
|
||||||
a5.value ("\t\",[]:");
|
a5.value ("\t\",[]:");
|
||||||
t.is (a5.composeF4 (), "name:\"&tab;",&open;&close;:\"", "Att::composeF4 fully encoded \\t\",[]:");
|
t.is (a5.composeF4 (), "name:\"&tab;&dquot;,&open;&close;:\"", "Att::composeF4 fully encoded \\t\",[]:");
|
||||||
|
|
||||||
Att a6 ("name", 6);
|
Att a6 ("name", 6);
|
||||||
t.is (a6.value_int (), 6, "Att::value_int get");
|
t.is (a6.value_int (), 6, "Att::value_int get");
|
||||||
@@ -174,12 +174,12 @@ int main (int argc, char** argv)
|
|||||||
|
|
||||||
n = Nibbler ("name:\""\"");
|
n = Nibbler ("name:\""\"");
|
||||||
a7.parse (n);
|
a7.parse (n);
|
||||||
t.is (a7.composeF4 (), "name:\""\"",
|
t.is (a7.composeF4 (), "name:\"&dquot;\"",
|
||||||
"Att::parse (name:\""\")");
|
"Att::parse (name:\""\")");
|
||||||
|
|
||||||
n = Nibbler ("name:\"&tab;",&open;&close;:\"");
|
n = Nibbler ("name:\"&tab;",&open;&close;:\"");
|
||||||
a7.parse (n);
|
a7.parse (n);
|
||||||
t.is (a7.composeF4 (), "name:\"&tab;",&open;&close;:\"",
|
t.is (a7.composeF4 (), "name:\"&tab;&dquot;,&open;&close;:\"",
|
||||||
"Att::parse (name:\"&tab;",&open;&close;:\")");
|
"Att::parse (name:\"&tab;",&open;&close;:\")");
|
||||||
|
|
||||||
n = Nibbler ("total gibberish");
|
n = Nibbler ("total gibberish");
|
||||||
@@ -216,19 +216,19 @@ int main (int argc, char** argv)
|
|||||||
good = true;
|
good = true;
|
||||||
try {a7.parse (n);} catch (...) {good = false;}
|
try {a7.parse (n);} catch (...) {good = false;}
|
||||||
t.ok (good, "Att::parse (name:\"value)");
|
t.ok (good, "Att::parse (name:\"value)");
|
||||||
t.is (a7.composeF4 (), "name:\""value\"", "Att::composeF4 -> name:\""value\"");
|
t.is (a7.composeF4 (), "name:\"&dquot;value\"", "Att::composeF4 -> name:\"&dquot;value\"");
|
||||||
|
|
||||||
n = Nibbler ("name:value\"");
|
n = Nibbler ("name:value\"");
|
||||||
good = true;
|
good = true;
|
||||||
try {a7.parse (n);} catch (...) {good = false;}
|
try {a7.parse (n);} catch (...) {good = false;}
|
||||||
t.ok (good, "Att::parse (name:value\")");
|
t.ok (good, "Att::parse (name:value\")");
|
||||||
t.is (a7.composeF4 (), "name:\"value"\"", "Att::composeF4 -> name:\"value"\"");
|
t.is (a7.composeF4 (), "name:\"value&dquot;\"", "Att::composeF4 -> name:\"value&dquot;\"");
|
||||||
|
|
||||||
n = Nibbler ("name:val\"ue");
|
n = Nibbler ("name:val\"ue");
|
||||||
good = true;
|
good = true;
|
||||||
try {a7.parse (n);} catch (...) {good = false;}
|
try {a7.parse (n);} catch (...) {good = false;}
|
||||||
t.ok (good, "Att::parse (name:val\"ue)");
|
t.ok (good, "Att::parse (name:val\"ue)");
|
||||||
t.is (a7.composeF4 (), "name:\"val"ue\"", "Att::composeF4 -> name:\"val"ue\"");
|
t.is (a7.composeF4 (), "name:\"val&dquot;ue\"", "Att::composeF4 -> name:\"val&dquot;ue\"");
|
||||||
|
|
||||||
n = Nibbler ("name\"");
|
n = Nibbler ("name\"");
|
||||||
good = true;
|
good = true;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ if (open my $fh, '>', 'basic.rc')
|
|||||||
|
|
||||||
# Test the usage command.
|
# Test the usage command.
|
||||||
my $output = qx{../task rc:basic.rc};
|
my $output = qx{../task rc:basic.rc};
|
||||||
like ($output, qr/You must specify a command, or a task ID to modify/, 'missing command and ID');
|
like ($output, qr/You must specify a command, or a task ID to modify/m, 'missing command and ID');
|
||||||
|
|
||||||
# Test the version command.
|
# Test the version command.
|
||||||
$output = qx{../task rc:basic.rc version};
|
$output = qx{../task rc:basic.rc version};
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ if (open my $fh, '>', 'before.rc')
|
|||||||
# Create some exampel data directly.
|
# Create some exampel data directly.
|
||||||
if (open my $fh, '>', 'pending.data')
|
if (open my $fh, '>', 'pending.data')
|
||||||
{
|
{
|
||||||
# 1230000000 = 12/22/2008
|
# 1229947200 = 12/22/2008
|
||||||
# 1240000000 = 4/17/2009
|
# 1240000000 = 4/17/2009
|
||||||
print $fh <<EOF;
|
print $fh <<EOF;
|
||||||
[description:"foo" entry:"1230000000" start:"1230000000" status:"pending" uuid:"27097693-91c2-4cbe-ba89-ddcc87e5582c"]
|
[description:"foo" entry:"1229947200" start:"1229947200" status:"pending" uuid:"27097693-91c2-4cbe-ba89-ddcc87e5582c"]
|
||||||
[description:"bar" entry:"1240000000" start:"1240000000" status:"pending" uuid:"08f72d91-964c-424b-8fd5-556434648b6b"]
|
[description:"bar" entry:"1240000000" start:"1240000000" status:"pending" uuid:"08f72d91-964c-424b-8fd5-556434648b6b"]
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
106
src/tests/bug.hasnt.t
Executable file
106
src/tests/bug.hasnt.t
Executable file
@@ -0,0 +1,106 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
################################################################################
|
||||||
|
## task - a command line task list manager.
|
||||||
|
##
|
||||||
|
## Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## This program 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 2 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, write to the
|
||||||
|
##
|
||||||
|
## Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor,
|
||||||
|
## Boston, MA
|
||||||
|
## 02110-1301
|
||||||
|
## USA
|
||||||
|
##
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 19;
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', 'hasnt.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=.\n",
|
||||||
|
"confirmation=no\n";
|
||||||
|
close $fh;
|
||||||
|
ok (-r 'hasnt.rc', 'Created hasnt.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1
|
||||||
|
qx{../task rc:hasnt.rc add foo};
|
||||||
|
|
||||||
|
# 2
|
||||||
|
qx{../task rc:hasnt.rc add foo};
|
||||||
|
qx{../task rc:hasnt.rc 2 annotate bar};
|
||||||
|
|
||||||
|
# 3
|
||||||
|
qx{../task rc:hasnt.rc add foo};
|
||||||
|
qx{../task rc:hasnt.rc 3 annotate bar};
|
||||||
|
sleep 2;
|
||||||
|
qx{../task rc:hasnt.rc 3 annotate baz};
|
||||||
|
|
||||||
|
# 4
|
||||||
|
qx{../task rc:hasnt.rc add bar};
|
||||||
|
|
||||||
|
# 5
|
||||||
|
qx{../task rc:hasnt.rc add bar};
|
||||||
|
qx{../task rc:hasnt.rc 5 annotate foo};
|
||||||
|
|
||||||
|
# 6
|
||||||
|
qx{../task rc:hasnt.rc add bar};
|
||||||
|
qx{../task rc:hasnt.rc 6 annotate foo};
|
||||||
|
sleep 2;
|
||||||
|
qx{../task rc:hasnt.rc 6 annotate baz};
|
||||||
|
|
||||||
|
#7
|
||||||
|
qx{../task rc:hasnt.rc add one};
|
||||||
|
qx{../task rc:hasnt.rc 7 annotate two};
|
||||||
|
sleep 2;
|
||||||
|
qx{../task rc:hasnt.rc 7 annotate three};
|
||||||
|
|
||||||
|
my $output = qx{../task rc:hasnt.rc ls description.has:foo};
|
||||||
|
like ($output, qr/\n 1/, '1 has foo -> yes');
|
||||||
|
like ($output, qr/\n 2/, '2 has foo -> yes');
|
||||||
|
like ($output, qr/\n 3/, '3 has foo -> yes');
|
||||||
|
unlike ($output, qr/\n 4/, '4 has foo -> no');
|
||||||
|
like ($output, qr/\n 5/, '5 has foo -> yes');
|
||||||
|
like ($output, qr/\n 6/, '6 has foo -> yes');
|
||||||
|
unlike ($output, qr/\n 7/, '7 has foo -> no');
|
||||||
|
|
||||||
|
$output = qx{../task rc:hasnt.rc ls description.hasnt:foo};
|
||||||
|
unlike ($output, qr/\n 1/, '1 hasnt foo -> no');
|
||||||
|
unlike ($output, qr/\n 2/, '2 hasnt foo -> no');
|
||||||
|
unlike ($output, qr/\n 3/, '3 hasnt foo -> no');
|
||||||
|
like ($output, qr/\n 4/, '4 hasnt foo -> yes');
|
||||||
|
unlike ($output, qr/\n 5/, '5 hasnt foo -> no');
|
||||||
|
unlike ($output, qr/\n 6/, '6 hasnt foo -> no');
|
||||||
|
like ($output, qr/\n 7/, '7 hasnt foo -> yes');
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink 'pending.data';
|
||||||
|
ok (!-r 'pending.data', 'Removed pending.data');
|
||||||
|
|
||||||
|
unlink 'completed.data';
|
||||||
|
ok (!-r 'completed.data', 'Removed completed.data');
|
||||||
|
|
||||||
|
unlink 'undo.data';
|
||||||
|
ok (!-r 'undo.data', 'Removed undo.data');
|
||||||
|
|
||||||
|
unlink 'hasnt.rc';
|
||||||
|
ok (!-r 'hasnt.rc', 'Removed hasnt.rc');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
65
src/tests/bug.range.t
Executable file
65
src/tests/bug.range.t
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
################################################################################
|
||||||
|
## task - a command line task list manager.
|
||||||
|
##
|
||||||
|
## Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## This program 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 2 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, write to the
|
||||||
|
##
|
||||||
|
## Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor,
|
||||||
|
## Boston, MA
|
||||||
|
## 02110-1301
|
||||||
|
## USA
|
||||||
|
##
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 8;
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', 'range.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=.\n",
|
||||||
|
"confirmation=no\n";
|
||||||
|
close $fh;
|
||||||
|
ok (-r 'range.rc', 'Created range.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add three tasks, and attempt to list the middle one within a range.
|
||||||
|
qx{../task rc:range.rc add one due:8/1/2009};
|
||||||
|
qx{../task rc:range.rc add two due:8/3/2009};
|
||||||
|
qx{../task rc:range.rc add three due:8/5/2009};
|
||||||
|
my $output = qx{../task rc:range.rc ls due.after:8/2/2009 due.before:8/4/2009};
|
||||||
|
unlike ($output, qr/one/, 'Missing prior to range');
|
||||||
|
like ($output, qr/two/, 'Found within range');
|
||||||
|
unlike ($output, qr/three/, 'Missing after range');
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink 'pending.data';
|
||||||
|
ok (!-r 'pending.data', 'Removed pending.data');
|
||||||
|
|
||||||
|
unlink 'completed.data';
|
||||||
|
ok (!-r 'completed.data', 'Removed completed.data');
|
||||||
|
|
||||||
|
unlink 'undo.data';
|
||||||
|
ok (!-r 'undo.data', 'Removed undo.data');
|
||||||
|
|
||||||
|
unlink 'range.rc';
|
||||||
|
ok (!-r 'range.rc', 'Removed range.rc');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
61
src/tests/bug.recur.t
Executable file
61
src/tests/bug.recur.t
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
################################################################################
|
||||||
|
## task - a command line task list manager.
|
||||||
|
##
|
||||||
|
## Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## This program 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 2 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, write to the
|
||||||
|
##
|
||||||
|
## Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor,
|
||||||
|
## Boston, MA
|
||||||
|
## 02110-1301
|
||||||
|
## USA
|
||||||
|
##
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 6;
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', 'recur.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=.\n",
|
||||||
|
"confirmation=no\n";
|
||||||
|
close $fh;
|
||||||
|
ok (-r 'recur.rc', 'Created recur.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a recurring task with no due date, look for expected error.
|
||||||
|
qx{../task rc:recur.rc add foo recur:daily};
|
||||||
|
my $output = qx{../task rc:recur.rc info 1};
|
||||||
|
unlike ($output, qr/Description\s+foo/, 'task not created - missing due date');
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink 'pending.data';
|
||||||
|
ok (!-r 'pending.data', 'Removed pending.data');
|
||||||
|
|
||||||
|
unlink 'completed.data';
|
||||||
|
ok (!-r 'completed.data', 'Removed completed.data');
|
||||||
|
|
||||||
|
unlink 'undo.data';
|
||||||
|
ok (!-r 'undo.data', 'Removed undo.data');
|
||||||
|
|
||||||
|
unlink 'recur.rc';
|
||||||
|
ok (!-r 'recur.rc', 'Removed recur.rc');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
62
src/tests/bug.start.extra.t
Executable file
62
src/tests/bug.start.extra.t
Executable file
@@ -0,0 +1,62 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
################################################################################
|
||||||
|
## task - a command line task list manager.
|
||||||
|
##
|
||||||
|
## Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## This program 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 2 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, write to the
|
||||||
|
##
|
||||||
|
## Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor,
|
||||||
|
## Boston, MA
|
||||||
|
## 02110-1301
|
||||||
|
## USA
|
||||||
|
##
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 7;
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', 'extra.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=.\n",
|
||||||
|
"confirmation=no\n";
|
||||||
|
close $fh;
|
||||||
|
ok (-r 'extra.rc', 'Created extra.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
qx{../task rc:extra.rc add foo};
|
||||||
|
my $output = qx{../task rc:extra.rc 1 start pri:L};
|
||||||
|
like ($output, qr/The 'start' command does not allow further modification of a task\./, 'no modifications allowed for start');
|
||||||
|
$output = qx{../task rc:extra.rc 1 stop pro:bar};
|
||||||
|
like ($output, qr/The 'stop' command does not allow further modification of a task\./, 'no modifications allowed for stop');
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink 'pending.data';
|
||||||
|
ok (!-r 'pending.data', 'Removed pending.data');
|
||||||
|
|
||||||
|
unlink 'completed.data';
|
||||||
|
ok (!-r 'completed.data', 'Removed completed.data');
|
||||||
|
|
||||||
|
unlink 'undo.data';
|
||||||
|
ok (!-r 'undo.data', 'Removed undo.data');
|
||||||
|
|
||||||
|
unlink 'extra.rc';
|
||||||
|
ok (!-r 'extra.rc', 'Removed extra.rc');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ if (open my $fh, '>', 'custom.rc')
|
|||||||
ok (-r 'custom.rc', 'Created custom.rc');
|
ok (-r 'custom.rc', 'Created custom.rc');
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate the usage screen, and locate the custom report on it.
|
# Add a recurring and non-recurring task, look for the indicator.
|
||||||
qx{../task rc:custom.rc add foo due:tomorrow recur:weekly};
|
qx{../task rc:custom.rc add foo due:tomorrow recur:weekly};
|
||||||
qx{../task rc:custom.rc add bar};
|
qx{../task rc:custom.rc add bar};
|
||||||
my $output = qx{../task rc:custom.rc foo 2>&1};
|
my $output = qx{../task rc:custom.rc foo 2>&1};
|
||||||
|
|||||||
62
src/tests/feature.exit.t
Executable file
62
src/tests/feature.exit.t
Executable file
@@ -0,0 +1,62 @@
|
|||||||
|
#! /usr/bin/perl
|
||||||
|
################################################################################
|
||||||
|
## task - a command line task list manager.
|
||||||
|
##
|
||||||
|
## Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
## All rights reserved.
|
||||||
|
##
|
||||||
|
## This program 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 2 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, write to the
|
||||||
|
##
|
||||||
|
## Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor,
|
||||||
|
## Boston, MA
|
||||||
|
## 02110-1301
|
||||||
|
## USA
|
||||||
|
##
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 7;
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', 'exit.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=.\n",
|
||||||
|
"confirmation=no\n";
|
||||||
|
close $fh;
|
||||||
|
ok (-r 'exit.rc', 'Created exit.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
qx{../task rc:exit.rc add foo};
|
||||||
|
my $exit_good = system ('../task rc:exit.rc ls foo 2>&1 >>/dev/null');
|
||||||
|
is ($exit_good, 0, 'task returns 0 on success');
|
||||||
|
my $exit_bad = system ('../task rc:exit.rc ls bar 2>&1 >>/dev/null');
|
||||||
|
isnt ($exit_bad, 0, 'task returns non-zero on failure');
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink 'pending.data';
|
||||||
|
ok (!-r 'pending.data', 'Removed pending.data');
|
||||||
|
|
||||||
|
unlink 'completed.data';
|
||||||
|
ok (!-r 'completed.data', 'Removed completed.data');
|
||||||
|
|
||||||
|
unlink 'undo.data';
|
||||||
|
ok (!-r 'undo.data', 'Removed undo.data');
|
||||||
|
|
||||||
|
unlink 'exit.rc';
|
||||||
|
ok (!-r 'exit.rc', 'Removed exit.rc');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
@@ -111,52 +111,25 @@ unlike ($output, qr/six/, 'g6');
|
|||||||
unlike ($output, qr/seven/, 'g7');
|
unlike ($output, qr/seven/, 'g7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list -tag};
|
$output = qx{../task rc:filter.rc list -tag};
|
||||||
unlike ($output, qr/one/, 'g1');
|
unlike ($output, qr/one/, 'h1');
|
||||||
like ($output, qr/two/, 'g2');
|
like ($output, qr/two/, 'h2');
|
||||||
like ($output, qr/three/, 'g3');
|
like ($output, qr/three/, 'h3');
|
||||||
like ($output, qr/four/, 'g4');
|
like ($output, qr/four/, 'h4');
|
||||||
unlike ($output, qr/five/, 'g5');
|
unlike ($output, qr/five/, 'h5');
|
||||||
like ($output, qr/six/, 'g6');
|
like ($output, qr/six/, 'h6');
|
||||||
like ($output, qr/seven/, 'g7');
|
like ($output, qr/seven/, 'h7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list -missing};
|
$output = qx{../task rc:filter.rc list -missing};
|
||||||
like ($output, qr/one/, 'g1');
|
like ($output, qr/one/, 'i1');
|
||||||
like ($output, qr/two/, 'g2');
|
like ($output, qr/two/, 'i2');
|
||||||
like ($output, qr/three/, 'g3');
|
like ($output, qr/three/, 'i3');
|
||||||
like ($output, qr/four/, 'g4');
|
like ($output, qr/four/, 'i4');
|
||||||
like ($output, qr/five/, 'g5');
|
like ($output, qr/five/, 'i5');
|
||||||
like ($output, qr/six/, 'g6');
|
like ($output, qr/six/, 'i6');
|
||||||
like ($output, qr/seven/, 'g7');
|
like ($output, qr/seven/, 'i7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list +tag -tag};
|
$output = qx{../task rc:filter.rc list +tag -tag};
|
||||||
unlike ($output, qr/one/, 'g1');
|
unlike ($output, qr/one/, 'j1');
|
||||||
unlike ($output, qr/two/, 'g2');
|
|
||||||
unlike ($output, qr/three/, 'g3');
|
|
||||||
unlike ($output, qr/four/, 'g4');
|
|
||||||
unlike ($output, qr/five/, 'g5');
|
|
||||||
unlike ($output, qr/six/, 'g6');
|
|
||||||
unlike ($output, qr/seven/, 'g7');
|
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:H};
|
|
||||||
like ($output, qr/one/, 'h1');
|
|
||||||
like ($output, qr/two/, 'h2');
|
|
||||||
unlike ($output, qr/three/, 'h3');
|
|
||||||
unlike ($output, qr/four/, 'h4');
|
|
||||||
unlike ($output, qr/five/, 'h5');
|
|
||||||
unlike ($output, qr/six/, 'h6');
|
|
||||||
unlike ($output, qr/seven/, 'h7');
|
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:};
|
|
||||||
unlike ($output, qr/one/, 'i1');
|
|
||||||
unlike ($output, qr/two/, 'i2');
|
|
||||||
like ($output, qr/three/, 'i3');
|
|
||||||
unlike ($output, qr/four/, 'i4');
|
|
||||||
unlike ($output, qr/five/, 'i5');
|
|
||||||
unlike ($output, qr/six/, 'i6');
|
|
||||||
unlike ($output, qr/seven/, 'i7');
|
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A foo};
|
|
||||||
like ($output, qr/one/, 'j1');
|
|
||||||
unlike ($output, qr/two/, 'j2');
|
unlike ($output, qr/two/, 'j2');
|
||||||
unlike ($output, qr/three/, 'j3');
|
unlike ($output, qr/three/, 'j3');
|
||||||
unlike ($output, qr/four/, 'j4');
|
unlike ($output, qr/four/, 'j4');
|
||||||
@@ -164,25 +137,25 @@ unlike ($output, qr/five/, 'j5');
|
|||||||
unlike ($output, qr/six/, 'j6');
|
unlike ($output, qr/six/, 'j6');
|
||||||
unlike ($output, qr/seven/, 'j7');
|
unlike ($output, qr/seven/, 'j7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A +tag};
|
$output = qx{../task rc:filter.rc list project:A priority:H};
|
||||||
like ($output, qr/one/, 'k1');
|
like ($output, qr/one/, 'k1');
|
||||||
unlike ($output, qr/two/, 'k2');
|
like ($output, qr/two/, 'k2');
|
||||||
unlike ($output, qr/three/, 'k3');
|
unlike ($output, qr/three/, 'k3');
|
||||||
unlike ($output, qr/four/, 'k4');
|
unlike ($output, qr/four/, 'k4');
|
||||||
unlike ($output, qr/five/, 'k5');
|
unlike ($output, qr/five/, 'k5');
|
||||||
unlike ($output, qr/six/, 'k6');
|
unlike ($output, qr/six/, 'k6');
|
||||||
unlike ($output, qr/seven/, 'k7');
|
unlike ($output, qr/seven/, 'k7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:H foo};
|
$output = qx{../task rc:filter.rc list project:A priority:};
|
||||||
like ($output, qr/one/, 'l1');
|
unlike ($output, qr/one/, 'l1');
|
||||||
unlike ($output, qr/two/, 'l2');
|
unlike ($output, qr/two/, 'l2');
|
||||||
unlike ($output, qr/three/, 'l3');
|
like ($output, qr/three/, 'l3');
|
||||||
unlike ($output, qr/four/, 'l4');
|
unlike ($output, qr/four/, 'l4');
|
||||||
unlike ($output, qr/five/, 'l5');
|
unlike ($output, qr/five/, 'l5');
|
||||||
unlike ($output, qr/six/, 'l6');
|
unlike ($output, qr/six/, 'l6');
|
||||||
unlike ($output, qr/seven/, 'l7');
|
unlike ($output, qr/seven/, 'l7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:H +tag};
|
$output = qx{../task rc:filter.rc list project:A foo};
|
||||||
like ($output, qr/one/, 'm1');
|
like ($output, qr/one/, 'm1');
|
||||||
unlike ($output, qr/two/, 'm2');
|
unlike ($output, qr/two/, 'm2');
|
||||||
unlike ($output, qr/three/, 'm3');
|
unlike ($output, qr/three/, 'm3');
|
||||||
@@ -191,7 +164,7 @@ unlike ($output, qr/five/, 'm5');
|
|||||||
unlike ($output, qr/six/, 'm6');
|
unlike ($output, qr/six/, 'm6');
|
||||||
unlike ($output, qr/seven/, 'm7');
|
unlike ($output, qr/seven/, 'm7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag};
|
$output = qx{../task rc:filter.rc list project:A +tag};
|
||||||
like ($output, qr/one/, 'n1');
|
like ($output, qr/one/, 'n1');
|
||||||
unlike ($output, qr/two/, 'n2');
|
unlike ($output, qr/two/, 'n2');
|
||||||
unlike ($output, qr/three/, 'n3');
|
unlike ($output, qr/three/, 'n3');
|
||||||
@@ -200,14 +173,41 @@ unlike ($output, qr/five/, 'n5');
|
|||||||
unlike ($output, qr/six/, 'n6');
|
unlike ($output, qr/six/, 'n6');
|
||||||
unlike ($output, qr/seven/, 'n7');
|
unlike ($output, qr/seven/, 'n7');
|
||||||
|
|
||||||
|
$output = qx{../task rc:filter.rc list project:A priority:H foo};
|
||||||
|
like ($output, qr/one/, 'o1');
|
||||||
|
unlike ($output, qr/two/, 'o2');
|
||||||
|
unlike ($output, qr/three/, 'o3');
|
||||||
|
unlike ($output, qr/four/, 'o4');
|
||||||
|
unlike ($output, qr/five/, 'o5');
|
||||||
|
unlike ($output, qr/six/, 'o6');
|
||||||
|
unlike ($output, qr/seven/, 'o7');
|
||||||
|
|
||||||
|
$output = qx{../task rc:filter.rc list project:A priority:H +tag};
|
||||||
|
like ($output, qr/one/, 'p1');
|
||||||
|
unlike ($output, qr/two/, 'p2');
|
||||||
|
unlike ($output, qr/three/, 'p3');
|
||||||
|
unlike ($output, qr/four/, 'p4');
|
||||||
|
unlike ($output, qr/five/, 'p5');
|
||||||
|
unlike ($output, qr/six/, 'p6');
|
||||||
|
unlike ($output, qr/seven/, 'p7');
|
||||||
|
|
||||||
|
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag};
|
||||||
|
like ($output, qr/one/, 'q1');
|
||||||
|
unlike ($output, qr/two/, 'q2');
|
||||||
|
unlike ($output, qr/three/, 'q3');
|
||||||
|
unlike ($output, qr/four/, 'q4');
|
||||||
|
unlike ($output, qr/five/, 'q5');
|
||||||
|
unlike ($output, qr/six/, 'q6');
|
||||||
|
unlike ($output, qr/seven/, 'q7');
|
||||||
|
|
||||||
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag baz};
|
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag baz};
|
||||||
unlike ($output, qr/one/, 'n1');
|
unlike ($output, qr/one/, 'r1');
|
||||||
unlike ($output, qr/two/, 'n2');
|
unlike ($output, qr/two/, 'r2');
|
||||||
unlike ($output, qr/three/, 'n3');
|
unlike ($output, qr/three/, 'r3');
|
||||||
unlike ($output, qr/four/, 'n4');
|
unlike ($output, qr/four/, 'r4');
|
||||||
unlike ($output, qr/five/, 'n5');
|
unlike ($output, qr/five/, 'r5');
|
||||||
unlike ($output, qr/six/, 'n6');
|
unlike ($output, qr/six/, 'r6');
|
||||||
unlike ($output, qr/seven/, 'n7');
|
unlike ($output, qr/seven/, 'r7');
|
||||||
|
|
||||||
# Cleanup.
|
# Cleanup.
|
||||||
unlink 'pending.data';
|
unlink 'pending.data';
|
||||||
|
|||||||
Reference in New Issue
Block a user