Feature - #296 Setting configuration variables in .taskrc

- Now supports 'task config name value', 'task config name ""', and
  'task config name' to directly modify the .taskrc file.
- Updated man page.
- Added unit tests.
- Modified existing config command to also display configuration
  variables that have no values.
This commit is contained in:
Paul Beckingham 2010-01-17 00:02:17 -05:00
parent c82469fa2c
commit 229a3d309c
7 changed files with 149 additions and 12 deletions

View file

@ -26,6 +26,9 @@
information. information.
+ The 'config' command now complains about use of deprecated color names in + The 'config' command now complains about use of deprecated color names in
your .taskrc file. your .taskrc file.
+ Added feature #296, that allows the 'config' command to modify your .taskrc
settings directly, with the command 'task config <name> <value>', or
'task config <name>' to remove the setting.
+ Task now supports nested .taskrc files using the "include /path" directive. + Task now supports nested .taskrc files using the "include /path" directive.
+ The 'entry', 'start' and 'end' columns now have equivalents that include the + The 'entry', 'start' and 'end' columns now have equivalents that include the
time, and are called 'entry_time', 'start_time', and 'end_time', for use in time, and are called 'entry_time', 'start_time', and 'end_time', for use in

View file

@ -129,8 +129,22 @@ Displays all possible colors, or a sample.
Shows the task version number Shows the task version number
.TP .TP
.B config .B config [name [value | '']]
Shows the current settings in the task configuration file. 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':
task config name value
This command sets a blank value. This has the effect of suppressing any
default value:
task config name ''
Finally, this command removes any 'name=...' entry from the .taskrc file:
task config name
.TP .TP
.B help .B help
@ -157,9 +171,13 @@ Shows all tasks matching the specified criteria
that are completed. that are completed.
.TP .TP
.B ls [tags] [attrs] [description] .B minimal [tags] [attrs] [description]
Provides a minimal listing of tasks with specified criteria. Provides a minimal listing of tasks with specified criteria.
.TP
.B ls [tags] [attrs] [description]
Provides a short listing of tasks with specified criteria.
.TP .TP
.B list [tags] [attrs] [description] .B list [tags] [attrs] [description]
Provides a more detailed listing of tasks with specified criteria. Provides a more detailed listing of tasks with specified criteria.

View file

@ -271,7 +271,10 @@ void Config::load (const std::string& file, int nest /* = 1 */)
// First time in, load the default values. // First time in, load the default values.
if (nest == 1) if (nest == 1)
{
setDefaults (); setDefaults ();
original_file = File (file);
}
// Read the file, then parse the contents. // Read the file, then parse the contents.
std::string contents; std::string contents;

View file

@ -30,6 +30,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <string> #include <string>
#include "File.h"
class Config : public std::map <std::string, std::string> class Config : public std::map <std::string, std::string>
{ {
@ -60,6 +61,9 @@ public:
std::string checkForDeprecatedColor (); std::string checkForDeprecatedColor ();
public:
File original_file;
private: private:
static std::string defaults; static std::string defaults;
}; };

View file

@ -505,6 +505,101 @@ int handleConfig (std::string &outs)
{ {
int rc = 0; int rc = 0;
std::stringstream out; std::stringstream out;
// Support:
// task config name value # set name to value
// task config name "" # set name to blank
// task config name # remove name
if (context.args.size () >= 2)
{
std::string name = context.args[1];
std::string value = "";
if (context.args.size () >= 3)
value = context.args[2];
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 (context.args.size () >= 3)
{
// 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 overwrite the value of '") + name + "' with '" + 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 (); int width = context.getWidth ();
std::vector <std::string> all; std::vector <std::string> all;
@ -534,12 +629,9 @@ int handleConfig (std::string &outs)
foreach (i, all) foreach (i, all)
{ {
std::string value = context.config.get (*i); std::string value = context.config.get (*i);
if (value != "") int row = table.addRow ();
{ table.addCell (row, 0, *i);
int row = table.addRow (); table.addCell (row, 1, value);
table.addCell (row, 0, *i);
table.addCell (row, 1, value);
}
} }
Color bold ("bold"); Color bold ("bold");

View file

@ -187,8 +187,8 @@ int shortUsage (std::string &outs)
table.addCell (row, 2, "Shows the task version number."); table.addCell (row, 2, "Shows the task version number.");
row = table.addRow (); row = table.addRow ();
table.addCell (row, 1, "task config"); table.addCell (row, 1, "task config [name [value | '']]");
table.addCell (row, 2, "Shows the task configuration."); table.addCell (row, 2, "Shows the task configuration, or can add, modify and remove settings.");
row = table.addRow (); row = table.addRow ();
table.addCell (row, 1, "task help"); table.addCell (row, 1, "task help");

View file

@ -29,7 +29,7 @@
use strict; use strict;
use warnings; use warnings;
use File::Path; use File::Path;
use Test::More tests => 8; use Test::More tests => 12;
# Create the rc file, using rc.name:value. # Create the rc file, using rc.name:value.
unlink 'foo.rc'; unlink 'foo.rc';
@ -51,6 +51,23 @@ qx{echo 'y'|../task rc:foo.rc rc.data.location:foo};
ok (-r 'foo.rc', 'Created default rc file'); ok (-r 'foo.rc', 'Created default rc file');
ok (-d 'foo', 'Created default data directory'); 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};
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};
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};
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};
unlike ($output, qr/^must_be_unique/ms, 'config removing a value');
rmtree 'foo', 0, 0; rmtree 'foo', 0, 0;
ok (!-r 'foo', 'Removed foo'); ok (!-r 'foo', 'Removed foo');