Skip to content

Commit ec008a9

Browse files
committed
fix(import[provenance]): Convert string entries to dict form for SKIP_UNCHANGED tagging
why: String-form config entries (e.g. "git+ssh://...") silently skip provenance tagging due to the isinstance(live, dict) guard, breaking future --prune for those entries. what: - Mirror the UPDATE_URL pattern: when live is a string, convert it to dict form {"repo": live, "metadata": {"imported_from": ...}} before stamping provenance - Add test_import_skip_unchanged_tags_provenance_string_entry verifying string entries get converted and tagged
1 parent fe36fbd commit ec008a9

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

src/vcspull/cli/import_cmd/_common.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,12 @@ def _run_import(
962962
if isinstance(live, dict):
963963
live.setdefault("metadata", {})["imported_from"] = import_source
964964
provenance_tagged_count += 1
965+
elif isinstance(live, str):
966+
raw_config[repo_workspace_label][repo.name] = {
967+
"repo": live,
968+
"metadata": {"imported_from": import_source},
969+
}
970+
provenance_tagged_count += 1
965971
elif action == ImportAction.SKIP_EXISTING:
966972
skip_existing_count += 1
967973
elif action == ImportAction.SKIP_PINNED:

tests/cli/test_import_repos.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3453,6 +3453,56 @@ def test_import_skip_unchanged_tags_provenance(
34533453
assert entry["metadata"]["imported_from"] == "github:testuser"
34543454

34553455

3456+
def test_import_skip_unchanged_tags_provenance_string_entry(
3457+
tmp_path: pathlib.Path,
3458+
monkeypatch: MonkeyPatch,
3459+
) -> None:
3460+
"""SKIP_UNCHANGED converts string entries to dict form for provenance."""
3461+
monkeypatch.setenv("HOME", str(tmp_path))
3462+
workspace = tmp_path / "repos"
3463+
workspace.mkdir()
3464+
config_file = tmp_path / ".vcspull.yaml"
3465+
3466+
# Existing entry as a plain string (not dict form)
3467+
save_config_yaml(
3468+
config_file,
3469+
{"~/repos/": {"repo1": _SSH}},
3470+
)
3471+
3472+
# Same URL → SKIP_UNCHANGED, should convert to dict and stamp provenance
3473+
importer = MockImporter(repos=[_make_repo("repo1")])
3474+
_run_import(
3475+
importer,
3476+
service_name="github",
3477+
target="testuser",
3478+
workspace=str(workspace),
3479+
mode="user",
3480+
language=None,
3481+
topics=None,
3482+
min_stars=0,
3483+
include_archived=False,
3484+
include_forks=False,
3485+
limit=100,
3486+
config_path_str=str(config_file),
3487+
dry_run=False,
3488+
yes=True,
3489+
output_json=False,
3490+
output_ndjson=False,
3491+
color="never",
3492+
sync=True,
3493+
import_source="github:testuser",
3494+
)
3495+
3496+
from vcspull._internal.config_reader import ConfigReader
3497+
3498+
final_config = ConfigReader._from_file(config_file)
3499+
assert final_config is not None
3500+
entry = final_config["~/repos/"]["repo1"]
3501+
assert isinstance(entry, dict), "String entry should be converted to dict form"
3502+
assert entry["repo"] == _SSH
3503+
assert entry["metadata"]["imported_from"] == "github:testuser"
3504+
3505+
34563506
# ---------------------------------------------------------------------------
34573507
# --prune standalone flag tests
34583508
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)