forked from qt-creator/qt-creator
Utils: Continue Environment/EnvironmentChange consolidation
Make Environment a stack of changes that gets "expanded" to a full environment before things are actively accessed. Later this expansion should be done lazily if possible. Task-number: QTCREATORBUG-28357 Change-Id: If1c7bfdb9f58b81e71c51ed87ee75d6964a47019 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -235,7 +235,7 @@ def qdump__Utils__Port(d, value):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def qdump__Utils__Environment(d, value):
|
def x_qdump__Utils__Environment(d, value):
|
||||||
qdump__Utils__NameValueDictionary(d, value)
|
qdump__Utils__NameValueDictionary(d, value)
|
||||||
|
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ def qdump__Utils__DictKey(d, value):
|
|||||||
d.putStringValue(value["name"])
|
d.putStringValue(value["name"])
|
||||||
|
|
||||||
|
|
||||||
def qdump__Utils__NameValueDictionary(d, value):
|
def x_qdump__Utils__NameValueDictionary(d, value):
|
||||||
dptr = d.extractPointer(value)
|
dptr = d.extractPointer(value)
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersion() >= 0x60000:
|
||||||
if dptr == 0:
|
if dptr == 0:
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ public:
|
|||||||
QString m_placeHolderText;
|
QString m_placeHolderText;
|
||||||
QString m_historyCompleterKey;
|
QString m_historyCompleterKey;
|
||||||
PathChooser::Kind m_expectedKind = PathChooser::File;
|
PathChooser::Kind m_expectedKind = PathChooser::File;
|
||||||
EnvironmentChange m_environmentChange;
|
Environment m_environment;
|
||||||
QPointer<ElidingLabel> m_labelDisplay;
|
QPointer<ElidingLabel> m_labelDisplay;
|
||||||
QPointer<FancyLineEdit> m_lineEditDisplay;
|
QPointer<FancyLineEdit> m_lineEditDisplay;
|
||||||
QPointer<PathChooser> m_pathChooserDisplay;
|
QPointer<PathChooser> m_pathChooserDisplay;
|
||||||
@@ -975,16 +975,11 @@ void StringAspect::setExpectedKind(const PathChooser::Kind expectedKind)
|
|||||||
d->m_pathChooserDisplay->setExpectedKind(expectedKind);
|
d->m_pathChooserDisplay->setExpectedKind(expectedKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringAspect::setEnvironmentChange(const EnvironmentChange &change)
|
|
||||||
{
|
|
||||||
d->m_environmentChange = change;
|
|
||||||
if (d->m_pathChooserDisplay)
|
|
||||||
d->m_pathChooserDisplay->setEnvironmentChange(change);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StringAspect::setEnvironment(const Environment &env)
|
void StringAspect::setEnvironment(const Environment &env)
|
||||||
{
|
{
|
||||||
setEnvironmentChange(EnvironmentChange::fromDictionary(env.toDictionary()));
|
d->m_environment = env;
|
||||||
|
if (d->m_pathChooserDisplay)
|
||||||
|
d->m_pathChooserDisplay->setEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringAspect::setBaseFileName(const FilePath &baseFileName)
|
void StringAspect::setBaseFileName(const FilePath &baseFileName)
|
||||||
@@ -1082,7 +1077,7 @@ void StringAspect::addToLayout(Layouting::LayoutBuilder &builder)
|
|||||||
d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
|
d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
|
||||||
if (d->m_validator)
|
if (d->m_validator)
|
||||||
d->m_pathChooserDisplay->setValidationFunction(d->m_validator);
|
d->m_pathChooserDisplay->setValidationFunction(d->m_validator);
|
||||||
d->m_pathChooserDisplay->setEnvironmentChange(d->m_environmentChange);
|
d->m_pathChooserDisplay->setEnvironment(d->m_environment);
|
||||||
d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName);
|
d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName);
|
||||||
d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal);
|
d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal);
|
||||||
if (defaultValue() == value())
|
if (defaultValue() == value())
|
||||||
|
|||||||
@@ -383,7 +383,6 @@ public:
|
|||||||
void setPlaceHolderText(const QString &placeHolderText);
|
void setPlaceHolderText(const QString &placeHolderText);
|
||||||
void setHistoryCompleter(const QString &historyCompleterKey);
|
void setHistoryCompleter(const QString &historyCompleterKey);
|
||||||
void setExpectedKind(const PathChooser::Kind expectedKind);
|
void setExpectedKind(const PathChooser::Kind expectedKind);
|
||||||
void setEnvironmentChange(const EnvironmentChange &change);
|
|
||||||
void setEnvironment(const Environment &env);
|
void setEnvironment(const Environment &env);
|
||||||
void setBaseFileName(const FilePath &baseFileName);
|
void setBaseFileName(const FilePath &baseFileName);
|
||||||
void setUndoRedoEnabled(bool readOnly);
|
void setUndoRedoEnabled(bool readOnly);
|
||||||
|
|||||||
@@ -19,84 +19,137 @@ Q_GLOBAL_STATIC_WITH_ARGS(Environment, staticSystemEnvironment,
|
|||||||
(QProcessEnvironment::systemEnvironment().toStringList()))
|
(QProcessEnvironment::systemEnvironment().toStringList()))
|
||||||
Q_GLOBAL_STATIC(QVector<EnvironmentProvider>, environmentProviders)
|
Q_GLOBAL_STATIC(QVector<EnvironmentProvider>, environmentProviders)
|
||||||
|
|
||||||
|
Environment::Environment()
|
||||||
|
: m_dict(HostOsInfo::hostOs())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Environment::Environment(OsType osType)
|
||||||
|
: m_dict(osType)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Environment::Environment(const QStringList &env, OsType osType)
|
||||||
|
: m_dict(osType)
|
||||||
|
{
|
||||||
|
m_changeItems.append(NameValueDictionary(env, osType));
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Environment(const NameValuePairs &nameValues)
|
||||||
|
{
|
||||||
|
m_changeItems.append(NameValueDictionary(nameValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Environment(const NameValueDictionary &dict)
|
||||||
|
{
|
||||||
|
m_changeItems.append(dict);
|
||||||
|
}
|
||||||
|
|
||||||
NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepend) const
|
NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepend) const
|
||||||
{
|
{
|
||||||
return m_dict.diff(other.m_dict, checkAppendPrepend);
|
const NameValueDictionary &dict = resolved();
|
||||||
|
const NameValueDictionary &otherDict = other.resolved();
|
||||||
|
return dict.diff(otherDict, checkAppendPrepend);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment::FindResult Environment::find(const QString &name) const
|
Environment::FindResult Environment::find(const QString &name) const
|
||||||
{
|
{
|
||||||
const auto it = m_dict.constFind(name);
|
const NameValueDictionary &dict = resolved();
|
||||||
if (it == m_dict.constEnd())
|
const auto it = dict.constFind(name);
|
||||||
|
if (it == dict.constEnd())
|
||||||
return {};
|
return {};
|
||||||
return Entry{it.key().name, it.value().first, it.value().second};
|
return Entry{it.key().name, it.value().first, it.value().second};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::forEachEntry(const std::function<void(const QString &, const QString &, bool)> &callBack) const
|
void Environment::forEachEntry(const std::function<void(const QString &, const QString &, bool)> &callBack) const
|
||||||
{
|
{
|
||||||
for (auto it = m_dict.m_values.constBegin(); it != m_dict.m_values.constEnd(); ++it)
|
const NameValueDictionary &dict = resolved();
|
||||||
|
for (auto it = dict.m_values.constBegin(); it != dict.m_values.constEnd(); ++it)
|
||||||
callBack(it.key().name, it.value().first, it.value().second);
|
callBack(it.key().name, it.value().first, it.value().second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Environment::operator==(const Environment &other) const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
const NameValueDictionary &otherDict = other.resolved();
|
||||||
|
return dict == otherDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::operator!=(const Environment &other) const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
const NameValueDictionary &otherDict = other.resolved();
|
||||||
|
return dict != otherDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Environment::value(const QString &key) const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict.value(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Environment::value_or(const QString &key, const QString &defaultValue) const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict.hasKey(key) ? dict.value(key) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasKey(const QString &key) const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
bool Environment::hasChanges() const
|
bool Environment::hasChanges() const
|
||||||
{
|
{
|
||||||
return m_dict.size() != 0;
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict.size() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OsType Environment::osType() const
|
||||||
|
{
|
||||||
|
return m_dict.m_osType;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList Environment::toStringList() const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict.toStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcessEnvironment Environment::toProcessEnvironment() const
|
QProcessEnvironment Environment::toProcessEnvironment() const
|
||||||
{
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
QProcessEnvironment result;
|
QProcessEnvironment result;
|
||||||
for (auto it = m_dict.m_values.constBegin(); it != m_dict.m_values.constEnd(); ++it) {
|
for (auto it = dict.m_values.constBegin(); it != dict.m_values.constEnd(); ++it) {
|
||||||
if (it.value().second)
|
if (it.value().second)
|
||||||
result.insert(it.key().name, expandedValueForKey(m_dict.key(it)));
|
result.insert(it.key().name, expandedValueForKey(dict.key(it)));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::appendOrSetPath(const FilePath &value)
|
void Environment::appendOrSetPath(const FilePath &value)
|
||||||
{
|
{
|
||||||
QTC_CHECK(value.osType() == osType());
|
QTC_CHECK(value.osType() == m_dict.m_osType);
|
||||||
if (value.isEmpty())
|
if (value.isEmpty())
|
||||||
return;
|
return;
|
||||||
appendOrSet("PATH", value.nativePath(),
|
appendOrSet("PATH", value.nativePath(), OsSpecificAspects::pathListSeparator(osType()));
|
||||||
QString(OsSpecificAspects::pathListSeparator(osType())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::prependOrSetPath(const FilePath &value)
|
void Environment::prependOrSetPath(const FilePath &value)
|
||||||
{
|
{
|
||||||
QTC_CHECK(value.osType() == osType());
|
QTC_CHECK(value.osType() == m_dict.m_osType);
|
||||||
if (value.isEmpty())
|
if (value.isEmpty())
|
||||||
return;
|
return;
|
||||||
prependOrSet("PATH", value.nativePath(),
|
prependOrSet("PATH", value.nativePath(), OsSpecificAspects::pathListSeparator(osType()));
|
||||||
QString(OsSpecificAspects::pathListSeparator(osType())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
|
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!key.contains('='), return );
|
addItem(Item{std::in_place_index_t<AppendOrSet>(), key, value, sep});
|
||||||
const auto it = m_dict.findKey(key);
|
|
||||||
if (it == m_dict.m_values.end()) {
|
|
||||||
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), {value, true});
|
|
||||||
} else {
|
|
||||||
// Append unless it is already there
|
|
||||||
const QString toAppend = sep + value;
|
|
||||||
if (!it.value().first.endsWith(toAppend))
|
|
||||||
it.value().first.append(toAppend);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::prependOrSet(const QString &key, const QString &value, const QString &sep)
|
void Environment::prependOrSet(const QString &key, const QString &value, const QString &sep)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!key.contains('='), return );
|
addItem(Item{std::in_place_index_t<PrependOrSet>(), key, value, sep});
|
||||||
const auto it = m_dict.findKey(key);
|
|
||||||
if (it == m_dict.m_values.end()) {
|
|
||||||
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), {value, true});
|
|
||||||
} else {
|
|
||||||
// Prepend unless it is already there
|
|
||||||
const QString toPrepend = value + sep;
|
|
||||||
if (!it.value().first.startsWith(toPrepend))
|
|
||||||
it.value().first.prepend(toPrepend);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
|
void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
|
||||||
@@ -105,11 +158,11 @@ void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
|
|||||||
switch (osType()) {
|
switch (osType()) {
|
||||||
case OsTypeWindows: {
|
case OsTypeWindows: {
|
||||||
const QChar sep = ';';
|
const QChar sep = ';';
|
||||||
prependOrSet("PATH", value.nativePath(), QString(sep));
|
prependOrSet("PATH", value.nativePath(), sep);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OsTypeMac: {
|
case OsTypeMac: {
|
||||||
const QString sep = ":";
|
const QChar sep = ':';
|
||||||
const QString nativeValue = value.nativePath();
|
const QString nativeValue = value.nativePath();
|
||||||
prependOrSet("DYLD_LIBRARY_PATH", nativeValue, sep);
|
prependOrSet("DYLD_LIBRARY_PATH", nativeValue, sep);
|
||||||
prependOrSet("DYLD_FRAMEWORK_PATH", nativeValue, sep);
|
prependOrSet("DYLD_FRAMEWORK_PATH", nativeValue, sep);
|
||||||
@@ -118,7 +171,7 @@ void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
|
|||||||
case OsTypeLinux:
|
case OsTypeLinux:
|
||||||
case OsTypeOtherUnix: {
|
case OsTypeOtherUnix: {
|
||||||
const QChar sep = ':';
|
const QChar sep = ':';
|
||||||
prependOrSet("LD_LIBRARY_PATH", value.nativePath(), QString(sep));
|
prependOrSet("LD_LIBRARY_PATH", value.nativePath(), sep);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -141,8 +194,7 @@ Environment Environment::systemEnvironment()
|
|||||||
|
|
||||||
void Environment::setupEnglishOutput()
|
void Environment::setupEnglishOutput()
|
||||||
{
|
{
|
||||||
m_dict.set("LC_MESSAGES", "en_US.utf8");
|
addItem(Item{std::in_place_index_t<SetupEnglishOutput>()});
|
||||||
m_dict.set("LANGUAGE", "en_US:en");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using SearchResultCallback = std::function<IterationPolicy(const FilePath &)>;
|
using SearchResultCallback = std::function<IterationPolicy(const FilePath &)>;
|
||||||
@@ -190,7 +242,8 @@ static FilePaths appendExeExtensions(const Environment &env, const FilePath &exe
|
|||||||
|
|
||||||
QString Environment::expandedValueForKey(const QString &key) const
|
QString Environment::expandedValueForKey(const QString &key) const
|
||||||
{
|
{
|
||||||
return expandVariables(m_dict.value(key));
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return expandVariables(dict.value(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void searchInDirectoriesHelper(const SearchResultCallback &resultCallback,
|
static void searchInDirectoriesHelper(const SearchResultCallback &resultCallback,
|
||||||
@@ -324,14 +377,16 @@ void Environment::setSystemEnvironment(const Environment &environment)
|
|||||||
*/
|
*/
|
||||||
QString Environment::expandVariables(const QString &input) const
|
QString Environment::expandVariables(const QString &input) const
|
||||||
{
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
|
||||||
QString result = input;
|
QString result = input;
|
||||||
|
|
||||||
if (osType() == OsTypeWindows) {
|
if (osType() == OsTypeWindows) {
|
||||||
for (int vStart = -1, i = 0; i < result.length(); ) {
|
for (int vStart = -1, i = 0; i < result.length(); ) {
|
||||||
if (result.at(i++) == '%') {
|
if (result.at(i++) == '%') {
|
||||||
if (vStart > 0) {
|
if (vStart > 0) {
|
||||||
const auto it = m_dict.findKey(result.mid(vStart, i - vStart - 1));
|
const auto it = dict.findKey(result.mid(vStart, i - vStart - 1));
|
||||||
if (it != m_dict.m_values.constEnd()) {
|
if (it != dict.m_values.constEnd()) {
|
||||||
result.replace(vStart - 1, i - vStart + 1, it->first);
|
result.replace(vStart - 1, i - vStart + 1, it->first);
|
||||||
i = vStart - 1 + it->first.length();
|
i = vStart - 1 + it->first.length();
|
||||||
vStart = -1;
|
vStart = -1;
|
||||||
@@ -403,6 +458,12 @@ QStringList Environment::expandVariables(const QStringList &variables) const
|
|||||||
return transform(variables, [this](const QString &i) { return expandVariables(i); });
|
return transform(variables, [this](const QString &i) { return expandVariables(i); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NameValueDictionary Environment::toDictionary() const
|
||||||
|
{
|
||||||
|
const NameValueDictionary &dict = resolved();
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
void EnvironmentProvider::addProvider(EnvironmentProvider &&provider)
|
void EnvironmentProvider::addProvider(EnvironmentProvider &&provider)
|
||||||
{
|
{
|
||||||
environmentProviders->append(std::move(provider));
|
environmentProviders->append(std::move(provider));
|
||||||
@@ -421,63 +482,125 @@ std::optional<EnvironmentProvider> EnvironmentProvider::provider(const QByteArra
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentChange::addSetValue(const QString &key, const QString &value)
|
void Environment::addItem(const Item &item)
|
||||||
{
|
{
|
||||||
m_changeItems.append(Item{std::in_place_index_t<SetValue>(), QPair<QString, QString>{key, value}});
|
m_dict.clear();
|
||||||
|
m_changeItems.append(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentChange::addUnsetValue(const QString &key)
|
void Environment::set(const QString &key, const QString &value, bool enabled)
|
||||||
{
|
{
|
||||||
m_changeItems.append(Item{std::in_place_index_t<UnsetValue>(), key});
|
addItem(Item{std::in_place_index_t<SetValue>(),
|
||||||
|
std::tuple<QString, QString, bool>{key, value, enabled}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentChange::addPrependToPath(const FilePaths &values)
|
void Environment::unset(const QString &key)
|
||||||
{
|
{
|
||||||
|
addItem(Item{std::in_place_index_t<UnsetValue>(), key});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::modify(const NameValueItems &items)
|
||||||
|
{
|
||||||
|
addItem(Item{std::in_place_index_t<Modify>(), items});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::prependToPath(const FilePaths &values)
|
||||||
|
{
|
||||||
|
m_dict.clear();
|
||||||
for (int i = values.size(); --i >= 0; ) {
|
for (int i = values.size(); --i >= 0; ) {
|
||||||
const FilePath value = values.at(i);
|
const FilePath value = values.at(i);
|
||||||
m_changeItems.append(Item{std::in_place_index_t<PrependToPath>(), value});
|
m_changeItems.append(Item{
|
||||||
|
std::in_place_index_t<PrependOrSet>(),
|
||||||
|
QString("PATH"),
|
||||||
|
value.nativePath(),
|
||||||
|
value.pathListSeparator()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentChange::addAppendToPath(const FilePaths &values)
|
void Environment::appendToPath(const FilePaths &values)
|
||||||
{
|
{
|
||||||
for (const FilePath &value : values)
|
m_dict.clear();
|
||||||
m_changeItems.append(Item{std::in_place_index_t<AppendToPath>(), value});
|
for (const FilePath &value : values) {
|
||||||
|
m_changeItems.append(Item{
|
||||||
|
std::in_place_index_t<AppendOrSet>(),
|
||||||
|
QString("PATH"),
|
||||||
|
value.nativePath(),
|
||||||
|
value.pathListSeparator()
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentChange EnvironmentChange::fromDictionary(const NameValueDictionary &dict)
|
const NameValueDictionary &Environment::resolved() const
|
||||||
{
|
{
|
||||||
EnvironmentChange change;
|
if (m_dict.size() != 0)
|
||||||
change.m_changeItems.append(Item{std::in_place_index_t<SetFixedDictionary>(), dict});
|
return m_dict;
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnvironmentChange::applyToEnvironment(Environment &env) const
|
|
||||||
{
|
|
||||||
for (const Item &item : m_changeItems) {
|
for (const Item &item : m_changeItems) {
|
||||||
switch (item.index()) {
|
switch (item.index()) {
|
||||||
case SetSystemEnvironment:
|
case SetSystemEnvironment:
|
||||||
env = Environment::systemEnvironment();
|
m_dict = Environment::systemEnvironment().toDictionary();
|
||||||
break;
|
break;
|
||||||
case SetFixedDictionary:
|
case SetFixedDictionary:
|
||||||
env = Environment(std::get<SetFixedDictionary>(item));
|
m_dict = std::get<SetFixedDictionary>(item);
|
||||||
break;
|
break;
|
||||||
case SetValue: {
|
case SetValue: {
|
||||||
const QPair<QString, QString> data = std::get<SetValue>(item);
|
auto [key, value, enabled] = std::get<SetValue>(item);
|
||||||
env.set(data.first, data.second);
|
m_dict.set(key, value, enabled);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UnsetValue:
|
case UnsetValue:
|
||||||
env.unset(std::get<UnsetValue>(item));
|
m_dict.unset(std::get<UnsetValue>(item));
|
||||||
break;
|
break;
|
||||||
case PrependToPath:
|
case PrependOrSet: {
|
||||||
env.prependOrSetPath(std::get<PrependToPath>(item));
|
auto [key, value, sep] = std::get<PrependOrSet>(item);
|
||||||
|
QTC_ASSERT(!key.contains('='), return m_dict);
|
||||||
|
const auto it = m_dict.findKey(key);
|
||||||
|
if (it == m_dict.m_values.end()) {
|
||||||
|
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), {value, true});
|
||||||
|
} else {
|
||||||
|
// Prepend unless it is already there
|
||||||
|
const QString toPrepend = value + sep;
|
||||||
|
if (!it.value().first.startsWith(toPrepend))
|
||||||
|
it.value().first.prepend(toPrepend);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AppendToPath:
|
}
|
||||||
env.appendOrSetPath(std::get<AppendToPath>(item));
|
case AppendOrSet: {
|
||||||
|
auto [key, value, sep] = std::get<AppendOrSet>(item);
|
||||||
|
QTC_ASSERT(!key.contains('='), return m_dict);
|
||||||
|
const auto it = m_dict.findKey(key);
|
||||||
|
if (it == m_dict.m_values.end()) {
|
||||||
|
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), {value, true});
|
||||||
|
} else {
|
||||||
|
// Prepend unless it is already there
|
||||||
|
const QString toAppend = sep + value;
|
||||||
|
if (!it.value().first.endsWith(toAppend))
|
||||||
|
it.value().first.append(toAppend);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Modify: {
|
||||||
|
NameValueItems items = std::get<Modify>(item);
|
||||||
|
m_dict.modify(items);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SetupEnglishOutput:
|
||||||
|
m_dict.set("LC_MESSAGES", "en_US.utf8");
|
||||||
|
m_dict.set("LANGUAGE", "en_US:en");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return m_dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment Environment::appliedToEnvironment(const Environment &base) const
|
||||||
|
{
|
||||||
|
Environment res = base;
|
||||||
|
res.m_dict.clear();
|
||||||
|
res.m_changeItems.append(m_changeItems);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -22,27 +22,24 @@ namespace Utils {
|
|||||||
class QTCREATOR_UTILS_EXPORT Environment final
|
class QTCREATOR_UTILS_EXPORT Environment final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Environment() : m_dict(HostOsInfo::hostOs()) {}
|
Environment();
|
||||||
explicit Environment(OsType osType) : m_dict(osType) {}
|
explicit Environment(OsType osType);
|
||||||
explicit Environment(const QStringList &env, OsType osType = HostOsInfo::hostOs())
|
explicit Environment(const QStringList &env, OsType osType = HostOsInfo::hostOs());
|
||||||
: m_dict(env, osType) {}
|
explicit Environment(const NameValuePairs &nameValues);
|
||||||
explicit Environment(const NameValuePairs &nameValues) : m_dict(nameValues) {}
|
explicit Environment(const NameValueDictionary &dict);
|
||||||
explicit Environment(const NameValueDictionary &dict) : m_dict(dict) {}
|
|
||||||
|
|
||||||
QString value(const QString &key) const { return m_dict.value(key); }
|
QString value(const QString &key) const;
|
||||||
QString value_or(const QString &key, const QString &defaultValue) const
|
QString value_or(const QString &key, const QString &defaultValue) const;
|
||||||
{
|
bool hasKey(const QString &key) const;
|
||||||
return m_dict.hasKey(key) ? m_dict.value(key) : defaultValue;
|
|
||||||
}
|
|
||||||
bool hasKey(const QString &key) const { return m_dict.hasKey(key); }
|
|
||||||
|
|
||||||
void set(const QString &key, const QString &value, bool enabled = true) { m_dict.set(key, value, enabled); }
|
void set(const QString &key, const QString &value, bool enabled = true);
|
||||||
void unset(const QString &key) { m_dict.unset(key); }
|
void unset(const QString &key);
|
||||||
void modify(const NameValueItems &items) { m_dict.modify(items); }
|
void modify(const NameValueItems &items);
|
||||||
|
|
||||||
bool hasChanges() const;
|
bool hasChanges() const;
|
||||||
|
|
||||||
QStringList toStringList() const { return m_dict.toStringList(); }
|
OsType osType() const;
|
||||||
|
QStringList toStringList() const;
|
||||||
QProcessEnvironment toProcessEnvironment() const;
|
QProcessEnvironment toProcessEnvironment() const;
|
||||||
|
|
||||||
void appendOrSet(const QString &key, const QString &value, const QString &sep = QString());
|
void appendOrSet(const QString &key, const QString &value, const QString &sep = QString());
|
||||||
@@ -54,6 +51,9 @@ public:
|
|||||||
void prependOrSetLibrarySearchPath(const FilePath &value);
|
void prependOrSetLibrarySearchPath(const FilePath &value);
|
||||||
void prependOrSetLibrarySearchPaths(const FilePaths &values);
|
void prependOrSetLibrarySearchPaths(const FilePaths &values);
|
||||||
|
|
||||||
|
void prependToPath(const FilePaths &values);
|
||||||
|
void appendToPath(const FilePaths &values);
|
||||||
|
|
||||||
void setupEnglishOutput();
|
void setupEnglishOutput();
|
||||||
|
|
||||||
FilePath searchInPath(const QString &executable,
|
FilePath searchInPath(const QString &executable,
|
||||||
@@ -74,76 +74,58 @@ public:
|
|||||||
FilePath expandVariables(const FilePath &input) const;
|
FilePath expandVariables(const FilePath &input) const;
|
||||||
QStringList expandVariables(const QStringList &input) const;
|
QStringList expandVariables(const QStringList &input) const;
|
||||||
|
|
||||||
OsType osType() const { return m_dict.osType(); }
|
NameValueDictionary toDictionary() const; // FIXME: avoid
|
||||||
|
|
||||||
NameValueDictionary toDictionary() const { return m_dict; } // FIXME: avoid
|
|
||||||
NameValueItems diff(const Environment &other, bool checkAppendPrepend = false) const; // FIXME: avoid
|
NameValueItems diff(const Environment &other, bool checkAppendPrepend = false) const; // FIXME: avoid
|
||||||
|
|
||||||
void setCombineWithDeviceEnvironment(bool combine) { m_combineWithDeviceEnvironment = combine; }
|
|
||||||
bool combineWithDeviceEnvironment() const { return m_combineWithDeviceEnvironment; }
|
|
||||||
|
|
||||||
struct Entry { QString key; QString value; bool enabled; };
|
struct Entry { QString key; QString value; bool enabled; };
|
||||||
using FindResult = std::optional<Entry>;
|
using FindResult = std::optional<Entry>;
|
||||||
FindResult find(const QString &name) const; // Note res->key may differ in case from name.
|
FindResult find(const QString &name) const; // Note res->key may differ in case from name.
|
||||||
|
|
||||||
void forEachEntry(const std::function<void (const QString &, const QString &, bool)> &callBack) const;
|
void forEachEntry(const std::function<void (const QString &, const QString &, bool)> &callBack) const;
|
||||||
|
|
||||||
friend bool operator!=(const Environment &first, const Environment &second)
|
bool operator!=(const Environment &other) const;
|
||||||
{
|
bool operator==(const Environment &other) const;
|
||||||
return first.m_dict != second.m_dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(const Environment &first, const Environment &second)
|
|
||||||
{
|
|
||||||
return first.m_dict == second.m_dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Environment systemEnvironment();
|
static Environment systemEnvironment();
|
||||||
|
|
||||||
static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!!
|
static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!!
|
||||||
static void setSystemEnvironment(const Environment &environment); // don't use at all!!!
|
static void setSystemEnvironment(const Environment &environment); // don't use at all!!!
|
||||||
|
|
||||||
private:
|
|
||||||
NameValueDictionary m_dict;
|
|
||||||
bool m_combineWithDeviceEnvironment = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT EnvironmentChange final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EnvironmentChange() = default;
|
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
SetSystemEnvironment,
|
SetSystemEnvironment,
|
||||||
SetFixedDictionary,
|
SetFixedDictionary,
|
||||||
SetValue,
|
SetValue,
|
||||||
UnsetValue,
|
UnsetValue,
|
||||||
PrependToPath,
|
PrependOrSet,
|
||||||
AppendToPath,
|
AppendOrSet,
|
||||||
|
Modify,
|
||||||
|
SetupEnglishOutput,
|
||||||
};
|
};
|
||||||
|
|
||||||
using Item = std::variant<
|
using Item = std::variant<
|
||||||
std::monostate, // SetSystemEnvironment dummy
|
std::monostate, // SetSystemEnvironment dummy
|
||||||
NameValueDictionary, // SetFixedDictionary
|
NameValueDictionary, // SetFixedDictionary
|
||||||
QPair<QString, QString>, // SetValue
|
std::tuple<QString, QString, bool>, // SetValue (key, value, enabled)
|
||||||
QString, // UnsetValue
|
QString, // UnsetValue (key)
|
||||||
FilePath, // PrependToPath
|
std::tuple<QString, QString, QString>, // PrependOrSet (key, value, separator)
|
||||||
FilePath // AppendToPath
|
std::tuple<QString, QString, QString>, // AppendOrSet (key, value, separator)
|
||||||
|
NameValueItems, // Modify
|
||||||
|
std::monostate // SetupEnglishOutput
|
||||||
>;
|
>;
|
||||||
|
|
||||||
static EnvironmentChange fromDictionary(const NameValueDictionary &dict);
|
void addItem(const Item &item);
|
||||||
|
|
||||||
void applyToEnvironment(Environment &) const;
|
Environment appliedToEnvironment(const Environment &base) const;
|
||||||
|
|
||||||
void addSetValue(const QString &key, const QString &value);
|
const NameValueDictionary &resolved() const;
|
||||||
void addUnsetValue(const QString &key);
|
|
||||||
void addPrependToPath(const FilePaths &values);
|
|
||||||
void addAppendToPath(const FilePaths &values);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<Item> m_changeItems;
|
mutable QList<Item> m_changeItems;
|
||||||
|
mutable NameValueDictionary m_dict; // Latest resolved.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using EnviromentChange = Environment;
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT EnvironmentProvider
|
class QTCREATOR_UTILS_EXPORT EnvironmentProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ namespace Utils {
|
|||||||
|
|
||||||
class DeviceFileAccess;
|
class DeviceFileAccess;
|
||||||
class Environment;
|
class Environment;
|
||||||
class EnvironmentChange;
|
|
||||||
enum class FileStreamHandle;
|
enum class FileStreamHandle;
|
||||||
|
|
||||||
template <class ...Args> using Continuation = std::function<void(Args...)>;
|
template <class ...Args> using Continuation = std::function<void(Args...)>;
|
||||||
|
|||||||
@@ -246,6 +246,8 @@ void CallerHandle::start(const QString &program, const QStringList &arguments)
|
|||||||
p.command = m_command;
|
p.command = m_command;
|
||||||
p.arguments = m_arguments;
|
p.arguments = m_arguments;
|
||||||
p.env = m_setup->m_environment.toStringList();
|
p.env = m_setup->m_environment.toStringList();
|
||||||
|
if (p.env.isEmpty())
|
||||||
|
p.env = Environment::systemEnvironment().toStringList();
|
||||||
p.workingDir = m_setup->m_workingDirectory.path();
|
p.workingDir = m_setup->m_workingDirectory.path();
|
||||||
p.processMode = m_setup->m_processMode;
|
p.processMode = m_setup->m_processMode;
|
||||||
p.writeData = m_setup->m_writeData;
|
p.writeData = m_setup->m_writeData;
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public:
|
|||||||
FilePath m_initialBrowsePathOverride;
|
FilePath m_initialBrowsePathOverride;
|
||||||
QString m_defaultValue;
|
QString m_defaultValue;
|
||||||
FilePath m_baseDirectory;
|
FilePath m_baseDirectory;
|
||||||
EnvironmentChange m_environmentChange;
|
Environment m_environment;
|
||||||
BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
|
BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
|
||||||
QList<QAbstractButton *> m_buttons;
|
QList<QAbstractButton *> m_buttons;
|
||||||
const MacroExpander *m_macroExpander = globalMacroExpander();
|
const MacroExpander *m_macroExpander = globalMacroExpander();
|
||||||
@@ -196,8 +196,7 @@ FilePath PathChooserPrivate::expandedPath(const FilePath &input) const
|
|||||||
|
|
||||||
FilePath path = input;
|
FilePath path = input;
|
||||||
|
|
||||||
Environment env = path.deviceEnvironment();
|
Environment env = m_environment.appliedToEnvironment(path.deviceEnvironment());
|
||||||
m_environmentChange.applyToEnvironment(env);
|
|
||||||
path = env.expandVariables(path);
|
path = env.expandVariables(path);
|
||||||
|
|
||||||
if (m_macroExpander)
|
if (m_macroExpander)
|
||||||
@@ -324,20 +323,15 @@ void PathChooser::setBaseDirectory(const FilePath &base)
|
|||||||
triggerChanged();
|
triggerChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathChooser::setEnvironment(const Environment &env)
|
|
||||||
{
|
|
||||||
setEnvironmentChange(EnvironmentChange::fromDictionary(env.toDictionary()));
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePath PathChooser::baseDirectory() const
|
FilePath PathChooser::baseDirectory() const
|
||||||
{
|
{
|
||||||
return d->m_baseDirectory;
|
return d->m_baseDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathChooser::setEnvironmentChange(const EnvironmentChange &env)
|
void PathChooser::setEnvironment(const Environment &env)
|
||||||
{
|
{
|
||||||
QString oldExpand = filePath().toString();
|
QString oldExpand = filePath().toString();
|
||||||
d->m_environmentChange = env;
|
d->m_environment = env;
|
||||||
if (filePath().toString() != oldExpand) {
|
if (filePath().toString() != oldExpand) {
|
||||||
triggerChanged();
|
triggerChanged();
|
||||||
emit rawPathChanged();
|
emit rawPathChanged();
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ namespace Utils {
|
|||||||
class CommandLine;
|
class CommandLine;
|
||||||
class MacroExpander;
|
class MacroExpander;
|
||||||
class Environment;
|
class Environment;
|
||||||
class EnvironmentChange;
|
|
||||||
class PathChooserPrivate;
|
class PathChooserPrivate;
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
|
class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
|
||||||
@@ -77,7 +76,6 @@ public:
|
|||||||
void setBaseDirectory(const FilePath &base);
|
void setBaseDirectory(const FilePath &base);
|
||||||
|
|
||||||
void setEnvironment(const Environment &env);
|
void setEnvironment(const Environment &env);
|
||||||
void setEnvironmentChange(const EnvironmentChange &change);
|
|
||||||
|
|
||||||
/** Returns the suggested label title when used in a form layout. */
|
/** Returns the suggested label title when used in a form layout. */
|
||||||
static QString label();
|
static QString label();
|
||||||
|
|||||||
@@ -353,13 +353,18 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QProcessEnvironment penv = m_setup.m_environment.toProcessEnvironment();
|
||||||
|
if (penv.isEmpty())
|
||||||
|
penv = Environment::systemEnvironment().toProcessEnvironment();
|
||||||
|
const QStringList senv = penv.toStringList();
|
||||||
|
|
||||||
bool startResult
|
bool startResult
|
||||||
= m_ptyProcess->startProcess(program,
|
= m_ptyProcess->startProcess(program,
|
||||||
HostOsInfo::isWindowsHost()
|
HostOsInfo::isWindowsHost()
|
||||||
? QStringList{m_setup.m_nativeArguments} << arguments
|
? QStringList{m_setup.m_nativeArguments} << arguments
|
||||||
: arguments,
|
: arguments,
|
||||||
m_setup.m_workingDirectory.nativePath(),
|
m_setup.m_workingDirectory.nativePath(),
|
||||||
m_setup.m_environment.toProcessEnvironment().toStringList(),
|
senv,
|
||||||
m_setup.m_ptyData->size().width(),
|
m_setup.m_ptyData->size().width(),
|
||||||
m_setup.m_ptyData->size().height());
|
m_setup.m_ptyData->size().height());
|
||||||
|
|
||||||
@@ -458,7 +463,9 @@ private:
|
|||||||
handler->setWindowsSpecificStartupFlags(m_setup.m_belowNormalPriority,
|
handler->setWindowsSpecificStartupFlags(m_setup.m_belowNormalPriority,
|
||||||
m_setup.m_createConsoleOnWindows);
|
m_setup.m_createConsoleOnWindows);
|
||||||
|
|
||||||
m_process->setProcessEnvironment(m_setup.m_environment.toProcessEnvironment());
|
const QProcessEnvironment penv = m_setup.m_environment.toProcessEnvironment();
|
||||||
|
if (!penv.isEmpty())
|
||||||
|
m_process->setProcessEnvironment(penv);
|
||||||
m_process->setWorkingDirectory(m_setup.m_workingDirectory.path());
|
m_process->setWorkingDirectory(m_setup.m_workingDirectory.path());
|
||||||
m_process->setStandardInputFile(m_setup.m_standardInputFile);
|
m_process->setStandardInputFile(m_setup.m_standardInputFile);
|
||||||
m_process->setProcessChannelMode(m_setup.m_processChannelMode);
|
m_process->setProcessChannelMode(m_setup.m_processChannelMode);
|
||||||
@@ -715,7 +722,6 @@ public:
|
|||||||
, q(parent)
|
, q(parent)
|
||||||
, m_killTimer(this)
|
, m_killTimer(this)
|
||||||
{
|
{
|
||||||
m_setup.m_controlEnvironment = Environment::systemEnvironment();
|
|
||||||
m_killTimer.setSingleShot(true);
|
m_killTimer.setSingleShot(true);
|
||||||
connect(&m_killTimer, &QTimer::timeout, this, [this] {
|
connect(&m_killTimer, &QTimer::timeout, this, [this] {
|
||||||
m_killTimer.stop();
|
m_killTimer.stop();
|
||||||
@@ -769,22 +775,6 @@ public:
|
|||||||
return rootCommand;
|
return rootCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment fullEnvironment() const
|
|
||||||
{
|
|
||||||
Environment env = m_setup.m_environment;
|
|
||||||
if (!env.hasChanges() && env.combineWithDeviceEnvironment()) {
|
|
||||||
// FIXME: Either switch to using EnvironmentChange instead of full Environments, or
|
|
||||||
// feed the full environment into the QtcProcess instead of fixing it up here.
|
|
||||||
// qWarning("QtcProcess::start: Empty environment set when running '%s'.",
|
|
||||||
// qPrintable(m_setup.m_commandLine.executable().toString()));
|
|
||||||
env = m_setup.m_commandLine.executable().deviceEnvironment();
|
|
||||||
}
|
|
||||||
// TODO: needs SshSettings
|
|
||||||
// if (m_runAsRoot)
|
|
||||||
// RunControl::provideAskPassEntry(env);
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
QtcProcess *q;
|
QtcProcess *q;
|
||||||
std::unique_ptr<ProcessBlockingInterface> m_blockingInterface;
|
std::unique_ptr<ProcessBlockingInterface> m_blockingInterface;
|
||||||
std::unique_ptr<ProcessInterface> m_process;
|
std::unique_ptr<ProcessInterface> m_process;
|
||||||
@@ -1227,7 +1217,6 @@ void QtcProcess::start()
|
|||||||
d->m_state = QProcess::Starting;
|
d->m_state = QProcess::Starting;
|
||||||
d->m_process->m_setup = d->m_setup;
|
d->m_process->m_setup = d->m_setup;
|
||||||
d->m_process->m_setup.m_commandLine = d->fullCommandLine();
|
d->m_process->m_setup.m_commandLine = d->fullCommandLine();
|
||||||
d->m_process->m_setup.m_environment = d->fullEnvironment();
|
|
||||||
d->emitGuardedSignal(&QtcProcess::starting);
|
d->emitGuardedSignal(&QtcProcess::starting);
|
||||||
d->m_process->start();
|
d->m_process->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,16 +482,6 @@ static QHash<QString, QString> merge(const QHash<QString, QString> &first,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Utils::Environment merge(const Utils::Environment &first, const Utils::Environment &second)
|
|
||||||
{
|
|
||||||
Utils::Environment result = first;
|
|
||||||
second.forEachEntry([&](const QString &key, const QString &value, bool) {
|
|
||||||
result.set(key, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CMakeConfig merge(const CMakeConfig &first, const CMakeConfig &second)
|
static CMakeConfig merge(const CMakeConfig &first, const CMakeConfig &second)
|
||||||
{
|
{
|
||||||
return Utils::setUnionMerge<CMakeConfig>(
|
return Utils::setUnionMerge<CMakeConfig>(
|
||||||
@@ -549,7 +539,7 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other)
|
|||||||
if (!environment && other.environment)
|
if (!environment && other.environment)
|
||||||
environment = other.environment;
|
environment = other.environment;
|
||||||
else if (environment && other.environment)
|
else if (environment && other.environment)
|
||||||
environment = merge(other.environment.value(), environment.value());
|
environment = environment.value().appliedToEnvironment(other.environment.value());
|
||||||
|
|
||||||
if (!warnings && other.warnings)
|
if (!warnings && other.warnings)
|
||||||
warnings = other.warnings;
|
warnings = other.warnings;
|
||||||
@@ -575,7 +565,7 @@ void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other)
|
|||||||
if (!environment && other.environment)
|
if (!environment && other.environment)
|
||||||
environment = other.environment;
|
environment = other.environment;
|
||||||
else if (environment && other.environment)
|
else if (environment && other.environment)
|
||||||
environment = merge(other.environment.value(), environment.value());
|
environment = environment.value().appliedToEnvironment(other.environment.value());
|
||||||
|
|
||||||
if (!configurePreset && other.configurePreset)
|
if (!configurePreset && other.configurePreset)
|
||||||
configurePreset = other.configurePreset;
|
configurePreset = other.configurePreset;
|
||||||
|
|||||||
@@ -438,9 +438,9 @@ void SystemSettingsWidget::resetFileBrowser()
|
|||||||
|
|
||||||
void SystemSettingsWidget::updatePath()
|
void SystemSettingsWidget::updatePath()
|
||||||
{
|
{
|
||||||
EnvironmentChange change;
|
Environment env;
|
||||||
change.addAppendToPath(VcsManager::additionalToolsPath());
|
env.appendToPath(VcsManager::additionalToolsPath());
|
||||||
m_patchChooser->setEnvironmentChange(change);
|
m_patchChooser->setEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemSettingsWidget::updateEnvironmentChangesLabel()
|
void SystemSettingsWidget::updateEnvironmentChangesLabel()
|
||||||
|
|||||||
@@ -570,19 +570,12 @@ void ExecutableAspect::setExpectedKind(const PathChooser::Kind expectedKind)
|
|||||||
Sets the environment in which paths will be searched when the expected kind
|
Sets the environment in which paths will be searched when the expected kind
|
||||||
of paths is chosen as PathChooser::Command or PathChooser::ExistingCommand
|
of paths is chosen as PathChooser::Command or PathChooser::ExistingCommand
|
||||||
to \a env.
|
to \a env.
|
||||||
|
|
||||||
\sa Utils::StringAspect::setEnvironmentChange()
|
|
||||||
*/
|
*/
|
||||||
void ExecutableAspect::setEnvironmentChange(const EnvironmentChange &change)
|
|
||||||
{
|
|
||||||
m_executable.setEnvironmentChange(change);
|
|
||||||
if (m_alternativeExecutable)
|
|
||||||
m_alternativeExecutable->setEnvironmentChange(change);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecutableAspect::setEnvironment(const Environment &env)
|
void ExecutableAspect::setEnvironment(const Environment &env)
|
||||||
{
|
{
|
||||||
setEnvironmentChange(EnvironmentChange::fromDictionary(env.toDictionary()));
|
m_executable.setEnvironment(env);
|
||||||
|
if (m_alternativeExecutable)
|
||||||
|
m_alternativeExecutable->setEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ public:
|
|||||||
void setPlaceHolderText(const QString &placeHolderText);
|
void setPlaceHolderText(const QString &placeHolderText);
|
||||||
void setHistoryCompleter(const QString &historyCompleterKey);
|
void setHistoryCompleter(const QString &historyCompleterKey);
|
||||||
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
|
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
|
||||||
void setEnvironmentChange(const Utils::EnvironmentChange &change);
|
|
||||||
void setEnvironment(const Utils::Environment &env);
|
void setEnvironment(const Utils::Environment &env);
|
||||||
void setDisplayStyle(Utils::StringAspect::DisplayStyle style);
|
void setDisplayStyle(Utils::StringAspect::DisplayStyle style);
|
||||||
|
|
||||||
|
|||||||
@@ -338,9 +338,6 @@ Environment LinuxDevicePrivate::getEnvironment()
|
|||||||
|
|
||||||
QtcProcess getEnvProc;
|
QtcProcess getEnvProc;
|
||||||
getEnvProc.setCommand({FilePath("env").onDevice(q->rootPath()), {}});
|
getEnvProc.setCommand({FilePath("env").onDevice(q->rootPath()), {}});
|
||||||
Environment inEnv;
|
|
||||||
inEnv.setCombineWithDeviceEnvironment(false);
|
|
||||||
getEnvProc.setEnvironment(inEnv);
|
|
||||||
getEnvProc.runBlocking();
|
getEnvProc.runBlocking();
|
||||||
|
|
||||||
const QString remoteOutput = getEnvProc.cleanedStdOut();
|
const QString remoteOutput = getEnvProc.cleanedStdOut();
|
||||||
@@ -919,16 +916,11 @@ LinuxDevice::LinuxDevice()
|
|||||||
d->m_terminals.removeOne(proc);
|
d->m_terminals.removeOne(proc);
|
||||||
});
|
});
|
||||||
|
|
||||||
// We recreate the same way that QtcProcess uses to create the actual environment.
|
|
||||||
const Environment finalEnv = (!env.hasChanges() && env.combineWithDeviceEnvironment())
|
|
||||||
? d->getEnvironment()
|
|
||||||
: env;
|
|
||||||
// If we will not set any environment variables, we can leave out the shell executable
|
// If we will not set any environment variables, we can leave out the shell executable
|
||||||
// as the "ssh ..." call will automatically launch the default shell if there are
|
// as the "ssh ..." call will automatically launch the default shell if there are
|
||||||
// no arguments. But if we will set environment variables, we need to explicitly
|
// no arguments. But if we will set environment variables, we need to explicitly
|
||||||
// specify the shell executable.
|
// specify the shell executable.
|
||||||
const QString shell = finalEnv.hasChanges() ? finalEnv.value_or("SHELL", "/bin/sh")
|
const QString shell = env.hasChanges() ? env.value_or("SHELL", "/bin/sh") : QString();
|
||||||
: QString();
|
|
||||||
|
|
||||||
proc->setCommand({filePath(shell), {}});
|
proc->setCommand({filePath(shell), {}});
|
||||||
proc->setTerminalMode(TerminalMode::On);
|
proc->setTerminalMode(TerminalMode::On);
|
||||||
|
|||||||
@@ -135,9 +135,9 @@ CommonSettingsWidget::CommonSettingsWidget(CommonOptionsPage *page)
|
|||||||
|
|
||||||
void CommonSettingsWidget::updatePath()
|
void CommonSettingsWidget::updatePath()
|
||||||
{
|
{
|
||||||
EnvironmentChange change;
|
Environment env;
|
||||||
change.addAppendToPath(Core::VcsManager::additionalToolsPath());
|
env.appendToPath(Core::VcsManager::additionalToolsPath());
|
||||||
m_page->settings().sshPasswordPrompt.setEnvironmentChange(change);
|
m_page->settings().sshPasswordPrompt.setEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonSettingsWidget::apply()
|
void CommonSettingsWidget::apply()
|
||||||
|
|||||||
Reference in New Issue
Block a user