Repository navigation
Commit 22162d7
* Start fix for #505
Assisted-by: Claude Code:claude-opus-5-5
* Refuse vendoring a Hatch workspace member
A vendored scan run from a member of a Hatch 1.16+ workspace wrote
{root:uri} references into the member's [project] dependencies and
reported success. Hatch's workspace environment reads a member's
static dependencies raw, so every sync of the workspace root env then
failed with pip's "No connection adapters were found for
'{root:uri}/...'" until someone hand-edited the member.
Detect a workspace environment declared in an ancestor pyproject.toml
or hatch.toml (up to the checkout root) that lists the project, the
way Hatch resolves members (globs, path tables, exclude, features and
self-referencing extras), and refuse the package with
pypi_hatch_unsupported before anything is written, pointing at hosted
or agent mode. Dependencies the workspace does not read raw (the
member's own env deps, unselected extras, dynamic metadata) are still
vendored.
Fixes #505
Assisted-by: Claude Code:claude-opus-5-5
* Find sibling Hatch workspace roots and more specs
Review follow-ups for the workspace-member refusal:
- look for a workspace root anywhere in the checkout, since Hatch
lets a root list a member beside it through a ../ spec
- read members written as an array of tables and specs using the
{root} and {home} context fields
- stop at the checkout root even when the member is that root
- match fnmatch patterns in linear time, and fold case and
separators on Windows the way Python's fnmatch does
- look a selected feature up by its exact key, as Hatch does
- tell a user whose member was vendored by an earlier run how to
undo it
- share the hatch.toml/pyproject env-table rule with the planner
Assisted-by: Claude Code:claude-opus-5-5
* Bound Hatch workspace reads like repo lookups
Read workspace candidates through the non-blocking regular-file
reader, so a FIFO at a pyproject.toml or hatch.toml path can't hang a
vendored scan, and walk ancestors with the shared repository lookup,
which stops at the checkout root, never enters the home directory and
honours GIT_CEILING_DIRECTORIES.
Assisted-by: Claude Code:claude-opus-5-5
* Match Hatch members reached through symlinks
Resolve each workspace member spec by listing directories the way
Hatch's find_members does, following symlinked directories, and
compare what it finds with the scanned project by real path. Roots are
looked for above both the spelled and the real path, so a member Hatch
reaches through a symlink is refused whichever path the scan was given.
Assisted-by: Claude Code:claude-opus-5-5
* Count member extras named across a Hatch workspace
Hatch's all_dependencies_complex expands a workspace member's raw
optional dependencies whenever any of the environment's requirement
strings names the member with an extra: the root's own dependencies,
its environments', or another member's (lib[s3]). Those groups reach
pip raw, so a vendored {root:uri} there breaks the workspace just
like a selected feature does. Count those extras as consumed.
Also say in the Hatch notes that a sibling root listing the member
through ../ is found as well.
Assisted-by: Claude Code:claude-opus-5-5
* Read workspace extras the way Hatch installs them
Collect the requirement strings that name the member from what the
workspace environment actually installs: the root's dependencies and
its environment features' extras, the environment's and its
templates' dependencies (from hatch.toml when that replaces the
pyproject tables), and the other members' dependencies and selected
features. Resolve the extras they name through the same normalized
lookup Hatch's resolve_extras uses, so a mixed-case extra name is
found and strings Hatch never installs select nothing.
Assisted-by: Claude Code:claude-opus-5-5
* Treat every extra of a Hatch workspace member as raw
Which optional dependencies a Hatch workspace environment installs from
a member depends on the whole workspace: the member's features,
<member>[extra] references from the root, environments, their
templates and dependency groups, and extras of other members that
reach it. Each review round found another path the precise model
missed, and a miss writes a {root:uri} that breaks every workspace
sync.
Once a workspace lists the member, count all its static dependencies
and optional dependencies as read raw instead. A refusal still leaves
hosted and agent mode, and the module shrinks to member discovery.
Assisted-by: Claude Code:claude-opus-5-5
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent a2253e0 commit 22162d7
6 files changed
Lines changed: 826 additions & 13 deletions
File tree
- crates
- socket-patch-cli/tests/e2e_vex_build
- socket-patch-core/src
- utils
- vendor
- docs/testing
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
740 | 740 | | |
741 | 741 | | |
742 | 742 | | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
141 | 161 | | |
142 | 162 | | |
143 | 163 | | |
| |||
146 | 166 | | |
147 | 167 | | |
148 | 168 | | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
| 169 | + | |
| 170 | + | |
161 | 171 | | |
162 | 172 | | |
163 | 173 | | |
| |||
0 commit comments