devready-cli 0.2.0__py3-none-any.whl → 1.0.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.
- devready/__init__.py +1 -1
- devready/checks/platform_checks.py +108 -0
- devready/checks/project.py +3 -2
- devready/cli.py +4 -1
- devready/explain.py +4 -0
- devready/runner.py +2 -1
- {devready_cli-0.2.0.dist-info → devready_cli-1.0.0.dist-info}/METADATA +5 -5
- {devready_cli-0.2.0.dist-info → devready_cli-1.0.0.dist-info}/RECORD +11 -10
- {devready_cli-0.2.0.dist-info → devready_cli-1.0.0.dist-info}/WHEEL +0 -0
- {devready_cli-0.2.0.dist-info → devready_cli-1.0.0.dist-info}/entry_points.txt +0 -0
- {devready_cli-0.2.0.dist-info → devready_cli-1.0.0.dist-info}/licenses/LICENSE +0 -0
devready/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""OS-specific pain points, each checked only when the project makes it relevant.
|
|
2
|
+
|
|
3
|
+
Windows: long paths, PowerShell execution policy (blocks npm.ps1), git line endings.
|
|
4
|
+
macOS/Linux: a compiler toolchain when the project looks like it builds native code.
|
|
5
|
+
Read-only; fixed argv only.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import shutil
|
|
11
|
+
import sys
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from devready.checks.extras import _run
|
|
16
|
+
from devready.models import Result, Status
|
|
17
|
+
|
|
18
|
+
NATIVE_HINTS = ("binding.gyp", "setup.py", "Gemfile", "Cargo.toml")
|
|
19
|
+
BLOCKING_POLICIES = {"Restricted", "AllSigned"}
|
|
20
|
+
KNOWN_POLICIES = BLOCKING_POLICIES | {"RemoteSigned", "Unrestricted", "Bypass", "Undefined"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _long_paths_enabled() -> bool | None:
|
|
24
|
+
try:
|
|
25
|
+
import winreg
|
|
26
|
+
|
|
27
|
+
with winreg.OpenKey(
|
|
28
|
+
winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\FileSystem"
|
|
29
|
+
) as key:
|
|
30
|
+
return bool(winreg.QueryValueEx(key, "LongPathsEnabled")[0])
|
|
31
|
+
except (ImportError, OSError):
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _windows(root: Path, run: Callable, which: Callable, long_paths: Callable) -> list[Result]:
|
|
36
|
+
out: list[Result] = []
|
|
37
|
+
if (root / "package.json").is_file():
|
|
38
|
+
if long_paths() is False:
|
|
39
|
+
out.append(
|
|
40
|
+
Result(
|
|
41
|
+
"platform.long_paths",
|
|
42
|
+
"Long paths",
|
|
43
|
+
Status.WARN,
|
|
44
|
+
"Windows long path support is off; deep node_modules trees can fail",
|
|
45
|
+
"Enable LongPathsEnabled (administrator) and git's core.longpaths.",
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
ps = which("powershell")
|
|
49
|
+
p = (
|
|
50
|
+
run([ps, "-NoProfile", "-NonInteractive", "-Command", "Get-ExecutionPolicy"])
|
|
51
|
+
if ps
|
|
52
|
+
else None
|
|
53
|
+
)
|
|
54
|
+
policy = p.stdout.strip() if p is not None and p.returncode == 0 else ""
|
|
55
|
+
if policy in BLOCKING_POLICIES:
|
|
56
|
+
out.append(
|
|
57
|
+
Result(
|
|
58
|
+
"platform.exec_policy",
|
|
59
|
+
"PowerShell policy",
|
|
60
|
+
Status.WARN,
|
|
61
|
+
f"PowerShell policy is {policy}; npm/pnpm .ps1 scripts will be blocked",
|
|
62
|
+
"Use cmd, or allow local scripts for your user: "
|
|
63
|
+
"Set-ExecutionPolicy -Scope CurrentUser RemoteSigned",
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
git = which("git")
|
|
67
|
+
if git and (root / ".git").exists() and not (root / ".gitattributes").is_file():
|
|
68
|
+
p = run([git, "-C", str(root), "config", "--get", "core.autocrlf"])
|
|
69
|
+
if p is not None and not p.stdout.strip():
|
|
70
|
+
out.append(
|
|
71
|
+
Result(
|
|
72
|
+
"platform.autocrlf",
|
|
73
|
+
"Line endings",
|
|
74
|
+
Status.WARN,
|
|
75
|
+
"core.autocrlf is unset and the repo has no .gitattributes",
|
|
76
|
+
"Add a .gitattributes with line-ending rules, or set core.autocrlf.",
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
return out
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _build_tools(root: Path, plat: str, run: Callable, which: Callable) -> list[Result]:
|
|
83
|
+
if not any((root / n).is_file() for n in NATIVE_HINTS):
|
|
84
|
+
return []
|
|
85
|
+
cid, title = "platform.build_tools", "Build tools"
|
|
86
|
+
if plat == "darwin":
|
|
87
|
+
xs = which("xcode-select")
|
|
88
|
+
p = run([xs, "-p"]) if xs else None
|
|
89
|
+
ok = p is not None and p.returncode == 0
|
|
90
|
+
fix = "Install the Xcode Command Line Tools: xcode-select --install"
|
|
91
|
+
else:
|
|
92
|
+
ok = any(which(c) for c in ("cc", "gcc", "clang")) and bool(which("make"))
|
|
93
|
+
fix = "Install a C compiler and make (for example your distro's build-essential)."
|
|
94
|
+
if ok:
|
|
95
|
+
return [Result(cid, title, Status.PASS, "compiler toolchain found")]
|
|
96
|
+
return [Result(cid, title, Status.WARN, "no compiler toolchain found for native builds", fix)]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def check_platform(
|
|
100
|
+
root: Path,
|
|
101
|
+
plat: str = sys.platform,
|
|
102
|
+
run: Callable = _run,
|
|
103
|
+
which: Callable = shutil.which,
|
|
104
|
+
long_paths: Callable = _long_paths_enabled,
|
|
105
|
+
) -> list[Result]:
|
|
106
|
+
if plat == "win32":
|
|
107
|
+
return _windows(root, run, which, long_paths)
|
|
108
|
+
return _build_tools(root, plat, run, which)
|
devready/checks/project.py
CHANGED
|
@@ -11,7 +11,7 @@ import re
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
13
|
from devready.models import Result, Status
|
|
14
|
-
from devready.versions import
|
|
14
|
+
from devready.versions import Version, parse_version, satisfies
|
|
15
15
|
|
|
16
16
|
MAX_BYTES = 1_000_000
|
|
17
17
|
|
|
@@ -25,7 +25,8 @@ def _read(path: Path) -> str | None:
|
|
|
25
25
|
def _compare(
|
|
26
26
|
check_id: str, title: str, source: str, spec: str, installed: Version | None, miss: Status
|
|
27
27
|
) -> Result:
|
|
28
|
-
|
|
28
|
+
# Echo only specs the matcher fully parses: plain words can pass SAFE_SPEC but are not versions.
|
|
29
|
+
shown = spec if satisfies((0, 0, 0), spec) is not None else "(unrecognized)"
|
|
29
30
|
if installed is None:
|
|
30
31
|
return Result(check_id, title, Status.SKIP, f"{source} wants {shown}; tool not found")
|
|
31
32
|
ok = satisfies(installed, spec)
|
devready/cli.py
CHANGED
|
@@ -16,7 +16,10 @@ EXIT_OK, EXIT_FAILED, EXIT_USAGE, EXIT_INTERNAL = 0, 1, 2, 3
|
|
|
16
16
|
|
|
17
17
|
def _text(results: list[Result]) -> str:
|
|
18
18
|
lines = ["DevReady - Environment Check", ""]
|
|
19
|
-
|
|
19
|
+
for r in results:
|
|
20
|
+
lines.append(f"[{r.status.value.upper():<5}] {r.title:<12} {r.summary}")
|
|
21
|
+
if r.status is not Status.PASS and r.suggestion:
|
|
22
|
+
lines.append(f" {r.suggestion}")
|
|
20
23
|
lines += ["", "No changes were made to your system."]
|
|
21
24
|
return "\n".join(lines)
|
|
22
25
|
|
devready/explain.py
CHANGED
|
@@ -47,4 +47,8 @@ EXPLANATIONS = {
|
|
|
47
47
|
"project.node.config": "require.node in .devready.json is a hard requirement (fails when unmet).",
|
|
48
48
|
"project.python.config": "require.python in .devready.json is a hard requirement (fails when unmet).",
|
|
49
49
|
"project.env.required": "Variable NAMES listed under env in .devready.json must be set in the environment. Values are never read.",
|
|
50
|
+
"platform.long_paths": "Windows only, when package.json exists. Without LongPathsEnabled, deeply nested node_modules paths can exceed 260 characters and installs fail.",
|
|
51
|
+
"platform.exec_policy": "Windows only, when package.json exists. A Restricted or AllSigned PowerShell policy blocks npm.ps1 ('running scripts is disabled'). Use cmd or relax the policy for your user.",
|
|
52
|
+
"platform.autocrlf": "Windows only, in a git repo without .gitattributes. Unset core.autocrlf can flip line endings between Windows and Linux/macOS contributors.",
|
|
53
|
+
"platform.build_tools": "macOS/Linux, when the project has binding.gyp, setup.py, Gemfile or Cargo.toml. Native dependencies need a compiler (Xcode CLT on macOS, cc/gcc/clang and make on Linux).",
|
|
50
54
|
}
|
devready/runner.py
CHANGED
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from devready.checks.config import check_config, load_config
|
|
7
7
|
from devready.checks.extras import check_disk, check_docker, check_git_identity
|
|
8
8
|
from devready.checks.health import check_health
|
|
9
|
+
from devready.checks.platform_checks import check_platform
|
|
9
10
|
from devready.checks.project import check_project
|
|
10
11
|
from devready.checks.python_check import check_python
|
|
11
12
|
from devready.checks.runtimes import check_runtimes
|
|
@@ -27,7 +28,7 @@ def run_checks(root: Path) -> list[Result]:
|
|
|
27
28
|
results += check_git_identity()
|
|
28
29
|
results += check_project(root, versions["node"], platform.python_version())
|
|
29
30
|
results += check_runtimes(root) + check_health(root)
|
|
30
|
-
results += check_docker(root) + check_disk(root)
|
|
31
|
+
results += check_docker(root) + check_platform(root) + check_disk(root)
|
|
31
32
|
results += (
|
|
32
33
|
[cfg_error] if cfg_error else check_config(cfg, versions["node"], platform.python_version())
|
|
33
34
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: devready-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A local-first, read-only CLI that checks a project's environment requirements against what is installed.
|
|
5
5
|
Project-URL: Homepage, https://devready-ten.vercel.app/
|
|
6
6
|
Project-URL: Repository, https://github.com/Evalogical-Inc/devReady
|
|
@@ -9,7 +9,7 @@ Author: Evalogical Inc
|
|
|
9
9
|
License-Expression: MIT
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
Keywords: ai-agents,claude-code,cli,codex,developer-tools,doctor,environment,mcp,nvmrc,onboarding,preflight
|
|
12
|
-
Classifier: Development Status ::
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
@@ -37,7 +37,7 @@ Built for humans, CI, and AI coding agents (Claude Code, Codex, any MCP client).
|
|
|
37
37
|
[](LICENSE)
|
|
38
38
|

|
|
39
39
|

|
|
40
|
-

|
|
41
41
|
|
|
42
42
|
</div>
|
|
43
43
|
|
|
@@ -193,9 +193,9 @@ args = ["--from", "devready-cli", "devready", "mcp"]
|
|
|
193
193
|
- Environment variable values are never read into output. Nothing leaves your machine.
|
|
194
194
|
- A passing report does **not** guarantee your project builds.
|
|
195
195
|
|
|
196
|
-
See [SECURITY.md](SECURITY.md) to report a vulnerability.
|
|
196
|
+
See [docs/security.md](docs/security.md) for the model, [docs/versioning.md](docs/versioning.md) for what stays stable, [docs/checks.md](docs/checks.md) for every check, and [SECURITY.md](SECURITY.md) to report a vulnerability.
|
|
197
197
|
|
|
198
|
-
## Limitations
|
|
198
|
+
## Limitations
|
|
199
199
|
|
|
200
200
|
- Checks today: Python, Git (+ identity set), Node.js, npm, project pins (`.nvmrc`, `.node-version`, `.python-version`, `.tool-versions`, `package.json` engines, `pyproject.toml` requires-python), `.env.example` vs `.env` key names, Docker CLI + daemon (only when the project has a Dockerfile/compose file), free disk space, and (only when the project declares them) Go, Ruby, Java, Rust, .NET, pnpm, Yarn and Bun pins, `.env` not git-ignored, `node_modules` vs lockfile, and declared ports already in use.
|
|
201
201
|
- The version-range matcher covers common npm/PEP 440 syntax; pre-releases and exotic ranges report `skip` rather than guess.
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
devready/__init__.py,sha256=
|
|
1
|
+
devready/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
|
2
2
|
devready/__main__.py,sha256=c-4qpm2SKZs1nENGzSnPnChNTo8iMwjY0XaPyAApn4I,60
|
|
3
3
|
devready/baseline.py,sha256=pfVzZ695bLEiSWKUBK0PNDp1S2UWTWj9lfUCDAsVS4g,1524
|
|
4
|
-
devready/cli.py,sha256=
|
|
5
|
-
devready/explain.py,sha256=
|
|
4
|
+
devready/cli.py,sha256=oetC_jJlXk4SlyB_oKqi5XYwDouFBjeT5Ya9vUmSfXc,4736
|
|
5
|
+
devready/explain.py,sha256=zVRUNzqtVdO-EcC6rUCLPuwswbMlo59xzncCBiSvi1M,5889
|
|
6
6
|
devready/formats.py,sha256=akN62ouKLeZQB6POcXNzINYKHwpUd4im0n2-9rtB8eE,3129
|
|
7
7
|
devready/mcp_server.py,sha256=zVm89kZL_-pZwTSWkt6rxKonytNklUSa0RCQkX0lzFk,3177
|
|
8
8
|
devready/models.py,sha256=KyGp3ie2LVQmuSfzLV8tbEH_hJyU5-Vi11d0JcQPAuE,646
|
|
9
|
-
devready/runner.py,sha256=
|
|
9
|
+
devready/runner.py,sha256=yjd7cdH0G-ksUD9viJ6coEB0iug7CazqWBQPlIW2lLU,1538
|
|
10
10
|
devready/versions.py,sha256=dXKIl1-qvcfadRNaCURMoftwx7YtadDZ-YfUp-85XZc,2112
|
|
11
11
|
devready/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
devready/checks/config.py,sha256=SGyIot_QXmZtPLIybtxnyJEFL2aV1NemSqX_fXbFI6A,3471
|
|
13
13
|
devready/checks/extras.py,sha256=pDJbFaAwjkLc92tcFagOmj-5c_vMx32_MtYa_DBfCz8,3428
|
|
14
14
|
devready/checks/health.py,sha256=woaaUL2TJ_biRuiStXqJtnvPua_y69bW2quNPlwd7tQ,4235
|
|
15
|
-
devready/checks/
|
|
15
|
+
devready/checks/platform_checks.py,sha256=_ayTrJalFf4k5As0jq-t8GDh4IOMmgZJJdhKU4rIujQ,4113
|
|
16
|
+
devready/checks/project.py,sha256=JTeSmkuz4Z7Jy5aQnP4o4TcdhQYRZfGaGhj6f0NslXw,6090
|
|
16
17
|
devready/checks/python_check.py,sha256=uQCd-N0LEwt9R5gwZm5mlYiPMST1JXVDNQOdZ5xpako,328
|
|
17
18
|
devready/checks/runtimes.py,sha256=OiC5LEhmfkiMseP2PbQS6Dc6TC2JhYNICU6LmdFFvqk,4446
|
|
18
19
|
devready/checks/tools.py,sha256=AiL9TdIREmY7tEkkpt62DELKuJ2lhu3XcA2yGak9QkA,1616
|
|
19
|
-
devready_cli-0.
|
|
20
|
-
devready_cli-0.
|
|
21
|
-
devready_cli-0.
|
|
22
|
-
devready_cli-0.
|
|
23
|
-
devready_cli-0.
|
|
20
|
+
devready_cli-1.0.0.dist-info/METADATA,sha256=Bl4J-zxCaKppIWKFH-iFOxw0WNCOxXMYM_LgYuUhJVk,10708
|
|
21
|
+
devready_cli-1.0.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
22
|
+
devready_cli-1.0.0.dist-info/entry_points.txt,sha256=7oAecSWtsIt7qLOP8PipOeDqhXCkEJat0oxhD4T1RpY,47
|
|
23
|
+
devready_cli-1.0.0.dist-info/licenses/LICENSE,sha256=S_AQsEw289FIsOgT-OPWL5JZeV8nn5kicwEq0r9qu7s,1071
|
|
24
|
+
devready_cli-1.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|