summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2012-12-07 16:17:26 +0100
committerJoerg Bornemann <joerg.bornemann@digia.com>2012-12-11 17:37:30 +0100
commitf3a9442a2a3af7ab33869050e959ada424e713f7 (patch)
treea0cad0499bc608a9105769cad87fa421dfba610e
parente9b8558b6c0de60bc7775ff17e808078120eb69e (diff)
downloadqbs-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.cpp66
-rw-r--r--src/app/qbs/commandlinefrontend.h1
-rw-r--r--src/app/qbs/parser/command.cpp13
-rw-r--r--src/app/qbs/parser/command.h2
-rw-r--r--src/app/qbs/parser/commandlineoption.cpp2
-rw-r--r--src/app/qbs/parser/commandlineparser.cpp6
-rw-r--r--src/app/qbs/parser/commandlineparser.h1
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;