mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-19 19:03:07 +02:00
Shadow Files
- Removed the shadow file feature, which has caused much suffering since version 1.4.3.
This commit is contained in:
parent
7fdac6a09e
commit
150f72eed4
8 changed files with 7 additions and 182 deletions
|
@ -194,6 +194,8 @@
|
||||||
- The 'total active time' information is removed from the 'info' report. This
|
- The 'total active time' information is removed from the 'info' report. This
|
||||||
was being misinterpreted as support for time tracking.
|
was being misinterpreted as support for time tracking.
|
||||||
- Removed unused tips files (thanks to dev-zero).
|
- Removed unused tips files (thanks to dev-zero).
|
||||||
|
- Removed shadow file feature, replacing it with an example hook scripts that
|
||||||
|
performs the same function.
|
||||||
|
|
||||||
------ current release ---------------------------
|
------ current release ---------------------------
|
||||||
|
|
||||||
|
|
7
NEWS
7
NEWS
|
@ -39,9 +39,6 @@ New configuration options in taskwarrior 2.4.0
|
||||||
Newly deprecated features in taskwarrior 2.4.0
|
Newly deprecated features in taskwarrior 2.4.0
|
||||||
|
|
||||||
- The alias '_query' is deprecated.
|
- The alias '_query' is deprecated.
|
||||||
- The 'shadow file' feature is deprecated.
|
|
||||||
- The 'total active time' information is removed from the 'info' report.
|
|
||||||
This was being misinterpreted as support for time tracking.
|
|
||||||
|
|
||||||
Removed features in 2.4.0
|
Removed features in 2.4.0
|
||||||
|
|
||||||
|
@ -59,6 +56,10 @@ Removed features in 2.4.0
|
||||||
- Removed the 'complete.all.projects' setting that was not used.
|
- Removed the 'complete.all.projects' setting that was not used.
|
||||||
- Removed support for 'report.X.limit', which can now be set in the report
|
- Removed support for 'report.X.limit', which can now be set in the report
|
||||||
filter 'limit:N'.
|
filter 'limit:N'.
|
||||||
|
- The 'total active time' information is removed from the 'info' report.
|
||||||
|
This was being misinterpreted as support for time tracking.
|
||||||
|
- The 'shadow file' feature is removed, but replaced with an example hook
|
||||||
|
script that performs the same function..
|
||||||
|
|
||||||
Known Issues
|
Known Issues
|
||||||
|
|
||||||
|
|
|
@ -1067,35 +1067,6 @@ The coefficients reflect the relative importance of the various terms in the
|
||||||
urgency calculation. These are default values, and may be modified to suit your
|
urgency calculation. These are default values, and may be modified to suit your
|
||||||
preferences, but it is important that you carefully consider any modifications.
|
preferences, but it is important that you carefully consider any modifications.
|
||||||
|
|
||||||
.SS SHADOW FILE
|
|
||||||
|
|
||||||
Note, this feature is deprecated in 2.4.0.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B
|
|
||||||
shadow.file=$HOME/.task/shadow.txt
|
|
||||||
If specified, designates a file path that will be automatically written to by
|
|
||||||
taskwarrior, whenever the task database changes. In other words, it is
|
|
||||||
automatically kept up to date. The shadow.command configuration variable is
|
|
||||||
used to determine which report is written to the shadow file. There is no color
|
|
||||||
used in the shadow file. This feature can be useful in maintaining a current
|
|
||||||
file for use by programs like GeekTool, Conky or Samurize.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B
|
|
||||||
shadow.command=list
|
|
||||||
This is the command that is run to maintain the shadow file, determined by the
|
|
||||||
.I shadow.file
|
|
||||||
configuration variable. The format is identical to that of
|
|
||||||
.I default.command
|
|
||||||
\&. Please see the corresponding documentation for that command.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B
|
|
||||||
shadow.notify=on
|
|
||||||
When this value is set to "on", taskwarrior will display a message whenever the
|
|
||||||
shadow file is updated by some task command.
|
|
||||||
|
|
||||||
.SS DEFAULTS
|
.SS DEFAULTS
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -276,11 +276,6 @@ std::string Config::_defaults =
|
||||||
"# and any trailing '.value'.\n"
|
"# and any trailing '.value'.\n"
|
||||||
"rule.precedence.color=due.today,active,blocking,blocked,overdue,due,scheduled,keyword.,project.,tag.,uda.,recurring,pri.,tagged,completed,deleted\n"
|
"rule.precedence.color=due.today,active,blocking,blocked,overdue,due,scheduled,keyword.,project.,tag.,uda.,recurring,pri.,tagged,completed,deleted\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# Shadow file support\n"
|
|
||||||
"#shadow.file=/tmp/shadow.txt # Location of shadow file\n"
|
|
||||||
"#shadow.command=list # Task command for shadow file\n"
|
|
||||||
"#shadow.notify=on # Footnote when updated\n"
|
|
||||||
"\n"
|
|
||||||
"#default.project=foo # Default project for 'add' command\n"
|
"#default.project=foo # Default project for 'add' command\n"
|
||||||
"#default.priority=M # Default priority for 'add' command\n"
|
"#default.priority=M # Default priority for 'add' command\n"
|
||||||
"#default.due=eom # Default due date for 'add' command\n"
|
"#default.due=eom # Default due date for 'add' command\n"
|
||||||
|
|
|
@ -406,13 +406,7 @@ int Context::dispatch (std::string &out)
|
||||||
throw std::string ("");
|
throw std::string ("");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int rc = c->execute (out);
|
return c->execute (out);
|
||||||
|
|
||||||
// Write commands cause an update of the shadow file, if configured.
|
|
||||||
if (! c->read_only ())
|
|
||||||
shadow ();
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (commands["help"]);
|
assert (commands["help"]);
|
||||||
|
@ -521,59 +515,6 @@ bool Context::verbose (const std::string& token)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This needs to be taken out and shot, as soon as hooks will allow.
|
|
||||||
void Context::shadow ()
|
|
||||||
{
|
|
||||||
std::string file_name = config.get ("shadow.file");
|
|
||||||
std::string command = config.get ("shadow.command");
|
|
||||||
std::string rcfile = rc_file;
|
|
||||||
|
|
||||||
// A missing shadow file command uses the default command instead.
|
|
||||||
if (command == "")
|
|
||||||
command = config.get ("default.command");
|
|
||||||
|
|
||||||
if (file_name != "" &&
|
|
||||||
command != "")
|
|
||||||
{
|
|
||||||
File shadow_file (file_name);
|
|
||||||
|
|
||||||
// Check for dangerous shadow file settings.
|
|
||||||
std::string location = config.get ("data.location");
|
|
||||||
if (shadow_file._data == location + "/pending.data")
|
|
||||||
throw std::string (STRING_CONTEXT_SHADOW_P);
|
|
||||||
|
|
||||||
if (shadow_file._data == location + "/completed.data")
|
|
||||||
throw std::string (STRING_CONTEXT_SHADOW_C);
|
|
||||||
|
|
||||||
if (shadow_file._data == location + "/undo.data")
|
|
||||||
throw std::string (STRING_CONTEXT_SHADOW_U);
|
|
||||||
|
|
||||||
if (shadow_file._data == location + "/backlog.data")
|
|
||||||
throw std::string (STRING_CONTEXT_SHADOW_B);
|
|
||||||
|
|
||||||
// Compose the command. Put the rc overrides up front, so that they may
|
|
||||||
// be overridden by rc.shadow.command.
|
|
||||||
command = program +
|
|
||||||
" rc.detection:off" + // No need to determine terminal size
|
|
||||||
" rc.color:off" + // Color off by default
|
|
||||||
" rc.gc:off " + // GC off, to reduce headaches
|
|
||||||
" rc.locking:off" + // No file locking
|
|
||||||
" rc:" + rcfile + " " + // Use specified rc file
|
|
||||||
command + // User specified command
|
|
||||||
" >" + // Capture
|
|
||||||
shadow_file._data; // User specified file
|
|
||||||
|
|
||||||
debug ("Running shadow command: " + command);
|
|
||||||
system (command.c_str ());
|
|
||||||
|
|
||||||
// Optionally display a notification that the shadow file was updated.
|
|
||||||
// TODO Convert to a verbosity token.
|
|
||||||
if (config.getBoolean ("shadow.notify"))
|
|
||||||
footnote (format (STRING_CONTEXT_SHADOW_UPDATE, shadow_file._data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
const std::vector <std::string> Context::getColumns () const
|
const std::vector <std::string> Context::getColumns () const
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,6 @@ public:
|
||||||
int initialize (int, const char**); // all startup
|
int initialize (int, const char**); // all startup
|
||||||
int run ();
|
int run ();
|
||||||
int dispatch (std::string&); // command handler dispatch
|
int dispatch (std::string&); // command handler dispatch
|
||||||
void shadow (); // shadow file update
|
|
||||||
|
|
||||||
int getWidth (); // determine terminal width
|
int getWidth (); // determine terminal width
|
||||||
int getHeight (); // determine terminal height
|
int getHeight (); // determine terminal height
|
||||||
|
|
|
@ -175,9 +175,6 @@ int CmdShow::execute (std::string& output)
|
||||||
" row.padding"
|
" row.padding"
|
||||||
" rule.precedence.color"
|
" rule.precedence.color"
|
||||||
" search.case.sensitive"
|
" search.case.sensitive"
|
||||||
" shadow.command"
|
|
||||||
" shadow.file"
|
|
||||||
" shadow.notify"
|
|
||||||
" shell.prompt"
|
" shell.prompt"
|
||||||
" tag.indicator"
|
" tag.indicator"
|
||||||
" taskd.server"
|
" taskd.server"
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
#! /usr/bin/env perl
|
|
||||||
################################################################################
|
|
||||||
##
|
|
||||||
## Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
|
|
||||||
##
|
|
||||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
## of this software and associated documentation files (the "Software"), to deal
|
|
||||||
## in the Software without restriction, including without limitation the rights
|
|
||||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
## copies of the Software, and to permit persons to whom the Software is
|
|
||||||
## furnished to do so, subject to the following conditions:
|
|
||||||
##
|
|
||||||
## The above copyright notice and this permission notice shall be included
|
|
||||||
## in all copies or substantial portions of the Software.
|
|
||||||
##
|
|
||||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
## SOFTWARE.
|
|
||||||
##
|
|
||||||
## http://www.opensource.org/licenses/mit-license.php
|
|
||||||
##
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use Test::More tests => 1;
|
|
||||||
|
|
||||||
# Ensure environment has no influence.
|
|
||||||
delete $ENV{'TASKDATA'};
|
|
||||||
delete $ENV{'TASKRC'};
|
|
||||||
|
|
||||||
use File::Basename;
|
|
||||||
my $ut = basename ($0);
|
|
||||||
my $rc = $ut . '.rc';
|
|
||||||
|
|
||||||
# Create the rc file.
|
|
||||||
if (open my $fh, '>', $rc)
|
|
||||||
{
|
|
||||||
print $fh "data.location=.\n",
|
|
||||||
"shadow.file=shadow.txt\n",
|
|
||||||
"shadow.command=list\n";
|
|
||||||
close $fh;
|
|
||||||
}
|
|
||||||
|
|
||||||
=pod
|
|
||||||
I found a bug in the current version of task. Using recur and a shadow file will
|
|
||||||
lead to an infinite loop. To reproduce it, define a shadow file in the .taskrc,
|
|
||||||
set a command for it that rebuilds the database, e.g. "list", and then add a
|
|
||||||
task with a recurrence set, e.g. "task add due:today recur:1d infinite loop".
|
|
||||||
Task will then loop forever and add the same recurring task until it runs out of
|
|
||||||
memory. So I checked the source and I believe I found the cause.
|
|
||||||
handleRecurrence() in task.cpp will modify the mask, but writes it only after it
|
|
||||||
has added all new tasks. Adding the task will, however, invoke onChangeCallback,
|
|
||||||
which starts the same process all over again.
|
|
||||||
=cut
|
|
||||||
|
|
||||||
eval
|
|
||||||
{
|
|
||||||
$SIG{'ALRM'} = sub {die "alarm\n"};
|
|
||||||
alarm 10;
|
|
||||||
my $output = qx{../src/task rc:$rc list 2>&1;
|
|
||||||
../src/task rc:$rc add due:today recur:1d infinite loop 2>&1;
|
|
||||||
../src/task rc:$rc info 1 2>&1};
|
|
||||||
alarm 0;
|
|
||||||
|
|
||||||
like ($output, qr/^Description\s+infinite loop\n/m, "$ut: no hang");
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($@ eq "alarm\n")
|
|
||||||
{
|
|
||||||
fail ("$ut: task hang on add or recurring task, with shadow file, for 10s");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cleanup.
|
|
||||||
unlink qw(shadow.txt pending.data completed.data undo.data backlog.data), $rc;
|
|
||||||
exit 0;
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue