File tree Expand file tree Collapse file tree
tests/specify_cli/bundles Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -196,22 +196,26 @@ def add_source(
196196 },
197197 Scope .PROJECT ,
198198 )
199+ id_collision = False
199200 for existing in catalogs :
200201 existing_source = CatalogSource .from_dict (existing , Scope .PROJECT )
201- if (
202- existing_source .id == requested_source .id
203- or existing_source .url == requested_source .url
204- ):
202+ if existing_source .url == requested_source .url :
205203 if (
206- existing_source .url == requested_source .url
207- and (not requested_id or existing_source .id == requested_source .id )
204+ (not requested_id or existing_source .id == requested_source .id )
208205 and existing_source .priority == requested_source .priority
209206 and existing_source .install_policy is requested_source .install_policy
210207 ):
211208 return existing_source , "unchanged"
212209 raise BundlerError (
213210 f"Catalog source '{ resolved_id } ' (or url) already exists in this project."
214211 )
212+ if existing_source .id == requested_source .id :
213+ id_collision = True
214+
215+ if id_collision :
216+ raise BundlerError (
217+ f"Catalog source '{ resolved_id } ' (or url) already exists in this project."
218+ )
215219
216220 entry = requested_source .to_dict ()
217221 catalogs .append (entry )
Original file line number Diff line number Diff line change @@ -153,6 +153,40 @@ def test_add_source_uses_existing_id_when_id_is_omitted(tmp_path: Path):
153153 assert second == first
154154
155155
156+ def test_add_source_prefers_url_match_over_derived_id_collision (tmp_path : Path ):
157+ project = tmp_path / "proj"
158+ (project / ".specify" ).mkdir (parents = True )
159+ cc ._write (
160+ project ,
161+ [
162+ {
163+ "id" : "example-com-target" ,
164+ "url" : "https://other.example/catalog.json" ,
165+ "priority" : 50 ,
166+ "install_policy" : "install-allowed" ,
167+ },
168+ {
169+ "id" : "custom" ,
170+ "url" : "https://example.com/target.json" ,
171+ "priority" : 50 ,
172+ "install_policy" : "install-allowed" ,
173+ },
174+ ],
175+ )
176+ original = cc ._config_path (project ).read_bytes ()
177+
178+ source , status = cc .add_source (
179+ project ,
180+ "https://example.com/target.json" ,
181+ policy = "install-allowed" ,
182+ priority = 50 ,
183+ )
184+
185+ assert status == "unchanged"
186+ assert source .id == "custom"
187+ assert cc ._config_path (project ).read_bytes () == original
188+
189+
156190def test_remove_source_accepts_relative_local_path (tmp_path : Path , monkeypatch ):
157191 """add_source stores a local path as an absolute url, so remove_source must
158192 accept the same relative path the caller added; otherwise `remove ./cat.json`
You can’t perform that action at this time.
0 commit comments