1# Copyright 2023 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Reads and parses the Pigweed config file. 15 16See also https://pigweed.dev/seed/0101-pigweed.json.html. 17""" 18 19import json 20import os 21 22try: 23 # This will only succeed when using config_file from Bazel. 24 from rules_python.python.runfiles import runfiles # type: ignore 25except (ImportError, ModuleNotFoundError): 26 runfiles = None 27 28 29def _resolve_env(env): 30 if env: 31 return env 32 return os.environ 33 34 35def _get_project_root(env): 36 for var in ('PW_PROJECT_ROOT', 'PW_ROOT'): 37 if var in env: 38 return env[var] 39 raise ValueError('environment variable PW_PROJECT_ROOT not set') 40 41 42def _pw_env_substitute(env, string): 43 if not isinstance(string, str): 44 return string 45 46 # Substitute in environment variables based on $pw_env{VAR_NAME} tokens. 47 for key, value in env.items(): 48 string = string.replace('$pw_env{' + key + '}', value) 49 50 if '$pw_env{' in string: 51 raise ValueError(f'Unresolved $pw_env\\{...} in JSON string: {string}') 52 53 return string 54 55 56def path(env=None): 57 """Return the path where pigweed.json should reside.""" 58 env = _resolve_env(env) 59 return os.path.join(_get_project_root(env=env), 'pigweed.json') 60 61 62def path_from_runfiles(): 63 r = runfiles.Create() 64 location = r.Rlocation("pigweed.json") 65 if location is None: 66 # Failed to find pigweed.json 67 raise ValueError("Failed to find pigweed.json") 68 69 return location 70 71 72def load(env=None): 73 """Load pigweed.json if it exists and return the contents.""" 74 if env is None and runfiles is not None: 75 config_path = path_from_runfiles() 76 else: 77 env = _resolve_env(env) 78 config_path = path(env=env) 79 80 if not os.path.isfile(config_path): 81 return {} 82 83 def hook(obj): 84 out = {} 85 for key, val in obj.items(): 86 out[key] = _pw_env_substitute(env, val) 87 return out 88 89 with open(config_path, 'r') as file: 90 return json.load(file, object_hook=hook) 91