gitgrip 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. gitgrip-1.5.0.dist-info/METADATA +13 -0
  2. gitgrip-1.5.0.dist-info/RECORD +80 -0
  3. gitgrip-1.5.0.dist-info/WHEEL +5 -0
  4. gitgrip-1.5.0.dist-info/entry_points.txt +2 -0
  5. gitgrip-1.5.0.dist-info/top_level.txt +2 -0
  6. gr2/__init__.py +0 -0
  7. gr2/overlay/__init__.py +6 -0
  8. gr2/overlay/activate.py +196 -0
  9. gr2/overlay/agent_manifest.py +138 -0
  10. gr2/overlay/cli.py +181 -0
  11. gr2/overlay/cross_repo.py +124 -0
  12. gr2/overlay/drivers.py +113 -0
  13. gr2/overlay/introspection.py +155 -0
  14. gr2/overlay/language_drivers.py +115 -0
  15. gr2/overlay/objects.py +412 -0
  16. gr2/overlay/perf.py +251 -0
  17. gr2/overlay/refs.py +36 -0
  18. gr2/overlay/trust.py +150 -0
  19. gr2/overlay/types.py +69 -0
  20. gr2/overlay/units.py +313 -0
  21. gr2/overlay/workspace_spec.py +59 -0
  22. gr2/prototypes/__init__.py +0 -0
  23. gr2/prototypes/cache_materialization_probe.py +190 -0
  24. gr2/prototypes/concurrent_event_stress.py +199 -0
  25. gr2/prototypes/concurrent_lease_stress.py +240 -0
  26. gr2/prototypes/concurrent_workspace_cap_stress.py +231 -0
  27. gr2/prototypes/contribution_protocol.py +665 -0
  28. gr2/prototypes/cross_mode_lane_stress.py +986 -0
  29. gr2/prototypes/jsonl_store.py +158 -0
  30. gr2/prototypes/lane_workspace_prototype.py +2088 -0
  31. gr2/prototypes/layout_model_probe.py +139 -0
  32. gr2/prototypes/propagation_daemon.py +546 -0
  33. gr2/prototypes/propagation_state_machine.py +1478 -0
  34. gr2/prototypes/python_exec_playground.py +194 -0
  35. gr2/prototypes/python_hook_runtime_playground.py +240 -0
  36. gr2/prototypes/python_migration_playground.py +144 -0
  37. gr2/prototypes/python_review_checkout_playground.py +242 -0
  38. gr2/prototypes/python_spec_apply_playground.py +282 -0
  39. gr2/prototypes/real_git_lane_materialization.py +248 -0
  40. gr2/prototypes/real_git_playground.py +334 -0
  41. gr2/prototypes/recall_lane_history.py +274 -0
  42. gr2/prototypes/repo_maintenance_prototype.py +659 -0
  43. gr2/prototypes/repo_transport_probe.py +147 -0
  44. gr2/python_cli/__init__.py +2 -0
  45. gr2/python_cli/__main__.py +6 -0
  46. gr2/python_cli/add.py +51 -0
  47. gr2/python_cli/app.py +2516 -0
  48. gr2/python_cli/branch.py +67 -0
  49. gr2/python_cli/channel_bridge.py +131 -0
  50. gr2/python_cli/clone_exec.py +1019 -0
  51. gr2/python_cli/commit.py +199 -0
  52. gr2/python_cli/config.py +291 -0
  53. gr2/python_cli/env_exec.py +419 -0
  54. gr2/python_cli/events.py +529 -0
  55. gr2/python_cli/execops.py +372 -0
  56. gr2/python_cli/failures.py +98 -0
  57. gr2/python_cli/file_exec.py +256 -0
  58. gr2/python_cli/gitops.py +226 -0
  59. gr2/python_cli/grip.py +1337 -0
  60. gr2/python_cli/grip_cli.py +493 -0
  61. gr2/python_cli/hooks.py +450 -0
  62. gr2/python_cli/launch_exec.py +786 -0
  63. gr2/python_cli/merge_verification.py +274 -0
  64. gr2/python_cli/migration.py +985 -0
  65. gr2/python_cli/open_gr_review.py +699 -0
  66. gr2/python_cli/platform.py +441 -0
  67. gr2/python_cli/pr.py +487 -0
  68. gr2/python_cli/project_review.py +314 -0
  69. gr2/python_cli/prune.py +365 -0
  70. gr2/python_cli/push.py +172 -0
  71. gr2/python_cli/review.py +462 -0
  72. gr2/python_cli/review_ephemeral.py +143 -0
  73. gr2/python_cli/review_run.py +621 -0
  74. gr2/python_cli/spec_apply.py +1285 -0
  75. gr2/python_cli/staging_cleanup.py +205 -0
  76. gr2/python_cli/syncops.py +920 -0
  77. gr2/python_cli/target.py +100 -0
  78. gr2/python_cli/workspace_snapshot.py +105 -0
  79. gr2/schemas/gr2-materialization-plan-v1.schema.json +191 -0
  80. gr2_overlay/__init__.py +37 -0
