CLI Command cleanup

This PR cleans up the `Command` classes in the CLI, introducing a
`DatabaseCommand` class for the commands operating on a database,
and a `getCommandLineParser` command to centralize the arguments
parsing and validation.

The opening of the database based on the CLI arguments and options
is now centralized in `DatabaseCommand.execute`, making it easy to
add new database opening features (like YubiKey support for the CLI).

Also a couple of bugs fixed:
  * `Create` was still using `stdout` for some error messages.
  * `Diceware` and `Generate` were not validating that the word count was an integer.
  * `Diceware` was also using `stdout` for some error messages.
This commit is contained in:
louib 2019-06-01 17:53:40 -04:00 committed by Jonathan White
parent 3cf171cbf5
commit 04360ed552
31 changed files with 591 additions and 637 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
*
* 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
@ -18,7 +18,6 @@
#include <cstdlib>
#include <stdio.h>
#include <QCommandLineParser>
#include <QFileInfo>
#include <QString>
#include <QTextStream>
@ -35,6 +34,8 @@ Create::Create()
{
name = QString("create");
description = QObject::tr("Create a new database.");
positionalArguments.append({QString("database"), QObject::tr("Path of the database."), QString("")});
options.append(Command::KeyFileOption);
}
Create::~Create()
@ -59,21 +60,13 @@ int Create::execute(const QStringList& arguments)
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
QCommandLineParser parser;
parser.setApplicationDescription(description);
parser.addPositionalArgument("database", QObject::tr("Path of the database."));
parser.addOption(Command::KeyFileOption);
parser.addHelpOption();
parser.process(arguments);
const QStringList args = parser.positionalArguments();
if (args.size() < 1) {
out << parser.helpText().replace("[options]", "create [options]");
QSharedPointer<QCommandLineParser> parser = getCommandLineParser(arguments);
if (parser.isNull()) {
return EXIT_FAILURE;
}
const QStringList args = parser->positionalArguments();
const QString& databaseFilename = args.at(0);
if (QFileInfo::exists(databaseFilename)) {
err << QObject::tr("File %1 already exists.").arg(databaseFilename) << endl;
@ -88,8 +81,8 @@ int Create::execute(const QStringList& arguments)
}
QSharedPointer<FileKey> fileKey;
if (parser.isSet(Command::KeyFileOption)) {
if (!loadFileKey(parser.value(Command::KeyFileOption), fileKey)) {
if (parser->isSet(Command::KeyFileOption)) {
if (!loadFileKey(parser->value(Command::KeyFileOption), fileKey)) {
err << QObject::tr("Loading the key file failed") << endl;
return EXIT_FAILURE;
}