workbay 0.0.0__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.
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .DS_Store
4
+ .venv/
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .pytest_cache/
workbay-0.0.0/PKG-INFO ADDED
@@ -0,0 +1,28 @@
1
+ Metadata-Version: 2.4
2
+ Name: workbay
3
+ Version: 0.0.0
4
+ Summary: WorkBay front-door name reservation. Ships no runtime code yet; install workbay-stack for the WorkBay runtime stack today.
5
+ Project-URL: Homepage, https://github.com/darce/workbay
6
+ Project-URL: Source, https://github.com/darce/workbay/tree/main/packages/workbay
7
+ Project-URL: Changelog, https://github.com/darce/workbay/blob/main/packages/workbay/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/darce/workbay/issues
9
+ License-Expression: MIT
10
+ Requires-Python: >=3.11
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=8; extra == 'dev'
13
+ Description-Content-Type: text/markdown
14
+
15
+ # workbay
16
+
17
+ Name reservation for the WorkBay front-door installer.
18
+
19
+ The single-command `workbay` installer is on its way. Until it lands,
20
+ install the runtime stack directly:
21
+
22
+ ```sh
23
+ pip install workbay-stack
24
+ ```
25
+
26
+ `workbay-stack` is a one-number version anchor that pulls every published
27
+ WorkBay runtime package. This `workbay` distribution carries no runtime code
28
+ yet and will become the single-command front door in a following release.
@@ -0,0 +1,14 @@
1
+ # workbay
2
+
3
+ Name reservation for the WorkBay front-door installer.
4
+
5
+ The single-command `workbay` installer is on its way. Until it lands,
6
+ install the runtime stack directly:
7
+
8
+ ```sh
9
+ pip install workbay-stack
10
+ ```
11
+
12
+ `workbay-stack` is a one-number version anchor that pulls every published
13
+ WorkBay runtime package. This `workbay` distribution carries no runtime code
14
+ yet and will become the single-command front door in a following release.
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env python3
2
+ """Build-time vendor of scripts/_scrub_core.py for hatch builds from sdist."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import re
7
+
8
+ INTERNAL_REF_PREFIXES = (
9
+ "AHMCP",
10
+ "AOMCP",
11
+ "APD",
12
+ "DCMCP",
13
+ "WBF",
14
+ "CHC",
15
+ "PA",
16
+ "MAINT",
17
+ "APM-SPEC-TR",
18
+ "WORKSTATE-REF",
19
+ )
20
+
21
+ INTERNAL_REF_RE = re.compile(
22
+ r"(?<![A-Za-z])(?:"
23
+ + "|".join(re.escape(prefix) for prefix in INTERNAL_REF_PREFIXES)
24
+ + r"|WS|WB|E[0-9]+)(?:[0-9]+)?(?:-[A-Z0-9]+)+"
25
+ )
26
+
27
+ PROCESS_REF_RES = (
28
+ re.compile(r"\b[Pp]lan\s+[0-9]{4}\b"),
29
+ re.compile(r"\b[Ss]lice\s+[0-9]+[A-Za-z]?\b"),
30
+ re.compile(r"\b[Ss]tep\s+[0-9]+/[0-9]+\b"),
31
+ )
32
+
33
+ INLINE_INTERNAL_PREFIX_RE = re.compile(
34
+ r"(?<![A-Za-z])(?:AHMCP|AOMCP|APD|DCMCP|WBF|CHC|APM-SPEC-TR)(?![A-Za-z])",
35
+ re.IGNORECASE,
36
+ )
37
+
38
+ INLINE_EPIC_REF_RE = re.compile(r"E([0-9]+)-([0-9]+(?:-[A-Z0-9]+)*)")
39
+
40
+ _COLLAPSE_RE = re.compile(
41
+ r"\b(?:internal|implementation note)(?:[ \t]+(?:internal|implementation note))+\b"
42
+ )
43
+
44
+
45
+ def scrub_text(text: str) -> str:
46
+ scrubbed = INTERNAL_REF_RE.sub("internal", text)
47
+ scrubbed = INLINE_INTERNAL_PREFIX_RE.sub("internal", scrubbed)
48
+ scrubbed = INLINE_EPIC_REF_RE.sub("internal", scrubbed)
49
+ for regex in PROCESS_REF_RES:
50
+ scrubbed = regex.sub("implementation note", scrubbed)
51
+ return _COLLAPSE_RE.sub("internal", scrubbed)
@@ -0,0 +1,288 @@
1
+ """Hatch build hook: scrub staged package copies into wheel+sdist artifacts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib.util
6
+ import shutil
7
+ import tempfile
8
+ from pathlib import Path
9
+ from typing import Any, NamedTuple, Protocol
10
+
11
+ try: # hatchling is a build-time-only dep (build-system.requires), not a test dep.
12
+ from hatchling.builders.hooks.plugin.interface import BuildHookInterface
13
+ from hatchling.metadata.plugin.interface import MetadataHookInterface
14
+ from hatchling.plugin import hookimpl
15
+ except ModuleNotFoundError: # keep pure discover_scrub_targets importable for tests
16
+ BuildHookInterface = object # type: ignore[assignment,misc]
17
+ MetadataHookInterface = object # type: ignore[assignment,misc]
18
+
19
+ def hookimpl(func): # type: ignore[no-redef]
20
+ return func
21
+
22
+ _TEXT_SUFFIXES = {
23
+ ".md",
24
+ ".py",
25
+ ".yaml",
26
+ ".yml",
27
+ ".json",
28
+ ".toml",
29
+ ".txt",
30
+ ".mk",
31
+ ".sh",
32
+ ".in",
33
+ ".cfg",
34
+ ".ini",
35
+ ".template",
36
+ ".j2",
37
+ }
38
+
39
+ # Build-support files vendored into the sdist so the wheel can be rebuilt from it.
40
+ # They carry the scrub matcher vocabulary verbatim (the literal AHMCP/AOMCP/... ids
41
+ # the transform looks for) and MUST NOT themselves be scrubbed — doing so rewrites
42
+ # those literals to "internal" and ships a gutted scrub engine. They ride into the
43
+ # sdist via hatchling's own only-include and are scan-exempt in the privacy gate
44
+ # (scripts/check_shipped_privacy.py: _SCAN_EXEMPT_RELPATHS), so skip them here.
45
+ _BUILD_SUPPORT_NAMES = {"_scrub_core.py", "hatch_build.py"}
46
+
47
+
48
+ class ScrubTarget(NamedTuple):
49
+ source_path: Path
50
+ wheel_prefix: str
51
+ is_dir: bool
52
+
53
+
54
+ class _WheelConfigView(Protocol):
55
+ packages: list[str] | None
56
+ only_include: list[str] | None
57
+ sources: list[str] | None
58
+
59
+
60
+ def _strip_src_prefix(path: str) -> str:
61
+ if path.startswith("src/"):
62
+ return path.removeprefix("src/")
63
+ return path
64
+
65
+
66
+ def _rel_entry(entry: str, *, root: Path) -> str:
67
+ entry_path = Path(entry)
68
+ if entry_path.is_absolute():
69
+ return entry_path.relative_to(root).as_posix()
70
+ return entry.replace("\\", "/")
71
+
72
+
73
+ def _wheel_prefix_for_entry(entry: str, *, root: Path) -> str:
74
+ rel = _rel_entry(entry, root=root)
75
+ if rel.endswith(".py"):
76
+ return Path(rel).name
77
+ return _strip_src_prefix(rel.rstrip("/"))
78
+
79
+
80
+ def discover_scrub_targets(
81
+ build_config: _WheelConfigView | Any,
82
+ *,
83
+ root: Path,
84
+ ) -> list[ScrubTarget]:
85
+ """Resolve layout-aware scrub targets from the wheel build config."""
86
+ packages = list(getattr(build_config, "packages", None) or [])
87
+ only_include = list(getattr(build_config, "only_include", None) or [])
88
+ sources = list(getattr(build_config, "sources", None) or [])
89
+
90
+ targets: list[ScrubTarget] = []
91
+ covered_sources: set[Path] = set()
92
+
93
+ def _append_target(source_path: Path, wheel_prefix: str) -> None:
94
+ resolved = source_path.resolve()
95
+ if resolved in covered_sources:
96
+ return
97
+ if not source_path.exists():
98
+ raise FileNotFoundError(source_path)
99
+ covered_sources.add(resolved)
100
+ targets.append(
101
+ ScrubTarget(
102
+ source_path=source_path,
103
+ wheel_prefix=wheel_prefix,
104
+ is_dir=source_path.is_dir(),
105
+ )
106
+ )
107
+
108
+ package_prefixes = {
109
+ _strip_src_prefix(_rel_entry(package, root=root).rstrip("/")) for package in packages
110
+ }
111
+
112
+ for package in packages:
113
+ rel = _rel_entry(package, root=root)
114
+ _append_target(root / rel, _strip_src_prefix(rel.rstrip("/")))
115
+
116
+ for entry in only_include:
117
+ rel = _rel_entry(entry, root=root)
118
+ if Path(rel).name in _BUILD_SUPPORT_NAMES:
119
+ # Vendored build machinery ships verbatim; never stage/scrub it.
120
+ continue
121
+ wheel_prefix = _wheel_prefix_for_entry(entry, root=root)
122
+ if rel.endswith(".py"):
123
+ source_path = root / rel
124
+ if not source_path.exists():
125
+ source_path = root / "src" / Path(rel).name
126
+ elif wheel_prefix in package_prefixes:
127
+ source_path = root / rel
128
+ else:
129
+ # Root-layout only-include names map to on-disk src/<pkg> trees.
130
+ candidate = root / "src" / wheel_prefix
131
+ source_path = candidate if candidate.exists() else root / rel
132
+ _append_target(source_path, wheel_prefix)
133
+
134
+ if targets:
135
+ return targets
136
+
137
+ if sources:
138
+ for source_root in sources:
139
+ rel = _rel_entry(source_root, root=root)
140
+ source_path = root / rel
141
+ if not source_path.exists():
142
+ raise FileNotFoundError(source_path)
143
+ wheel_prefix = _strip_src_prefix(rel.rstrip("/"))
144
+ targets.append(
145
+ ScrubTarget(
146
+ source_path=source_path,
147
+ wheel_prefix=wheel_prefix,
148
+ is_dir=source_path.is_dir(),
149
+ )
150
+ )
151
+ return targets
152
+
153
+ return targets
154
+
155
+
156
+ def _load_scrub_text():
157
+ scrub_core = Path(__file__).resolve().parent / "_scrub_core.py"
158
+ spec = importlib.util.spec_from_file_location("scrub_core_build", scrub_core)
159
+ assert spec and spec.loader
160
+ module = importlib.util.module_from_spec(spec)
161
+ spec.loader.exec_module(module)
162
+ return module.scrub_text
163
+
164
+
165
+ def _should_scrub(path: Path) -> bool:
166
+ return path.suffix.lower() in _TEXT_SUFFIXES or path.name in {
167
+ "Makefile",
168
+ "LICENSE",
169
+ "README.md",
170
+ }
171
+
172
+
173
+ def _scrub_tree(tree: Path, scrub_text) -> None:
174
+ for path in tree.rglob("*"):
175
+ if not path.is_file() or path.is_symlink():
176
+ continue
177
+ if not _should_scrub(path):
178
+ continue
179
+ try:
180
+ original = path.read_text(encoding="utf-8")
181
+ except (UnicodeDecodeError, OSError):
182
+ continue
183
+ scrubbed = scrub_text(original)
184
+ if scrubbed != original:
185
+ path.write_text(scrubbed, encoding="utf-8")
186
+
187
+
188
+ def _stage_target(staging: Path, target: ScrubTarget, scrub_text) -> Path:
189
+ if target.is_dir:
190
+ staged = staging / target.wheel_prefix
191
+ # Drop compiled bytecode/caches: force_include bypasses the sdist `exclude`
192
+ # globs, so an uncleaned source tree would otherwise ship unscanned .pyc.
193
+ shutil.copytree(
194
+ target.source_path,
195
+ staged,
196
+ ignore=shutil.ignore_patterns("__pycache__", "*.pyc", "*.pyo"),
197
+ )
198
+ _scrub_tree(staged, scrub_text)
199
+ return staged
200
+
201
+ staged = staging / target.wheel_prefix
202
+ staged.parent.mkdir(parents=True, exist_ok=True)
203
+ shutil.copy2(target.source_path, staged)
204
+ if _should_scrub(staged):
205
+ original = staged.read_text(encoding="utf-8")
206
+ scrubbed = scrub_text(original)
207
+ if scrubbed != original:
208
+ staged.write_text(scrubbed, encoding="utf-8")
209
+ return staged
210
+
211
+
212
+ def _force_include_staged(
213
+ force_include: dict[str, str],
214
+ staged_root: Path,
215
+ wheel_prefix: str,
216
+ ) -> None:
217
+ for path in staged_root.rglob("*"):
218
+ if not path.is_file():
219
+ continue
220
+ rel = path.relative_to(staged_root).as_posix()
221
+ force_include[str(path)] = f"{wheel_prefix}/{rel}" if rel else wheel_prefix
222
+
223
+
224
+ class ScrubAtBuildHook(BuildHookInterface):
225
+ PLUGIN_NAME = "custom"
226
+
227
+ @property
228
+ def _staging_dirs(self) -> list[Path]:
229
+ dirs = getattr(self, "_staging_dirs_store", None)
230
+ if dirs is None:
231
+ dirs = []
232
+ self._staging_dirs_store = dirs
233
+ return dirs
234
+
235
+ def initialize(self, version: str, build_data: dict) -> None:
236
+ scrub_text = _load_scrub_text()
237
+ root = Path(self.root)
238
+ targets = discover_scrub_targets(self.build_config, root=root)
239
+ if not targets:
240
+ return
241
+
242
+ staging = Path(tempfile.mkdtemp(prefix="workbay-scrub-stage-", dir=None))
243
+ if not staging.is_absolute():
244
+ staging = staging.resolve()
245
+ self._staging_dirs.append(staging)
246
+ force_include = build_data.setdefault("force_include", {})
247
+
248
+ for target in targets:
249
+ staged = _stage_target(staging, target, scrub_text)
250
+ if target.is_dir:
251
+ _force_include_staged(force_include, staged, target.wheel_prefix)
252
+ else:
253
+ force_include[str(staged)] = target.wheel_prefix
254
+
255
+ def finalize(self, version: str, build_data: dict, artifact_path: str) -> None:
256
+ while self._staging_dirs:
257
+ shutil.rmtree(self._staging_dirs.pop(), ignore_errors=True)
258
+
259
+
260
+ class ScrubMetadataHook(MetadataHookInterface):
261
+ PLUGIN_NAME = "custom"
262
+
263
+ def update(self, metadata: dict) -> None:
264
+ """Scrub the README long-description hatchling bakes into core metadata.
265
+
266
+ hatchling resolves ``readme`` -> the Description in wheel METADATA / sdist
267
+ PKG-INFO straight from the authored README, OUTSIDE the build hook's
268
+ force_include payload, so internal refs there would ship unscrubbed. A
269
+ package opts in by declaring ``dynamic = ["readme"]`` (and dropping the
270
+ static ``readme`` key); we supply the scrubbed long-description here.
271
+ """
272
+ scrub_text = _load_scrub_text()
273
+ readme_path = Path(self.root) / "README.md"
274
+ if readme_path.is_file():
275
+ metadata["readme"] = {
276
+ "content-type": "text/markdown",
277
+ "text": scrub_text(readme_path.read_text(encoding="utf-8")),
278
+ }
279
+
280
+
281
+ @hookimpl
282
+ def hatch_register_build_hook():
283
+ return ScrubAtBuildHook
284
+
285
+
286
+ @hookimpl
287
+ def hatch_register_metadata_hook():
288
+ return ScrubMetadataHook
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "workbay"
7
+ version = "0.0.0"
8
+ description = "WorkBay front-door name reservation. Ships no runtime code yet; install workbay-stack for the WorkBay runtime stack today."
9
+ readme = "README.md"
10
+ # The front door itself floors at 3.11 (it carries no member pins, so it is not
11
+ # bound by the strictest member's 3.12 floor like workbay-stack is).
12
+ requires-python = ">=3.11"
13
+ license = "MIT"
14
+
15
+ [project.urls]
16
+ Homepage = "https://github.com/darce/workbay"
17
+ Source = "https://github.com/darce/workbay/tree/main/packages/workbay"
18
+ Changelog = "https://github.com/darce/workbay/blob/main/packages/workbay/CHANGELOG.md"
19
+ Issues = "https://github.com/darce/workbay/issues"
20
+
21
+ [project.optional-dependencies]
22
+ dev = [
23
+ "pytest>=8",
24
+ ]
25
+
26
+ [tool.hatch.build.hooks.custom]
27
+ path = "hatch_build.py"
28
+
29
+ # Scrub-at-build shape mirrors workbay-stack: only-include the remapped IMPORT
30
+ # name (not src/<pkg>) so hatchling ships nothing raw and the hook's scrubbed
31
+ # force-include is the sole copy. Rebuild-safe via the sdist top-level <pkg>.
32
+ [tool.hatch.build.targets.wheel]
33
+ only-include = ["workbay"]
34
+
35
+ [tool.hatch.build.targets.sdist]
36
+ only-include = ["workbay", "hatch_build.py", "_scrub_core.py"]
37
+ exclude = ["**/__pycache__", "**/*.pyc"]
38
+
39
+ [tool.pytest.ini_options]
40
+ testpaths = ["tests"]
41
+ addopts = "-ra"
@@ -0,0 +1,8 @@
1
+ """Placeholder anchor module: ``workbay`` reserves the front-door name.
2
+
3
+ This distribution ships no runtime code yet. It reserves the ``workbay``
4
+ name on PyPI ahead of the single-command front-door installer. Install
5
+ ``workbay-stack`` for the published WorkBay runtime stack today.
6
+ """
7
+
8
+ __version__ = "0.0.0"