aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/qbs/parser/commandlineoption.cpp
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2012-11-30 12:33:23 +0100
committerChristian Kandeler <christian.kandeler@digia.com>2012-12-05 11:53:34 +0100
commitaba4f72df71a406c04a065ceaf2f3d2ea8b9edbb (patch)
treef00cc81119f66c6717cd277058b9558342fda98e /src/app/qbs/parser/commandlineoption.cpp
parenta42474e5ce1c06ef2bfdc5d0ce8098b8e43be22b (diff)
Redo help output.
It's not feasible to document all commands and options correctly in one help screen. Instead, we now have a main help screen listing all possible commands and one dedicated help screen for every command. The more thorough and precise help output goes hand in hand with fixing a number of parsing bugs and underspecified commands. This, in turn, necessitated a refactoring of the command line parser, which is now much more modular. Change-Id: Id18f8c609d7d4a797a06598c3df4bc9ba02c9615 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/app/qbs/parser/commandlineoption.cpp')
-rw-r--r--src/app/qbs/parser/commandlineoption.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp
new file mode 100644
index 000000000..019884b6f
--- /dev/null
+++ b/src/app/qbs/parser/commandlineoption.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Build Suite.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+#include "commandlineoption.h"
+
+#include <logging/logger.h>
+#include <logging/translator.h>
+#include <tools/error.h>
+
+namespace qbs {
+using namespace Internal;
+
+CommandLineOption::~CommandLineOption()
+{
+}
+
+void CommandLineOption::parse(CommandType command, const QString &representation, QStringList &input)
+{
+ m_command = command;
+ doParse(representation, input);
+}
+
+QString CommandLineOption::getArgument(const QString &representation, QStringList &input)
+{
+ if (input.isEmpty()) {
+ throw Error(Tr::tr("Invalid use of option '%1': Missing argument.\nUsage: %2")
+ .arg(representation, description(command())));
+ }
+ return input.takeFirst();
+}
+
+QString FileOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2 <file>\n"
+ "\tUse <file> as the project file.\n"
+ "\tIf <file> is a directory and it contains a single file ending in '.qbs', "
+ "that file will be used.\n"
+ "\tIf this option is not given at all, the behavior is the same as for '-f .'.\n")
+ .arg(longRepresentation(), shortRepresentation());
+}
+
+QString FileOption::shortRepresentation() const
+{
+ return QLatin1String("-f");
+}
+
+QString FileOption::longRepresentation() const
+{
+ return QLatin1String("--file");
+}
+
+void FileOption::doParse(const QString &representation, QStringList &input)
+{
+ m_projectFilePath = getArgument(representation, input);
+}
+
+static QString loglevelLongRepresentation() { return QLatin1String("--log-level"); }
+
+QString VerboseOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2\n"
+ "\tBe more verbose. Increases the log level by one.\n"
+ "\tThis option can be given more than once. Excessive occurrences have no effect.\n"
+ "\tIf the option '%3' appears anywhere on the command line in addition to this option,\n"
+ "\tits value is taken as the base which to increase.\n")
+ .arg(longRepresentation(), shortRepresentation(), loglevelLongRepresentation());
+}
+
+QString VerboseOption::shortRepresentation() const
+{
+ return QLatin1String("-v");
+}
+
+QString VerboseOption::longRepresentation() const
+{
+ return QLatin1String("--more-verbose");
+}
+
+QString QuietOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2\n"
+ "\tBe more quiet. Decreases the log level by one.\n"
+ "\tThis option can be given more than once. Excessive occurrences have no effect.\n"
+ "\tIf option '%3' appears anywhere on the command line in addition to this option,\n"
+ "\tits value is taken as the base which to decrease.\n")
+ .arg(longRepresentation(), shortRepresentation(), loglevelLongRepresentation());
+}
+
+QString QuietOption::shortRepresentation() const
+{
+ return QLatin1String("-q");
+}
+
+QString QuietOption::longRepresentation() const
+{
+ return QLatin1String("--less-verbose");
+}
+
+QString JobsOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2 <n>\n"
+ "\tUse <n> concurrent build jobs. <n> must be an integer greater than zero. "
+ "The default is the number of cores.\n")
+ .arg(longRepresentation(), shortRepresentation());
+}
+
+QString JobsOption::shortRepresentation() const
+{
+ return QLatin1String("-j");
+}
+
+QString JobsOption::longRepresentation() const
+{
+ return QLatin1String("--jobs");
+}
+
+void JobsOption::doParse(const QString &representation, QStringList &input)
+{
+ const QString jobCountString = getArgument(representation, input);
+ bool stringOk;
+ m_jobCount = jobCountString.toInt(&stringOk);
+ if (!stringOk || m_jobCount <= 0)
+ throw Error(Tr::tr("Invalid use of option '%1': Illegal job count '%2'.\nUsage: %3")
+ .arg(representation, jobCountString, description(command())));
+}
+
+QString KeepGoingOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2\n"
+ "\tKeep going when errors occur (if at all possible).\n")
+ .arg(longRepresentation(), shortRepresentation());
+}
+
+QString KeepGoingOption::shortRepresentation() const
+{
+ return QLatin1String("-k");
+}
+
+QString KeepGoingOption::longRepresentation() const
+{
+ return QLatin1String("--keep-going");
+}
+
+QString DryRunOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2\n"
+ "\tDry run. No commands will be executed and no permanent changes to the "
+ "build graph will be done.\n").arg(longRepresentation(), shortRepresentation());
+}
+
+QString DryRunOption::shortRepresentation() const
+{
+ return QLatin1String("-n");
+}
+
+QString DryRunOption::longRepresentation() const
+{
+ return QLatin1String("--dry-run");
+}
+
+QString ShowProgressOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1\n"
+ "\tShow a progress bar. Implies '%2=%3'.\n").arg(longRepresentation(),
+ loglevelLongRepresentation(), Logger::logLevelName(LoggerMinLevel));
+}
+
+QString ShowProgressOption::longRepresentation() const
+{
+ return QLatin1String("--show-progress");
+}
+
+void StringListOption::doParse(const QString &representation, QStringList &input)
+{
+ m_arguments = getArgument(representation, input).split(QLatin1Char(','));
+ if (m_arguments.isEmpty()) {
+ throw Error(Tr::tr("Invalid use of option '%1': Argument list must not be empty.\n"
+ "Usage: %2").arg(representation, description(command())));
+ }
+ foreach (const QString &element, m_arguments) {
+ if (element.isEmpty()) {
+ throw Error(Tr::tr("Invalid use of option '%1': Argument list must not contain "
+ "empty elements.\nUsage: %2")
+ .arg(representation, description(command())));
+ }
+ }
+}
+
+QString ChangedFilesOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1 <file>[,<file>...]\n"
+ "\tAssume these and only these files have changed.\n").arg(longRepresentation());
+}
+
+QString ChangedFilesOption::longRepresentation() const
+{
+ return QLatin1String("--changed-files");
+}
+
+QString ProductsOption::description(CommandType command) const
+{
+ const QString prefix = Tr::tr("%1|%2").arg(longRepresentation(), shortRepresentation());
+ if (command == ShellCommandType) {
+ return Tr::tr("%1 <name>\n"
+ "\tUse the specified product.\n").arg(prefix);
+ }
+ return Tr::tr("%1 <name>[,<name>...]\n"
+ "\tTake only the specified products into account.\n").arg(prefix);
+}
+
+QString ProductsOption::shortRepresentation() const
+{
+ return QLatin1String("-p");
+}
+
+QString ProductsOption::longRepresentation() const
+{
+ return QLatin1String("--products");
+}
+
+static QStringList allLogLevelStrings()
+{
+ QStringList result;
+ for (int i = static_cast<int>(LoggerMinLevel); i <= static_cast<int>(LoggerMaxLevel); ++i)
+ result << Logger::logLevelName(static_cast<LoggerLevel>(i));
+ return result;
+}
+
+LogLevelOption::LogLevelOption() : m_logLevel(Logger::defaultLevel())
+{
+}
+
+QString LogLevelOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1 <level>\n"
+ "\tUse the specified log level. Possible values are '%2'.\n"
+ "\tThe default is '%3'.\n").arg(longRepresentation(),
+ allLogLevelStrings().join(QLatin1String("', '")),
+ Logger::logLevelName(Logger::defaultLevel()));
+}
+
+QString LogLevelOption::longRepresentation() const
+{
+ return loglevelLongRepresentation();
+}
+
+void LogLevelOption::doParse(const QString &representation, QStringList &input)
+{
+ const QString levelString = getArgument(representation, input);
+ const QList<LoggerLevel> levels = QList<LoggerLevel>() << LoggerError << LoggerWarning
+ << LoggerInfo << LoggerDebug << LoggerTrace;
+ foreach (LoggerLevel l, levels) {
+ if (Logger::logLevelName(l) == levelString) {
+ m_logLevel = l;
+ return;
+ }
+ }
+ throw Error(Tr::tr("Invalid use of option '%1': Unknown log level '%2'.\nUsage: %3")
+ .arg(representation, levelString, description(command())));
+}
+
+} // namespace qbs