diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2012-12-07 16:17:26 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2012-12-11 17:37:30 +0100 |
commit | f3a9442a2a3af7ab33869050e959ada424e713f7 (patch) | |
tree | a0cad0499bc608a9105769cad87fa421dfba610e | |
parent | e9b8558b6c0de60bc7775ff17e808078120eb69e (diff) | |
download | qbs-f3a9442a2a3af7ab33869050e959ada424e713f7.tar.gz |
Make the "run" command easier to use.
Instead of forcing the user to give the file name of the executable
(which is usually different on Linux and Windows) and trying to find a
product for it, we now take the product name and deduce the executable.
This is a much more sensible approach.
Change-Id: Id90be26a83194761e04dcabc19c2a26ff5062d95
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r-- | src/app/qbs/commandlinefrontend.cpp | 66 | ||||
-rw-r--r-- | src/app/qbs/commandlinefrontend.h | 1 | ||||
-rw-r--r-- | src/app/qbs/parser/command.cpp | 13 | ||||
-rw-r--r-- | src/app/qbs/parser/command.h | 2 | ||||
-rw-r--r-- | src/app/qbs/parser/commandlineoption.cpp | 2 | ||||
-rw-r--r-- | src/app/qbs/parser/commandlineparser.cpp | 6 | ||||
-rw-r--r-- | src/app/qbs/parser/commandlineparser.h | 1 |
7 files changed, 36 insertions, 55 deletions
diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp index 0a4b50dc6..5cabc7d92 100644 --- a/src/app/qbs/commandlinefrontend.cpp +++ b/src/app/qbs/commandlinefrontend.cpp @@ -63,6 +63,7 @@ void CommandLineFrontend::start() { try { switch (m_parser.command()) { + case RunCommandType: case ShellCommandType: if (m_parser.products().count() > 1) { throw Error(Tr::tr("Invalid use of command '%1': Cannot use more than one " @@ -70,7 +71,6 @@ void CommandLineFrontend::start() .arg(m_parser.commandName(), m_parser.commandDescription())); } // Fall-through intended. - case RunCommandType: case PropertiesCommandType: case StatusCommandType: if (m_parser.buildConfigurations().count() > 1) { @@ -218,12 +218,7 @@ void CommandLineFrontend::handleProjectsResolved() makeClean(); break; case ShellCommandType: - if (m_parser.products().count() == 0 - && m_projects.first().projectData().products().count() > 1) { - throw Error(Tr::tr("Ambiguous use of command '%1': No product given for project " - "with more than one product.\nUsage: %2") - .arg(m_parser.commandName(), m_parser.commandDescription())); - } + checkForExactlyOneProduct(); qApp->exit(runShell()); break; case StatusCommandType: { @@ -311,39 +306,26 @@ void CommandLineFrontend::build() int CommandLineFrontend::runTarget() { - ProductData productToRun; - QString productFileName; - - const QString targetName = m_parser.runTargetName(); - Q_ASSERT(m_projects.count() == 1); - const Project &project = m_projects.first(); - foreach (const ProductData &product, productsToUse().value(project)) { - const QString executable = project.targetExecutable(product); - if (executable.isEmpty()) - continue; - if (!targetName.isEmpty() && !executable.endsWith(targetName)) - continue; - if (!productFileName.isEmpty()) { - qbsError() << tr("There is more than one executable target in " - "the project. Please specify which target " - "you want to run."); - return EXIT_FAILURE; + try { + checkForExactlyOneProduct(); + const ProductMap &productMap = productsToUse(); + Q_ASSERT(productMap.count() == 1); + const Project &project = productMap.begin().key(); + const QList<ProductData> &products = productMap.begin().value(); + Q_ASSERT(products.count() == 1); + const ProductData productToRun = products.first(); + const QString executableFilePath = project.targetExecutable(productToRun); + if (executableFilePath.isEmpty()) { + throw Error(Tr::tr("Cannot run: Product '%1' is not an application.") + .arg(productToRun.name())); } - productFileName = executable; - productToRun = product; - } - - if (productToRun.name().isEmpty()) { - if (targetName.isEmpty()) - qbsError() << tr("Can't find a suitable product to run."); - else - qbsError() << tr("No such target: '%1'").arg(targetName); + RunEnvironment runEnvironment = project.getRunEnvironment(productToRun, + QProcessEnvironment::systemEnvironment()); + return runEnvironment.runTarget(executableFilePath, m_parser.runArgs()); + } catch (const Error &error) { + qbsError() << error.toString(); return EXIT_FAILURE; } - - RunEnvironment runEnvironment = project.getRunEnvironment(productToRun, - QProcessEnvironment::systemEnvironment()); - return runEnvironment.runTarget(productFileName, m_parser.runArgs()); } void CommandLineFrontend::updateTimestamps() @@ -373,4 +355,14 @@ void CommandLineFrontend::connectJob(AbstractJob *job) } } +void CommandLineFrontend::checkForExactlyOneProduct() +{ + if (m_parser.products().count() == 0 + && m_projects.first().projectData().products().count() > 1) { + throw Error(Tr::tr("Ambiguous use of command '%1': No product given for project " + "with more than one product.\nUsage: %2") + .arg(m_parser.commandName(), m_parser.commandDescription())); + } +} + } // namespace qbs diff --git a/src/app/qbs/commandlinefrontend.h b/src/app/qbs/commandlinefrontend.h index 5bb93c4bb..614677575 100644 --- a/src/app/qbs/commandlinefrontend.h +++ b/src/app/qbs/commandlinefrontend.h @@ -70,6 +70,7 @@ private: void updateTimestamps(); void connectBuildJobs(); void connectJob(AbstractJob *job); + void checkForExactlyOneProduct(); const CommandLineParser &m_parser; QList<AbstractJob *> m_resolveJobs; diff --git a/src/app/qbs/parser/command.cpp b/src/app/qbs/parser/command.cpp index 1fa78ce07..d556619cf 100644 --- a/src/app/qbs/parser/command.cpp +++ b/src/app/qbs/parser/command.cpp @@ -214,9 +214,11 @@ QString RunCommand::shortDescription() const QString RunCommand::longDescription() const { QString description = Tr::tr("qbs %1 [options] [variant] [property:value] ... " - "-- <target> <args>\n").arg(representation()); - description += Tr::tr("Runs the specified target with the specified arguments.\n"); - description += Tr::tr("The project will be built if it is not up to date; " + "[ -- <arguments>]\n").arg(representation()); + description += Tr::tr("Run the specified product's executable with the specified arguments.\n"); + description += Tr::tr("If the project has only one product, the '%1' option may be omitted.\n") + .arg(optionPool().productsOption()->longRepresentation()); + description += Tr::tr("The product will be built if it is not up to date; " "see the '%2' command.\n").arg(buildCommandRepresentation()); return description += supportedOptionsDescription(); } @@ -251,11 +253,6 @@ void RunCommand::parseMore(QStringList &input) addOneToAdditionalArguments(arg); } - if (input.isEmpty()) { - throw Error(Tr::tr("Invalid use of command '%1': Needs an executable to run.\nUsage: %2") - .arg(representation(), longDescription())); - } - m_targetName = input.takeFirst(); m_targetParameters = input; input.clear(); } diff --git a/src/app/qbs/parser/command.h b/src/app/qbs/parser/command.h index e073a0294..6a31f65e3 100644 --- a/src/app/qbs/parser/command.h +++ b/src/app/qbs/parser/command.h @@ -97,7 +97,6 @@ class RunCommand : public Command { public: RunCommand(CommandLineOptionPool &optionPool) : Command(optionPool) {} - QString targetName() const { return m_targetName; } QStringList targetParameters() const { return m_targetParameters; } private: @@ -108,7 +107,6 @@ private: QList<CommandLineOption::Type> supportedOptions() const; void parseMore(QStringList &input); - QString m_targetName; QStringList m_targetParameters; }; diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp index 77a7a6935..8617a6a58 100644 --- a/src/app/qbs/parser/commandlineoption.cpp +++ b/src/app/qbs/parser/commandlineoption.cpp @@ -233,7 +233,7 @@ QString ChangedFilesOption::longRepresentation() const QString ProductsOption::description(CommandType command) const { const QString prefix = Tr::tr("%1|%2").arg(longRepresentation(), shortRepresentation()); - if (command == ShellCommandType) { + if (command == ShellCommandType || command == RunCommandType) { return Tr::tr("%1 <name>\n" "\tUse the specified product.\n").arg(prefix); } diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp index a1af61c85..1519bca65 100644 --- a/src/app/qbs/parser/commandlineparser.cpp +++ b/src/app/qbs/parser/commandlineparser.cpp @@ -118,12 +118,6 @@ BuildOptions CommandLineParser::buildOptions() const return d->buildOptions; } -QString CommandLineParser::runTargetName() const -{ - Q_ASSERT(d->command->type() == RunCommandType); - return static_cast<RunCommand *>(d->command)->targetName(); -} - QStringList CommandLineParser::runArgs() const { Q_ASSERT(d->command->type() == RunCommandType); diff --git a/src/app/qbs/parser/commandlineparser.h b/src/app/qbs/parser/commandlineparser.h index f1fbea949..a20697240 100644 --- a/src/app/qbs/parser/commandlineparser.h +++ b/src/app/qbs/parser/commandlineparser.h @@ -52,7 +52,6 @@ public: QString commandDescription() const; QString projectFilePath() const; BuildOptions buildOptions() const; - QString runTargetName() const; QStringList runArgs() const; QStringList products() const; QList<QVariantMap> buildConfigurations() const; |