diff options
author | Jake Petroules <jake.petroules@theqtcompany.com> | 2015-11-11 19:51:58 -0800 |
---|---|---|
committer | Jake Petroules <jake.petroules@theqtcompany.com> | 2015-12-01 10:38:40 +0000 |
commit | ddd37d1b881e02c87ca580336a5f12b4941bb093 (patch) | |
tree | d30b03c5838aaa2b4d49c98976fc07d159ceb35d | |
parent | d3897b2220d99fe2011972ea806c7433771f59fe (diff) |
Roll the global getEnv and currentEnv functions into Environment.
Change-Id: Ife3f9c53ad3fb43364c53fe7c6c08aa3983b9221
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
20 files changed, 122 insertions, 81 deletions
diff --git a/doc/reference/jsextensions/jsextension-environment.qdoc b/doc/reference/jsextensions/jsextension-environment.qdoc new file mode 100644 index 000000000..3975bf14c --- /dev/null +++ b/doc/reference/jsextensions/jsextension-environment.qdoc @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** 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 The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +/*! + \contentspage index.html + \page jsextension-environment.html + \ingroup list-of-builtin-services + + \title Environment Service + \brief Provides operations on the system environment. + + The \c Environment service offers access to the system environment or process environment. + + \section1 Available Operations + + \section2 currentEnv + \code + Environment.currentEnv(): { [key: string]: string; } + \endcode + Returns the environment of \QBS in the current context as an object whose properties are + the environment variables. + + \section2 getEnv + \code + Environment.getEnv(key: string): string + \endcode + Tries to find a variable with the given name in the current context's environment and returns + its value. If no such variable could be found, \c undefined is returned. + + \section2 putEnv + \code + Environment.putEnv(key: string, value: string): void + \endcode + Sets the value of the environment variable with the given name in the build or run environment. + This method is only available in the \c Module.setupBuildEnvironment and + \c Module.setupRunEnvironment scripts. + + \section2 unsetEnv + \code + Environment.unsetEnv(key: string): void + \endcode + Unsets the environment variable with the given name from the build or run environment. + This method is only available in the \c Module.setupBuildEnvironment and + \c Module.setupRunEnvironment scripts. +*/ diff --git a/doc/reference/jsextensions/jsextensions-general.qdoc b/doc/reference/jsextensions/jsextensions-general.qdoc index 409b4c838..1e63ce574 100644 --- a/doc/reference/jsextensions/jsextensions-general.qdoc +++ b/doc/reference/jsextensions/jsextensions-general.qdoc @@ -42,20 +42,6 @@ \section1 Available Operations - \section2 qbs.currentEnv - \code - qbs.currentEnv(): { [key: string]: string; } - \endcode - Returns the environment of \QBS in the current context as an object whose properties are - the environment variables. - - \section2 qbs.getEnv - \code - qbs.getEnv(key: string): string - \endcode - Tries to find a variable with the given name in the build environment and returns its value. If - no such variable could be found, \c undefined is returned. - \section2 loadFile \code loadFile(filePath: string): any diff --git a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs index 29e954891..18d30faae 100644 --- a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs @@ -29,6 +29,7 @@ ****************************************************************************/ import qbs +import qbs.Environment import qbs.File import qbs.FileInfo @@ -36,7 +37,7 @@ PathProbe { // Inputs property stringList hostOS: qbs.hostOS - environmentPaths: qbs.getEnv("ANDROID_NDK_ROOT") + environmentPaths: Environment.getEnv("ANDROID_NDK_ROOT") // Outputs property var hostArch diff --git a/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs index 372e1a0ce..fb004703c 100644 --- a/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs @@ -29,12 +29,13 @@ ****************************************************************************/ import qbs +import qbs.Environment import qbs.File import qbs.FileInfo import "../../../modules/Android/sdk/utils.js" as SdkUtils PathProbe { - environmentPaths: qbs.getEnv("ANDROID_HOME") + environmentPaths: Environment.getEnv("ANDROID_HOME") // Outputs property var buildToolsVersions diff --git a/share/qbs/imports/qbs/Probes/JdkProbe.qbs b/share/qbs/imports/qbs/Probes/JdkProbe.qbs index b67d59177..00672a197 100644 --- a/share/qbs/imports/qbs/Probes/JdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/JdkProbe.qbs @@ -29,6 +29,7 @@ ****************************************************************************/ import qbs +import qbs.Environment import qbs.File import qbs.FileInfo import qbs.Process @@ -39,7 +40,7 @@ PathProbe { property stringList hostOS: qbs.hostOS property string architecture: qbs.architecture - environmentPaths: qbs.getEnv("JAVA_HOME") + environmentPaths: Environment.getEnv("JAVA_HOME") platformPaths: [ "/usr/lib/jvm/default-java", // Debian/Ubuntu "/etc/alternatives/java_sdk_openjdk", // Fedora diff --git a/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs b/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs index b0e2dfca0..ecaf91180 100644 --- a/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs +++ b/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs @@ -29,6 +29,7 @@ ****************************************************************************/ import qbs +import qbs.Environment import qbs.FileInfo BinaryProbe { @@ -36,8 +37,8 @@ BinaryProbe { platformPaths: { var paths = base; if (qbs.hostOS.contains("windows")) { - var env32 = qbs.getEnv("PROGRAMFILES(X86)"); - var env64 = qbs.getEnv("PROGRAMFILES"); + var env32 = Environment.getEnv("PROGRAMFILES(X86)"); + var env64 = Environment.getEnv("PROGRAMFILES"); if (env64 === env32 && env64.endsWith(" (x86)")) env64 = env64.slice(0, -(" (x86)".length)); // QTBUG-3845 paths.push(FileInfo.joinPaths(env64, "nodejs")); diff --git a/share/qbs/imports/qbs/Probes/path-probe.js b/share/qbs/imports/qbs/Probes/path-probe.js index 418d451ff..4f634876a 100644 --- a/share/qbs/imports/qbs/Probes/path-probe.js +++ b/share/qbs/imports/qbs/Probes/path-probe.js @@ -28,6 +28,7 @@ ** ****************************************************************************/ +var Environment = loadExtension("qbs.Environment"); var File = loadExtension("qbs.File"); var FileInfo = loadExtension("qbs.FileInfo"); var ModUtils = loadExtension("qbs.ModUtils"); @@ -47,7 +48,7 @@ function configure(names, nameSuffixes, nameFilter, pathPrefixes, pathSuffixes, // FIXME: Add getenv support var envs = ModUtils.concatAll(platformEnvironmentPaths, environmentPaths); for (var i = 0; i < envs.length; ++i) { - var value = qbs.getEnv(envs[i]) || ''; + var value = Environment.getEnv(envs[i]) || ''; if (value.length > 0) _paths = _paths.concat(value.split(pathListSeparator)); } diff --git a/share/qbs/modules/qbs/common.qbs b/share/qbs/modules/qbs/common.qbs index 733a3096f..c0c05e114 100644 --- a/share/qbs/modules/qbs/common.qbs +++ b/share/qbs/modules/qbs/common.qbs @@ -29,6 +29,7 @@ ****************************************************************************/ import qbs 1.0 +import qbs.Environment import qbs.FileInfo import qbs.ModUtils import qbs.PathTools @@ -120,10 +121,10 @@ Module { // private properties property string windowsRegistryKey: "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion" property path windowsSystemRoot: FileInfo.fromWindowsSeparators(Utilities.getNativeSetting(windowsRegistryKey, "SystemRoot")) - property path windowsShellPath: FileInfo.fromWindowsSeparators(getEnv("COMSPEC")) || FileInfo.joinPaths(windowsSystemRoot, "System32", "cmd.exe") + property path windowsShellPath: FileInfo.fromWindowsSeparators(Environment.getEnv("COMSPEC")) || FileInfo.joinPaths(windowsSystemRoot, "System32", "cmd.exe") property var commonRunEnvironment: { - var env = qbs.currentEnv(); + var env = Environment.currentEnv(); if (targetOS.contains("windows")) { var newEntry = FileInfo.toWindowsSeparators(FileInfo.joinPaths(installRoot, installPrefix)); diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs index ad54b6cd2..f9b717867 100644 --- a/share/qbs/modules/xcode/xcode.qbs +++ b/share/qbs/modules/xcode/xcode.qbs @@ -1,5 +1,6 @@ import qbs import qbs.BundleTools +import qbs.Environment import qbs.File import qbs.FileInfo import qbs.DarwinTools @@ -108,7 +109,7 @@ Module { } property path provisioningProfilesPath: { - return FileInfo.joinPaths(qbs.getEnv("HOME"), "Library/MobileDevice/Provisioning Profiles"); + return FileInfo.joinPaths(Environment.getEnv("HOME"), "Library/MobileDevice/Provisioning Profiles"); } readonly property var _availableSdks: Utils.sdkInfoList(sdksPath) diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp index be327dd18..9e70e1362 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.cpp +++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp @@ -515,7 +515,7 @@ bool BuildGraphLoader::checkProductForChanges(const ResolvedProductPtr &restored const ResolvedProductPtr &newlyResolvedProduct) { // This check must come first, as it can prevent build data rescuing as a side effect. - // TODO: Similar special checks must be done for qbs.getEnv() and File.exists() in + // TODO: Similar special checks must be done for Environment.getEnv() and File.exists() in // commands (or possibly it could be reasonable to just forbid such "dynamic" constructs // within commands). if (checkForPropertyChanges(restoredProduct, newlyResolvedProduct)) diff --git a/src/lib/corelib/jsextensions/environmentextension.cpp b/src/lib/corelib/jsextensions/environmentextension.cpp index 922a1b2df..aec712ea0 100644 --- a/src/lib/corelib/jsextensions/environmentextension.cpp +++ b/src/lib/corelib/jsextensions/environmentextension.cpp @@ -82,11 +82,11 @@ QScriptValue EnvironmentExtension::js_ctor(QScriptContext *context, QScriptEngin } static QProcessEnvironment *getProcessEnvironment(QScriptContext *context, QScriptEngine *engine, - const QString &func) + const QString &func, bool doThrow = true) { QVariant v = engine->property("_qbs_procenv"); QProcessEnvironment *procenv = reinterpret_cast<QProcessEnvironment *>(v.value<void *>()); - if (!procenv) + if (!procenv && doThrow) throw context->throwError(QScriptContext::UnknownError, QStringLiteral("%1 can only be called from ").arg(func) + QStringLiteral("Module.setupBuildEnvironment and ") + @@ -99,9 +99,21 @@ QScriptValue EnvironmentExtension::js_getEnv(QScriptContext *context, QScriptEng if (Q_UNLIKELY(context->argumentCount() != 1)) return context->throwError(QScriptContext::SyntaxError, QStringLiteral("getEnv expects 1 argument")); - const QProcessEnvironment * const procenv = getProcessEnvironment(context, engine, - QStringLiteral("getEnv")); - return engine->toScriptValue(procenv->value(context->argument(0).toString())); + const QProcessEnvironment env = static_cast<ScriptEngine *>(engine)->environment(); + const QProcessEnvironment *procenv = getProcessEnvironment(context, engine, + QStringLiteral("getEnv"), false); + if (!procenv) + procenv = &env; + + const QString name = context->argument(0).toString(); + const QString value = procenv->value(name); + + // Don't track environment variable access inside environment setup scripts + // since change tracking is irrelevant for them + if (procenv == &env) + static_cast<ScriptEngine *>(engine)->addEnvironmentVariable(name, value); + + return value.isNull() ? engine->undefinedValue() : value; } QScriptValue EnvironmentExtension::js_putEnv(QScriptContext *context, QScriptEngine *engine) @@ -128,8 +140,11 @@ QScriptValue EnvironmentExtension::js_unsetEnv(QScriptContext *context, QScriptE QScriptValue EnvironmentExtension::js_currentEnv(QScriptContext *context, QScriptEngine *engine) { Q_UNUSED(context); - const QProcessEnvironment * const procenv = getProcessEnvironment(context, engine, - QStringLiteral("currentEnv")); + const QProcessEnvironment env = static_cast<ScriptEngine *>(engine)->environment(); + const QProcessEnvironment *procenv = getProcessEnvironment(context, engine, + QStringLiteral("currentEnv"), false); + if (!procenv) + procenv = &env; QScriptValue envObject = engine->newObject(); foreach (const QString &key, procenv->keys()) envObject.setProperty(key, QScriptValue(procenv->value(key))); diff --git a/src/lib/corelib/language/builtinvalue.h b/src/lib/corelib/language/builtinvalue.h index 6734eba54..a04f4d15f 100644 --- a/src/lib/corelib/language/builtinvalue.h +++ b/src/lib/corelib/language/builtinvalue.h @@ -41,8 +41,6 @@ class BuiltinValue : public Value public: enum Builtin { - GetEnvFunction, - CurrentEnvFunction }; static BuiltinValuePtr create(Builtin builtin); diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index ccd4158a0..88fec0e8e 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -280,8 +280,6 @@ EvaluatorScriptClass::EvaluatorScriptClass(ScriptEngine *scriptEngine, const Log , m_logger(logger) , m_valueCacheEnabled(false) { - m_getEnvBuiltin = scriptEngine->newFunction(js_getEnv, 1); - m_currentEnvBuiltin = scriptEngine->newFunction(js_currentEnv, 0); } QScriptClass::QueryFlags EvaluatorScriptClass::queryProperty(const QScriptValue &object, @@ -515,38 +513,11 @@ void EvaluatorScriptClass::setValueCacheEnabled(bool enabled) QScriptValue EvaluatorScriptClass::scriptValueForBuiltin(BuiltinValue::Builtin builtin) const { switch (builtin) { - case BuiltinValue::GetEnvFunction: - return m_getEnvBuiltin; - case BuiltinValue::CurrentEnvFunction: - return m_currentEnvBuiltin; } QBS_ASSERT(!"unhandled builtin", ;); return QScriptValue(); } -QScriptValue EvaluatorScriptClass::js_getEnv(QScriptContext *context, QScriptEngine *engine) -{ - if (Q_UNLIKELY(context->argumentCount() < 1)) { - return context->throwError(QScriptContext::SyntaxError, - QLatin1String("getEnv expects 1 argument")); - } - const QString name = context->argument(0).toString(); - ScriptEngine * const e = static_cast<ScriptEngine *>(engine); - const QString value = e->environment().value(name); - e->addEnvironmentVariable(name, value); - return value.isNull() ? engine->undefinedValue() : value; -} - -QScriptValue EvaluatorScriptClass::js_currentEnv(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(context); - const QProcessEnvironment env = static_cast<ScriptEngine *>(engine)->environment(); - QScriptValue envObject = engine->newObject(); - foreach (const QString &key, env.keys()) - envObject.setProperty(key, QScriptValue(env.value(key))); - return envObject; -} - QScriptValue EvaluatorScriptClass::js_consoleError(QScriptContext *context, QScriptEngine *engine, Logger *logger) { diff --git a/src/lib/corelib/language/evaluatorscriptclass.h b/src/lib/corelib/language/evaluatorscriptclass.h index 5277cf9d6..c2ab37632 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.h +++ b/src/lib/corelib/language/evaluatorscriptclass.h @@ -62,9 +62,6 @@ public: void setValueCacheEnabled(bool enabled); QScriptValue scriptValueForBuiltin(BuiltinValue::Builtin builtin) const; - static QScriptValue js_getEnv(QScriptContext *context, QScriptEngine *engine); - static QScriptValue js_currentEnv(QScriptContext *context, QScriptEngine *engine); - static QScriptValue js_consoleError(QScriptContext *context, QScriptEngine *engine, Logger *logger); static QScriptValue js_consoleWarn(QScriptContext *context, QScriptEngine *engine, @@ -101,8 +98,6 @@ private: QueryResult m_queryResult; Logger m_logger; bool m_valueCacheEnabled; - QScriptValue m_getEnvBuiltin; - QScriptValue m_currentEnvBuiltin; QStack<JSSourceValue *> m_sourceValueStack; QSet<Value *> m_currentNextChain; }; diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 8a0087a07..460ca8926 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -1256,10 +1256,6 @@ static QStringList hostOS() void ModuleLoader::setupBaseModulePrototype(Item *prototype) { - prototype->setProperty(QLatin1String("getEnv"), - BuiltinValue::create(BuiltinValue::GetEnvFunction)); - prototype->setProperty(QLatin1String("currentEnv"), - BuiltinValue::create(BuiltinValue::CurrentEnvFunction)); prototype->setProperty(QLatin1String("hostOS"), VariantValue::create(hostOS())); prototype->setProperty(QLatin1String("libexecPath"), VariantValue::create(m_parameters.libexecPath())); diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index ab72d7d57..b30d090ab 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -516,10 +516,6 @@ private: void ScriptEngine::installQbsBuiltins() { globalObject().setProperty(QLatin1String("qbs"), m_qbsObject = newObject()); - installQbsFunction(QLatin1String("getEnv"), - EvaluatorScriptClass::js_getEnv); - installQbsFunction(QLatin1String("currentEnv"), - EvaluatorScriptClass::js_currentEnv); globalObject().setProperty(QLatin1String("console"), m_consoleObject = newObject()); installConsoleFunction(QLatin1String("debug"), diff --git a/src/lib/corelib/language/testdata/builtinFunctionInSearchPathsProperty.qbs b/src/lib/corelib/language/testdata/builtinFunctionInSearchPathsProperty.qbs index dd0c81593..0df9f4d5c 100644 --- a/src/lib/corelib/language/testdata/builtinFunctionInSearchPathsProperty.qbs +++ b/src/lib/corelib/language/testdata/builtinFunctionInSearchPathsProperty.qbs @@ -1,8 +1,9 @@ import qbs +import qbs.Environment Project { qbsSearchPaths: { - if (!qbs.getEnv("PATH")) - throw "qbs.getEnv doesn't seem to work"; + if (!Environment.getEnv("PATH")) + throw "Environment.getEnv doesn't seem to work"; } } diff --git a/src/lib/corelib/language/testdata/environmentvariable.qbs b/src/lib/corelib/language/testdata/environmentvariable.qbs index b930e8511..2e04c7991 100644 --- a/src/lib/corelib/language/testdata/environmentvariable.qbs +++ b/src/lib/corelib/language/testdata/environmentvariable.qbs @@ -1,3 +1,5 @@ +import qbs.Environment + Product { - name: qbs.getEnv("PRODUCT_NAME") + name: Environment.getEnv("PRODUCT_NAME") } diff --git a/tests/auto/blackbox/testdata/propertyChanges/project.qbs b/tests/auto/blackbox/testdata/propertyChanges/project.qbs index 785fb010b..cd842c12e 100644 --- a/tests/auto/blackbox/testdata/propertyChanges/project.qbs +++ b/tests/auto/blackbox/testdata/propertyChanges/project.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.Environment import qbs.File import qbs.TextFile @@ -18,7 +19,7 @@ Project { } CppApplication { name: "product 3" - cpp.defines: qbs.getEnv("QBS_BLACKBOX_DEFINE") + cpp.defines: Environment.getEnv("QBS_BLACKBOX_DEFINE") files: "source3.cpp" } DynamicLibrary { diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs index 451b0a25a..05060acd7 100644 --- a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs @@ -1,14 +1,15 @@ import qbs +import qbs.Environment import qbs.File import "fileList.js" as FileList CppApplication { - property stringList filesFromEnv: qbs.getEnv("QBS_TEST_PULL_IN_FILE_VIA_ENV") + property stringList filesFromEnv: Environment.getEnv("QBS_TEST_PULL_IN_FILE_VIA_ENV") ? ["environmentChange.cpp"] : [] files: ["main.cpp"].concat(FileList.fileList()).concat(filesFromEnv).concat(FileList.filesFromFs(qbs)) Group { - condition: qbs.getEnv("INCLUDE_PATH_TEST") + condition: Environment.getEnv("INCLUDE_PATH_TEST") name: "file that needs help from the environment to find a header" files: "including.cpp" } |