@@ -415,6 +415,36 @@ def fake_clone(url, dest, **kwargs):
415415 assert registry .get ("adminer" ).path == f"repos/{ DIRNAME } /adminer"
416416
417417
418+ def test_registry_yml_parsed_once_for_multiple_plugins_same_repo (
419+ self , registry , devbase_root
420+ ):
421+ # Two legacy plugins from the same repo with a healthy local_path clone:
422+ # _ensure_repo_cloned takes the fast path (returns reg_info=None) for
423+ # both, so migrate()'s per-URL reg_info cache must collapse the lazy
424+ # registry.yml parse to one per repo instead of one per plugin.
425+ plugins = [
426+ {"name" : "p1" , "path" : "p1" , "projects" : ["p1" ]},
427+ {"name" : "p2" , "path" : "p2" , "projects" : ["p2" ]},
428+ ]
429+ _make_repo_clone (devbase_root , plugins )
430+ _register_repo (registry , plugins )
431+ for p in plugins :
432+ _make_legacy_copy (devbase_root , p ["name" ], p )
433+ registry .add (_installed (p ["name" ], f"plugins/{ p ['name' ]} " ))
434+
435+ import devbase .plugin .installer as installer_mod
436+ real_parse = installer_mod .parse_registry_yml
437+ with patch (
438+ "devbase.plugin.installer.parse_registry_yml" ,
439+ side_effect = real_parse ,
440+ ) as spy_parse :
441+ result = migrate (registry )
442+
443+ assert sorted (result .migrated ) == ["p1" , "p2" ]
444+ # Without the cache this would be 2 (one lazy parse per plugin).
445+ assert spy_parse .call_count == 1
446+
447+
418448class TestMigrateKeepsLinked :
419449 def test_linked_install_keeps_plugins_dir (self , registry , devbase_root ):
420450 plugins = [{"name" : "adminer" , "path" : "adminer" , "projects" : ["adminer" ]}]
0 commit comments