Merge branch '1.9.4' of tasktools.org:task into 1.9.4

Conflicts:
	ChangeLog
This commit is contained in:
Paul Beckingham 2010-12-23 23:16:05 -05:00
commit 18c770141d
6 changed files with 213 additions and 48 deletions

View file

@ -35,12 +35,17 @@
+ Fixed bug #538, where some color legend items were not readable. + Fixed bug #538, where some color legend items were not readable.
+ Fixed bug #539, where the man page task-color(5) contained a line that + Fixed bug #539, where the man page task-color(5) contained a line that
began with a ' and was not displayed. began with a ' and was not displayed.
+ Fixed bug #540, where user names containing @s could not be parsed
+ Fixed bug #542, which sorted the countdown columns incorrectly (thanks to + Fixed bug #542, which sorted the countdown columns incorrectly (thanks to
Michelle Crane). Michelle Crane).
+ Fixed bug #555, which caused a segfault when logging a task with a project + Fixed bug #555, which caused a segfault when logging a task with a project
(thanks to Itay Perl). (thanks to Itay Perl).
+ Fixed bug #570, which used unsupported brace expansion with dash (default
/bin/sh in Ubuntu)
+ Fixed bug #579, which displayed incorrect counts when using the 'limit:N' + Fixed bug #579, which displayed incorrect counts when using the 'limit:N'
filter (thanks to Thomas Sattler). filter (thanks to Thomas Sattler).
+ Fixed bug #580, where reusing the merge uri for autopush failed when the
uri was taken from taskrc.
+ Applied patch to fix bug #581, in which backslashes in annotations and + Applied patch to fix bug #581, in which backslashes in annotations and
descriptions caused problems (thanks to Itay Perl). descriptions caused problems (thanks to Itay Perl).

View file

@ -134,6 +134,21 @@ https://host[:port]/path/to/undo.data
ftp://[user@]host[:port]/path/to/undo.data ftp://[user@]host[:port]/path/to/undo.data
.RE .RE
You can use single quotes to encapsulate user names that contain delimiting
characters like '@', '/' or ':', e.g.:
.br
.RS
ssh://'user@name'@host/
.RE
Remember to escape the quotes on your shell:
.br
.RS
$ task push ftp://\'user@name\':host/
.RE
.SH CONFLICTS .SH CONFLICTS
When modifications on the local and remote machine conflict, for example if When modifications on the local and remote machine conflict, for example if
both machines change the project name of the same task to different values, both machines change the project name of the same task to different values,

View file

