@@ -181,12 +181,107 @@ def test_parse_agent_spec_ignores_local_prefix() -> None:
181181 assert spec is None
182182
183183
184- def test_readme_conflict_handling_logic (tmp_path : pathlib .Path ) -> None :
185- """Test the basic README conflict detection logic (simplified version).
184+ def test_readme_and_pyproject_conflict_handling_in_folder_mode (
185+ tmp_path : pathlib .Path ,
186+ ) -> None :
187+ """Test conflict handling for in-folder updates - both README and pyproject.toml should be preserved."""
188+ import shutil
189+
190+ # Set up directories
191+ final_destination = tmp_path / "destination"
192+ final_destination .mkdir (parents = True )
193+ generated_project_dir = tmp_path / "generated"
194+ generated_project_dir .mkdir (parents = True )
195+
196+ # Create existing README in destination
197+ existing_readme_content = (
198+ "# Existing Project\n \n This is my existing README content."
199+ )
200+ (final_destination / "README.md" ).write_text (existing_readme_content )
201+
202+ # Create existing pyproject.toml in destination
203+ existing_pyproject_content = """[build-system]
204+ requires = ["setuptools>=45", "wheel"]
205+ build-backend = "setuptools.build_meta"
206+
207+ [project]
208+ name = "existing-project"
209+ version = "0.1.0"
210+ """
211+ (final_destination / "pyproject.toml" ).write_text (existing_pyproject_content )
212+
213+ # Create templated README in generated project
214+ templated_readme_content = "# Test Project\n \n This is the templated README content."
215+ (generated_project_dir / "README.md" ).write_text (templated_readme_content )
216+
217+ # Create templated pyproject.toml in generated project
218+ templated_pyproject_content = """[build-system]
219+ requires = ["poetry-core"]
220+ build-backend = "poetry.core.masonry.api"
221+
222+ [tool.poetry]
223+ name = "templated-project"
224+ version = "0.1.0"
225+ """
226+ (generated_project_dir / "pyproject.toml" ).write_text (templated_pyproject_content )
227+
228+ # Also create a non-conflicting file
229+ (generated_project_dir / "other_file.py" ).write_text ("# Other file content" )
230+
231+ # Simulate the in-folder copying logic from process_template (in_folder=True)
232+ in_folder = True
233+ for item in generated_project_dir .iterdir ():
234+ dest_item = final_destination / item .name
235+
236+ # Use the same logic as the updated process_template function
237+ should_preserve_file = item .name .lower ().startswith ("readme" ) or (
238+ item .name == "pyproject.toml" and in_folder
239+ )
240+ if should_preserve_file and (final_destination / item .name ).exists ():
241+ # The existing file stays, save the templated one with a different name
242+ base_name = item .stem
243+ extension = item .suffix
244+ dest_item = final_destination / f"starter_pack_{ base_name } { extension } "
245+
246+ if item .is_dir ():
247+ if dest_item .exists ():
248+ shutil .rmtree (dest_item )
249+ shutil .copytree (item , dest_item , dirs_exist_ok = True )
250+ else :
251+ shutil .copy2 (item , dest_item )
252+
253+ # Verify results
254+ original_readme = final_destination / "README.md"
255+ templated_readme = final_destination / "starter_pack_README.md"
256+ original_pyproject = final_destination / "pyproject.toml"
257+ templated_pyproject = final_destination / "starter_pack_pyproject.toml"
258+ other_file = final_destination / "other_file.py"
259+
260+ # Original README should be preserved with original content
261+ assert original_readme .exists ()
262+ assert original_readme .read_text () == existing_readme_content
263+
264+ # Templated README should be saved with new name
265+ assert templated_readme .exists ()
266+ assert templated_readme .read_text () == templated_readme_content
267+
268+ # Original pyproject.toml should be preserved with original content (in-folder mode)
269+ assert original_pyproject .exists ()
270+ assert original_pyproject .read_text () == existing_pyproject_content
271+
272+ # Templated pyproject.toml should be saved with new name (in-folder mode)
273+ assert templated_pyproject .exists ()
274+ assert templated_pyproject .read_text () == templated_pyproject_content
186275
187- Note: This tests the conflict detection pattern, but the actual process_template
188- function now uses base template README instead of templated README when conflicts occur.
189- """
276+ # Other files should copy normally
277+ assert other_file .exists ()
278+ assert other_file .read_text () == "# Other file content"
279+
280+
281+ def test_readme_and_pyproject_conflict_handling_remote_template_mode (
282+ tmp_path : pathlib .Path ,
283+ ) -> None :
284+ """Test conflict handling for remote templates - README preserved, pyproject.toml should be overwritten."""
190285 import shutil
191286
192287 # Set up directories
@@ -201,23 +296,46 @@ def test_readme_conflict_handling_logic(tmp_path: pathlib.Path) -> None:
201296 )
202297 (final_destination / "README.md" ).write_text (existing_readme_content )
203298
299+ # Create existing pyproject.toml in destination
300+ existing_pyproject_content = """[build-system]
301+ requires = ["setuptools>=45", "wheel"]
302+ build-backend = "setuptools.build_meta"
303+
304+ [project]
305+ name = "existing-project"
306+ version = "0.1.0"
307+ """
308+ (final_destination / "pyproject.toml" ).write_text (existing_pyproject_content )
309+
204310 # Create templated README in generated project
205311 templated_readme_content = "# Test Project\n \n This is the templated README content."
206312 (generated_project_dir / "README.md" ).write_text (templated_readme_content )
207313
314+ # Create templated pyproject.toml in generated project
315+ templated_pyproject_content = """[build-system]
316+ requires = ["poetry-core"]
317+ build-backend = "poetry.core.masonry.api"
318+
319+ [tool.poetry]
320+ name = "templated-project"
321+ version = "0.1.0"
322+ """
323+ (generated_project_dir / "pyproject.toml" ).write_text (templated_pyproject_content )
324+
208325 # Also create a non-conflicting file
209326 (generated_project_dir / "other_file.py" ).write_text ("# Other file content" )
210327
211- # Simulate the in-folder copying logic from process_template
328+ # Simulate the remote template copying logic from process_template (in_folder=False)
329+ in_folder = False
212330 for item in generated_project_dir .iterdir ():
213331 dest_item = final_destination / item .name
214332
215- # Special handling for README files - rename templated README if conflict exists
216- if (
217- item .name . lower (). startswith ( "readme" )
218- and ( final_destination / item . name ). exists ( )
219- ):
220- # The existing README stays, save the templated one with a different name
333+ # Use the same logic as the updated process_template function
334+ should_preserve_file = item . name . lower (). startswith ( "readme" ) or (
335+ item .name == "pyproject.toml" and in_folder
336+ )
337+ if should_preserve_file and ( final_destination / item . name ). exists ( ):
338+ # The existing file stays, save the templated one with a different name
221339 base_name = item .stem
222340 extension = item .suffix
223341 dest_item = final_destination / f"starter_pack_{ base_name } { extension } "
@@ -232,6 +350,8 @@ def test_readme_conflict_handling_logic(tmp_path: pathlib.Path) -> None:
232350 # Verify results
233351 original_readme = final_destination / "README.md"
234352 templated_readme = final_destination / "starter_pack_README.md"
353+ pyproject_file = final_destination / "pyproject.toml"
354+ templated_pyproject_backup = final_destination / "starter_pack_pyproject.toml"
235355 other_file = final_destination / "other_file.py"
236356
237357 # Original README should be preserved with original content
@@ -242,6 +362,13 @@ def test_readme_conflict_handling_logic(tmp_path: pathlib.Path) -> None:
242362 assert templated_readme .exists ()
243363 assert templated_readme .read_text () == templated_readme_content
244364
365+ # pyproject.toml should be overwritten with templated content (remote template mode)
366+ assert pyproject_file .exists ()
367+ assert pyproject_file .read_text () == templated_pyproject_content
368+
369+ # No backup pyproject.toml should exist (remote template mode)
370+ assert not templated_pyproject_backup .exists ()
371+
245372 # Other files should copy normally
246373 assert other_file .exists ()
247374 assert other_file .read_text () == "# Other file content"
0 commit comments