napkinstack 0.9.3__tar.gz → 0.9.4__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.
- {napkinstack-0.9.3 → napkinstack-0.9.4}/PKG-INFO +4 -4
- {napkinstack-0.9.3 → napkinstack-0.9.4}/README.md +3 -3
- {napkinstack-0.9.3 → napkinstack-0.9.4}/pyproject.toml +2 -2
- {napkinstack-0.9.3 → napkinstack-0.9.4}/pyproject.toml.orig +2 -2
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/__init__.py +2 -2
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/provenance.py +19 -1
- {napkinstack-0.9.3 → napkinstack-0.9.4}/LICENSE +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/assurance.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/cli.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/compat.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/discovery.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/doctor.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/__init__.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/boundaries.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/hygiene.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/manifests.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/plan.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/fitness/pr_scope.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/landed.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/modules.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/project.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/pull_request.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/settings.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/skills.py +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/contracts/AGENTS.md +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/contracts/MANIFEST.yaml +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/contracts/README.md +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/contracts/docs/runbook.md +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/contracts/tests/.gitkeep +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/module/AGENTS.md +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/module/MANIFEST.yaml +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/module/README.md +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/module/src/.gitkeep +0 -0
- {napkinstack-0.9.3 → napkinstack-0.9.4}/src/napkinstack/templates/module/tests/.gitkeep +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: napkinstack
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Summary: Engineering framework for several teams and their agents working in one repository: modules, contracts, guardrails in CI.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -20,7 +20,7 @@ modules, contracts, guardrails in CI. On the Django or Rails model, one command
|
|
|
20
20
|
the project, which then receives new versions on demand; no application stack is imposed.
|
|
21
21
|
Positioning and vocabulary: [`PRODUCT.md`](PRODUCT.md) §1.
|
|
22
22
|
|
|
23
|
-
> **Status: v0.9.
|
|
23
|
+
> **Status: v0.9.4, published** on [PyPI](https://pypi.org/project/napkinstack/).
|
|
24
24
|
> What each version changes, engine and project apart: [`CHANGELOG.md`](CHANGELOG.md).
|
|
25
25
|
> What is open: [`docs/governance/workstreams.md`](docs/governance/workstreams.md).
|
|
26
26
|
|
|
@@ -84,8 +84,8 @@ To try it without installing anything, or to install it from this repository ins
|
|
|
84
84
|
registry — always pinned to a release tag:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.9.
|
|
88
|
-
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.9.
|
|
87
|
+
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.9.4" nstack init my-project
|
|
88
|
+
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.9.4"
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
**Two channels, one published artefact.** The registry publishes: the PyPI artefact of a
|
|
@@ -5,7 +5,7 @@ modules, contracts, guardrails in CI. On the Django or Rails model, one command
|
|
|
5
5
|
the project, which then receives new versions on demand; no application stack is imposed.
|
|
6
6
|
Positioning and vocabulary: [`PRODUCT.md`](PRODUCT.md) §1.
|
|
7
7
|
|
|
8
|
-
> **Status: v0.9.
|
|
8
|
+
> **Status: v0.9.4, published** on [PyPI](https://pypi.org/project/napkinstack/).
|
|
9
9
|
> What each version changes, engine and project apart: [`CHANGELOG.md`](CHANGELOG.md).
|
|
10
10
|
> What is open: [`docs/governance/workstreams.md`](docs/governance/workstreams.md).
|
|
11
11
|
|
|
@@ -69,8 +69,8 @@ To try it without installing anything, or to install it from this repository ins
|
|
|
69
69
|
registry — always pinned to a release tag:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.9.
|
|
73
|
-
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.9.
|
|
72
|
+
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.9.4" nstack init my-project
|
|
73
|
+
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.9.4"
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
**Two channels, one published artefact.** The registry publishes: the PyPI artefact of a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "napkinstack"
|
|
3
|
-
version = "0.9.
|
|
3
|
+
version = "0.9.4"
|
|
4
4
|
description = "Engineering framework for several teams and their agents working in one repository: modules, contracts, guardrails in CI."
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
license = "MIT"
|
|
@@ -27,5 +27,5 @@ dev = ["pytest==9.1.1"]
|
|
|
27
27
|
required-version = ">=0.12.14,<0.13"
|
|
28
28
|
|
|
29
29
|
[build-system]
|
|
30
|
-
requires = ["uv_build>=0.12.14,<0.
|
|
30
|
+
requires = ["uv_build>=0.12.14,<0.14"]
|
|
31
31
|
build-backend = "uv_build"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "napkinstack"
|
|
3
|
-
version = "0.9.
|
|
3
|
+
version = "0.9.4"
|
|
4
4
|
description = "Engineering framework for several teams and their agents working in one repository: modules, contracts, guardrails in CI."
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
license = "MIT"
|
|
@@ -23,5 +23,5 @@ dev = ["pytest==9.1.1"]
|
|
|
23
23
|
required-version = ">=0.12.14,<0.13"
|
|
24
24
|
|
|
25
25
|
[build-system]
|
|
26
|
-
requires = ["uv_build>=0.12.14,<0.
|
|
26
|
+
requires = ["uv_build>=0.12.14,<0.14"]
|
|
27
27
|
build-backend = "uv_build"
|
|
@@ -14,6 +14,7 @@ import importlib.metadata
|
|
|
14
14
|
import json
|
|
15
15
|
import re
|
|
16
16
|
import subprocess
|
|
17
|
+
import tomllib
|
|
17
18
|
from pathlib import Path
|
|
18
19
|
from urllib.parse import urlparse
|
|
19
20
|
from urllib.request import url2pathname
|
|
@@ -24,6 +25,23 @@ ANSWERS = ".copier-answers.yml"
|
|
|
24
25
|
PUBLISHED = re.compile(r"v\d+\.\d+\.\d+")
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
def version() -> str:
|
|
29
|
+
"""The engine's version. An editable install's metadata is written once, at install, and the
|
|
30
|
+
checkout moves on: its own pyproject.toml says the version its source is at (D122)."""
|
|
31
|
+
distribution = importlib.metadata.distribution("napkinstack")
|
|
32
|
+
try:
|
|
33
|
+
data = json.loads(distribution.read_text("direct_url.json") or "{}")
|
|
34
|
+
except json.JSONDecodeError: # read at import: a damaged record never stops the engine
|
|
35
|
+
return distribution.version
|
|
36
|
+
if data.get("dir_info", {}).get("editable"):
|
|
37
|
+
source = Path(url2pathname(urlparse(data.get("url", "")).path)) / "pyproject.toml"
|
|
38
|
+
try:
|
|
39
|
+
return str(tomllib.loads(source.read_text(encoding="utf-8"))["project"]["version"])
|
|
40
|
+
except (OSError, KeyError, tomllib.TOMLDecodeError):
|
|
41
|
+
pass
|
|
42
|
+
return distribution.version
|
|
43
|
+
|
|
44
|
+
|
|
27
45
|
def engine() -> tuple[str, str | None]:
|
|
28
46
|
"""(version, origin): origin is None for a version installed from the registry."""
|
|
29
47
|
distribution = importlib.metadata.distribution("napkinstack")
|
|
@@ -44,7 +62,7 @@ def engine() -> tuple[str, str | None]:
|
|
|
44
62
|
path = Path(url2pathname(urlparse(data.get("url", "")).path))
|
|
45
63
|
commit = subprocess.run(["git", "describe", "--always", "--dirty"], cwd=path,
|
|
46
64
|
capture_output=True, text=True).stdout.strip() if path.is_dir() else ""
|
|
47
|
-
return
|
|
65
|
+
return version(), f"a local checkout at {commit or 'an unknown commit'}"
|
|
48
66
|
|
|
49
67
|
|
|
50
68
|
def recorded(root: Path) -> str | None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|