Utils: Make Environment has-a NameValueDictory instead of is-a

We need a somewhat more wholistic approach on how to communicate
environment data and changes in the code, a single fixed map
doesn't cut it.

Change-Id: Ifbed254e7e0f4a76f8627e77030889c326f551d4
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2022-06-01 12:34:08 +02:00
parent 9524a3f025
commit 5de18c67f0
5 changed files with 81 additions and 28 deletions

View File

@@ -40,10 +40,15 @@ Q_GLOBAL_STATIC_WITH_ARGS(Environment, staticSystemEnvironment,
Q_GLOBAL_STATIC(QVector<EnvironmentProvider>, environmentProviders)
NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepend) const
{
return m_dict.diff(other.m_dict, checkAppendPrepend);
}
QProcessEnvironment Environment::toProcessEnvironment() const
{
QProcessEnvironment result;
for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
for (auto it = m_dict.m_values.constBegin(); it != m_dict.m_values.constEnd(); ++it) {
if (it.value().second)
result.insert(it.key().name, expandedValueForKey(key(it)));
}
@@ -52,28 +57,28 @@ QProcessEnvironment Environment::toProcessEnvironment() const
void Environment::appendOrSetPath(const FilePath &value)
{
QTC_CHECK(value.osType() == m_osType);
QTC_CHECK(value.osType() == osType());
if (value.isEmpty())
return;
appendOrSet("PATH", value.nativePath(),
QString(OsSpecificAspects::pathListSeparator(m_osType)));
QString(OsSpecificAspects::pathListSeparator(osType())));
}
void Environment::prependOrSetPath(const FilePath &value)
{
QTC_CHECK(value.osType() == m_osType);
QTC_CHECK(value.osType() == osType());
if (value.isEmpty())
return;
prependOrSet("PATH", value.nativePath(),
QString(OsSpecificAspects::pathListSeparator(m_osType)));
QString(OsSpecificAspects::pathListSeparator(osType())));
}
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
{
QTC_ASSERT(!key.contains('='), return );
const auto it = findKey(key);
if (it == m_values.end()) {
m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
const auto it = m_dict.findKey(key);
if (it == m_dict.m_values.end()) {
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), qMakePair(value, true));
} else {
// Append unless it is already there
const QString toAppend = sep + value;
@@ -85,9 +90,9 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS
void Environment::prependOrSet(const QString &key, const QString &value, const QString &sep)
{
QTC_ASSERT(!key.contains('='), return );
const auto it = findKey(key);
if (it == m_values.end()) {
m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
const auto it = m_dict.findKey(key);
if (it == m_dict.m_values.end()) {
m_dict.m_values.insert(DictKey(key, m_dict.nameCaseSensitivity()), qMakePair(value, true));
} else {
// Prepend unless it is already there
const QString toPrepend = value + sep;
@@ -98,8 +103,8 @@ void Environment::prependOrSet(const QString &key, const QString &value, const Q
void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
{
QTC_CHECK(value.osType() == m_osType);
switch (m_osType) {
QTC_CHECK(value.osType() == osType());
switch (osType()) {
case OsTypeWindows: {
const QChar sep = ';';
prependOrSet("PATH", value.nativePath(), QString(sep));
@@ -137,8 +142,8 @@ Environment Environment::systemEnvironment()
void Environment::setupEnglishOutput()
{
set("LC_MESSAGES", "en_US.utf8");
set("LANGUAGE", "en_US:en");
m_dict.set("LC_MESSAGES", "en_US.utf8");
m_dict.set("LANGUAGE", "en_US:en");
}
static FilePath searchInDirectory(const QStringList &execs,
@@ -166,7 +171,7 @@ QStringList Environment::appendExeExtensions(const QString &executable) const
{
QStringList execs(executable);
const QFileInfo fi(executable);
if (m_osType == OsTypeWindows) {
if (osType() == OsTypeWindows) {
// Check all the executable extensions on windows:
// PATHEXT is only used if the executable has no extension
if (fi.suffix().isEmpty()) {
@@ -202,7 +207,7 @@ bool Environment::isSameExecutable(const QString &exe1, const QString &exe2) con
QString Environment::expandedValueForKey(const QString &key) const
{
return expandVariables(value(key));
return expandVariables(m_dict.value(key));
}
static FilePath searchInDirectoriesHelper(const Environment &env,
@@ -308,7 +313,7 @@ FilePaths Environment::path() const
FilePaths Environment::pathListValue(const QString &varName) const
{
const QStringList pathComponents = expandedValueForKey(varName).split(
OsSpecificAspects::pathListSeparator(m_osType), Qt::SkipEmptyParts);
OsSpecificAspects::pathListSeparator(osType()), Qt::SkipEmptyParts);
return transform(pathComponents, &FilePath::fromUserInput);
}
@@ -333,12 +338,12 @@ QString Environment::expandVariables(const QString &input) const
{
QString result = input;
if (m_osType == OsTypeWindows) {
if (osType() == OsTypeWindows) {
for (int vStart = -1, i = 0; i < result.length(); ) {
if (result.at(i++) == '%') {
if (vStart > 0) {
const auto it = findKey(result.mid(vStart, i - vStart - 1));
if (it != m_values.constEnd()) {
const auto it = m_dict.findKey(result.mid(vStart, i - vStart - 1));
if (it != m_dict.m_values.constEnd()) {
result.replace(vStart - 1, i - vStart + 1, it->first);
i = vStart - 1 + it->first.length();
vStart = -1;