@@ -0,0 +1,143 @@
1
+ """Review-ephemeral lane materialization: blobless + sparse, from the persistent
2
+ per-host review mirror, NEVER through ``materialize_lane_clone``.
3
+
4
+ A review lane is read-only and ephemeral -- nobody commits into it and it is
5
+ ``rm -rf``'d when the review closes. Sections 8.1 (complete history) and 8.2 (no
6
+ external object sharing) that ``materialize_lane_clone`` enforces exist to protect
7
+ a MUTABLE work lane's independent state; a review lane does not need them, and a
8
+ blobless clone keeps the whole commit+tree graph, so patch-id, diff, and
9
+ merge-base all work (measured: identical base..head patch-id vs a full clone).
10
+ Blobless is the only ``.git`` reducer (shallow is out -- a base..head review must
11
+ reach an arbitrary base); sparse is the working-tree reducer, using EXACTLY
12
+ ``review-clone.sh``'s two rules so the two tools cannot disagree:
13
+
14
+ 1. the profile is ignore-syntax and comes from, in order: the in-repo
15
+ ``.review-exclude`` at the reviewed ref (read from the bare mirror), else the
16
+ gripspace fallback ``<profile_dir>/<repo>.exclude`` (``SYNAPT_REVIEW_PROFILE_DIR``,
17
+ the same env ``review-clone.sh`` honors), else none (whole tree, still blobless);
18
+ 2. every path ``base..head`` touches is appended AFTER the profile as an explicit
19
+ ``/path`` include, so a review can never be missing a file it is about (later
20
+ patterns win in ``--no-cone`` sparse-checkout).
21
+
22
+ This lane KIND never enters the work-lane clone seam, so it cannot weaken 8.1/8.2.
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import os
27
+ import subprocess
28
+ from pathlib import Path
29
+
30
+ REVIEW_EPHEMERAL_KIND = "review-ephemeral"
31
+
32
+
33
+ class ReviewEphemeralError(Exception):
34
+ pass
35
+
36
+
37
+ def _git(cwd: Path, *args: str) -> subprocess.CompletedProcess[str]:
38
+ return subprocess.run(["git", *args], cwd=cwd, text=True, capture_output=True, check=False)
39
+
40
+
41
+ def review_profile_dir() -> Path | None:
42
+ """The gripspace-level sparse-profile fallback dir, honoring the same
43
+ ``SYNAPT_REVIEW_PROFILE_DIR`` override review-clone.sh honors. gr2 is
44
+ repo-layout-agnostic, so with the env unset there is NO gripspace fallback and
45
+ only an in-repo ``.review-exclude`` applies (which is versioned with the repo
46
+ and always found)."""
47
+ value = os.environ.get("SYNAPT_REVIEW_PROFILE_DIR")
48
+ return Path(value) if value else None
49
+
50
+
51
+ def resolve_sparse_profile(mirror: Path, ref: str, repo_name: str) -> tuple[str, str]:
52
+ """Resolve the sparse profile for ``ref`` by review-clone.sh's precedence.
53
+
54
+ Returns ``(profile_content, source_label)``; empty content means no profile
55
+ (whole tree, still blobless)."""
56
+ shown = _git(mirror, "show", f"{ref}:.review-exclude")
57
+ if shown.returncode == 0 and shown.stdout.strip():
58
+ return shown.stdout, f"in-repo .review-exclude @ {ref}"
59
+ pdir = review_profile_dir()
60
+ if pdir is not None:
61
+ fallback = pdir / f"{repo_name}.exclude"
62
+ if fallback.is_file():
63
+ return fallback.read_text(), f"fallback {fallback}"
64
+ return "", "none"
65
+
66
+
67
+ def _pattern_lines(profile_content: str, touched_paths: list[str]) -> list[str]:
68
+ """Profile lines (comments/blanks stripped) first, then each touched path as an
69
+ explicit ``/path`` include -- review-clone.sh's exact ordering."""
70
+ lines: list[str] = []
71
+ for raw in profile_content.splitlines():
72
+ line = raw.strip()
73
+ if not line or line.startswith("#"):
74
+ continue
75
+ lines.append(line)
76
+ for p in touched_paths:
77
+ p = p.strip()
78
+ if p:
79
+ lines.append("/" + p.lstrip("/"))
80
+ return lines
81
+
82
+
83
+ def touched_paths(mirror: Path, base: str, head: str) -> list[str]:
84
+ """The paths ``base..head`` touches (the range-union source). Read from the
85
+ bare mirror, which holds the complete commit+tree graph."""
86
+ proc = _git(mirror, "diff", "--name-only", base, head)
87
+ if proc.returncode != 0:
88
+ raise ReviewEphemeralError(
89
+ f"cannot compute base..head touched paths ({base[:8]}..{head[:8]}) in {mirror}: "
90
+ f"{proc.stderr.strip()}"
91
+ )
92
+ return [p for p in proc.stdout.splitlines() if p.strip()]
93
+
94
+
95
+ def materialize_review_ephemeral(
96
+ *,
97
+ mirror: Path,
98
+ dest: Path,
99
+ head: str,
100
+ base: str,
101
+ repo_name: str,
102
+ echo=lambda _l: None,
103
+ ) -> dict[str, str]:
104
+ """Materialize a review lane as a BLOBLESS + SPARSE clone from the mirror.
105
+
106
+ Returns provenance: the profile source, the pattern count, and the resulting
107
+ HEAD. Refuses if the checked-out HEAD is not the requested head."""
108
+ mirror = Path(mirror)
109
+ dest = Path(dest)
110
+ if dest.exists():
111
+ raise ReviewEphemeralError(f"review-ephemeral destination already exists: {dest}")
112
+
113
+ profile_content, profile_source = resolve_sparse_profile(mirror, head, repo_name)
114
+ patterns = _pattern_lines(profile_content, touched_paths(mirror, base, head))
115
+
116
+ dest.parent.mkdir(parents=True, exist_ok=True)
117
+ cloned = subprocess.run(
118
+ ["git", "clone", "--quiet", "--no-checkout", "--filter=blob:none",
119
+ f"file://{mirror}", str(dest)],
120
+ text=True, capture_output=True, check=False,
121
+ )
122
+ if cloned.returncode != 0:
123
+ raise ReviewEphemeralError(f"blobless clone from {mirror} failed: {cloned.stderr.strip()}")
124
+
125
+ # Sparse only when there is a profile AND patterns; a bare range-union with no
126
+ # profile would narrow to just the changed files, hiding their context, so a
127
+ # profile-less repo stays whole-tree (blobless), matching review-clone.sh.
128
+ if profile_content.strip() and patterns:
129
+ applied = subprocess.run(
130
+ ["git", "-C", str(dest), "sparse-checkout", "set", "--no-cone", "--stdin"],
131
+ input="\n".join(patterns) + "\n", text=True, capture_output=True, check=False,
132
+ )
133
+ if applied.returncode != 0:
134
+ raise ReviewEphemeralError(f"sparse-checkout set failed in {dest}: {applied.stderr.strip()}")
135
+
136
+ checked = _git(dest, "checkout", "--quiet", head)
137
+ if checked.returncode != 0:
138
+ raise ReviewEphemeralError(f"cannot check out review head {head} in {dest}: {checked.stderr.strip()}")
139
+ got = _git(dest, "rev-parse", "HEAD").stdout.strip()
140
+ if got != head:
141
+ raise ReviewEphemeralError(f"review-ephemeral lane is at {got}, not the requested head {head}")
142
+
143
+ return {"profile_source": profile_source, "patterns": str(len(patterns)), "head": got}