diff --git a/outputview/outputexecutejob.cpp b/outputview/outputexecutejob.cpp --- a/outputview/outputexecutejob.cpp +++ b/outputview/outputexecutejob.cpp @@ -466,13 +466,16 @@ QProcessEnvironment OutputExecuteJobPrivate::effectiveEnvironment() const { - QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); const EnvironmentGroupList environmentGroup( KSharedConfig::openConfig() ); QString environmentProfile = m_owner->environmentProfile(); if( environmentProfile.isEmpty() ) { environmentProfile = environmentGroup.defaultGroup(); } - OutputExecuteJobPrivate::mergeEnvironment( environment, environmentGroup.variables( environmentProfile ) ); + QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); + auto userEnv = environmentGroup.variables(environmentProfile); + expandVariables(userEnv, environment); + + OutputExecuteJobPrivate::mergeEnvironment( environment, userEnv ); OutputExecuteJobPrivate::mergeEnvironment( environment, m_environmentOverrides ); if( m_properties.testFlag( OutputExecuteJob::PortableMessages ) ) { environment.remove( "LC_ALL" ); diff --git a/util/environmentgrouplist.h b/util/environmentgrouplist.h --- a/util/environmentgrouplist.h +++ b/util/environmentgrouplist.h @@ -24,6 +24,7 @@ #include +class QProcessEnvironment; class KConfig; template class QMap; class QString; @@ -140,6 +141,8 @@ }; +KDEVPLATFORMUTIL_EXPORT void expandVariables(QMap& variables, const QProcessEnvironment& environment); + } #endif diff --git a/util/environmentgrouplist.cpp b/util/environmentgrouplist.cpp --- a/util/environmentgrouplist.cpp +++ b/util/environmentgrouplist.cpp @@ -25,6 +25,8 @@ #include +#include +#include namespace KDevelop { class EnvironmentGroupListPrivate @@ -201,3 +203,21 @@ return env; } + +void KDevelop::expandVariables(QMap& variables, const QProcessEnvironment& environment) +{ + QRegularExpression rVar("(? + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef TESTENVIRONMENT_H +#define TESTENVIRONMENT_H + +#include + +class TestEnvironment : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testExpandVariables_data(); + void testExpandVariables(); +}; + +#endif // TESTENVIRONMENT_H diff --git a/util/tests/test_environment.cpp b/util/tests/test_environment.cpp new file mode 100644 --- /dev/null +++ b/util/tests/test_environment.cpp @@ -0,0 +1,81 @@ +/* + * This file is part of KDevelop + * + * Copyright 2015 Artur Puzio + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "test_environment.h" + +#include "util/environmentgrouplist.h" + +#include + +QTEST_MAIN(TestEnvironment); + +using ProcEnv = QMap; + +void TestEnvironment::testExpandVariables_data() +{ + QTest::addColumn("env"); + QTest::addColumn("expectedEnv"); + + QTest::newRow("no variables") << ProcEnv({}) << ProcEnv({}); + QTest::newRow("simple variables") << ProcEnv{ + {"VAR1","data"}, + {"Var2","some other data"} + } << ProcEnv({ + {"VAR1","data"}, + {"Var2","some other data"} + }); + QTest::newRow("PATH append and prepend") << ProcEnv({ + {"PATH","/home/usr/bin:$PATH:/home/user/folder"} + }) << ProcEnv({ + {"PATH", "/home/usr/bin:/bin:/usr/bin:/home/user/folder"} + }); + QTest::newRow("\\$VAR") << ProcEnv({ + {"MY_VAR","\\$PATH something \\$HOME"} + }) << ProcEnv({ + {"MY_VAR","$PATH something $HOME"} + }); + QTest::newRow("spaces, \\$VAR after $VAR") << ProcEnv({ + {"MY_VAR","$PATH:$HOME something \\$HOME"} + }) << ProcEnv({ + {"MY_VAR","/bin:/usr/bin:/home/tom something $HOME"} + }); + QTest::newRow("VAR2=$VAR1") << ProcEnv({ + {"VAR1","/some/path"},{"VAR2","$VAR1"} + }) << ProcEnv({ + {"VAR1","/some/path"},{"VAR2",""} + }); +} + +void TestEnvironment::testExpandVariables() +{ + QFETCH(ProcEnv, env); + QFETCH(ProcEnv, expectedEnv); + + QProcessEnvironment fakeSysEnv; + fakeSysEnv.insert("PATH","/bin:/usr/bin"); + fakeSysEnv.insert("HOME","/home/tom"); + + KDevelop::expandVariables(env, fakeSysEnv); + + for (auto it = expectedEnv.cbegin(); it!= expectedEnv.cend(); ++it) { + QCOMPARE(env.value(it.key()), it.value()); + } +}