mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
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:
parent
c82469fa2c
commit
229a3d309c
7 changed files with 149 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
104
src/command.cpp
104
src/command.cpp
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue