Skip to content

Commit

Permalink
Resolve env variables in bazelrc
Browse files Browse the repository at this point in the history
Bazel will now try to resolve environment variables
provided in bazelrc files.
If environmetn variable is not found text will remain
unchanged.

Format to be used: ${FOO}

Example:
  import ${GIT_ROOT}/some/path/bazel.rc
  • Loading branch information
anthpi authored and pilkjaer committed Mar 31, 2021
1 parent c981413 commit 0f9940e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/main/cpp/rc_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "src/main/cpp/rc_file.h"

#include <algorithm>
#include <regex>
#include <utility>

#include "src/main/cpp/blaze_util.h"
Expand Down Expand Up @@ -79,6 +80,29 @@ RcFile::ParseError RcFile::ParseFile(const string& filename,
continue;
}

// Resolve env variables if possible
std::regex env_var_regex("\\$\\{(.*?)\\}");
std::smatch env_matcher;
vector <string> env_var_to_replace;
// Finding env variable names to replace
string tmp_line = line;
while(regex_search(tmp_line, env_matcher, env_var_regex)) {
env_var_to_replace.push_back(env_matcher[1].str());
tmp_line = env_matcher.suffix();
}
// Loop through found env variables, try to resolve them and replace if found
for (int i = env_var_to_replace.size() - 1; i >= 0; i--){
std::string env_var_p = blaze::GetEnv(env_var_to_replace[i].c_str());
if(!env_var_p.empty()) {
std::string replacement = "${"+ env_var_to_replace[i] +"}";
size_t pos = 0;
while ((pos = line.find(replacement, pos)) != std::string::npos) {
line.replace(pos, replacement.length(), env_var_p);
pos += replacement.length();
}
}
}

vector<string> words;

// This will treat "#" as a comment, and properly
Expand Down
43 changes: 43 additions & 0 deletions src/test/cpp/rc_options_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif

#include <vector>

#include "src/main/cpp/blaze_util.h"
Expand Down Expand Up @@ -251,6 +258,42 @@ TEST_F(RcOptionsTest, ManyArgStartup) {
}});
}

TEST_F(RcOptionsTest, EnvVariableMissing) {
WriteRc("env_var_missing.bazelrc",
"startup ${RC_MISSING} foo");
SuccessfullyParseRcWithExpectedArgs(
"env_var_missing.bazelrc",
{{"startup",{"${RC_MISSING}","foo"}}});
}

TEST_F(RcOptionsTest, EnvVariableResolved) {
#if defined(_WIN32)
ASSERT_NE(::SetEnvironmentVariable("RC_TEST", "startup foo"), 0);
#else
setenv("RC_TEST", "startup foo", 1);
#endif
WriteRc("env_var.bazelrc",
"${RC_TEST}");
SuccessfullyParseRcWithExpectedArgs(
"env_var.bazelrc",
{{"startup", {"foo"}}});
}

TEST_F(RcOptionsTest, EnvVariableResolvedMultiple) {
#if defined(_WIN32)
ASSERT_NE(::SetEnvironmentVariable("RC_TEST", "startup"), 0);
ASSERT_NE(::SetEnvironmentVariable("RC_TEST_ARG", "foo"), 0);
#else
setenv("RC_TEST", "startup", 1);
setenv("RC_TEST_ARG", "foo", 1);
#endif
WriteRc("env_var_multi.bazelrc",
"${RC_TEST} ${RC_TEST_ARG}");
SuccessfullyParseRcWithExpectedArgs(
"env_var_multi.bazelrc",
{{"startup", {"foo"}}});
}

TEST_F(RcOptionsTest, MultipleCommands) {
WriteRc("multiple_commands_intermixed.bazelrc",
"startup foo\n"
Expand Down

0 comments on commit 0f9940e

Please sign in to comment.