diff options
| author | Jake Petroules <jake.petroules@petroules.com> | 2013-11-20 17:09:41 -0500 |
|---|---|---|
| committer | Jake Petroules <jake.petroules@petroules.com> | 2013-11-26 16:13:35 +0100 |
| commit | dbb39fc1fce3686a5161d68e89e96086fc664556 (patch) | |
| tree | 7651a5a1e885805eaec99105abcaf61bd865667f | |
| parent | d7656eef2decad018759cae7f18c4e66c3a688bf (diff) | |
| download | qbs-dbb39fc1fce3686a5161d68e89e96086fc664556.tar.gz | |
Support specifying the Qbs build directory as a command line option.
Also supports changing the default build directory ('.') using the
'preferences.defaultBuildDirectory' property.
Task-number: QBS-462
Change-Id: Id3d05d2f5b14197bd3af2e7f9d55bdd263809716
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
| -rw-r--r-- | src/app/qbs/commandlinefrontend.cpp | 2 | ||||
| -rw-r--r-- | src/app/qbs/parser/command.cpp | 4 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineoption.cpp | 33 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineoption.h | 17 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineoptionpool.cpp | 8 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineoptionpool.h | 1 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineparser.cpp | 29 | ||||
| -rw-r--r-- | src/app/qbs/parser/commandlineparser.h | 1 | ||||
| -rw-r--r-- | src/lib/tools/preferences.cpp | 8 | ||||
| -rw-r--r-- | src/lib/tools/preferences.h | 1 | ||||
| -rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 44 | ||||
| -rw-r--r-- | tests/auto/blackbox/tst_blackbox.h | 7 |
12 files changed, 136 insertions, 19 deletions
diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp index a2264c497..2cbd087d0 100644 --- a/src/app/qbs/commandlinefrontend.cpp +++ b/src/app/qbs/commandlinefrontend.cpp @@ -121,7 +121,7 @@ void CommandLineFrontend::start() + QLatin1String("/../")); SetupProjectParameters params; params.setProjectFilePath(m_parser.projectFilePath()); - params.setBuildRoot(QDir::currentPath()); + params.setBuildRoot(m_parser.projectBuildDirectory()); params.setSearchPaths(Preferences(m_settings).searchPaths(qbsRootPath)); params.setPluginPaths(Preferences(m_settings).pluginPaths(qbsRootPath)); params.setIgnoreDifferentProjectFilePath(m_parser.force()); diff --git a/src/app/qbs/parser/command.cpp b/src/app/qbs/parser/command.cpp index c9f24a36a..f20eedf35 100644 --- a/src/app/qbs/parser/command.cpp +++ b/src/app/qbs/parser/command.cpp @@ -169,6 +169,7 @@ static QList<CommandLineOption::Type> resolveOptions() { return QList<CommandLineOption::Type>() << CommandLineOption::FileOptionType + << CommandLineOption::BuildDirectoryOptionType << CommandLineOption::LogLevelOptionType << CommandLineOption::VerboseOptionType << CommandLineOption::QuietOptionType @@ -345,6 +346,7 @@ QList<CommandLineOption::Type> ShellCommand::supportedOptions() const { return QList<CommandLineOption::Type>() << CommandLineOption::FileOptionType + << CommandLineOption::BuildDirectoryOptionType << CommandLineOption::LogLevelOptionType << CommandLineOption::VerboseOptionType << CommandLineOption::QuietOptionType @@ -375,6 +377,7 @@ QList<CommandLineOption::Type> StatusCommand::supportedOptions() const { return QList<CommandLineOption::Type>() << CommandLineOption::FileOptionType + << CommandLineOption::BuildDirectoryOptionType << CommandLineOption::LogLevelOptionType << CommandLineOption::VerboseOptionType << CommandLineOption::QuietOptionType @@ -408,6 +411,7 @@ QList<CommandLineOption::Type> UpdateTimestampsCommand::supportedOptions() const { return QList<CommandLineOption::Type>() << CommandLineOption::FileOptionType + << CommandLineOption::BuildDirectoryOptionType << CommandLineOption::LogLevelOptionType << CommandLineOption::VerboseOptionType << CommandLineOption::QuietOptionType diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp index c9d21c405..21fe05b41 100644 --- a/src/app/qbs/parser/commandlineoption.cpp +++ b/src/app/qbs/parser/commandlineoption.cpp @@ -81,6 +81,39 @@ void FileOption::doParse(const QString &representation, QStringList &input) m_projectFilePath = getArgument(representation, input); } +QString BuildDirectoryOption::description(CommandType command) const +{ + Q_UNUSED(command); + return Tr::tr("%1|%2 <directory>\n" + "\tBuild in the given directory. The default value is the current directory\n" + "\tunless preferences.defaultBuildDirectory is set.\n" + "\tRelative paths will be interpreted relative to the current directory.\n" + "\tIf the directory does not exist, it will be created. Use the special\n" + "\tvalue '%3' as a placeholder for the name of the directory\n" + "\tcontaining the project file.\n") + .arg(longRepresentation(), shortRepresentation(), magicProjectString()); +} + +QString BuildDirectoryOption::shortRepresentation() const +{ + return QLatin1String("-d"); +} + +QString BuildDirectoryOption::longRepresentation() const +{ + return QLatin1String("--build-directory"); +} + +QString BuildDirectoryOption::magicProjectString() +{ + return QLatin1String("@project"); +} + +void BuildDirectoryOption::doParse(const QString &representation, QStringList &input) +{ + m_projectBuildDirectory = getArgument(representation, input); +} + static QString loglevelLongRepresentation() { return QLatin1String("--log-level"); } QString VerboseOption::description(CommandType command) const diff --git a/src/app/qbs/parser/commandlineoption.h b/src/app/qbs/parser/commandlineoption.h index 8457ef4cb..585128d7a 100644 --- a/src/app/qbs/parser/commandlineoption.h +++ b/src/app/qbs/parser/commandlineoption.h @@ -40,6 +40,7 @@ class CommandLineOption public: enum Type { FileOptionType, + BuildDirectoryOptionType, LogLevelOptionType, VerboseOptionType, QuietOptionType, JobsOptionType, KeepGoingOptionType, @@ -87,6 +88,22 @@ private: QString m_projectFilePath; }; +class BuildDirectoryOption : public CommandLineOption +{ +public: + QString projectBuildDirectory() const { return m_projectBuildDirectory; } + static QString magicProjectString(); + +private: + QString description(CommandType command) const; + QString shortRepresentation() const; + QString longRepresentation() const; + void doParse(const QString &representation, QStringList &input); + +private: + QString m_projectBuildDirectory; +}; + class CountingOption : public CommandLineOption { public: diff --git a/src/app/qbs/parser/commandlineoptionpool.cpp b/src/app/qbs/parser/commandlineoptionpool.cpp index a7a0d7ab7..d675700d8 100644 --- a/src/app/qbs/parser/commandlineoptionpool.cpp +++ b/src/app/qbs/parser/commandlineoptionpool.cpp @@ -43,6 +43,9 @@ CommandLineOption *CommandLineOptionPool::getOption(CommandLineOption::Type type case CommandLineOption::FileOptionType: option = new FileOption; break; + case CommandLineOption::BuildDirectoryOptionType: + option = new BuildDirectoryOption; + break; case CommandLineOption::LogLevelOptionType: option = new LogLevelOption; break; @@ -101,6 +104,11 @@ FileOption *CommandLineOptionPool::fileOption() const return static_cast<FileOption *>(getOption(CommandLineOption::FileOptionType)); } +BuildDirectoryOption *CommandLineOptionPool::buildDirectoryOption() const +{ + return static_cast<BuildDirectoryOption *>(getOption(CommandLineOption::BuildDirectoryOptionType)); +} + LogLevelOption *CommandLineOptionPool::logLevelOption() const { return static_cast<LogLevelOption *>(getOption(CommandLineOption::LogLevelOptionType)); diff --git a/src/app/qbs/parser/commandlineoptionpool.h b/src/app/qbs/parser/commandlineoptionpool.h index 46c36a9d9..ccb5b0421 100644 --- a/src/app/qbs/parser/commandlineoptionpool.h +++ b/src/app/qbs/parser/commandlineoptionpool.h @@ -42,6 +42,7 @@ public: CommandLineOption *getOption(CommandLineOption::Type type) const; FileOption *fileOption() const; + BuildDirectoryOption *buildDirectoryOption() const; LogLevelOption *logLevelOption() const; VerboseOption *verboseOption() const; QuietOption *quietOption() const; diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp index 40c0fa3e2..46d1e6173 100644 --- a/src/app/qbs/parser/commandlineparser.cpp +++ b/src/app/qbs/parser/commandlineparser.cpp @@ -69,6 +69,7 @@ public: QString generalHelp() const; void setupProjectFile(); + void setupBuildDirectory(); void setupProgress(); void setupLogLevel(); void setupBuildOptions(); @@ -81,6 +82,7 @@ public: Settings *settings; Command *command; QString projectFilePath; + QString projectBuildDirectory; BuildOptions buildOptions; CommandLineOptionPool optionPool; CommandPool commandPool; @@ -129,6 +131,11 @@ QString CommandLineParser::projectFilePath() const return d->projectFilePath; } +QString CommandLineParser::projectBuildDirectory() const +{ + return d->projectBuildDirectory; +} + BuildOptions CommandLineParser::buildOptions() const { return d->buildOptions; @@ -351,6 +358,7 @@ void CommandLineParser::CommandLineParserPrivate::doParse() return; setupProjectFile(); + setupBuildDirectory(); setupProgress(); setupLogLevel(); setupBuildOptions(); @@ -464,6 +472,27 @@ void CommandLineParser::CommandLineParserPrivate::setupProjectFile() qbsDebug() << "Using project file '" << QDir::toNativeSeparators(projectFilePath) << "'."; } +void CommandLineParser::CommandLineParserPrivate::setupBuildDirectory() +{ + projectBuildDirectory = optionPool.buildDirectoryOption()->projectBuildDirectory(); + if (projectBuildDirectory.isEmpty()) { + projectBuildDirectory = Preferences(settings).defaultBuildDirectory(); + if (projectBuildDirectory.isEmpty()) { + qbsDebug() << "No project build directory given; using current directory."; + projectBuildDirectory = QDir::currentPath(); + } else { + qbsDebug() << "No project build directory given; using directory from preferences."; + } + } + + QDir dir(QFileInfo(projectFilePath).path()); + projectBuildDirectory.replace(optionPool.buildDirectoryOption()->magicProjectString(), + dir.dirName()); + + if (!QFileInfo(projectBuildDirectory).isAbsolute()) + projectBuildDirectory = QDir::currentPath() + QLatin1Char('/') + projectBuildDirectory; +} + void CommandLineParser::CommandLineParserPrivate::setupBuildOptions() { buildOptions.setDryRun(dryRun()); diff --git a/src/app/qbs/parser/commandlineparser.h b/src/app/qbs/parser/commandlineparser.h index 16994437c..e6a0dded7 100644 --- a/src/app/qbs/parser/commandlineparser.h +++ b/src/app/qbs/parser/commandlineparser.h @@ -54,6 +54,7 @@ public: QString commandName() const; QString commandDescription() const; QString projectFilePath() const; + QString projectBuildDirectory() const; BuildOptions buildOptions() const; CleanOptions cleanOptions() const; InstallOptions installOptions() const; diff --git a/src/lib/tools/preferences.cpp b/src/lib/tools/preferences.cpp index f8ed01740..18552807f 100644 --- a/src/lib/tools/preferences.cpp +++ b/src/lib/tools/preferences.cpp @@ -72,6 +72,14 @@ QString Preferences::shell() const } /*! + * \brief Returns the default build directory used by Qbs if none is specified. + */ +QString Preferences::defaultBuildDirectory() const +{ + return getPreference(QLatin1String("defaultBuildDirectory")).toString(); +} + +/*! * \brief Returns the list of paths where qbs looks for module definitions and such. * If there is no such setting, \c qbsRootPath will be used to look up a fallback location. */ diff --git a/src/lib/tools/preferences.h b/src/lib/tools/preferences.h index d79ee8aa5..1d6f9dbad 100644 --- a/src/lib/tools/preferences.h +++ b/src/lib/tools/preferences.h @@ -45,6 +45,7 @@ public: bool useColoredOutput() const; int jobs() const; QString shell() const; + QString defaultBuildDirectory() const; QStringList searchPaths(const QString &qbsRootPath = QString()) const; QStringList pluginPaths(const QString &qbsRootPath = QString()) const; diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index cc817242c..503ae8560 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -71,7 +71,15 @@ TestBlackbox::TestBlackbox() int TestBlackbox::runQbs(const QbsRunParameters ¶ms) { - QStringList args = params.arguments; + QStringList args; + args << params.command; + if ((QStringList() << QLatin1String("") << QLatin1String("build") << QLatin1String("clean") + << QLatin1String("install") << QLatin1String("resolve") << QLatin1String("run") + << QLatin1String("shell") << QLatin1String("status") << QLatin1String("update-timestamps")) + .contains(params.command)) { + args.append(QStringList(QLatin1String("-d")) << QLatin1String(".")); + } + args << params.arguments; if (params.useProfile) args.append(QLatin1String("profile:") + buildProfileName); QString cmdLine = qbsExecutableFilePath; @@ -272,7 +280,7 @@ void TestBlackbox::build_project_dry_run() QDir::setCurrent(testDataDir + projectSubDir); rmDirR(buildDir); - QCOMPARE(runQbs(QbsRunParameters("-n")), 0); + QCOMPARE(runQbs(QbsRunParameters(QStringList("-n"))), 0); const QStringList &buildDirContents = QDir(buildDir).entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); QVERIFY2(buildDirContents.isEmpty(), qPrintable(buildDirContents.join(" "))); @@ -358,7 +366,7 @@ void TestBlackbox::resolve_project_dry_run() QDir::setCurrent(testDataDir + projectSubDir); rmDirR(buildDir); - QCOMPARE(runQbs(QbsRunParameters(QStringList("resolve") << "-n")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("resolve"), QStringList("-n"))), 0); QVERIFY2(!QFile::exists(productFileName), qPrintable(productFileName)); QVERIFY2(!QFile::exists(buildGraphPath), qPrintable(buildGraphPath)); } @@ -388,7 +396,7 @@ void TestBlackbox::clean() QCOMPARE(runQbs(), 0); QVERIFY(QFile(appObjectFilePath).exists()); QVERIFY(QFile(appExeFilePath).exists()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts"))), 0); QVERIFY(!QFile(appObjectFilePath).exists()); QVERIFY(!QFile(appExeFilePath).exists()); QVERIFY(!QFile(depObjectFilePath).exists()); @@ -398,7 +406,8 @@ void TestBlackbox::clean() QCOMPARE(runQbs(), 0); QVERIFY(QFile(appObjectFilePath).exists()); QVERIFY(QFile(appExeFilePath).exists()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-n")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), + QStringList("--all-artifacts") << "-n")), 0); QVERIFY(QFile(appObjectFilePath).exists()); QVERIFY(QFile(appExeFilePath).exists()); QVERIFY(QFile(depObjectFilePath).exists()); @@ -410,7 +419,8 @@ void TestBlackbox::clean() QVERIFY(QFile(appExeFilePath).exists()); QVERIFY(QFile(depObjectFilePath).exists()); QVERIFY(QFile(depExeFilePath).exists()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-p" << "dep")), + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), + QStringList("--all-artifacts") << "-p" << "dep")), 0); QVERIFY(QFile(appObjectFilePath).exists()); QVERIFY(QFile(appExeFilePath).exists()); @@ -423,7 +433,8 @@ void TestBlackbox::clean() QVERIFY(QFile(appExeFilePath).exists()); QVERIFY(QFile(depObjectFilePath).exists()); QVERIFY(QFile(depExeFilePath).exists()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-p" << "app")), + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), + QStringList("--all-artifacts") << "-p" << "app")), 0); QVERIFY(!QFile(appObjectFilePath).exists()); QVERIFY(!QFile(appExeFilePath).exists()); @@ -929,7 +940,7 @@ void TestBlackbox::wildcardRenaming() QCOMPARE(runQbs(QbsRunParameters("install")), 0); QVERIFY(QFileInfo(defaultInstallRoot + "/pioniere.txt").exists()); QFile::rename(QDir::currentPath() + "/pioniere.txt", QDir::currentPath() + "/fdj.txt"); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0); QVERIFY(!QFileInfo(defaultInstallRoot + "/pioniere.txt").exists()); QVERIFY(QFileInfo(defaultInstallRoot + "/fdj.txt").exists()); } @@ -942,7 +953,7 @@ void TestBlackbox::recursiveRenaming() QVERIFY(QFileInfo(defaultInstallRoot + "/dir/subdir/blubb.txt").exists()); waitForNewTimestamp(); QVERIFY(QFile::rename(QDir::currentPath() + "/dir/wasser.txt", QDir::currentPath() + "/dir/wein.txt")); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0); QVERIFY(!QFileInfo(defaultInstallRoot + "/dir/wasser.txt").exists()); QVERIFY(QFileInfo(defaultInstallRoot + "/dir/wein.txt").exists()); QVERIFY(QFileInfo(defaultInstallRoot + "/dir/subdir/blubb.txt").exists()); @@ -1420,7 +1431,7 @@ void TestBlackbox::properQuoting() { QDir::setCurrent(testDataDir + "/proper quoting"); QCOMPARE(runQbs(), 0); - QbsRunParameters params(QStringList() << "run" << "-qp" << "Hello World"); + QbsRunParameters params(QLatin1String("run"), QStringList() << "-q" << "-p" << "Hello World"); params.expectFailure = true; // Because the exit code is non-zero. QCOMPARE(runQbs(params), 156); const char * const expectedOutput = "whitespaceless\ncontains space\ncontains\ttab\n" @@ -1442,7 +1453,7 @@ void TestBlackbox::installedApp() QVERIFY(QFile::exists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp")))); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--install-root" + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--install-root") << (testDataDir + "/installed-app"))), 0); QVERIFY(QFile::exists(testDataDir + HostOsInfo::appendExecutableSuffix("/installed-app/usr/bin/installedApp"))); @@ -1451,7 +1462,7 @@ void TestBlackbox::installedApp() QVERIFY(addedFile.open(QIODevice::WriteOnly)); addedFile.close(); QVERIFY(addedFile.exists()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0); QVERIFY(QFile::exists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp")))); QVERIFY(!addedFile.exists()); @@ -1465,7 +1476,7 @@ void TestBlackbox::installedApp() projectFile.resize(0); projectFile.write(content); QVERIFY(projectFile.flush()); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install"))), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0); QVERIFY(QFile::exists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/bin/installedApp")))); @@ -1475,13 +1486,14 @@ void TestBlackbox::installedApp() projectFile.resize(0); projectFile.write(content); projectFile.close(); - QCOMPARE(runQbs(QbsRunParameters(QStringList("install"))), 0); + QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0); QVERIFY(QFile::exists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/custom/installedApp")))); rmDirR(buildDir); QbsRunParameters params; - params.arguments << "install" << "--no-build"; + params.command = "install"; + params.arguments << "--no-build"; params.expectFailure = true; QVERIFY(runQbs(params) != 0); QVERIFY(m_qbsStderr.contains("No build graph")); @@ -1489,7 +1501,7 @@ void TestBlackbox::installedApp() void TestBlackbox::toolLookup() { - QbsRunParameters params(QStringList("detect-toolchains") << "--help"); + QbsRunParameters params(QLatin1String("detect-toolchains"), QStringList("--help")); params.useProfile = false; QCOMPARE(runQbs(params), 0); } diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 43c1d1d12..64ccf84b9 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -45,12 +45,14 @@ public: init(); } - QbsRunParameters(const QStringList &args) : arguments(args) + QbsRunParameters(const QString &cmd, const QStringList &args = QStringList()) + : command(cmd), arguments(args) { init(); } - QbsRunParameters(const QString &arg) : arguments(arg) + QbsRunParameters(const QStringList &args) + : arguments(args) { init(); } @@ -62,6 +64,7 @@ public: environment = QProcessEnvironment::systemEnvironment(); } + QString command; QStringList arguments; QProcessEnvironment environment; bool expectFailure; |
