Skip to content

adopt-project.py: _github_name reads no owner over 39 characters or repository over 100, so plan --source <50 b's>/Thing never asks gh for a name GitHub cannot hold, no remedy offers --org <50 b's>, and check and execute never clone such a record again (#1129) - #1194

Draft
brettheap wants to merge 1 commit into
fix/1003-adopt-unenterable-sourcefrom
fix/1129-github-name-limits

Conversation

@brettheap

@brettheap brettheap commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Lane 4's W1129 for #1129, RV1122's NIT-1 on #1122 (#1122 issuecomment-6319493639). This is a draft, and a reviewer follows.

Stacked on #1122. This PR's base is fix/1003-adopt-unenterable-source (#1122, head c01c4d73), not main. It lands only after the v1.2.0 tag, and only after #1122. Why it is stacked: see "Why stacked" below.

What

adopt-project.py, _github_name: an owner of more than GITHUB_OWNER_MAX (39) characters, or a repository of more than GITHUB_NAME_MAX (100), counted once the trailing .git is dropped, names no owner/repo. The file already imports both limits from shape_materialize.

    if len(owner) > GITHUB_OWNER_MAX or len(repo) > GITHUB_NAME_MAX:
        return None

Every reader of _github_name now gives the same answer for such a spelling:

Reader Used by Before Now
_source_spec plan, check and execute --source taken as GitHub's name: gh repo clone asked, or source-ambiguous beside a directory of that spelling a path: read in place where it is one, source-unresolvable ("neither a path that exists nor an org/repo name") where it is not
_repository_in_url a url --source, github.com/... too gh repo clone asked source-unresolvable, "names no owner/repo on github.com", before any stat
_recorded_repository check and execute, a plan's clone gone (cloned: true) "is cloned again from GitHub", gh repo clone asked source-unresolvable, "the plan's source.repository, ..., names no owner/repo on github.com"
_held_repository check and execute, a source with no origin held to the record: plan-not-the-source, remedy --org <40 c's> holds the plan to nothing, as a record that names no owner/repo does
_source_there beside a directory this user cannot search #1122: no url unchanged: no url (the name is None now)

_refuse_another_repository's remedy (adopt-not-the-source) is reached only after _source_spec, so it never offers --org <a name GitHub cannot hold> for an org/repo --source now.

#1122's guard in _source_there is redundant, and is folded in. _source_there is called only by _source_spec and _repository_in_url, and both take name from _github_name. So a name past the limits now arrives as None, and the name is None branch gives the same refusal #1122's guard gave. The guard is gone, if name is None: is back, and the docstring says the limits are asked in _github_name. The merge with main and with #1122 is clean (see "Merges").

Why stacked. The textual merge with #1122 is clean, but the two do not hold together as they stand. A github.com/ spelling past the limits is now refused by _repository_in_url before any stat, so four of #1122's rows, which expected source-unreadable from _source_there, fail on the combination:

  • [bare-github-url];
  • [www-github-url];
  • [bare-github-url-owner-one-over-EIO];
  • [bare-github-url-owner-one-over-EACCES].

This PR moves those three params out of #1122's _source_there tests, with a comment pointing to the new file. There they assert the new answer (source-unresolvable, no url), with the control at the limit kept: two readings and the url.

No refusal code is new or changed, and no help text or docs/cli.md sentence changes: --source's help already says source-unresolvable refuses "one that is neither a path that exists nor an org/repo".

Behaviour that changes besides the refusal

Before and after

Probed with a gh first on PATH that logs each call and refuses it (exit 4), and with:

  • GH_TOKEN=bogus, an empty GH_CONFIG_DIR;
  • GIT_SSH_COMMAND=false, GIT_CONFIG_GLOBAL an empty file, GIT_CONFIG_NOSYSTEM=1;
  • uid 1000, Python 3.12.3, run in an empty directory.

Each row is plan --source <it> --project <repo> --org <owner>, except where --org is said. main 961640c6 gave the same answers as #1122's head on every row.

--source #1122 head c01c4d73 this head
<50 b's>/Thing, --org <50 b's> (the issue's) gh repo clone <50 b's>/Thing (1 call), source-unclonable source-unresolvable, 0 calls
<50 b's>/Thing, --org testorg (the issue's) adopt-not-the-source, remedy --project Thing --org <50 b's>, 0 calls source-unresolvable, no --org offered, 0 calls
<40 c's>/Thing 1 call source-unresolvable, 0 calls
testorg/<101 r's>, and with .git 1 call each source-unresolvable, 0 calls
<40 c's>/<101 r's> 1 call source-unresolvable, 0 calls
https://github.com/<40 c's>/Thing, github.com/<40 c's>/Thing 1 call each source-unresolvable ("names no owner/repo on github.com"), 0 calls
<39 c's>/Thing, testorg/<100 r's>, testorg/<100 r's>.git (controls) 1 call each (.git dropped) the same
<39 c's>/Thing, --org testorg (control) adopt-not-the-source, remedy --org <39 c's> the same

Tests

The landing gate's environment throughout:

  • /usr/bin/python3 -m pytest -p no:cacheprovider, Python 3.12.3;
  • a stub gh first on PATH, GH_TOKEN=bogus, an empty GH_CONFIG_DIR;
  • GIT_CONFIG_GLOBAL set to an empty file, GIT_CONFIG_NOSYSTEM=1;
  • the test author and committer variables, and EMAIL;
  • GIT_SSH_COMMAND, GIT_ALLOW_PROTOCOL and the LANES_* variables unset.

New file tests/test_adopt_source_github_limits.py, 48 rows, ASCII only. It skips on Windows: the logging gh is a /bin/sh script, and the moved rows need a POSIX File name too long. Each child puts the logging gh ahead of the suite's guard, and every execute gets --local-remote-dir.

Test Rows What it asserts #1122 head main this head
test_plan_asks_gh_for_a_name_github_can_hold (control) 6 owner 39, repository 100, 100 + .git, both at, a url and a bare url: gh logged exactly repo clone <name> <work>/source-readonly/<repo> -- --quiet, once 6 pass 6 pass 6 pass
test_plan_never_asks_gh_for_a_name_github_cannot_hold 9 owner 40 and 50, repository 101 and 101 + .git, both over, and four url spellings: the gh log empty, exit 2, the source-unresolvable line, no plan, no work directory 9 fail at the gh log (cloning ...) 9 fail, the same 9 pass
test_a_github_url_past_the_limits_is_refused_before_any_stat (moved from #1122) 4 [www.]github.com/<300 a's>/Thing with a real File name too long; github.com/<40 a's>/Thing with stat refused (EIO, EACCES): source-unresolvable, no url; control at 39, both readings and the url 4 fail at the code (source-unreadable, "cannot be told") 4 fail, the same 4 pass
test_no_remedy_offers_an_org_github_cannot_hold 3 --org testorg with owner 40, 50, both over: no --org <owner>, no adopt-not-the-source; control at 39 offers --org <39 c's> 3 fail at --org <owner> offered 3 fail, the same 3 pass
test_a_directory_github_cannot_name_is_read_in_place 2 ./<40 c's>/Thing, ./testorg/<101 r's> repositories here: exit 0, recorded in place, no repository, 0 gh calls; control at the limit is source-ambiguous 2 fail at the exit (source-ambiguous) 2 fail, the same 2 pass
test_a_recorded_name_github_can_hold_is_cloned_again (control) 4 check, execute: the NOTE and 1 gh call 4 pass 4 pass 4 pass
test_a_recorded_name_github_cannot_hold_is_never_cloned_again 6 check, execute; owner 40, repository 101, both: the gh log empty, the source-unresolvable line, no "cloned again" 6 fail at the gh log (the NOTE, "cloned again") 6 fail, the same 6 pass
test_check_and_execute_read_a_source_name_as_plan_reads_it 10 check, execute with --source: 4 controls at the limits (1 gh call), 6 past them (0 calls, source-unresolvable) 6 fail at the gh log; 4 pass the same 10 pass
test_a_record_github_cannot_hold_offers_no_org 4 check, execute (no --yes); a source with no origin, record owner 40 and 50: no --org <owner>, no plan-not-the-source; plan ok / adopt-unconfirmed; control at 39 keeps plan-not-the-source and --org <39 c's> 4 fail at --org <owner> offered 4 fail, the same 4 pass

Totals for the 48 rows:

Every row that is not a control fails on both bases, at the assertion that names the defect, not at a setup step. The 14 controls pass on all three.

#1122's file tests/test_adopt_unsearchable_source.py: 40 rows at this head, from 44. Three params moved out: the two url rows, and the url row's EIO and EACCES variants. Before the move, those four rows failed at this head (source-unresolvable against source-unreadable), and the other 40 passed.

Mutants

Each was applied to this head's adopt-project.py (sha256 d494ba0e...) by exact substitution of the new guard line, and run against this file, test_adopt_unsearchable_source.py and test_adopt_unenterable_source_and_locale.py (101 tests). After each one the file was restored from its saved bytes and its sha256 checked. Unmutated, all 101 pass. All 8 were killed.

Mutant Killed by
M1: owner limit one lower (> GITHUB_OWNER_MAX - 1) 24: the owner-39 controls (plan, --source, the recorded clone, the remedy, the directory, the held record, the moved rows' controls), and #1122's 5 owner controls at 39
M2: owner limit one higher (+ 1) 15: every owner-40 row (plan, url, --source, the recorded clone, the remedy, the directory, the held record, the 2 moved EIO/EACCES rows), and #1122's 2 owner-one-over rows
M3: repository limit one lower (- 1) 15: the repository-100 controls, and #1122's 5 repository controls at 100
M4: repository limit one higher (+ 1) 11: every repository-101 row, and #1122's 2 repository-one-over rows
M5: owner limit removed 25
M6: repository limit removed 15
M7: both limits removed (no guard anywhere, since #1122's is folded in) 46: every refused row here, and 12 of #1122's
M8: the repository counted with its .git (len(segments[1])) 1: test_plan_asks_gh_for_a_name_github_can_hold[repository-100-dot-git]

Gate

Run on the scratch merge w1129-gate at ca06ad25a: a merge of main 961640c6 and this head 900f77af. Its tree, 90fbea0e, is the one git merge-tree --write-tree origin/main HEAD gives, and main has not moved since. The environment is the one under "Tests"; targeted files only, never the full suite. Every run ended with rc=0.

Test files, 23:

File Passed Skipped
test_adopt_source_github_limits (new) 48 0
test_adopt_unsearchable_source 40 0
test_adopt_unenterable_source_and_locale 13 0
test_adopt_check_plan_name 45 0
test_adopt_source_clone_record 100 0
test_adopt_template_values 78 0
test_adopt_work_dir_refusal 53 0
test_windows_paths 46 0
test_adopt_clone_claimed 42 0
test_adopt_late_failure 88 0
test_adopt_plan_flag_refusals_first 89 0
test_adopt_temp_work_roots 9 0
test_adopt_origin_repository 30 0
test_adopt_plan 66 1
test_adopt_project_is_the_source 23 0
test_adopt_relative_submodule_url 34 0
test_adopt_split_branch 47 0
test_adopt_values_as_typed 40 0
test_adopt_plan_escapes 59 0
test_path_guard_hygiene 49 0
test_repo_hygiene 101 0
test_scaffold_leg_path_collisions 104 0
test_github_name_limits 64 0
Total 1268 1

tests/test_shape_doctor.py, all 448 collected ids, in 8 shards of 56 (the shard lists together hold every collected id exactly once; every adopt-project.py change is gated with it):

Shard Ids Passed Skipped
d01 56 56 0
d02 56 56 0
d03 56 55 1
d04 56 55 1
d05 56 55 1
d06 56 56 0
d07 56 56 0
d08 56 56 0
Total 448 445 3

Totals: 1713 passed, 4 skipped, 0 failed, 0 errors. The skips are the host's: three test_shape_doctor.py rows that print the PowerShell line and need powershell.exe on a Windows host, and one test_adopt_plan.py row that needs SHAPE_MEDXEHR_CLONE, a read-only clone of MedxSoft/MedxEHR.

The gate paused after d02 for disk space and ran d03 to d08 later, on the same scratch merge, whose head did not change.

Merges

git merge-tree --write-tree, this head 900f77af against each of these; all are clean (rc=0, no conflict):

Against Head Tree
main 961640c6 90fbea0e
#1122, the base c01c4d73 e2cea9b3 (this head's own tree)
#1186 07486a49 78702414
#1180 6cd96b8b eff9e4db
#1178 c4beba19 b79abc31
#1177 5208e874 91156ae6
#1171 8162b874 87e2ce31
#1170 24ee133a f001382d
#1169 25805102 b58ed451
#1154 8a782833 2e67c977
#1153 ff33ba12 070c39b2
#1143 7af5fabc 7237b405
#1141 7a2711d0 c0bcaf88
#1125 9549006f c16ff99a
#1123 5c3908f8 aba16ad4
#1121 1c517375 6e1f5cb9
#1120 c55e55e3 845f0ab5
#1119 bba168bd ab6af7c8
#1118 2307036a 1d53a9d9
#1106 504a1dd6 60cd4c67
#1105 b28f40de b5f065ec
#1189 8684af86 352b9e86
#1190 00f959c6 6335ed44

These are the open PRs that touch adopt-project.py, and #1122 also touches tests/test_adopt_unsearchable_source.py. #1189 and #1190 opened, and #1169 and #1171 moved, after the first run of these; the four were merged again at the heads shown, just before the push, and the other heads were read again and had not moved. The merge with #1122 is clean as text, and see "Why stacked" for what it does not settle.

Out of scope

Closes #1129

🤖 Generated with Claude Code
Lane: openreposhape-4 (openRepoShape-4)

Summary by Sourcery

Reject GitHub owner and repository names that exceed supported lengths before resolution or cloning, while preserving valid boundary names and local-path adoption.

Bug Fixes:

  • Prevent GitHub API and clone operations for source names exceeding GitHub’s owner or repository length limits.
  • Make all source, URL, recorded-plan, and remediation checks consistently treat overlong GitHub names as unresolvable.
  • Allow local directories whose spellings exceed GitHub’s limits to be adopted as local sources without offering invalid GitHub remedies.

Enhancements:

  • Centralize GitHub name-length validation in _github_name and align source resolution behavior across plan, check, and execute.

Tests:

  • Add comprehensive coverage for boundary and over-limit names, URL handling, local directories, recorded plans, and prevention of invalid gh calls.
  • Update unsearchable-source tests to cover over-limit GitHub URLs in the dedicated limit test suite.

… repository over 100, so `plan --source <50 b's>/Thing` never asks `gh` for a name GitHub cannot hold, no remedy offers `--org <50 b's>`, and `check` and `execute` never clone such a record again (#1129)

GitHub gives an owner at most GITHUB_OWNER_MAX (39) characters and a
repository at most GITHUB_NAME_MAX (100). `_github_name` now gives no name
past either, counted once the `.git` is dropped, so every reader of it
answers alike: `_source_spec` reads such a spelling as a path (in place
where it is one, `source-unresolvable` where it is not), `_repository_in_url`
refuses a url of it, and `_recorded_repository` and `_held_repository` read a
plan's record of it as naming no repository.

Stacked on #1122 (fix/1003-adopt-unenterable-source): its guard on the two
limits in `_source_there` is folded into this one question, and its three
`github.com/` rows move to the new file, since such a url is now refused
before any `stat`.

New rows: tests/test_adopt_source_github_limits.py (48).

Lane: openreposhape-4 (openRepoShape-4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR centralizes GitHub name-length validation in _github_name, ensuring over-limit owner/repository spellings are never sent to gh or surfaced as invalid remediation targets, while local paths and valid boundary names retain their existing behavior; extensive cross-reader and regression tests cover the new semantics.

Sequence diagram for rejecting over-limit GitHub sources

sequenceDiagram
    actor User
    participant AdoptProject
    participant GitHubCLI
    User->>AdoptProject: plan --source owner/repo
    AdoptProject->>AdoptProject: _github_name(source)
    alt owner or repo exceeds GitHub limit
        AdoptProject-->>User: source-unresolvable
        Note over AdoptProject,GitHubCLI: No clone request is made
    else name is within limits
        AdoptProject->>GitHubCLI: repo clone owner/repo
        GitHubCLI-->>AdoptProject: clone result
    end
Loading

Sequence diagram for recorded source handling during check and execute

sequenceDiagram
    actor User
    participant AdoptProject
    participant GitHubCLI
    User->>AdoptProject: check or execute plan
    AdoptProject->>AdoptProject: _recorded_repository(source.repository)
    alt recorded owner or repo exceeds limit
        AdoptProject-->>User: source-unresolvable
        Note over AdoptProject,GitHubCLI: No reclone is attempted
    else recorded name is valid
        AdoptProject->>GitHubCLI: repo clone recorded repository
        GitHubCLI-->>AdoptProject: clone result
    end
Loading

Flow diagram for GitHub source name validation

flowchart TD
    A["--source spelling"] --> B[_github_name]
    B -->|"valid owner/repo within limits"| C["GitHub repository name"]
    B -->|"over-limit or invalid spelling"| D["None"]
    C --> E[_source_spec]
    C --> F[_repository_in_url]
    C --> G[_recorded_repository]
    C --> H[_held_repository]
    D --> I["Treat as local path or refuse as source-unresolvable"]
    E --> J["Existing path read in place"]
    F --> K["URL refused before stat"]
    G --> L["Recorded repository is not cloned again"]
    H --> M["No invalid --org remedy"]
Loading

File-Level Changes

Change Details Files
Reject GitHub owner and repository names that exceed GitHub's length limits at the shared name parser.
  • Return no GitHub name for owners over 39 characters or repositories over 100 characters after removing .git.
  • Make source, URL, recorded-plan, and held-source readers consistently treat over-limit spellings as non-repositories.
  • Remove the now-redundant length checks from _source_there while preserving filesystem error handling for valid GitHub names.
adopt-project.py
Add comprehensive coverage for over-limit names and preserve boundary behavior.
  • Test plan, check, and execute behavior for over-limit owners, repositories, URLs, local directories, and recorded plans.
  • Verify no gh invocation or invalid --org remediation occurs for names GitHub cannot hold.
  • Retain controls for the 39-character owner and 100-character repository limits, including .git handling.
  • Move URL-specific cases from unsearchable-source tests to the new limit-focused test module.
tests/test_adopt_source_github_limits.py
tests/test_adopt_unsearchable_source.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sonarqubecloud

Copy link
Copy Markdown

@brettheap

Copy link
Copy Markdown
Contributor Author

RV1194: independent review of #1194 at 900f77af: READY

No MUST and no SHOULD. There are three NITs, each for a follow-up. NIT-1 and NIT-2 share one cause outside _github_name: the reader of a source's origin has no limits. RV1194 began this review and stopped at an account swap. RV1194-cont finished it from RV1194's scripts and measurements, without redoing them.

Heads, read at 12:01Z and again at 12:48Z: this PR 900f77af; its base, #1122, c01c4d73; main 961640c6.

What I measured

The limits are GitHub's. A user or an organisation gets at most 39 characters, and a repository at most 100 (github-limits, checked against GitHub's own validation messages).

  • GitHub's documentation on usernames for external authentication gives 39 for an Enterprise Managed username too, short code included. So the _ let by for those users stays within the limit.
  • GITHUB_SEGMENT_RE is [A-Za-z0-9_.-]+, ASCII only, so len() counts what GitHub counts.
  • The check runs once the .git is dropped.

Every reader. _github_name has four callers: _source_spec, _repository_in_url, _recorded_repository and _held_repository, which calls it twice.

  • Every gh repo clone goes through Source.clone, which only _source_spec and _recorded_repository feed.
  • The other gh calls (repo view, repo create, pr create, repo edit) use the plan's org: and names. When there is no --local-remote-dir, _what_cannot_be_held checks those first, the 39-character org: limit included.
  • _held_repository's second reading, of the last two directories of a path origin, cannot change an answer. It is compared, by an ASCII casefold(), with a record already within the limits, so a name past them can never be equal to it (M16 below).

Rows. The new file tests/test_adopt_source_github_limits.py:

Tree Result
this head 900f77af 48 passed
#1122's head c01c4d73 34 failed, 14 passed
main 961640c6 34 failed, 14 passed

Probe. I ran 56 commands (plan, check and execute) on each of the three trees.

On this head:

Mutants

Each mutant was applied to this head's adopt-project.py (sha256 d494ba0e...) by exact substitution. Each ran against the new file, test_adopt_unsearchable_source.py and test_adopt_unenterable_source_and_locale.py, 101 tests in all. After each, the file was restored from its saved bytes and its sha256 checked, and the tree ended clean.

  • M1 to M8 are W1129's, run again. Each failed exactly the set of tests it failed in W1129's run.
  • M9 to M16 are mine. M12 to M16 give _github_name a limits=True parameter and pass limits=False from one caller only. They show that each reader is pinned by its own rows.
Mutant Result
M0: unmutated 101 passed
M1: owner limit one lower killed, 24
M2: owner limit one higher killed, 15
M3: repository limit one lower killed, 15
M4: repository limit one higher killed, 11
M5: owner limit removed killed, 25
M6: repository limit removed killed, 15
M7: both limits removed killed, 46
M8: the repository counted with its .git killed, 1: [repository-100-dot-git]
M9: len(owner) >= GITHUB_OWNER_MAX killed, 24
M10: len(repo) >= GITHUB_NAME_MAX killed, 15
M11: the check moved before the .git is dropped killed, 1: [repository-100-dot-git]
M12: _held_repository reads the record without the limits killed, 4: test_a_record_github_cannot_hold_offers_no_org, owner 40 and 50, check and execute
M13: _recorded_repository without the limits killed, 6: test_a_recorded_name_github_cannot_hold_is_never_cloned_again
M14: _repository_in_url without the limits killed, 8: the 4 moved rows, and the 4 url rows of test_plan_never_asks_gh_for_a_name_github_cannot_hold
M15: _source_spec without the limits killed, 28: 16 in the new file and 12 in #1122's
M16: _held_repository's second reading without the limits survived, 101 passed: an equivalent mutant (see "Every reader")

Gate

The gate ran on a scratch merge commit, b56236aa: main 961640c6 merged with 900f77af, which brings #1122 in.

  • Its tree, 90fbea0e, is the one git merge-tree --write-tree origin/main 900f77af gives.
  • Against main, it changes only adopt-project.py, tests/test_adopt_source_github_limits.py and tests/test_adopt_unsearchable_source.py.

The environment:

  • /usr/bin/python3 -m pytest -p no:cacheprovider, Python 3.12.3, tmp_path_retention_policy=failed;
  • a stub gh first on PATH, GH_TOKEN=bogus and an empty GH_CONFIG_DIR;
  • GIT_CONFIG_GLOBAL an empty file, and GIT_CONFIG_NOSYSTEM=1;
  • the test author and committer, and EMAIL;
  • GIT_SSH_COMMAND, GIT_ALLOW_PROTOCOL and the LANES_* variables unset.

Every run ended rc=0.

FIN1129's 23 files, each run alone: 1268 passed, 1 skipped. These are the PR body's counts, file by file.

File Passed Skipped
test_adopt_source_github_limits 48 0
test_adopt_unsearchable_source 40 0
test_adopt_unenterable_source_and_locale 13 0
test_adopt_check_plan_name 45 0
test_adopt_source_clone_record 100 0
test_adopt_template_values 78 0
test_adopt_work_dir_refusal 53 0
test_windows_paths 46 0
test_adopt_clone_claimed 42 0
test_adopt_late_failure 88 0
test_adopt_plan_flag_refusals_first 89 0
test_adopt_temp_work_roots 9 0
test_adopt_origin_repository 30 0
test_adopt_plan 66 1
test_adopt_project_is_the_source 23 0
test_adopt_relative_submodule_url 34 0
test_adopt_split_branch 47 0
test_adopt_values_as_typed 40 0
test_adopt_plan_escapes 59 0
test_path_guard_hygiene 49 0
test_repo_hygiene 101 0
test_scaffold_leg_path_collisions 104 0
test_github_name_limits 64 0

tests/test_shape_doctor.py: all 448 collected ids, 445 passed and 3 skipped.

  • They ran in 8 shards of 56, from a bash script, with ids one per line. Together the shard lists hold every collected id exactly once.
  • Each shard had a 2400 s timeout and started with at least 17G free.
  • The shards gave d01 56 passed; d02 56; d03, d04 and d05 55 passed and 1 skipped each; d06, d07 and d08 56 each.

Totals: 1713 passed, 4 skipped, 0 failed, 0 errors. These are FIN1129's counts exactly. The skips belong to the host: SHAPE_MEDXEHR_CLONE is unset for one test_adopt_plan row, and three doctor rows print the PowerShell line only on a Windows host.

Beyond FIN1129's list: one pytest run of 495 tests, all passed. Its 327 new tests are test_adopt_execute_refusals (181), test_github_limits_init_check_org (96), test_adopt_spelled_names (27) and test_adopt_github_exits (23). test_github_limits_init_check_org checks adopt-project.py check against GitHub's limits and is not in FIN1129's list. It imports fixtures from test_github_name_limits and test_scaffold_leg_path_collisions, so those two files (64 and 104) ran in the same pytest call.

Merge-trees

Every git merge-tree --write-tree below gave rc=0 with no conflict.

Findings

NIT-1: a local source's origin past the limits is still offered --org <40 c's>.

Fix: a follow-up issue to apply the same two limits in _remote_repository, so that a name past either is no org/repo, as a path is. Then plan records repository: null for such an origin, and no remedy offers the name.

NIT-2: the same plan is held, or not, depending on whether origin is still there. P29: a local source whose origin is https://gitlab.com/<40 c's>/Thing.git is planned with --org <40 c's>. The plan is written (exit 0) and records repository: <40 c's>/Thing. Its org: is then edited to testorg:

check #1122's head this head
origin still there exit 1, plan-not-the-source, --org <40 c's> offered exit 1, the same
origin removed exit 1, plan-not-the-source, --org <40 c's> offered exit 0, plan ok
  • RV1194's C05 and C06 rows show the same plan ok: a record of owner 40 or 50 with no origin, where execute stops at adopt-unconfirmed.
  • The no-origin answer is the one the PR body states. It matches the existing rule that a record naming no owner/repo holds the plan to nothing, and a name GitHub cannot hold is no GitHub repository to hold the plan to.
  • So the live reading is the one that disagrees, and the fix is NIT-1's: with the limits in _remote_repository, both readings hold nothing. Add this pair of checks to that follow-up's rows.

NIT-3: github.com/<40 c's>/Thing is refused even when it is a directory here (P24).

Fix, optional: when the spelling is a path here, have _repository_in_url's refusal say so, and offer ./<spelling>.

Lane: openreposhape-4 (openRepoShape-4)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant