Skip to content

Commit 9b6086c

Browse files
author
DevForge Engineer
committed
fix(scan): use Path.name instead of Path.stem to preserve dots in env names
Closes #37. Path.stem strips the final dotted segment of directory names, causing silent collisions for dirs like "prod.v2" and "prod". Path.name preserves the full basename.
1 parent adb713d commit 9b6086c

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

‎src/configdrift/cli.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def scan(
267267
# Use directory basenames as env names
268268
dir_mapping = {}
269269
for d in dirs:
270-
env_name = Path(d).stem
270+
env_name = Path(d).name
271271
dir_mapping[env_name] = d
272272
else:
273273
console.print(

‎tests/test_cli.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,40 @@ def test_scan_env_and_toml_dirs(self):
405405
data = json.loads(result.stdout)
406406
assert "prod" in data
407407

408+
def test_scan_dir_names_with_dots_preserved(self):
409+
"""Dir names containing dots must not be truncated by Path.stem."""
410+
with tempfile.TemporaryDirectory() as tmpdir:
411+
dev_dir = Path(tmpdir) / "dev"
412+
prod_us = Path(tmpdir) / "prod.us"
413+
prod_eu = Path(tmpdir) / "prod.eu"
414+
dev_dir.mkdir()
415+
prod_us.mkdir()
416+
prod_eu.mkdir()
417+
(dev_dir / "c.yaml").write_text(yaml.dump({"host": "localhost"}))
418+
(prod_us / "c.yaml").write_text(yaml.dump({"host": "us.example.com"}))
419+
(prod_eu / "c.yaml").write_text(yaml.dump({"host": "eu.example.com"}))
420+
421+
# Table output: all 3 envs must appear as distinct columns
422+
result = runner.invoke(
423+
app,
424+
["scan", str(dev_dir), str(prod_us), str(prod_eu)],
425+
)
426+
assert result.exit_code == 0, f"STDOUT: {result.stdout}"
427+
assert "dev →" in result.stdout, "Baseline 'dev' should appear in table"
428+
assert "prod.us" in result.stdout, f"Missing prod.us in output:\n{result.stdout}"
429+
assert "prod.eu" in result.stdout, f"Missing prod.eu in output:\n{result.stdout}"
430+
431+
# JSON output: both targets must be separate keys (not collapsed)
432+
result2 = runner.invoke(
433+
app,
434+
["scan", str(dev_dir), str(prod_us), str(prod_eu), "--output", "json"],
435+
)
436+
assert result2.exit_code == 0, f"STDOUT: {result2.stdout}"
437+
data = json.loads(result2.stdout)
438+
assert "prod.us" in data, f"Missing prod.us in {list(data.keys())}"
439+
assert "prod.eu" in data, f"Missing prod.eu in {list(data.keys())}"
440+
assert len(data) == 2, f"Expected 2 targets, got {len(data)}: {list(data.keys())}"
441+
408442
def test_scan_no_changes_env_skipped_in_table(self):
409443
"""Scan with multiple envs where one has no changes."""
410444
with tempfile.TemporaryDirectory() as tmpdir:

0 commit comments

Comments
 (0)