assurance-cli 0.2.2__tar.gz → 0.2.3__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.
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/PKG-INFO +8 -2
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/README.md +6 -0
- assurance_cli-0.2.3/assurance_cli/__init__.py +19 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/baseline.py +22 -2
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/cli.py +12 -2
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/PKG-INFO +8 -2
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/SOURCES.txt +2 -1
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/requires.txt +1 -1
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/pyproject.toml +2 -2
- assurance_cli-0.2.3/tests/test_version.py +33 -0
- assurance_cli-0.2.2/assurance_cli/__init__.py +0 -8
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/LICENSE +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/__main__.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/gather.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/paths.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/profile.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli/setdiff.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/dependency_links.txt +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/entry_points.txt +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/assurance_cli.egg-info/top_level.txt +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/setup.cfg +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/tests/test_cli.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/tests/test_read_only.py +0 -0
- {assurance_cli-0.2.2 → assurance_cli-0.2.3}/tests/test_setdiff.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: assurance-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: CLI for folder assurance checks — coverage, staleness, and baselines.
|
|
5
5
|
Author-email: "I-Ops Operations Intelligence, LLC" <hello@i-ops.dev>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: assurance-core>=0.3.
|
|
22
|
+
Requires-Dist: assurance-core>=0.3.3
|
|
23
23
|
Requires-Dist: openpyxl>=3.1
|
|
24
24
|
Provides-Extra: dev
|
|
25
25
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
@@ -56,6 +56,10 @@ No account · no API key · no network call · **no model decides any of it**
|
|
|
56
56
|
|
|
57
57
|
## Three commands
|
|
58
58
|
|
|
59
|
+
**`diff` is the general one.** `check` is the special case for a folder of
|
|
60
|
+
dated or numbered *tabular* files — if your files are `.md`, or named in a format it can't read, use
|
|
61
|
+
`diff` and declare the set yourself.
|
|
62
|
+
|
|
59
63
|
### `assurance diff` — any two sets of keys
|
|
60
64
|
|
|
61
65
|
```bash
|
|
@@ -99,6 +103,8 @@ every ratio so you can disagree with the denominator, not just the result.
|
|
|
99
103
|
|
|
100
104
|
```bash
|
|
101
105
|
assurance init ~/thesis-data
|
|
106
|
+
# Baseline written to ~/thesis-data/.assurance.json — 34 tabular files recorded.
|
|
107
|
+
|
|
102
108
|
# ... weeks pass, several people touch the folder ...
|
|
103
109
|
assurance check ~/thesis-data --against-baseline
|
|
104
110
|
```
|
|
@@ -29,6 +29,10 @@ No account · no API key · no network call · **no model decides any of it**
|
|
|
29
29
|
|
|
30
30
|
## Three commands
|
|
31
31
|
|
|
32
|
+
**`diff` is the general one.** `check` is the special case for a folder of
|
|
33
|
+
dated or numbered *tabular* files — if your files are `.md`, or named in a format it can't read, use
|
|
34
|
+
`diff` and declare the set yourself.
|
|
35
|
+
|
|
32
36
|
### `assurance diff` — any two sets of keys
|
|
33
37
|
|
|
34
38
|
```bash
|
|
@@ -72,6 +76,8 @@ every ratio so you can disagree with the denominator, not just the result.
|
|
|
72
76
|
|
|
73
77
|
```bash
|
|
74
78
|
assurance init ~/thesis-data
|
|
79
|
+
# Baseline written to ~/thesis-data/.assurance.json — 34 tabular files recorded.
|
|
80
|
+
|
|
75
81
|
# ... weeks pass, several people touch the folder ...
|
|
76
82
|
assurance check ~/thesis-data --against-baseline
|
|
77
83
|
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""assurance-cli — folder checks anyone can run without I-Ops.
|
|
2
|
+
|
|
3
|
+
Shared filesystem I/O (`paths`, `profile`, `gather`) lives in this package so `assurance-mcp` can
|
|
4
|
+
import it instead of duplicating the profiler. MCP depends on this package for gathering only; the
|
|
5
|
+
CLI does not depend on MCP. Two copies of the profiler is how they disagree.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Read from the installed distribution rather than typed here. A hardcoded literal is a second place
|
|
9
|
+
# the version lives, and the second place is the one that goes stale: these sat at "0.1.0" through
|
|
10
|
+
# five releases and were reported by an outside reviewer on 2026-08-29. One source of truth is
|
|
11
|
+
# `pyproject.toml`, and this reads what was actually installed from it.
|
|
12
|
+
from importlib.metadata import PackageNotFoundError, version as _version
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
__version__ = _version("assurance-cli")
|
|
16
|
+
except PackageNotFoundError: # running from a source tree that was never installed
|
|
17
|
+
__version__ = "0.0.0+unknown"
|
|
18
|
+
|
|
19
|
+
__all__ = ["__version__"]
|
|
@@ -19,7 +19,12 @@ def init_baseline(folder: str, *, update: bool = False) -> dict[str, Any]:
|
|
|
19
19
|
root = resolve_folder(folder)
|
|
20
20
|
path = root / BASELINE_NAME
|
|
21
21
|
if path.exists() and not update:
|
|
22
|
-
return {
|
|
22
|
+
return {
|
|
23
|
+
"written": False,
|
|
24
|
+
"path": str(path),
|
|
25
|
+
"reason": "baseline already exists; use --update",
|
|
26
|
+
"summary": f"A baseline already exists at {path}. Pass --update to overwrite it.",
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
entries: dict[str, Any] = {}
|
|
25
30
|
for file_path in sorted(root.rglob("*")):
|
|
@@ -50,7 +55,22 @@ def init_baseline(folder: str, *, update: bool = False) -> dict[str, Any]:
|
|
|
50
55
|
"files": entries,
|
|
51
56
|
}
|
|
52
57
|
path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
53
|
-
|
|
58
|
+
# A summary, because text mode renders one and prints nothing without it. `assurance init`
|
|
59
|
+
# wrote the file and then said nothing at all, so success was indistinguishable from a hung
|
|
60
|
+
# command — reported by an outside reviewer 2026-08-29. The count is the useful half: a baseline
|
|
61
|
+
# over zero files is a baseline that will never notice anything.
|
|
62
|
+
noun = "file" if len(entries) == 1 else "files"
|
|
63
|
+
return {
|
|
64
|
+
"written": True,
|
|
65
|
+
"path": str(path),
|
|
66
|
+
"file_count": len(entries),
|
|
67
|
+
"summary": (
|
|
68
|
+
f"Baseline written to {path} — {len(entries)} tabular {noun} recorded. "
|
|
69
|
+
"Re-check with `assurance check <folder> --against-baseline`."
|
|
70
|
+
if entries
|
|
71
|
+
else f"Baseline written to {path} — no tabular files found, so it records nothing."
|
|
72
|
+
),
|
|
73
|
+
}
|
|
54
74
|
|
|
55
75
|
|
|
56
76
|
def check_against_baseline(folder: str) -> dict[str, Any]:
|
|
@@ -14,14 +14,24 @@ from assurance_cli.setdiff import KeySpecError, diff_sets, format_diff
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def main(argv: list[str] | None = None) -> int:
|
|
17
|
-
parser = argparse.ArgumentParser(
|
|
17
|
+
parser = argparse.ArgumentParser(
|
|
18
|
+
prog="assurance",
|
|
19
|
+
description=(
|
|
20
|
+
"Did the job cover everything it was supposed to cover? Arithmetic, not models. "
|
|
21
|
+
"`diff` is the general command — it compares any two sets of keys. `check` is the "
|
|
22
|
+
"special case for a folder of dated or numbered files."
|
|
23
|
+
),
|
|
24
|
+
)
|
|
18
25
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
19
26
|
|
|
20
27
|
init_parser = sub.add_parser("init", help="Write .assurance.json baseline")
|
|
21
28
|
init_parser.add_argument("folder", help="Folder to baseline")
|
|
22
29
|
init_parser.add_argument("--update", action="store_true", help="Overwrite an existing baseline")
|
|
23
30
|
|
|
24
|
-
check_parser = sub.add_parser(
|
|
31
|
+
check_parser = sub.add_parser(
|
|
32
|
+
"check",
|
|
33
|
+
help="Special case: a folder of DATED or NUMBERED files (tabular). For anything else use `diff`",
|
|
34
|
+
)
|
|
25
35
|
check_parser.add_argument("folder", help="Folder to check")
|
|
26
36
|
check_parser.add_argument("--expect", choices=["monthly", "quarterly", "weekly", "daily", "numbered"])
|
|
27
37
|
check_parser.add_argument("--from", dest="from_point", metavar="FROM")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: assurance-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: CLI for folder assurance checks — coverage, staleness, and baselines.
|
|
5
5
|
Author-email: "I-Ops Operations Intelligence, LLC" <hello@i-ops.dev>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: assurance-core>=0.3.
|
|
22
|
+
Requires-Dist: assurance-core>=0.3.3
|
|
23
23
|
Requires-Dist: openpyxl>=3.1
|
|
24
24
|
Provides-Extra: dev
|
|
25
25
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
@@ -56,6 +56,10 @@ No account · no API key · no network call · **no model decides any of it**
|
|
|
56
56
|
|
|
57
57
|
## Three commands
|
|
58
58
|
|
|
59
|
+
**`diff` is the general one.** `check` is the special case for a folder of
|
|
60
|
+
dated or numbered *tabular* files — if your files are `.md`, or named in a format it can't read, use
|
|
61
|
+
`diff` and declare the set yourself.
|
|
62
|
+
|
|
59
63
|
### `assurance diff` — any two sets of keys
|
|
60
64
|
|
|
61
65
|
```bash
|
|
@@ -99,6 +103,8 @@ every ratio so you can disagree with the denominator, not just the result.
|
|
|
99
103
|
|
|
100
104
|
```bash
|
|
101
105
|
assurance init ~/thesis-data
|
|
106
|
+
# Baseline written to ~/thesis-data/.assurance.json — 34 tabular files recorded.
|
|
107
|
+
|
|
102
108
|
# ... weeks pass, several people touch the folder ...
|
|
103
109
|
assurance check ~/thesis-data --against-baseline
|
|
104
110
|
```
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "assurance-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "CLI for folder assurance checks — coverage, staleness, and baselines."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
11
11
|
authors = [{ name = "I-Ops Operations Intelligence, LLC", email = "hello@i-ops.dev" }]
|
|
12
12
|
requires-python = ">=3.10"
|
|
13
13
|
dependencies = [
|
|
14
|
-
"assurance-core>=0.3.
|
|
14
|
+
"assurance-core>=0.3.3",
|
|
15
15
|
"openpyxl>=3.1",
|
|
16
16
|
]
|
|
17
17
|
keywords = ["cli", "ai-agents", "governance", "auditing", "assurance", "reproducibility"]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""`__version__` must agree with `pyproject.toml`.
|
|
2
|
+
|
|
3
|
+
Both were hardcoded at "0.1.0" and sat there through five releases, so anyone reading
|
|
4
|
+
`assurance_cli.__version__` was told the wrong thing. Reported by an outside reviewer 2026-08-29.
|
|
5
|
+
|
|
6
|
+
They now read the installed distribution's metadata, which makes `pyproject.toml` the only place a
|
|
7
|
+
version is written. This is the guard that the two agree: CI installs the package immediately before
|
|
8
|
+
running the suite, so the metadata is current there. Locally it can lag a version behind after an
|
|
9
|
+
edit — `pip install -e .` resyncs it, and a lagging editable install is exactly the drift worth
|
|
10
|
+
being told about.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import re
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
import assurance_cli
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _declared() -> str:
|
|
22
|
+
text = (Path(__file__).resolve().parent.parent / "pyproject.toml").read_text(encoding="utf-8")
|
|
23
|
+
match = re.search(r'^version = "([^"]+)"', text, re.MULTILINE)
|
|
24
|
+
assert match, "pyproject.toml has no version"
|
|
25
|
+
return match.group(1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_version_agrees_with_pyproject() -> None:
|
|
29
|
+
assert assurance_cli.__version__ == _declared()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_version_is_not_a_placeholder() -> None:
|
|
33
|
+
assert assurance_cli.__version__ != "0.0.0+unknown"
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"""assurance-cli — folder checks anyone can run without I-Ops.
|
|
2
|
-
|
|
3
|
-
Shared filesystem I/O (`paths`, `profile`, `gather`) lives in this package so `assurance-mcp` can
|
|
4
|
-
import it instead of duplicating the profiler. MCP depends on this package for gathering only; the
|
|
5
|
-
CLI does not depend on MCP. Two copies of the profiler is how they disagree.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
__version__ = "0.1.0"
|
|
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
|