workstate-stack 0.1.1__tar.gz
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.
- workstate_stack-0.1.1/PKG-INFO +47 -0
- workstate_stack-0.1.1/README.md +28 -0
- workstate_stack-0.1.1/pyproject.toml +39 -0
- workstate_stack-0.1.1/setup.cfg +4 -0
- workstate_stack-0.1.1/src/workstate_stack/__init__.py +7 -0
- workstate_stack-0.1.1/src/workstate_stack.egg-info/PKG-INFO +47 -0
- workstate_stack-0.1.1/src/workstate_stack.egg-info/SOURCES.txt +9 -0
- workstate_stack-0.1.1/src/workstate_stack.egg-info/dependency_links.txt +1 -0
- workstate_stack-0.1.1/src/workstate_stack.egg-info/requires.txt +8 -0
- workstate_stack-0.1.1/src/workstate_stack.egg-info/top_level.txt +1 -0
- workstate_stack-0.1.1/tests/test_stack_pins.py +224 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: workstate-stack
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers).
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/darce/workstate
|
|
7
|
+
Project-URL: Source, https://github.com/darce/workstate/tree/main/packages/workstate-stack
|
|
8
|
+
Project-URL: Changelog, https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md
|
|
9
|
+
Project-URL: Issues, https://github.com/darce/workstate/issues
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: workstate-protocol==0.2.2
|
|
13
|
+
Requires-Dist: mcp-workstate-handoff==0.12.4
|
|
14
|
+
Requires-Dist: mcp-workstate-orchestrator==0.6.1
|
|
15
|
+
Requires-Dist: workstate-bootstrap==0.8.3
|
|
16
|
+
Requires-Dist: workstate-system==0.2.2
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
19
|
+
|
|
20
|
+
# workstate-stack
|
|
21
|
+
|
|
22
|
+
One-number version anchor for the Workstate runtime stack.
|
|
23
|
+
|
|
24
|
+
Installing or upgrading this meta-package pulls every published Workstate
|
|
25
|
+
runtime member at the exact versions released together:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install --upgrade workstate-stack
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
|
|
32
|
+
gated by `make stack-pins-check`):
|
|
33
|
+
|
|
34
|
+
- `workstate-protocol`
|
|
35
|
+
- `mcp-workstate-handoff`
|
|
36
|
+
- `mcp-workstate-orchestrator`
|
|
37
|
+
- `workstate-bootstrap`
|
|
38
|
+
- `workstate-system`
|
|
39
|
+
|
|
40
|
+
Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
|
|
41
|
+
`workstate-codex-bridge` (optional host-specific bridge; future
|
|
42
|
+
`workstate-stack[codex]` extra).
|
|
43
|
+
|
|
44
|
+
The package ships no code — `workstate_stack` is an empty module for wheel
|
|
45
|
+
validity. Consumers normally reach it through `make workstate-update`
|
|
46
|
+
(implementation note), which upgrades this anchor and then re-materializes the repo
|
|
47
|
+
overlay via `workstate-bootstrap update`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# workstate-stack
|
|
2
|
+
|
|
3
|
+
One-number version anchor for the Workstate runtime stack.
|
|
4
|
+
|
|
5
|
+
Installing or upgrading this meta-package pulls every published Workstate
|
|
6
|
+
runtime member at the exact versions released together:
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pip install --upgrade workstate-stack
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
|
|
13
|
+
gated by `make stack-pins-check`):
|
|
14
|
+
|
|
15
|
+
- `workstate-protocol`
|
|
16
|
+
- `mcp-workstate-handoff`
|
|
17
|
+
- `mcp-workstate-orchestrator`
|
|
18
|
+
- `workstate-bootstrap`
|
|
19
|
+
- `workstate-system`
|
|
20
|
+
|
|
21
|
+
Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
|
|
22
|
+
`workstate-codex-bridge` (optional host-specific bridge; future
|
|
23
|
+
`workstate-stack[codex]` extra).
|
|
24
|
+
|
|
25
|
+
The package ships no code — `workstate_stack` is an empty module for wheel
|
|
26
|
+
validity. Consumers normally reach it through `make workstate-update`
|
|
27
|
+
(implementation note), which upgrades this anchor and then re-materializes the repo
|
|
28
|
+
overlay via `workstate-bootstrap update`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "workstate-stack"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
# Floor must match the strictest member pin (mcp-workstate-handoff >=3.12);
|
|
11
|
+
# a looser floor makes `uv sync` unresolvable and aborts `make task-start`.
|
|
12
|
+
requires-python = ">=3.12"
|
|
13
|
+
license = { text = "MIT" }
|
|
14
|
+
# Exact pins are GENERATED — never hand-edit. `make stack-pins-sync` rewrites
|
|
15
|
+
# the block from sibling pyproject versions; `make stack-pins-check` gates
|
|
16
|
+
# check-all and release on the pins matching.
|
|
17
|
+
dependencies = [
|
|
18
|
+
# >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>
|
|
19
|
+
"workstate-protocol==0.2.2",
|
|
20
|
+
"mcp-workstate-handoff==0.12.4",
|
|
21
|
+
"mcp-workstate-orchestrator==0.6.1",
|
|
22
|
+
"workstate-bootstrap==0.8.3",
|
|
23
|
+
"workstate-system==0.2.2",
|
|
24
|
+
# <<< STACK PINS <<<
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/darce/workstate"
|
|
29
|
+
Source = "https://github.com/darce/workstate/tree/main/packages/workstate-stack"
|
|
30
|
+
Changelog = "https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md"
|
|
31
|
+
Issues = "https://github.com/darce/workstate/issues"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=8",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
where = ["src"]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""Empty anchor module: ``workstate-stack`` ships no code of its own.
|
|
2
|
+
|
|
3
|
+
The distribution exists solely to carry exact ``==`` pins on the published
|
|
4
|
+
Workstate runtime members (see ``pyproject.toml``), so consumers upgrade the
|
|
5
|
+
whole stack with one version number:
|
|
6
|
+
``pip install --upgrade workstate-stack``.
|
|
7
|
+
"""
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: workstate-stack
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers).
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/darce/workstate
|
|
7
|
+
Project-URL: Source, https://github.com/darce/workstate/tree/main/packages/workstate-stack
|
|
8
|
+
Project-URL: Changelog, https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md
|
|
9
|
+
Project-URL: Issues, https://github.com/darce/workstate/issues
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: workstate-protocol==0.2.2
|
|
13
|
+
Requires-Dist: mcp-workstate-handoff==0.12.4
|
|
14
|
+
Requires-Dist: mcp-workstate-orchestrator==0.6.1
|
|
15
|
+
Requires-Dist: workstate-bootstrap==0.8.3
|
|
16
|
+
Requires-Dist: workstate-system==0.2.2
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
19
|
+
|
|
20
|
+
# workstate-stack
|
|
21
|
+
|
|
22
|
+
One-number version anchor for the Workstate runtime stack.
|
|
23
|
+
|
|
24
|
+
Installing or upgrading this meta-package pulls every published Workstate
|
|
25
|
+
runtime member at the exact versions released together:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install --upgrade workstate-stack
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
|
|
32
|
+
gated by `make stack-pins-check`):
|
|
33
|
+
|
|
34
|
+
- `workstate-protocol`
|
|
35
|
+
- `mcp-workstate-handoff`
|
|
36
|
+
- `mcp-workstate-orchestrator`
|
|
37
|
+
- `workstate-bootstrap`
|
|
38
|
+
- `workstate-system`
|
|
39
|
+
|
|
40
|
+
Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
|
|
41
|
+
`workstate-codex-bridge` (optional host-specific bridge; future
|
|
42
|
+
`workstate-stack[codex]` extra).
|
|
43
|
+
|
|
44
|
+
The package ships no code — `workstate_stack` is an empty module for wheel
|
|
45
|
+
validity. Consumers normally reach it through `make workstate-update`
|
|
46
|
+
(implementation note), which upgrades this anchor and then re-materializes the repo
|
|
47
|
+
overlay via `workstate-bootstrap update`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/workstate_stack/__init__.py
|
|
4
|
+
src/workstate_stack.egg-info/PKG-INFO
|
|
5
|
+
src/workstate_stack.egg-info/SOURCES.txt
|
|
6
|
+
src/workstate_stack.egg-info/dependency_links.txt
|
|
7
|
+
src/workstate_stack.egg-info/requires.txt
|
|
8
|
+
src/workstate_stack.egg-info/top_level.txt
|
|
9
|
+
tests/test_stack_pins.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
workstate_stack
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""Pin-sync gate for the ``workstate-stack`` meta-package (implementation note implementation note).
|
|
2
|
+
|
|
3
|
+
The meta-package is the single version anchor consumers install: its
|
|
4
|
+
``dependencies`` block carries exact ``==`` pins on every published stack
|
|
5
|
+
member. Pins are never hand-edited — ``scripts/stack_pins.py sync``
|
|
6
|
+
regenerates them from sibling ``pyproject.toml`` versions and
|
|
7
|
+
``scripts/stack_pins.py check`` (``make stack-pins-check``) fails when they
|
|
8
|
+
drift, so a member bump can never ship without moving the meta pins.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import importlib.util
|
|
14
|
+
import json
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
20
|
+
SOURCE_STACK_PINS = REPO_ROOT / "scripts" / "stack_pins.py"
|
|
21
|
+
|
|
22
|
+
EXPECTED_MEMBERS = (
|
|
23
|
+
"workstate-protocol",
|
|
24
|
+
"mcp-workstate-handoff",
|
|
25
|
+
"mcp-workstate-orchestrator",
|
|
26
|
+
"workstate-bootstrap",
|
|
27
|
+
"workstate-system",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _load_module():
|
|
32
|
+
spec = importlib.util.spec_from_file_location(
|
|
33
|
+
"stack_pins_under_test", SOURCE_STACK_PINS
|
|
34
|
+
)
|
|
35
|
+
assert spec and spec.loader
|
|
36
|
+
module = importlib.util.module_from_spec(spec)
|
|
37
|
+
# Register before exec so @dataclass (under `from __future__ import
|
|
38
|
+
# annotations`) can resolve the module via sys.modules[cls.__module__].
|
|
39
|
+
sys.modules[spec.name] = module
|
|
40
|
+
spec.loader.exec_module(module)
|
|
41
|
+
return module
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _write(path: Path, text: str) -> None:
|
|
45
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
path.write_text(text, encoding="utf-8")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _member_pyproject(name: str, version: str) -> str:
|
|
50
|
+
return f'[project]\nname = "{name}"\nversion = "{version}"\n'
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _stack_pyproject(pins: dict[str, str] | None) -> str:
|
|
54
|
+
"""Stack pyproject with the generated pins block carrying ``pins``."""
|
|
55
|
+
lines = [
|
|
56
|
+
"[build-system]",
|
|
57
|
+
'requires = ["setuptools>=68", "wheel"]',
|
|
58
|
+
'build-backend = "setuptools.build_meta"',
|
|
59
|
+
"",
|
|
60
|
+
"[project]",
|
|
61
|
+
'name = "workstate-stack"',
|
|
62
|
+
'version = "0.1.0"',
|
|
63
|
+
'description = "fixture"',
|
|
64
|
+
'requires-python = ">=3.11"',
|
|
65
|
+
"dependencies = [",
|
|
66
|
+
" # >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>",
|
|
67
|
+
]
|
|
68
|
+
for distribution, version in (pins or {}).items():
|
|
69
|
+
lines.append(f' "{distribution}=={version}",')
|
|
70
|
+
lines.extend(
|
|
71
|
+
[
|
|
72
|
+
" # <<< STACK PINS <<<",
|
|
73
|
+
"]",
|
|
74
|
+
"",
|
|
75
|
+
"[tool.setuptools.packages.find]",
|
|
76
|
+
'where = ["src"]',
|
|
77
|
+
"",
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
return "\n".join(lines)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _build_repo(
|
|
84
|
+
tmp_path: Path,
|
|
85
|
+
*,
|
|
86
|
+
member_versions: dict[str, str] | None = None,
|
|
87
|
+
stack_pins: dict[str, str] | None = None,
|
|
88
|
+
omit_stack_block: bool = False,
|
|
89
|
+
) -> Path:
|
|
90
|
+
"""Synthetic monorepo: release manifest, member pyprojects, stack pyproject."""
|
|
91
|
+
repo = tmp_path / "repo"
|
|
92
|
+
versions = dict(member_versions or {})
|
|
93
|
+
for member in EXPECTED_MEMBERS:
|
|
94
|
+
versions.setdefault(member, "1.0.0")
|
|
95
|
+
# Non-member packages prove the member set is closed.
|
|
96
|
+
versions.setdefault("mcp-workstate-canvas", "9.9.9")
|
|
97
|
+
versions.setdefault("workstate-codex-bridge", "9.9.9")
|
|
98
|
+
|
|
99
|
+
packages = []
|
|
100
|
+
for name, version in versions.items():
|
|
101
|
+
path = f"packages/{name}"
|
|
102
|
+
_write(repo / path / "pyproject.toml", _member_pyproject(name, version))
|
|
103
|
+
packages.append(
|
|
104
|
+
{
|
|
105
|
+
"name": name,
|
|
106
|
+
"path": path,
|
|
107
|
+
"distribution": name,
|
|
108
|
+
"artifact_prefix": name.replace("-", "_"),
|
|
109
|
+
"publish": name != "mcp-workstate-canvas",
|
|
110
|
+
"test_command": "python -m pytest -q",
|
|
111
|
+
"changelog": f"{path}/CHANGELOG.md",
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
_write(
|
|
115
|
+
repo / "config" / "release" / "packages.json",
|
|
116
|
+
json.dumps({"packages": packages}, indent=2) + "\n",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if omit_stack_block:
|
|
120
|
+
stack_text = _stack_pyproject(None).replace(
|
|
121
|
+
" # >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>\n",
|
|
122
|
+
"",
|
|
123
|
+
).replace(" # <<< STACK PINS <<<\n", "")
|
|
124
|
+
else:
|
|
125
|
+
pins = stack_pins
|
|
126
|
+
if pins is None:
|
|
127
|
+
pins = {member: versions[member] for member in EXPECTED_MEMBERS}
|
|
128
|
+
stack_text = _stack_pyproject(pins)
|
|
129
|
+
_write(repo / "packages" / "workstate-stack" / "pyproject.toml", stack_text)
|
|
130
|
+
return repo
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_member_set_is_exactly_the_published_runtime_stack():
|
|
134
|
+
module = _load_module()
|
|
135
|
+
assert tuple(module.STACK_MEMBERS) == EXPECTED_MEMBERS
|
|
136
|
+
assert "mcp-workstate-canvas" not in module.STACK_MEMBERS
|
|
137
|
+
assert "workstate-codex-bridge" not in module.STACK_MEMBERS
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_check_passes_when_pins_match_member_versions(tmp_path: Path):
|
|
141
|
+
module = _load_module()
|
|
142
|
+
repo = _build_repo(tmp_path, member_versions={"workstate-system": "0.2.1"})
|
|
143
|
+
ok, messages = module.check(repo)
|
|
144
|
+
assert ok, messages
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_check_flags_drifted_pin(tmp_path: Path):
|
|
148
|
+
module = _load_module()
|
|
149
|
+
versions = {member: "1.0.0" for member in EXPECTED_MEMBERS}
|
|
150
|
+
stale = dict(versions)
|
|
151
|
+
stale["workstate-system"] = "0.9.0"
|
|
152
|
+
repo = _build_repo(tmp_path, member_versions=versions, stack_pins=stale)
|
|
153
|
+
ok, messages = module.check(repo)
|
|
154
|
+
assert not ok
|
|
155
|
+
blob = "\n".join(messages)
|
|
156
|
+
assert "workstate-system" in blob
|
|
157
|
+
assert "0.9.0" in blob and "1.0.0" in blob
|
|
158
|
+
assert "stack-pins-sync" in blob # remediation is named, not implied
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def test_check_flags_missing_member_pin(tmp_path: Path):
|
|
162
|
+
module = _load_module()
|
|
163
|
+
pins = {member: "1.0.0" for member in EXPECTED_MEMBERS}
|
|
164
|
+
del pins["mcp-workstate-handoff"]
|
|
165
|
+
repo = _build_repo(tmp_path, stack_pins=pins)
|
|
166
|
+
ok, messages = module.check(repo)
|
|
167
|
+
assert not ok
|
|
168
|
+
assert any("mcp-workstate-handoff" in line for line in messages)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_sync_rewrites_drifted_pins_then_check_passes(tmp_path: Path):
|
|
172
|
+
module = _load_module()
|
|
173
|
+
versions = {member: "2.3.4" for member in EXPECTED_MEMBERS}
|
|
174
|
+
stale = {member: "0.0.1" for member in EXPECTED_MEMBERS}
|
|
175
|
+
repo = _build_repo(tmp_path, member_versions=versions, stack_pins=stale)
|
|
176
|
+
|
|
177
|
+
changed = module.sync(repo)
|
|
178
|
+
assert changed
|
|
179
|
+
|
|
180
|
+
text = (repo / "packages" / "workstate-stack" / "pyproject.toml").read_text()
|
|
181
|
+
for member in EXPECTED_MEMBERS:
|
|
182
|
+
assert f'"{member}==2.3.4"' in text
|
|
183
|
+
ok, messages = module.check(repo)
|
|
184
|
+
assert ok, messages
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def test_sync_is_idempotent_and_preserves_surrounding_content(tmp_path: Path):
|
|
188
|
+
module = _load_module()
|
|
189
|
+
repo = _build_repo(tmp_path)
|
|
190
|
+
pyproject = repo / "packages" / "workstate-stack" / "pyproject.toml"
|
|
191
|
+
before = pyproject.read_text()
|
|
192
|
+
|
|
193
|
+
assert module.sync(repo) is False # already in sync -> no rewrite
|
|
194
|
+
after = pyproject.read_text()
|
|
195
|
+
assert after == before
|
|
196
|
+
assert 'name = "workstate-stack"' in after
|
|
197
|
+
assert "[tool.setuptools.packages.find]" in after
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_missing_sentinel_block_is_a_clear_error(tmp_path: Path):
|
|
201
|
+
module = _load_module()
|
|
202
|
+
repo = _build_repo(tmp_path, omit_stack_block=True)
|
|
203
|
+
ok, messages = module.check(repo)
|
|
204
|
+
assert not ok
|
|
205
|
+
assert any("STACK PINS" in line for line in messages)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_cli_check_exit_codes(tmp_path: Path):
|
|
209
|
+
module = _load_module()
|
|
210
|
+
repo = _build_repo(tmp_path)
|
|
211
|
+
assert module.main(["check", "--repo-root", str(repo)]) == 0
|
|
212
|
+
|
|
213
|
+
stale = {member: "0.0.1" for member in EXPECTED_MEMBERS}
|
|
214
|
+
drifted = _build_repo(tmp_path / "drift", stack_pins=stale)
|
|
215
|
+
assert module.main(["check", "--repo-root", str(drifted)]) == 1
|
|
216
|
+
assert module.main(["sync", "--repo-root", str(drifted)]) == 0
|
|
217
|
+
assert module.main(["check", "--repo-root", str(drifted)]) == 0
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def test_real_repo_pins_are_in_sync():
|
|
221
|
+
"""The committed meta-package pins always match sibling versions."""
|
|
222
|
+
module = _load_module()
|
|
223
|
+
ok, messages = module.check(REPO_ROOT)
|
|
224
|
+
assert ok, messages
|