Skip to content

Commit 4de9970

Browse files
committed
cli(feat[privacy]): Contract home paths in JSON/NDJSON output
why: Fix inconsistency where workspace_root used ~/ but path showed full /home/username/ paths, exposing usernames and reducing portability what: - Apply contract_user_home() to path field in list.py (flat and tree views) - Apply contract_user_home() to path field in status.py (status dict) - Apply contract_user_home() to path field in sync.py (PlanEntry and events) - All JSON/NDJSON output now consistently uses ~/... notation - Human output already used tilde notation (unchanged) Before: {"path": "/home/username/code/flask", "workspace_root": "~/code/"} After: {"path": "~/code/flask", "workspace_root": "~/code/"} Benefits: - Consistency: Both path and workspace_root now use tilde - Privacy: No username exposure in JSON dumps - Portability: Configs/output work across different machines - Matches shell conventions and user expectations refs: Breaking change - automation may need to expand ~ to absolute paths
1 parent 639c049 commit 4de9970

File tree

3 files changed

+7
-7
lines changed

3 files changed

+7
-7
lines changed

src/vcspull/cli/list.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,12 @@ def _output_flat(
161161
repo_url = repo.get("url", repo.get("pip_url", "unknown"))
162162
repo_path = repo.get("path", "unknown")
163163

164-
# JSON/NDJSON output
164+
# JSON/NDJSON output (contract home for privacy/portability)
165165
formatter.emit(
166166
{
167167
"name": repo_name,
168168
"url": str(repo_url),
169-
"path": str(repo_path),
169+
"path": contract_user_home(repo_path),
170170
"workspace_root": str(repo.get("workspace_root", "")),
171171
}
172172
)
@@ -212,12 +212,12 @@ def _output_tree(
212212
repo_url = repo.get("url", repo.get("pip_url", "unknown"))
213213
repo_path = repo.get("path", "unknown")
214214

215-
# JSON/NDJSON output
215+
# JSON/NDJSON output (contract home for privacy/portability)
216216
formatter.emit(
217217
{
218218
"name": repo_name,
219219
"url": str(repo_url),
220-
"path": str(repo_path),
220+
"path": contract_user_home(repo_path),
221221
"workspace_root": workspace,
222222
}
223223
)

src/vcspull/cli/status.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ def check_repo_status(repo: ConfigDict, detailed: bool = False) -> dict[str, t.A
263263

264264
status: dict[str, t.Any] = {
265265
"name": repo_name,
266-
"path": str(repo_path),
266+
"path": contract_user_home(repo_path),
267267
"workspace_root": workspace_root,
268268
"exists": False,
269269
"is_git": False,

src/vcspull/cli/sync.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def _build_plan_entry(
264264

265265
return PlanEntry(
266266
name=str(repo.get("name", "unknown")),
267-
path=str(repo_path),
267+
path=contract_user_home(repo_path),
268268
workspace_root=workspace_root,
269269
action=action,
270270
detail=detail,
@@ -724,7 +724,7 @@ def silent_progress(output: str, timestamp: datetime) -> None:
724724
event: dict[str, t.Any] = {
725725
"reason": "sync",
726726
"name": repo_name,
727-
"path": str(repo_path),
727+
"path": contract_user_home(repo_path),
728728
"workspace_root": str(workspace_label),
729729
}
730730

0 commit comments

Comments
 (0)