Skip to content

Commit bab29c2

Browse files
only use dropin configs when option config.dropins is true
Boolean option `config.dropins` must be set to `true` so that dropin configs are considered.
1 parent de473e3 commit bab29c2

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

src/west/configuration.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,34 @@ def from_path(path: Path | None) -> '_InternalCF | None':
7777

7878
def __init__(self, path: Path):
7979
self.cp = _configparser()
80-
self.dropin_cp = _configparser()
8180
self.path = path if path.exists() else None
82-
dropin_dir = Path(f'{path}.d')
83-
self.dropin_dir = dropin_dir if dropin_dir.exists() else None
81+
if self.path:
82+
self.cp.read(self.path, encoding='utf-8')
83+
84+
# consider dropin configs
85+
self.dropin_cp = _configparser()
86+
self.dropin_dir = None
8487
self.dropin_paths = []
85-
if self.dropin_dir:
86-
# dropin configs are applied in alphabetical order
87-
for conf in sorted(self.dropin_dir.iterdir()):
88-
# only consider .conf files
89-
if conf.suffix.lower() == '.conf':
90-
self.dropin_paths.append(self.dropin_dir / conf)
91-
self._read()
88+
# dropin configs must be enabled in config
89+
if self.cp.getboolean('config', 'dropins', fallback=False):
90+
# dropin dir is the config path with .d suffix
91+
dropin_dir = Path(f'{path}.d')
92+
self.dropin_dir = dropin_dir if dropin_dir.exists() else None
93+
if self.dropin_dir:
94+
# dropin configs are applied in alphabetical order
95+
for conf in sorted(self.dropin_dir.iterdir()):
96+
# only consider .conf files
97+
if conf.suffix == '.conf':
98+
self.dropin_paths.append(self.dropin_dir / conf)
99+
if self.dropin_paths:
100+
self.dropin_cp.read(self.dropin_paths, encoding='utf-8')
92101

93102
def _paths(self) -> list[Path]:
94103
ret = [p for p in self.dropin_paths]
95104
if self.path:
96105
ret.append(self.path)
97106
return ret
98107

99-
def _read(self):
100-
if self.path:
101-
self.cp.read(self.path, encoding='utf-8')
102-
if self.dropin_paths:
103-
self.dropin_cp.read(self.dropin_paths, encoding='utf-8')
104-
105108
def _write(self):
106109
if not self.path:
107110
raise WestNotFound('No config file exists that can be written')

tests/test_config.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def test_config_list_paths_extended():
139139
{WEST_CONFIG_LOCAL}
140140
''').splitlines()
141141

142-
# create some dropins files
142+
# create some dropin config files
143143
dropin_files = [
144144
pathlib.Path(WEST_CONFIG_GLOBAL + '.d') / 'a.conf',
145145
pathlib.Path(WEST_CONFIG_GLOBAL + '.d') / 'z.conf',
@@ -283,24 +283,25 @@ def test_local_creation():
283283
assert 'pytest' not in cfg(f=GLOBAL)
284284
assert cfg(f=LOCAL)['pytest']['key'] == 'val'
285285

286-
TEST_CASES_CONFIG_D = [
286+
TEST_CASES_DROPIN_CONFIGS = [
287287
# (flag, env_var)
288288
('', 'WEST_CONFIG_LOCAL'),
289289
('--local', 'WEST_CONFIG_LOCAL'),
290290
('--system', 'WEST_CONFIG_SYSTEM'),
291291
('--global', 'WEST_CONFIG_GLOBAL'),
292292
]
293293

294-
@pytest.mark.parametrize("test_case", TEST_CASES_CONFIG_D)
295-
def test_config_d_local(test_case):
294+
@pytest.mark.parametrize("test_case", TEST_CASES_DROPIN_CONFIGS)
295+
def test_config_dropins(test_case):
296296
flag, env_var = test_case
297297
config_path = pathlib.Path(os.environ[env_var])
298-
config_d_dir = pathlib.Path(f'{config_path}.d')
299-
config_d_dir.mkdir()
298+
dropin_configs_dir = pathlib.Path(f'{config_path}.d')
299+
dropin_configs_dir.mkdir()
300300

301301
# write value in actual config file
302302
cmd(f'config {flag} pytest.key val')
303303
cmd(f'config {flag} pytest.config-only val')
304+
cmd(f'config {flag} config.dropins true')
304305

305306
# read config value via command line
306307
stdout = cmd(f'config {flag} pytest.key')
@@ -316,10 +317,13 @@ def test_config_d_local(test_case):
316317
key = val
317318
config-only = val
318319
320+
[config]
321+
dropins = true
322+
319323
''')
320324

321325
# create a dropin config under .d
322-
with open(config_d_dir / 'a.conf', 'w') as conf:
326+
with open(dropin_configs_dir / 'a.conf', 'w') as conf:
323327
conf.write(textwrap.dedent('''
324328
[pytest]
325329
key = from dropin a
@@ -328,7 +332,7 @@ def test_config_d_local(test_case):
328332
'''))
329333

330334
# create a dropin config under .d
331-
with open(config_d_dir / 'z.conf', 'w') as conf:
335+
with open(dropin_configs_dir / 'z.conf', 'w') as conf:
332336
conf.write(textwrap.dedent('''
333337
[pytest]
334338
dropin-only = from dropin z
@@ -358,16 +362,20 @@ def test_config_d_local(test_case):
358362
[pytest]
359363
key = val
360364
365+
[config]
366+
dropins = true
367+
361368
''')
362369

363-
# remove config file
370+
# remove config file and only set config.dropins true again
364371
config_path.unlink()
372+
cmd(f'config {flag} config.dropins true')
365373

366374
# values from config are unset now
367375
stderr = cmd_raises(f'config {flag} pytest.config-only', subprocess.CalledProcessError)
368376
assert 'ERROR: pytest.config-only is unset' == stderr.rstrip()
369377

370-
# dropin applies now, since config does not exist
378+
# dropin config values are used now, since they are not set in config
371379
stdout = cmd(f'config {flag} pytest.key')
372380
assert 'from dropin a' == stdout.rstrip()
373381
# alphabetical order (z.conf is overwriting a.conf)
@@ -383,6 +391,14 @@ def test_config_d_local(test_case):
383391
# deletion of a value that is not existing anymore should fail
384392
cmd_raises(f'config {flag} -d pytest.config-only', subprocess.CalledProcessError)
385393

394+
# remove config (config.dropins is false by default)
395+
config_path.unlink()
396+
397+
# values from dropin configs are not considered now
398+
cmd_raises(f'config {flag} pytest.key', subprocess.CalledProcessError)
399+
cmd_raises(f'config {flag} pytest.dropin-only', subprocess.CalledProcessError)
400+
cmd_raises(f'config {flag} pytest.dropin-only-a', subprocess.CalledProcessError)
401+
cmd_raises(f'config {flag} pytest.dropin-only-z', subprocess.CalledProcessError)
386402

387403
def test_local_creation_with_topdir():
388404
# Like test_local_creation, with a specified topdir.

0 commit comments

Comments
 (0)