From 51e5a18384be72c82103006e08c9b9d139bc98f0 Mon Sep 17 00:00:00 2001 From: Federico Hernandez Date: Mon, 7 Jun 2010 23:35:58 +0200 Subject: [PATCH] Enhancement - #307 show command - introduced new show command to display configuration settings - config command is used to just set config values - modified documentation - modified some unit tests calling 'task config' to 'task show' --- doc/man/task.1 | 12 +- i18n/strings.en-US | 1 + src/Cmd.cpp | 2 + src/Context.cpp | 1 + src/command.cpp | 235 +++++++++++++++++++---------------- src/i18n.h | 1 + src/main.h | 1 + src/report.cpp | 6 +- src/tests/color.deprecated.t | 2 +- src/tests/config.obsolete.t | 2 +- src/tests/rc.override.t | 4 +- src/tests/rc.t | 14 +-- 12 files changed, 156 insertions(+), 125 deletions(-) diff --git a/doc/man/task.1 b/doc/man/task.1 index 45e65b07f..1b2aef36b 100644 --- a/doc/man/task.1 +++ b/doc/man/task.1 @@ -129,12 +129,16 @@ Shows the task version number .B help Shows the long usage text. +.TP show +Shows the current settings in the task configuration file. If a section-name is +specified just the settings for the particular section will be displayed. +Section-names are: alias, calendar, color, general, holiday, report. + .TP .B config [name [value | '']] -Shows the current settings in the task configuration file. Also supports -directly modifying the .taskrc file. This command either modifies -the 'name' setting with a new value of 'value', or adds a new entry that -is equivalent to 'name=value': +Add, modify and remove settings directly in the task configuration. +This command either modifies the 'name' setting with a new value of 'value', +or adds a new entry that is equivalent to 'name=value': task config name value diff --git a/i18n/strings.en-US b/i18n/strings.en-US index 68f3a537b..d684ab4c6 100644 --- a/i18n/strings.en-US +++ b/i18n/strings.en-US @@ -59,6 +59,7 @@ 228 version 229 shell 230 config +231 show # 3xx Attributes - must be sequential 300 project diff --git a/src/Cmd.cpp b/src/Cmd.cpp index c3c240926..e2f9cfc94 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -126,6 +126,7 @@ void Cmd::load () commands.push_back (context.stringtable.get (CMD_CALENDAR, "calendar")); commands.push_back (context.stringtable.get (CMD_COLORS, "colors")); commands.push_back (context.stringtable.get (CMD_CONFIG, "config")); + commands.push_back (context.stringtable.get (CMD_SHOW, "show")); commands.push_back (context.stringtable.get (CMD_DELETE, "delete")); commands.push_back (context.stringtable.get (CMD_DONE, "done")); commands.push_back (context.stringtable.get (CMD_DUPLICATE, "duplicate")); @@ -211,6 +212,7 @@ bool Cmd::isReadOnlyCommand () command == context.stringtable.get (CMD_CALENDAR, "calendar") || command == context.stringtable.get (CMD_COLORS, "colors") || command == context.stringtable.get (CMD_CONFIG, "config") || + command == context.stringtable.get (CMD_SHOW, "show") || command == context.stringtable.get (CMD_HELP, "help") || command == context.stringtable.get (CMD_INFO, "info") || command == context.stringtable.get (CMD_PROJECTS, "projects") || diff --git a/src/Context.cpp b/src/Context.cpp index aa26d4030..6b8ddffc3 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -210,6 +210,7 @@ int Context::dispatch (std::string &out) else if (cmd.command == "colors") { rc = handleColor (out); } else if (cmd.command == "version") { rc = handleVersion (out); } else if (cmd.command == "config") { rc = handleConfig (out); } + else if (cmd.command == "show") { rc = handleShow (out); } else if (cmd.command == "help") { rc = longUsage (out); } else if (cmd.command == "stats") { rc = handleReportStats (out); } else if (cmd.command == "info") { rc = handleInfo (out); } diff --git a/src/command.cpp b/src/command.cpp index 55b4ece56..fa0296585 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -601,7 +601,7 @@ int handleVersion (std::string &outs) } //////////////////////////////////////////////////////////////////////////////// -int handleConfig (std::string &outs) +int handleShow (std::string &outs) { int rc = 0; @@ -614,114 +614,6 @@ int handleConfig (std::string &outs) std::vector args; split (args, context.task.get ("description"), ' '); - // Support: - // task config name value # set name to value - // task config name "" # set name to blank - // task config name # remove name - if (args.size () > 0) - { - std::string name = args[0]; - std::string value = ""; - - if (args.size () > 1) - { - for (unsigned int i = 1; i < args.size (); ++i) - { - if (i > 1) - value += " "; - - value += args[i]; - } - } - - if (name != "") - { - bool change = false; - - // Read .taskrc (or equivalent) - std::string contents; - File::read (context.config.original_file, contents); - - // task config name value - // task config name "" - if (args.size () > 1 || - context.args[context.args.size () - 1] == "") - { - // Find existing entry & overwrite - std::string::size_type pos = contents.find (name + "="); - if (pos != std::string::npos) - { - std::string::size_type eol = contents.find_first_of ("\r\f\n", pos); - if (eol == std::string::npos) - throw std::string ("Cannot find EOL after entry '") + name + "'"; - - if (confirm (std::string ("Are you sure you want to change the value of '") - + name - + "' from '" - + context.config.get(name) - + "' to '" - + value + "'?")) - { - contents = contents.substr (0, pos) - + name + "=" + value - + contents.substr (eol); - change = true; - } - } - - // Not found, so append instead. - else - { - if (confirm (std::string ("Are you sure you want to add '") + name + "' with a value of '" + value + "'?")) - { - contents = contents - + "\n" - + name + "=" + value - + "\n"; - change = true; - } - } - } - - // task config name - else - { - // Remove name - std::string::size_type pos = contents.find (name + "="); - if (pos == std::string::npos) - throw std::string ("No entry named '") + name + "' found"; - - std::string::size_type eol = contents.find_first_of ("\r\f\n", pos); - if (eol == std::string::npos) - throw std::string ("Cannot find EOL after entry '") + name + "'"; - - if (confirm (std::string ("Are you sure you want to remove '") + name + "'?")) - { - contents = contents.substr (0, pos) + contents.substr (eol + 1); - change = true; - } - } - - // Write .taskrc (or equivalent) - if (change) - { - File::write (context.config.original_file, contents); - out << "Config file " - << context.config.original_file.data - << " modified." - << std::endl; - } - else - out << "No changes made." << std::endl; - } - else - throw std::string ("Specify the name of a config variable to modify."); - - outs = out.str (); - return rc; - } - - // No arguments - display config values instead. int width = context.getWidth (); std::vector all; @@ -955,6 +847,131 @@ int handleConfig (std::string &outs) return rc; } +//////////////////////////////////////////////////////////////////////////////// +int handleConfig (std::string &outs) +{ + int rc = 0; + + if (context.hooks.trigger ("pre-config-command")) + { + std::stringstream out; + + // Obtain the arguments from the description. That way, things like '--' + // have already been handled. + std::vector args; + split (args, context.task.get ("description"), ' '); + + // Support: + // task config name value # set name to value + // task config name "" # set name to blank + // task config name # remove name + if (args.size () > 0) + { + std::string name = args[0]; + std::string value = ""; + + if (args.size () > 1) + { + for (unsigned int i = 1; i < args.size (); ++i) + { + if (i > 1) + value += " "; + + value += args[i]; + } + } + + if (name != "") + { + bool change = false; + + // Read .taskrc (or equivalent) + std::string contents; + File::read (context.config.original_file, contents); + + // task config name value + // task config name "" + if (args.size () > 1 || + context.args[context.args.size () - 1] == "") + { + // Find existing entry & overwrite + std::string::size_type pos = contents.find (name + "="); + if (pos != std::string::npos) + { + std::string::size_type eol = contents.find_first_of ("\r\f\n", pos); + if (eol == std::string::npos) + throw std::string ("Cannot find EOL after entry '") + name + "'"; + + if (confirm (std::string ("Are you sure you want to change the value of '") + + name + + "' from '" + + context.config.get(name) + + "' to '" + + value + "'?")) + { + contents = contents.substr (0, pos) + + name + "=" + value + + contents.substr (eol); + change = true; + } + } + + // Not found, so append instead. + else + { + if (confirm (std::string ("Are you sure you want to add '") + name + "' with a value of '" + value + "'?")) + { + contents = contents + + "\n" + + name + "=" + value + + "\n"; + change = true; + } + } + } + + // task config name + else + { + // Remove name + std::string::size_type pos = contents.find (name + "="); + if (pos == std::string::npos) + throw std::string ("No entry named '") + name + "' found"; + + std::string::size_type eol = contents.find_first_of ("\r\f\n", pos); + if (eol == std::string::npos) + throw std::string ("Cannot find EOL after entry '") + name + "'"; + + if (confirm (std::string ("Are you sure you want to remove '") + name + "'?")) + { + contents = contents.substr (0, pos) + contents.substr (eol + 1); + change = true; + } + } + + // Write .taskrc (or equivalent) + if (change) + { + File::write (context.config.original_file, contents); + out << "Config file " + << context.config.original_file.data + << " modified." + << std::endl; + } + else + out << "No changes made." << std::endl; + } + else + throw std::string ("Specify the name of a config variable to modify."); + outs = out.str (); + context.hooks.trigger ("post-config-command"); + } + else + throw std::string ("Specify the name of a config variable to modify."); + } + return rc; +} + //////////////////////////////////////////////////////////////////////////////// int handleDelete (std::string &outs) { diff --git a/src/i18n.h b/src/i18n.h index ac5127da1..4d3816d15 100644 --- a/src/i18n.h +++ b/src/i18n.h @@ -96,6 +96,7 @@ #define CMD_VERSION 228 #define CMD_SHELL 229 #define CMD_CONFIG 230 +#define CMD_SHOW 231 // 3xx Attributes #define ATT_PROJECT 300 diff --git a/src/main.h b/src/main.h index 66831cc48..19e6c1b42 100644 --- a/src/main.h +++ b/src/main.h @@ -71,6 +71,7 @@ int handleCompletionConfig (std::string &); int handleCompletionVersion (std::string &); int handleVersion (std::string &); int handleConfig (std::string &); +int handleShow (std::string &); int handleDelete (std::string &); int handleStart (std::string &); int handleStop (std::string &); diff --git a/src/report.cpp b/src/report.cpp index 4338f12a5..117ae3d8d 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -206,9 +206,13 @@ int shortUsage (std::string &outs) table.addCell (row, 1, "task version"); table.addCell (row, 2, "Shows the task version number."); + row = table.addRow (); + table.addCell (row, 1, "task show [section-name]"); + table.addCell (row, 2, "Shows the task entire configuration or a specific section."); + row = table.addRow (); table.addCell (row, 1, "task config [name [value | '']]"); - table.addCell (row, 2, "Shows the task configuration, or can add, modify and remove settings."); + table.addCell (row, 2, "Add, modify and remove settings in the task configuration."); row = table.addRow (); table.addCell (row, 1, "task help"); diff --git a/src/tests/color.deprecated.t b/src/tests/color.deprecated.t index d396840bc..74d176b18 100755 --- a/src/tests/color.deprecated.t +++ b/src/tests/color.deprecated.t @@ -41,7 +41,7 @@ if (open my $fh, '>', 'color.rc') } # Test the add command. -my $output = qx{../task rc:color.rc config}; +my $output = qx{../task rc:color.rc show}; like ($output, qr/that use deprecated underscores/ms, 'Deprecated color detected'); # Cleanup. diff --git a/src/tests/config.obsolete.t b/src/tests/config.obsolete.t index 4c883a636..3599e6a84 100755 --- a/src/tests/config.obsolete.t +++ b/src/tests/config.obsolete.t @@ -40,7 +40,7 @@ if (open my $fh, '>', 'obsolete.rc') } # Test the add command. -my $output = qx{../task rc:obsolete.rc config}; +my $output = qx{../task rc:obsolete.rc show}; like ($output, qr/Your .taskrc file contains these unrecognized variables:\n/, 'unsupported configuration variable'); diff --git a/src/tests/rc.override.t b/src/tests/rc.override.t index e6b56466f..f4df61ad6 100755 --- a/src/tests/rc.override.t +++ b/src/tests/rc.override.t @@ -39,10 +39,10 @@ if (open my $fh, '>', 'rc.rc') ok (-r 'rc.rc', 'Created rc.rc'); } -my $output = qx{../task rc:rc.rc config}; +my $output = qx{../task rc:rc.rc show}; like ($output, qr/\sfoo\s+bar/, 'unmodified'); -$output = qx{../task rc:rc.rc rc.foo:baz config}; +$output = qx{../task rc:rc.rc rc.foo:baz show}; like ($output, qr/\sfoo\s+baz/, 'overridden'); unlink 'rc.rc'; diff --git a/src/tests/rc.t b/src/tests/rc.t index 740e11a76..24172ee60 100755 --- a/src/tests/rc.t +++ b/src/tests/rc.t @@ -53,34 +53,34 @@ ok (-d 'foo', 'Created default data directory'); # Add a setting. qx{echo 'y'|../task rc:foo.rc config must_be_unique old}; -my $output = qx{../task rc:foo.rc config}; +my $output = qx{../task rc:foo.rc show}; like ($output, qr/^must_be_unique\s+old$/ms, 'config setting a new value'); qx{echo 'y'|../task rc:foo.rc config must_be_unique new}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; like ($output, qr/^must_be_unique\s+new$/ms, 'config overwriting an existing value'); qx{echo 'y'|../task rc:foo.rc config must_be_unique ''}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; like ($output, qr/^must_be_unique$/ms, 'config setting a blank value'); qx{echo 'y'|../task rc:foo.rc config must_be_unique}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; unlike ($output, qr/^must_be_unique/ms, 'config removing a value'); # 'report.:b' is designed to get past the config command checks for recognized # names. qx{echo 'y'|../task rc:foo.rc config -- report.:b +c}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; like ($output, qr/^report\.:b\s+\+c/ms, 'the -- operator is working'); # Make sure the value is accepted if it has multiple words. qx{echo 'y'|../task rc:foo.rc config must_be_unique 'one two three'}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; like ($output, qr/^must_be_unique\s+one two three$/ms, 'config allows multi-word quoted values'); qx{echo 'y'|../task rc:foo.rc config must_be_unique one two three}; -$output = qx{../task rc:foo.rc config}; +$output = qx{../task rc:foo.rc show}; like ($output, qr/^must_be_unique\s+one two three$/ms, 'config allows multi-word unquoted values'); rmtree 'foo', 0, 0;