feat(mirror,create): make MIRRORS single source of truth and exclude PyPI from git config
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled

- Treat MIRRORS as the only authority for mirror URLs
- Filter non-git URLs (e.g. PyPI) from git remotes and push URLs
- Prefer SSH git URLs when determining primary origin
- Ensure mirror probing only targets valid git remotes
- Refactor repository create into service-based architecture
- Write PyPI metadata exclusively to MIRRORS, never to git config
- Add integration test verifying PyPI is not written into .git/config
- Update preview and unit tests to match new create flow

https://chatgpt.com/share/69415c61-1c5c-800f-86dd-0405edec25db
This commit is contained in:
Kevin Veen-Birkenbach
2025-12-16 14:19:19 +01:00
parent 374f4ed745
commit 8583fdf172
19 changed files with 792 additions and 418 deletions

View File

@@ -2,9 +2,9 @@ from __future__ import annotations
import unittest
from pkgmgr.actions.repository.create import (
RepoParts,
_parse_identifier,
from pkgmgr.actions.repository.create.model import RepoParts
from pkgmgr.actions.repository.create.parser import (
parse_identifier,
_parse_git_url,
_strip_git_suffix,
_split_host_port,
@@ -22,7 +22,7 @@ class TestRepositoryCreateParsing(unittest.TestCase):
self.assertEqual(_split_host_port("example.com:"), ("example.com", None))
def test_parse_identifier_plain(self) -> None:
parts = _parse_identifier("github.com/owner/repo")
parts = parse_identifier("github.com/owner/repo")
self.assertIsInstance(parts, RepoParts)
self.assertEqual(parts.host, "github.com")
self.assertEqual(parts.port, None)
@@ -30,7 +30,7 @@ class TestRepositoryCreateParsing(unittest.TestCase):
self.assertEqual(parts.name, "repo")
def test_parse_identifier_with_port(self) -> None:
parts = _parse_identifier("gitea.example.com:2222/org/repo")
parts = parse_identifier("gitea.example.com:2222/org/repo")
self.assertEqual(parts.host, "gitea.example.com")
self.assertEqual(parts.port, "2222")
self.assertEqual(parts.owner, "org")

View File

@@ -0,0 +1,43 @@
from __future__ import annotations
import unittest
from unittest.mock import patch
from pkgmgr.actions.repository.create.templates import TemplateRenderer
class TestTemplateRendererPreview(unittest.TestCase):
def test_render_preview_does_not_write(self) -> None:
# Ensure TemplateRenderer does not try to resolve real repo root.
with (
patch(
"pkgmgr.actions.repository.create.templates.TemplateRenderer._resolve_templates_dir",
return_value="/tpl",
),
patch(
"pkgmgr.actions.repository.create.templates.os.walk",
return_value=[("/tpl", [], ["README.md.j2"])],
),
patch(
"pkgmgr.actions.repository.create.templates.os.path.relpath",
return_value="README.md.j2",
),
patch("pkgmgr.actions.repository.create.templates.os.makedirs") as mk,
patch("pkgmgr.actions.repository.create.templates.open", create=True) as op,
patch("pkgmgr.actions.repository.create.templates.Environment") as env_cls,
):
renderer = TemplateRenderer()
renderer.render(
repo_dir="/repo",
context={"repository": "x"},
preview=True,
)
mk.assert_not_called()
op.assert_not_called()
env_cls.assert_not_called()
if __name__ == "__main__":
unittest.main()

View File

@@ -1,35 +0,0 @@
from __future__ import annotations
import unittest
from unittest.mock import patch
from pkgmgr.actions.repository.scaffold import render_default_templates
class TestScaffoldRenderPreview(unittest.TestCase):
def test_render_preview_does_not_write(self) -> None:
with (
patch("pkgmgr.actions.repository.scaffold._templates_dir", return_value="/tpl"),
patch("pkgmgr.actions.repository.scaffold.os.path.isdir", return_value=True),
patch("pkgmgr.actions.repository.scaffold.os.walk", return_value=[("/tpl", [], ["README.md.j2"])]),
patch("pkgmgr.actions.repository.scaffold.os.path.relpath", return_value="README.md.j2"),
patch("pkgmgr.actions.repository.scaffold.os.makedirs") as mk,
patch("pkgmgr.actions.repository.scaffold.open", create=True) as op,
patch("pkgmgr.actions.repository.scaffold.Environment") as env_cls,
):
env = env_cls.return_value
env.get_template.return_value.render.return_value = "X"
render_default_templates(
"/repo",
context={"repository": "x"},
preview=True,
)
mk.assert_not_called()
op.assert_not_called()
env.get_template.assert_not_called()
if __name__ == "__main__":
unittest.main()