command line: introduced --print-databases
Listing databases is now a dedicated operation, instead of being done whenever syncevolution was invoked without parameters. Advantages: - can be combined with property assignments for backends which do not work without that additional information - can be done for configured sources
This commit is contained in:
parent
765ed0f833
commit
bf6bab8f03
35
README.rst
35
README.rst
|
@ -13,8 +13,8 @@ synchronize personal information management data
|
|||
SYNOPSIS
|
||||
========
|
||||
|
||||
Show available sources:
|
||||
syncevolution
|
||||
List databases:
|
||||
syncevolution --print-databases [<properties>] [<config> <source>]
|
||||
|
||||
Show information about configuration(s):
|
||||
syncevolution --print-servers|--print-configs|--print-peers
|
||||
|
@ -115,13 +115,32 @@ context, without modifying a specific peer. This can be done by using
|
|||
`@default` (or some other context name) without anything before the
|
||||
`at` sign. The empty string "" is the same as `@default`. ::
|
||||
|
||||
syncevolution
|
||||
syncevolution --print-databases [<properties>] [<config> <source>]
|
||||
|
||||
If no arguments are given, then SyncEvolution will list all available
|
||||
data sources regardless whether there is a configuration file for them
|
||||
or not. The output includes the identifiers which can then be used to
|
||||
select those sources in a configuration file. For each source one can
|
||||
set a different synchronization mode in its configuration file. ::
|
||||
If no additional arguments are given, then SyncEvolution will list all
|
||||
available backends and the databases that can be accessed through each
|
||||
backend. This works without existing configurations. However, some
|
||||
backends, like for example the CalDAV backend, need additional
|
||||
information (like credentials or URL of a remote server). This
|
||||
additional information can be provided on the command line with
|
||||
property assignments (`username=...`) or in an existing configuration.
|
||||
|
||||
When listing all databases of all active sources, the output starts
|
||||
with a heading that lists the values for the `backend` property which
|
||||
select the backend, followed by the databases. Each database has a
|
||||
name and a unique ID (in brackets). Typically both can be used as
|
||||
value of the 'database' property. One database might be marked as
|
||||
`default`. It will be used when `database` is not set explicitly.
|
||||
|
||||
When selecting an existing source configuration or specifying the `backend`
|
||||
property on the command line, only the databases for that backend
|
||||
are listed and the initial line shows how that backend was selected
|
||||
(<config>/<source> resp. backend value).
|
||||
|
||||
Some backends do not support listing of databases. For example, the
|
||||
file backend synchronizes directories with one file per item and
|
||||
always needs an explicit `database` configuration because it cannot guess
|
||||
which directory it is meant to use.
|
||||
|
||||
syncevolution <config>
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ using namespace std;
|
|||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <fstream>
|
||||
|
@ -193,6 +194,9 @@ bool Cmdline::parse(vector<string> &parsed)
|
|||
m_dontrun = true;
|
||||
m_template = temp.substr (1);
|
||||
}
|
||||
} else if(boost::iequals(m_argv[opt], "--print-databases")) {
|
||||
operations.push_back(m_argv[opt]);
|
||||
m_printDatabases = true;
|
||||
} else if(boost::iequals(m_argv[opt], "--print-servers") ||
|
||||
boost::iequals(m_argv[opt], "--print-peers") ||
|
||||
boost::iequals(m_argv[opt], "--print-configs")) {
|
||||
|
@ -396,6 +400,7 @@ bool Cmdline::isSync()
|
|||
m_printServers || boost::trim_copy(m_server) == "?" ||
|
||||
m_printTemplates || m_dontrun ||
|
||||
m_argc == 1 || (m_useDaemon.wasSet() && m_argc == 2) ||
|
||||
m_printDatabases ||
|
||||
m_printConfig || m_remove ||
|
||||
(m_server == "" && m_argc > 1) ||
|
||||
m_configure || m_migrate ||
|
||||
|
@ -661,33 +666,73 @@ bool Cmdline::run() {
|
|||
}
|
||||
} else if (m_dontrun) {
|
||||
// user asked for information
|
||||
} else if (m_argc == 1 || (m_useDaemon.wasSet() && m_argc == 2)) {
|
||||
// no parameters: list databases and short usage
|
||||
} else if (m_printDatabases) {
|
||||
// list databases
|
||||
const SourceRegistry ®istry(SyncSource::getSourceRegistry());
|
||||
boost::shared_ptr<FilterConfigNode> sharedNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> configNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> hiddenNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> trackingNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> serverNode(new VolatileConfigNode());
|
||||
SyncSourceNodes nodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, "");
|
||||
SyncSourceParams params("list", nodes, boost::shared_ptr<SyncConfig>());
|
||||
|
||||
BOOST_FOREACH(const RegisterSyncSource *source, registry) {
|
||||
BOOST_FOREACH(const Values::value_type &alias, source->m_typeValues) {
|
||||
if (!alias.empty() && source->m_enabled) {
|
||||
SourceType type(*alias.begin());
|
||||
sharedNode->setProperty("backend", type.m_backend);
|
||||
sharedNode->setProperty("databaseFormat", type.m_localFormat);
|
||||
auto_ptr<SyncSource> source(SyncSource::createSource(params, false));
|
||||
if (source.get() != NULL) {
|
||||
listSources(*source, boost::join(alias, " = "));
|
||||
m_out << "\n";
|
||||
boost::shared_ptr<SyncSourceNodes> nodes;
|
||||
std::string header;
|
||||
boost::shared_ptr<SyncContext> context;
|
||||
FilterConfigNode::ConfigFilter sourceFilter = m_props.createSourceFilter(m_server, "");
|
||||
FilterConfigNode::ConfigFilter::const_iterator backend = sourceFilter.find("backend");
|
||||
|
||||
if (!m_server.empty()) {
|
||||
// list for specific backend chosen via config
|
||||
if (m_sources.size() != 1) {
|
||||
SE_THROW(StringPrintf("must specify exactly one source after the config name '%s'",
|
||||
m_server.c_str()));
|
||||
}
|
||||
context.reset(new SyncContext(m_server));
|
||||
if (!context->exists()) {
|
||||
SE_THROW(StringPrintf("config '%s' does not exist", m_server.c_str()));
|
||||
}
|
||||
nodes.reset(new SyncSourceNodes(context->getSyncSourceNodesNoTracking(*m_sources.begin())));
|
||||
header = StringPrintf("%s/%s", m_server.c_str(), m_sources.begin()->c_str());
|
||||
if (!nodes->dataConfigExists()) {
|
||||
SE_THROW(StringPrintf("%s does not exist",
|
||||
header.c_str()));
|
||||
}
|
||||
} else {
|
||||
context.reset(new SyncContext);
|
||||
boost::shared_ptr<FilterConfigNode> sharedNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> configNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> hiddenNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> trackingNode(new VolatileConfigNode());
|
||||
boost::shared_ptr<FilterConfigNode> serverNode(new VolatileConfigNode());
|
||||
nodes.reset(new SyncSourceNodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, ""));
|
||||
header = backend != sourceFilter.end() ?
|
||||
backend->second :
|
||||
"???";
|
||||
}
|
||||
nodes->getProperties()->setFilter(sourceFilter);
|
||||
FilterConfigNode::ConfigFilter syncFilter = m_props.createSyncFilter(m_server);
|
||||
context->setConfigFilter(true, "", syncFilter);
|
||||
|
||||
SyncSourceParams params("list", *nodes, context);
|
||||
if (!m_server.empty() || backend != sourceFilter.end()) {
|
||||
// list for specific backend
|
||||
auto_ptr<SyncSource> source(SyncSource::createSource(params, false, NULL));
|
||||
if (source.get() != NULL) {
|
||||
listSources(*source, header);
|
||||
m_out << "\n";
|
||||
} else {
|
||||
m_out << header << "\n cannot list databases" << std::endl;
|
||||
}
|
||||
} else {
|
||||
// list for all backends
|
||||
BOOST_FOREACH(const RegisterSyncSource *source, registry) {
|
||||
BOOST_FOREACH(const Values::value_type &alias, source->m_typeValues) {
|
||||
if (!alias.empty() && source->m_enabled) {
|
||||
SourceType type(*alias.begin());
|
||||
nodes->getProperties()->setProperty("backend", type.m_backend);
|
||||
auto_ptr<SyncSource> source(SyncSource::createSource(params, false));
|
||||
if (source.get() != NULL) {
|
||||
listSources(*source, boost::join(alias, " = "));
|
||||
m_out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usage(false);
|
||||
} else if (m_printConfig) {
|
||||
boost::shared_ptr<SyncConfig> config;
|
||||
ConfigProps syncFilter;
|
||||
|
@ -2276,7 +2321,7 @@ class CmdlineTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testConfigureTemplates);
|
||||
CPPUNIT_TEST(testConfigureSources);
|
||||
CPPUNIT_TEST(testOldConfigure);
|
||||
CPPUNIT_TEST(testListSources);
|
||||
CPPUNIT_TEST(testPrintDatabases);
|
||||
CPPUNIT_TEST(testMigrate);
|
||||
CPPUNIT_TEST(testMigrateContext);
|
||||
CPPUNIT_TEST(testMigrateAutoSync);
|
||||
|
@ -3858,12 +3903,61 @@ protected:
|
|||
return expected;
|
||||
}
|
||||
|
||||
void testListSources() {
|
||||
// pick the varargs constructor; NULL alone is ambiguous
|
||||
TestCmdline cmdline(NULL, NULL);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
// exact output varies, do not test
|
||||
void testPrintDatabases() {
|
||||
{
|
||||
// full output
|
||||
TestCmdline cmdline("--print-databases", (char *)0);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
// exact output varies, do not test
|
||||
}
|
||||
bool haveEDS;
|
||||
{
|
||||
// limit output to one specific backend
|
||||
TestCmdline cmdline("--print-databases", "backend=evolution-contacts", (char *)0);
|
||||
cmdline.doit();
|
||||
if (cmdline.m_err.str().find("not one of the valid values") != std::string::npos) {
|
||||
// not enabled, only this error messages expected
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
} else {
|
||||
// enabled, no error, one entry
|
||||
haveEDS = true;
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
CPPUNIT_ASSERT(boost::starts_with(cmdline.m_out.str(), "evolution-contacts:\n"));
|
||||
int entries = 0;
|
||||
BOOST_FOREACH(const std::string &line,
|
||||
boost::tokenizer< boost::char_separator<char> >(cmdline.m_out.str(),
|
||||
boost::char_separator<char>("\n"))) {
|
||||
if (!boost::starts_with(line, " ")) {
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL(1, entries);
|
||||
}
|
||||
}
|
||||
if (haveEDS) {
|
||||
// limit output to one specific backend, chosen via config
|
||||
{
|
||||
TestCmdline cmdline("--configure", "backend=evolution-contacts", "@foo-config", "bar-source", (char *)0);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
}
|
||||
{
|
||||
TestCmdline cmdline("--print-databases", "@foo-config", "bar-source", (char *)0);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
CPPUNIT_ASSERT(boost::starts_with(cmdline.m_out.str(), "@foo-config/bar-source:\n"));
|
||||
int entries = 0;
|
||||
BOOST_FOREACH(const std::string &line,
|
||||
boost::tokenizer< boost::char_separator<char> >(cmdline.m_out.str(),
|
||||
boost::char_separator<char>("\n"))) {
|
||||
if (!boost::starts_with(line, " ")) {
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL(1, entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testMigrate() {
|
||||
|
|
|
@ -143,6 +143,7 @@ protected:
|
|||
Bool m_remove;
|
||||
Bool m_run;
|
||||
Bool m_migrate;
|
||||
Bool m_printDatabases;
|
||||
Bool m_printServers;
|
||||
Bool m_printTemplates;
|
||||
Bool m_printConfig;
|
||||
|
|
Loading…
Reference in a new issue