• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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