@ -198,54 +198,74 @@ void Uri::parse ()
} }
std::string::size_type pos; std::string::size_type pos;
std::string uripart; std::string uripart;
std::string pathDelimiter = "/"; std::string pathDelimiter = "/";
user = ""; user = "";
port = ""; port = "";
// skip ^.*:// // skip ^.*://
if ((pos = data.find ("://")) != std::string::npos) if ((pos = data.find ("://")) != std::string::npos)
{ {
protocol = data.substr(0, pos); protocol = data.substr(0, pos);
data = data.substr (pos+3); data = data.substr (pos+3);
// standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data // standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data
pathDelimiter = "/"; pathDelimiter = "/";
} }
else else
{ {
protocol = "ssh"; protocol = "ssh";
// scp-like syntax: [user@]host.xz:path/to/undo.data // scp-like syntax: [user@]host.xz:path/to/undo.data
pathDelimiter = ":"; pathDelimiter = ":";
} }
// get host part // user delimited by single quotes?
if ((pos = data.find (pathDelimiter)) != std::string::npos) if ( data[0] == '\''
{ && (pos = data.find("'", 1)) != std::string::npos )
host = data.substr (0, pos); {
path = data.substr (pos+1); if (data[pos+1] == '@')
} {
else // end of user name
{ user = data.substr (1, pos-1);
data = data.substr (pos+2);
}
else
{
throw std::string ("Could not parse uri '") + data + "', wrong usage of single quotes.";
}
}
else
{
// find user name
if ((pos = data.find ("@")) != std::string::npos)
{
user = data.substr (0, pos);
data = data.substr (pos+1);
}
}
// get host, port and path
if ((pos = data.find (pathDelimiter)) != std::string::npos)
{
host = data.substr (0, pos);
path = data.substr (pos+1);
}
else
{
throw std::string ("The uri '") + data + "' is not in the expected format."; throw std::string ("The uri '") + data + "' is not in the expected format.";
} }
// parse host // port specified?
if ((pos = host.find ("@")) != std::string::npos) // remark: this find() will never be != npos for scp-like syntax
{ // because we found pathDelimiter, which is ":", before
user = host.substr (0, pos); if ((pos = host.find (":")) != std::string::npos)
host = host.substr (pos+1); {
} port = host.substr (pos+1);
host = host.substr (0,pos);
// remark: this find() will never be != npos for scp-like syntax }
// because we found pathDelimiter, which is ":", before
if ((pos = host.find (":")) != std::string::npos)
{
port = host.substr (pos+1);
host = host.substr (0,pos);
}
parsed = true; parsed = true;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// vim: et ts=2 sw=2

View file

@ -590,13 +590,6 @@ void handleMerge (std::string& outs)
Uri uri (file, "merge"); Uri uri (file, "merge");
uri.parse(); uri.parse();
if (sAutopush == "ask")
{
// expand uri
Uri push (file, "push");
pushfile = push.data;
}
if (uri.data.length ()) if (uri.data.length ())
{ {
Directory location (context.config.get ("data.location")); Directory location (context.config.get ("data.location"));
@ -627,10 +620,11 @@ void handleMerge (std::string& outs)
if (tmpfile != "") if (tmpfile != "")
remove (tmpfile.c_str ()); remove (tmpfile.c_str ());
if ( ((sAutopush == "ask") && (confirm ("Would you like to push the merged changes to \'" + pushfile + "\'?")) ) if ( ((sAutopush == "ask") && (confirm ("Would you like to push the merged changes to \'" + uri.data + "\'?")) )
|| (bAutopush) ) || (bAutopush) )
{ {
std::string out; std::string out;
context.task.set ("description", uri.data);
handlePush (out); handlePush (out);
} }
} }

108
src/tests/bug.580.t Executable file
View file

@ -0,0 +1,108 @@
#! /usr/bin/perl
################################################################################
## taskwarrior - a command line task list manager.
##
## Copyright 2006 - 2010, Paul Beckingham, Federico Hernandez.
## 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 => 16;
use File::Copy;
use constant false => 0;
use constant true => 1;
# Create data locations
mkdir("local", 0755);
ok(-e 'local', "Created directory local");
mkdir("remote", 0755);
ok(-e 'remote', "Created directory remote");
# Create the rc files.
if (open my $fh, '>', 'local.rc')
{
print $fh "data.location=./local\n",
"confirmation=no\n",
"merge.default.uri=remote/\n",
"merge.autopush=yes\n";
close $fh;
ok (-r 'local.rc', 'Created local.rc');
}
if (open my $fh, '>', 'remote.rc')
{
print $fh "data.location=./remote\n",
"confirmation=no\n",
"merge.autopush=no\n";
close $fh;
ok (-r 'remote.rc', 'Created remote.rc');
}
# add a remote task
qx{../task rc:remote.rc add remote task};
# add a local task
qx(../task rc:local.rc add local task);
# merge and autopush
qx{../task rc:local.rc merge};
my $output = qx{../task rc:remote.rc ls};
like ($output, qr/local task/, "autopush failed");
# Cleanup.
unlink 'local/pending.data';
ok (!-r 'local/pending.data', 'Removed local/pending.data');
unlink 'local/completed.data';
ok (!-r 'local/completed.data', 'Removed local/completed.data');
unlink 'local/undo.data';
ok (!-r 'local/undo.data', 'Removed local/undo.data');
unlink 'local/undo.save';
ok (!-r 'local/undo.save', 'Removed local/undo.save');
unlink 'local.rc';
ok (!-r 'local.rc', 'Removed local.rc');
unlink 'remote/pending.data';
ok (!-r 'remote/pending.data', 'Removed remote/pending.data');
unlink 'remote/completed.data';
ok (!-r 'remote/completed.data', 'Removed remote/completed.data');
unlink 'remote/undo.data';
ok (!-r 'remote/undo.data', 'Removed remote/undo.data');
unlink 'remote.rc';
ok (!-r 'remote.rc', 'Removed remote.rc');
rmdir("remote");
ok (!-e "remote", "Removed dir remote");
rmdir("local");
ok (!-e "local", "Removed dir local");
exit 0;

View file

@ -35,7 +35,7 @@ Context context;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
UnitTest t (30); UnitTest t (44);
Uri uri1 ("asfd://user@host/folder/"); Uri uri1 ("asfd://user@host/folder/");
uri1.parse (); uri1.parse ();
@ -88,6 +88,29 @@ int main (int argc, char** argv)
uri6.parse (); uri6.parse ();
t.is (uri6.path, "/home/user/.task/", "Uri::expand() test"); t.is (uri6.path, "/home/user/.task/", "Uri::expand() test");
Uri uri7 ("ftp://'user@name'@host:321/path/to/x");
uri7.parse ();
t.is (uri7.user, "user@name", "Uri::parse() : ftp://'user@name'@host:321/path/to/x");
t.is (uri7.host, "host", "Uri::parse() : ftp://'user@name'@host:321/path/to/x");
t.is (uri7.port, "321", "Uri::parse() : ftp://'user@name'@host:321/path/to/x");
t.is (uri7.path, "path/to/x", "Uri::parse() : ftp://'user@name'@host:321/path/to/x");
t.is (uri7.protocol, "ftp", "Uri::parse() : ftp://'user@name'@host:321/path/to/x");
Uri uri8 ("http://'us/er@n:ame'@host/path/to/x");
uri8.parse ();
t.is (uri8.user, "us/er@n:ame", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x");
t.is (uri8.host, "host", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x");
t.is (uri8.port, "", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x");
t.is (uri8.path, "path/to/x", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x");
t.is (uri8.protocol, "http", "Uri::parse() : http://'us/er@n:ame'@host/path/to/x");
Uri uri9 ("'user@name'@host:path/to/x");
uri9.parse ();
t.is (uri9.user, "user@name", "Uri::parse() : 'user@name'@host:path/to/x");
t.is (uri9.host, "host", "Uri::parse() : 'user@name'@host:path/to/x");
t.is (uri9.port, "", "Uri::parse() : 'user@name'@host:path/to/x");
t.is (uri9.path, "path/to/x", "Uri::parse() : 'user@name'@host:path/to/x");
return 0; return 0;
} }