feat(ais_core): implement repo_resolve library + minimal migration (#470, Issue #1b) - #487
Open
SaJaToGu wants to merge 1 commit into
Open
feat(ais_core): implement repo_resolve library + minimal migration (#470, Issue #1b)#487SaJaToGu wants to merge 1 commit into
SaJaToGu wants to merge 1 commit into
Conversation
SaJaToGu
force-pushed
the
ais-fix-470-repo-resolution
branch
from
June 28, 2026 16:06
b8edeb7 to
fc4731c
Compare
…ssue #1b) Strict parallel-implementation + comparison-tests approach (per #470 review): 1. ais_core/repo_resolve.py: full implementation of the three resolvers from the issue acceptance criteria, plus internal helpers _validate_component, _read_git_remote_url, _parse_git_remote_url, _canonical_remote, _parse_http_or_ssh. - resolve_from_owner_repo(owner, repo): pure normalize, no API call, validates GitHub naming rules (1-39 owner, 1-100 repo, alnum + - _ . + no leading/trailing separators). - resolve_from_git_remote(path): reads remote.origin.url via 'git -C path config --get' (local git binary, no network), parses via urllib.parse for HTTPS / ssh:// / git@ forms. - resolve_repo_hint(hint): dispatches to the appropriate resolver — directory hint -> git-remote, 'owner/repo' -> split+normalize, bare 'repo' -> GITHUB_USER env default. 2. tests/test_ais_core/test_repo_resolve.py: 34 tests covering - Unit tests for each public function - Direct URL-parser tests (https with/without .git, with trailing slash, ssh short form, ssh:// form, invalid) - Characterization test: _legacy_resolve() helper pins the pre-#470 behaviour (NOT exported, test-only, documents that the library CHANGES whitespace handling as an explicit semantic tightening) - Comparison tests: library and _legacy_resolve() agree on the (owner, repo) case for realistic owners - No-network test: monkey-patch subprocess/socket to ensure resolve_from_owner_repo makes no network calls 3. scripts/solve_issues.py: ONE small migration point after the preflight_checks block. Calls resolve_from_owner_repo(user, args.repo) to validate the integration. The result is currently unused; no broad refactor of args.repo / user handling per the strict-pattern directive. Old logic for owner-from-config stays untouched. Tests: 120 OK in 1.068s (full ais_core suite: repo_resolve, json_contract, run_state, secret_filter, issue_resolve). Refs #470
SaJaToGu
force-pushed
the
ais-fix-470-repo-resolution
branch
from
June 28, 2026 20:18
fc4731c to
8028c57
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #470 (Issue #1b — Wave 1b, Repo-Resolution)
Strict Parallel-Implementation + Comparison-Tests approach
Per the #470 review feedback, this PR follows the
expand-and-contract pattern: implement the new library
functionality in parallel to existing script logic, pin the
existing behaviour with characterization tests, write
comparison tests that show library and legacy agree on the
simple
(owner, repo)case, then migrate ONE smallintegration point with no broad refactor.
What's in this PR
ais_core/repo_resolve.py— new libraryResolvedRepo(NamedTuple):owner,repo,remote,local_pathresolve_from_owner_repo(owner, repo) -> ResolvedRepo(1-39 owner, 1-100 repo, alnum +
-_.+ noleading/trailing separators), strips whitespace, returns
ResolvedRepowith canonicalhttps://github.com/{owner}/{repo}andlocal_path=None.resolve_from_git_remote(path) -> ResolvedReporemote.origin.urlvia localgit -C path config --get(no network). Parses via
urllib.parsefor HTTPS, ssh://,and
git@host:owner/repoforms.ResolvedRepowithlocal_pathset.resolve_repo_hint(hint) -> ResolvedReporesolve_from_git_remote"owner/repo"→ split +resolve_from_owner_repo"repo"→resolve_from_owner_repowithGITHUB_USERenv-var defaultInternal helpers:
_validate_component,_read_git_remote_url,_parse_git_remote_url,_canonical_remote,_parse_http_or_ssh.tests/test_ais_core/test_repo_resolve.py— 34 tests.git, withtrailing slash, SSH short form,
ssh://form, invalid input)_legacy_resolve()helper pins thepre-0.10.0 Issue #1b — Repo-Resolution extrahieren (ein Script nutzt es) #470 behaviour. NOT exported as a production function;
test-only, and explicitly documents that the library CHANGES
whitespace handling (semantic tightening) versus the legacy.
_legacy_resolve()agreeon the
(owner, repo)case for realistic owners(SaJaToGu, python, microsoft).
mock.patchonsubprocess.runandurllib.request.urlopenconfirmsresolve_from_owner_repomakes no network calls.
scripts/solve_issues.py— ONE small integration pointAfter the preflight_checks block, this single call exercises the
library code path:
The result is deliberately unused. Per the strict-pattern
directive, the migration is a single integration point that
proves the library works against the script's actual values, with
no broad refactor of the existing
args.repo/userhandling.Old logic for "owner from config" stays untouched.
Out of scope (intentional)
resolve_from_owner_repodoesnot verify the repo exists on github.com.
args.repo/userthrough the library beyondthe one smoke-use call.
_legacy_resolve()— it ispinned in test_legacy_resolve_basic to keep the
comparison-test infrastructure intact.
Tests
python -m unittest tests.test_ais_core.test_repo_resolve \ tests.test_ais_core.test_json_contract \ tests.test_ais_core.test_run_state \ tests.test_ais_core.test_secret_filter \ tests.test_ais_core.test_issue_resolve→ 120 tests, 1.068s, all OK.
LOC
ais_core/repo_resolve.pytests/test_ais_core/test_repo_resolve.pyscripts/solve_issues.py(delta)Parent issue
Part of #468 (Release 0.10.0 — AIS Tooling Interface).