Skip to content

Commit 50cbc34

Browse files
thorsten-kleinpdgendt
authored andcommitted
support 'west config --list-paths'
The command prints a list of all configuration files currently considered and existing. They are listed in the order as they are loaded.
1 parent c81a1fc commit 50cbc34

File tree

3 files changed

+112
-7
lines changed

3 files changed

+112
-7
lines changed

src/west/app/config.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,28 @@
3535
3636
- Linux, macOS, Windows: <workspace-root-directory>/.west/config
3737
38-
You can override these files' locations with the WEST_CONFIG_SYSTEM,
39-
WEST_CONFIG_GLOBAL, and WEST_CONFIG_LOCAL environment variables.
40-
4138
Configuration values from later configuration files override configuration
4239
from earlier ones. Local values have highest precedence, and system values
4340
lowest.
4441
45-
To get a value for <name>, type:
42+
The config file location for each according config level can be changed with
43+
environment variables:
44+
- WEST_CONFIG_SYSTEM
45+
- WEST_CONFIG_GLOBAL
46+
- WEST_CONFIG_LOCAL
47+
48+
All `west config` commands can be applied for a specific configuration level by
49+
providing one of the following arguments:
50+
--local | --system | --global
51+
52+
The following command prints a list of all configuration files currently
53+
considered and existing (listed in the order as they are loaded):
54+
west config --list-paths
55+
56+
To get the value for config option <name>, type:
4657
west config <name>
4758
48-
To set a value for <name>, type:
59+
To set a value for config option <name>, type:
4960
west config <name> <value>
5061
5162
To append to a value for <name>, type:
@@ -99,6 +110,11 @@ def do_add_parser(self, parser_adder):
99110
"action to perform (give at most one)"
100111
).add_mutually_exclusive_group()
101112

113+
group.add_argument(
114+
'--list-paths',
115+
action='store_true',
116+
help='list all config files that are currently considered by west config',
117+
)
102118
group.add_argument(
103119
'-l', '--list', action='store_true', help='list all options and their values'
104120
)
@@ -153,13 +169,15 @@ def do_run(self, args, user_args):
153169
if args.list:
154170
if args.name:
155171
self.parser.error('-l cannot be combined with name argument')
156-
elif not args.name:
172+
elif not args.name and not args.list_paths:
157173
self.parser.error('missing argument name (to list all options and values, use -l)')
158174
elif args.append:
159175
if args.value is None:
160176
self.parser.error('-a requires both name and value')
161177

162-
if args.list:
178+
if args.list_paths:
179+
self.list_paths(args)
180+
elif args.list:
163181
self.list(args)
164182
elif delete:
165183
self.delete(args)
@@ -170,6 +188,11 @@ def do_run(self, args, user_args):
170188
else:
171189
self.write(args)
172190

191+
def list_paths(self, args):
192+
config_paths = self.config.get_paths(args.configfile or ALL)
193+
for config_path in config_paths:
194+
self.inf(config_path)
195+
173196
def list(self, args):
174197
what = args.configfile or ALL
175198
for option, value in self.config.items(configfile=what):

src/west/configuration.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ def __init__(self, topdir: PathType | None = None):
183183
self._global = _InternalCF.from_path(self._global_path)
184184
self._local = _InternalCF.from_path(self._local_path)
185185

186+
def get_paths(self, location: ConfigFile = ConfigFile.ALL):
187+
ret = []
188+
if self._global and location in [ConfigFile.GLOBAL, ConfigFile.ALL]:
189+
ret.append(self._global.path)
190+
if self._system and location in [ConfigFile.SYSTEM, ConfigFile.ALL]:
191+
ret.append(self._system.path)
192+
if self._local and location in [ConfigFile.LOCAL, ConfigFile.ALL]:
193+
ret.append(self._local.path)
194+
return ret
195+
186196
def get(
187197
self, option: str, default: str | None = None, configfile: ConfigFile = ConfigFile.ALL
188198
) -> str | None:

tests/test_config.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import pathlib
88
import subprocess
9+
import textwrap
910
from typing import Any
1011

1112
import pytest
@@ -93,6 +94,77 @@ def test_config_global():
9394
assert 'pytest' not in lcl
9495

9596

97+
TEST_CASES_CONFIG_LIST_PATHS = [
98+
# (flag, env_var)
99+
('--local', 'WEST_CONFIG_LOCAL'),
100+
('--system', 'WEST_CONFIG_SYSTEM'),
101+
('--global', 'WEST_CONFIG_GLOBAL'),
102+
]
103+
104+
105+
@pytest.mark.parametrize("test_case", TEST_CASES_CONFIG_LIST_PATHS)
106+
def test_config_list_paths_env(test_case):
107+
'''Test that --list-paths considers the env variables'''
108+
flag, env_var = test_case
109+
110+
# create the config
111+
cmd(f'config {flag} pytest.key val')
112+
113+
# check that the config is listed now
114+
stdout = cmd(f'config {flag} --list-paths')
115+
config_path = pathlib.Path(os.environ[env_var])
116+
assert f'{config_path}' == stdout.rstrip()
117+
118+
# config is only listed if it exists
119+
config_path.unlink()
120+
stdout = cmd(f'config {flag} --list-paths')
121+
assert '' == stdout.rstrip()
122+
123+
124+
def test_config_list_paths():
125+
WEST_CONFIG_LOCAL = os.environ['WEST_CONFIG_LOCAL']
126+
WEST_CONFIG_GLOBAL = os.environ['WEST_CONFIG_GLOBAL']
127+
WEST_CONFIG_SYSTEM = os.environ['WEST_CONFIG_SYSTEM']
128+
129+
# create the configs
130+
cmd('config --local pytest.key val')
131+
cmd('config --global pytest.key val')
132+
cmd('config --system pytest.key val')
133+
134+
# list the configs
135+
stdout = cmd('config --list-paths')
136+
assert (
137+
stdout.splitlines()
138+
== textwrap.dedent(f'''\
139+
{WEST_CONFIG_GLOBAL}
140+
{WEST_CONFIG_SYSTEM}
141+
{WEST_CONFIG_LOCAL}
142+
''').splitlines()
143+
)
144+
145+
# do not list any configs if no config files currently exist
146+
# (Note: even no local config exists, same as outside any west workspace)
147+
pathlib.Path(WEST_CONFIG_GLOBAL).unlink()
148+
pathlib.Path(WEST_CONFIG_SYSTEM).unlink()
149+
pathlib.Path(WEST_CONFIG_LOCAL).unlink()
150+
stdout = cmd('config --list-paths')
151+
assert stdout.splitlines() == []
152+
153+
# list local config as it exists (determined from filesystem, not from env)
154+
del os.environ['WEST_CONFIG_LOCAL']
155+
default_config = pathlib.Path('.west') / 'config'
156+
default_config.parent.mkdir()
157+
default_config.write_text(
158+
textwrap.dedent('''\
159+
[manifest]
160+
path = any
161+
file = west.yml
162+
''')
163+
)
164+
stdout = cmd('config --list-paths')
165+
assert stdout.splitlines() == [str(default_config.absolute())]
166+
167+
96168
def test_config_local():
97169
# test_config_system for local variables.
98170
cmd('config --local pytest.local foo')

0 commit comments

Comments
 (0)