From d44e5926358180a949718cde75e50675a7b43e1c Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Thu, 23 Dec 2010 22:15:11 +0100 Subject: [PATCH 1/2] Bug #580 - reuse merge uri for autopush --- src/command.cpp | 10 +--- src/tests/bug.580.t | 108 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 8 deletions(-) create mode 100755 src/tests/bug.580.t diff --git a/src/command.cpp b/src/command.cpp index 830f254e8..5e03cd235 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -590,13 +590,6 @@ void handleMerge (std::string& outs) Uri uri (file, "merge"); uri.parse(); - if (sAutopush == "ask") - { - // expand uri - Uri push (file, "push"); - pushfile = push.data; - } - if (uri.data.length ()) { Directory location (context.config.get ("data.location")); @@ -627,10 +620,11 @@ void handleMerge (std::string& outs) if (tmpfile != "") 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) ) { std::string out; + context.task.set ("description", uri.data); handlePush (out); } } diff --git a/src/tests/bug.580.t b/src/tests/bug.580.t new file mode 100755 index 000000000..c5db8d279 --- /dev/null +++ b/src/tests/bug.580.t @@ -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; From ee77debfcedecc6a6a8880cec1bcefa94857a48d Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Fri, 24 Dec 2010 01:00:03 +0100 Subject: [PATCH 2/2] Bug #540 - fixed issue with user names containing @ characters - updated ChangeLog - updated task-sync.5 --- ChangeLog | 5 +++ doc/man/task-sync.5 | 15 +++++++ src/Uri.cpp | 98 +++++++++++++++++++++++++++------------------ src/tests/uri.t.cpp | 25 +++++++++++- 4 files changed, 103 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f3728955..266be29e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,12 +35,17 @@ + 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 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 Michelle Crane). + Fixed bug #555, which caused a segfault when logging a task with a project (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' filter (thanks to Thomas Sattler). + + Fixed bug #580, where reusing the merge uri for autopush failed when the + uri was taken from taskrc ------ old releases ------------------------------ diff --git a/doc/man/task-sync.5 b/doc/man/task-sync.5 index 35428a7bc..f8b8ecb1d 100644 --- a/doc/man/task-sync.5 +++ b/doc/man/task-sync.5 @@ -134,6 +134,21 @@ https://host[:port]/path/to/undo.data ftp://[user@]host[:port]/path/to/undo.data .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 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, diff --git a/src/Uri.cpp b/src/Uri.cpp index 87c57d74a..208a46b21 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -198,54 +198,74 @@ void Uri::parse () } std::string::size_type pos; - std::string uripart; - std::string pathDelimiter = "/"; + std::string uripart; + std::string pathDelimiter = "/"; - user = ""; - port = ""; + user = ""; + port = ""; // skip ^.*:// if ((pos = data.find ("://")) != std::string::npos) - { - protocol = data.substr(0, pos); - data = data.substr (pos+3); - // standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data - pathDelimiter = "/"; - } - else - { - protocol = "ssh"; - // scp-like syntax: [user@]host.xz:path/to/undo.data - pathDelimiter = ":"; - } + { + protocol = data.substr(0, pos); + data = data.substr (pos+3); + // standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data + pathDelimiter = "/"; + } + else + { + protocol = "ssh"; + // scp-like syntax: [user@]host.xz:path/to/undo.data + pathDelimiter = ":"; + } - // get host part - if ((pos = data.find (pathDelimiter)) != std::string::npos) - { - host = data.substr (0, pos); - path = data.substr (pos+1); - } - else - { + // user delimited by single quotes? + if ( data[0] == '\'' + && (pos = data.find("'", 1)) != std::string::npos ) + { + if (data[pos+1] == '@') + { + // 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."; - } + } - // parse host - if ((pos = host.find ("@")) != std::string::npos) - { - user = host.substr (0, pos); - host = host.substr (pos+1); - } - - // 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); - } + // port specified? + // 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; } //////////////////////////////////////////////////////////////////////////////// +// vim: et ts=2 sw=2 diff --git a/src/tests/uri.t.cpp b/src/tests/uri.t.cpp index 1d8913a1a..3af786331 100644 --- a/src/tests/uri.t.cpp +++ b/src/tests/uri.t.cpp @@ -35,7 +35,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (30); + UnitTest t (44); Uri uri1 ("asfd://user@host/folder/"); uri1.parse (); @@ -88,6 +88,29 @@ int main (int argc, char** argv) uri6.parse (); 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; }