1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload(":env_variables.bzl", _CAPTURED_ENV_VARS = "CAPTURED_ENV_VARS") 16*7594170eSAndroid Build Coastguard Worker 17*7594170eSAndroid Build Coastguard Worker_ALLOWED_SPECIAL_CHARACTERS = [ 18*7594170eSAndroid Build Coastguard Worker "/", 19*7594170eSAndroid Build Coastguard Worker "_", 20*7594170eSAndroid Build Coastguard Worker "-", 21*7594170eSAndroid Build Coastguard Worker "'", 22*7594170eSAndroid Build Coastguard Worker ".", 23*7594170eSAndroid Build Coastguard Worker " ", 24*7594170eSAndroid Build Coastguard Worker] 25*7594170eSAndroid Build Coastguard Worker 26*7594170eSAndroid Build Coastguard Worker# Since we write the env var value literally into a .bzl file, ensure that the string 27*7594170eSAndroid Build Coastguard Worker# does not contain special characters like '"', '\n' and '\'. Use an allowlist approach 28*7594170eSAndroid Build Coastguard Worker# and check that the remaining string is alphanumeric. 29*7594170eSAndroid Build Coastguard Workerdef _validate_env_value(env_var, env_value): 30*7594170eSAndroid Build Coastguard Worker if env_value == "": 31*7594170eSAndroid Build Coastguard Worker return 32*7594170eSAndroid Build Coastguard Worker sanitized_env_value = env_value 33*7594170eSAndroid Build Coastguard Worker for allowed_char in _ALLOWED_SPECIAL_CHARACTERS: 34*7594170eSAndroid Build Coastguard Worker sanitized_env_value = sanitized_env_value.replace(allowed_char, "") 35*7594170eSAndroid Build Coastguard Worker if not sanitized_env_value.isalnum(): 36*7594170eSAndroid Build Coastguard Worker fail("The value of " + 37*7594170eSAndroid Build Coastguard Worker env_var + 38*7594170eSAndroid Build Coastguard Worker " can only consist of alphanumeric and " + 39*7594170eSAndroid Build Coastguard Worker str(_ALLOWED_SPECIAL_CHARACTERS) + 40*7594170eSAndroid Build Coastguard Worker " characters: " + 41*7594170eSAndroid Build Coastguard Worker str(env_value)) 42*7594170eSAndroid Build Coastguard Worker 43*7594170eSAndroid Build Coastguard Workerdef _env_impl(rctx): 44*7594170eSAndroid Build Coastguard Worker captured_env = {} 45*7594170eSAndroid Build Coastguard Worker for var in _CAPTURED_ENV_VARS: 46*7594170eSAndroid Build Coastguard Worker value = rctx.os.environ.get(var) 47*7594170eSAndroid Build Coastguard Worker if value != None: 48*7594170eSAndroid Build Coastguard Worker _validate_env_value(var, value) 49*7594170eSAndroid Build Coastguard Worker captured_env[var] = value 50*7594170eSAndroid Build Coastguard Worker 51*7594170eSAndroid Build Coastguard Worker rctx.file("BUILD.bazel", """ 52*7594170eSAndroid Build Coastguard Workerexports_files(["env.bzl"]) 53*7594170eSAndroid Build Coastguard Worker""") 54*7594170eSAndroid Build Coastguard Worker 55*7594170eSAndroid Build Coastguard Worker rctx.file("env.bzl", """ 56*7594170eSAndroid Build Coastguard Workerenv = { 57*7594170eSAndroid Build Coastguard Worker %s 58*7594170eSAndroid Build Coastguard Worker} 59*7594170eSAndroid Build Coastguard Worker""" % "\n ".join([ 60*7594170eSAndroid Build Coastguard Worker '"%s": "%s",' % (var, value) 61*7594170eSAndroid Build Coastguard Worker for var, value in captured_env.items() 62*7594170eSAndroid Build Coastguard Worker ])) 63*7594170eSAndroid Build Coastguard Worker 64*7594170eSAndroid Build Coastguard Workerenv_repository = repository_rule( 65*7594170eSAndroid Build Coastguard Worker implementation = _env_impl, 66*7594170eSAndroid Build Coastguard Worker configure = True, 67*7594170eSAndroid Build Coastguard Worker local = True, 68*7594170eSAndroid Build Coastguard Worker environ = _CAPTURED_ENV_VARS, 69*7594170eSAndroid Build Coastguard Worker doc = "A repository rule to capture environment variables.", 70*7594170eSAndroid Build Coastguard Worker) 71