driverclient 0.2.6__tar.gz → 0.2.7__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.
- {driverclient-0.2.6 → driverclient-0.2.7}/PKG-INFO +1 -1
- {driverclient-0.2.6 → driverclient-0.2.7}/pyproject.toml +1 -1
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/__init__.py +1 -1
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/main.py +2 -0
- driverclient-0.2.7/src/driverclient/ops/diagnose.py +158 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/.gitignore +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/README.md +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/__main__.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/config.json +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/config.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/core/__init__.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/core/hardware.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/core/http.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/core/hwid.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/core/proc.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/events.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/__init__.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/automate.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/capture.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/install.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/resolve.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/ops/scan.py +0 -0
- {driverclient-0.2.6 → driverclient-0.2.7}/src/driverclient/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: driverclient
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Driver Server client with an embeddable connector for config injection at runtime.
|
|
5
5
|
Project-URL: Homepage, https://example.com/driverclient
|
|
6
6
|
Author-email: Raja Sanaullah <sanaullah@99technologies.com>
|
|
@@ -26,6 +26,7 @@ from driverclient.ops.capture import (
|
|
|
26
26
|
wu_full,
|
|
27
27
|
wu_update,
|
|
28
28
|
)
|
|
29
|
+
from driverclient.ops.diagnose import run_diagnostics
|
|
29
30
|
from driverclient.ops.install import resolve_and_install
|
|
30
31
|
from driverclient.ops.resolve import resolve
|
|
31
32
|
from driverclient.ops.scan import scan
|
|
@@ -40,6 +41,7 @@ _OPERATIONS: dict[str, callable] = {
|
|
|
40
41
|
"wu-update": wu_update,
|
|
41
42
|
"wu-full": wu_full,
|
|
42
43
|
"automate": run_automation,
|
|
44
|
+
"test": run_diagnostics,
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
client/ops/diagnose.py — the `test` command. READ-ONLY.
|
|
3
|
+
|
|
4
|
+
Shows, side by side and per device:
|
|
5
|
+
• what the machine detects (scan: devices, HWIDs, driver_name, versions)
|
|
6
|
+
• what the repo serves back (resolve: to_install / already_current /
|
|
7
|
+
not_found / stale)
|
|
8
|
+
• what capture-delta WOULD harvest, and how that compares to capture-all.
|
|
9
|
+
|
|
10
|
+
No install, no upload, no Windows Update — nothing changes. Use it to verify
|
|
11
|
+
the identity/matching end to end and to see exactly why capture-delta uploads
|
|
12
|
+
fewer packages than capture-all.
|
|
13
|
+
|
|
14
|
+
Public API:
|
|
15
|
+
run_diagnostics() -> dict
|
|
16
|
+
"""
|
|
17
|
+
from driverclient import events
|
|
18
|
+
from driverclient.config import get
|
|
19
|
+
from driverclient.core import hwid as hwid_mod
|
|
20
|
+
from driverclient.ops.capture import _enumerate_all_packages, _find_installed_packages_for_hwids
|
|
21
|
+
from driverclient.ops.resolve import resolve
|
|
22
|
+
from driverclient.ops.scan import scan
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _short(name: str, n: int = 44) -> str:
|
|
26
|
+
name = name or ""
|
|
27
|
+
return name if len(name) <= n else name[: n - 1] + "…"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _verdict_for(dev, matched: dict, nf_set: set, stale_set: set):
|
|
31
|
+
"""Classify one device against the repo response."""
|
|
32
|
+
mids = hwid_mod.matchable_ids(dev.hwids)
|
|
33
|
+
for mid in mids:
|
|
34
|
+
if mid in matched:
|
|
35
|
+
return "INSTALL", matched[mid], mid
|
|
36
|
+
for mid in mids:
|
|
37
|
+
if mid in stale_set:
|
|
38
|
+
return "STALE", "", mid
|
|
39
|
+
for mid in mids:
|
|
40
|
+
if mid in nf_set:
|
|
41
|
+
return "NOT_IN_REPO", "", mid
|
|
42
|
+
if dev.has_driver:
|
|
43
|
+
return "CURRENT/COVERED", "", (mids[0] if mids else "")
|
|
44
|
+
return "NO_DRIVER/SW", "", (mids[0] if mids else "")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def run_diagnostics() -> dict:
|
|
48
|
+
cfg = get()
|
|
49
|
+
events.start("test", "=" * 64)
|
|
50
|
+
events.start("test", " TEST — scan vs repo (READ-ONLY: no install / upload / WU)")
|
|
51
|
+
events.start("test", "=" * 64)
|
|
52
|
+
|
|
53
|
+
scan_result = scan(force=True)
|
|
54
|
+
resolve_result = resolve(force=False) # consumes the fresh scan just done
|
|
55
|
+
|
|
56
|
+
drivers = resolve_result.drivers
|
|
57
|
+
not_found = list(resolve_result.not_found)
|
|
58
|
+
stale = list(getattr(resolve_result, "stale", []) or [])
|
|
59
|
+
|
|
60
|
+
matched: dict[str, str] = {}
|
|
61
|
+
for d in drivers:
|
|
62
|
+
h = d.get("hwid")
|
|
63
|
+
if h:
|
|
64
|
+
matched[hwid_mod.canonicalize(h)] = d.get("package_id", "?")
|
|
65
|
+
nf_set = {hwid_mod.canonicalize(h) for h in not_found}
|
|
66
|
+
stale_set = {hwid_mod.canonicalize(h) for h in stale}
|
|
67
|
+
|
|
68
|
+
# ── SCAN side ────────────────────────────────────────────────────────
|
|
69
|
+
events.progress("test", "")
|
|
70
|
+
events.progress(
|
|
71
|
+
"test",
|
|
72
|
+
f"── SCAN (system detected) ── {scan_result.vendor} {scan_result.model} | "
|
|
73
|
+
f"OS {scan_result.os_build} | machine {scan_result.machine_id}",
|
|
74
|
+
)
|
|
75
|
+
events.progress(
|
|
76
|
+
"test",
|
|
77
|
+
f" {len(scan_result.devices)} devices | {len(scan_result.has_driver)} with driver | "
|
|
78
|
+
f"{len(scan_result.missing_driver)} without | "
|
|
79
|
+
f"{len(scan_result.installed_versions)} installed-version entries",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# ── RESOLVE side ─────────────────────────────────────────────────────
|
|
83
|
+
events.progress("test", "")
|
|
84
|
+
events.progress("test", f"── RESOLVE (repo {cfg.get('local_repo_url')}) ──")
|
|
85
|
+
events.progress(
|
|
86
|
+
"test",
|
|
87
|
+
f" to_install={len(drivers)} already_current={resolve_result.already_current} "
|
|
88
|
+
f"not_found={len(not_found)} stale={len(stale)}",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# ── Per-device cross reference ───────────────────────────────────────
|
|
92
|
+
order = ["INSTALL", "STALE", "NOT_IN_REPO", "CURRENT/COVERED", "NO_DRIVER/SW"]
|
|
93
|
+
buckets: dict[str, list[str]] = {k: [] for k in order}
|
|
94
|
+
for dev in scan_result.devices:
|
|
95
|
+
v, pkg, mid = _verdict_for(dev, matched, nf_set, stale_set)
|
|
96
|
+
drv = "inbox" if dev.is_inbox else (dev.driver_name or "no-drv")
|
|
97
|
+
ver = f" v{dev.installed_version}" if dev.installed_version else ""
|
|
98
|
+
line = f"{_short(dev.device_name)} [{dev.class_name or '-'}] {drv}{ver}"
|
|
99
|
+
if v == "INSTALL":
|
|
100
|
+
line += f" → repo pkg {pkg}"
|
|
101
|
+
elif mid:
|
|
102
|
+
line += f" ({mid})"
|
|
103
|
+
buckets[v].append(line)
|
|
104
|
+
|
|
105
|
+
events.progress("test", "")
|
|
106
|
+
events.progress("test", "── PER-DEVICE (scan ⟷ repo) ──")
|
|
107
|
+
for v in order:
|
|
108
|
+
events.progress("test", f" [{v}] {len(buckets[v])}")
|
|
109
|
+
for line in buckets[v]:
|
|
110
|
+
events.progress("test", f" {line}")
|
|
111
|
+
|
|
112
|
+
# ── Harvest preview vs capture-all ───────────────────────────────────
|
|
113
|
+
delta = set(not_found) | set(stale)
|
|
114
|
+
to_harvest = _find_installed_packages_for_hwids(delta, scan_result, cfg)
|
|
115
|
+
all_pkgs = _enumerate_all_packages(cfg)
|
|
116
|
+
|
|
117
|
+
events.progress("test", "")
|
|
118
|
+
events.progress(
|
|
119
|
+
"test",
|
|
120
|
+
f"── HARVEST PREVIEW — capture-delta WOULD upload {len(to_harvest)} OEM package(s) ──",
|
|
121
|
+
)
|
|
122
|
+
for p in to_harvest:
|
|
123
|
+
events.progress(
|
|
124
|
+
"test",
|
|
125
|
+
f" {p.get('published_name')} "
|
|
126
|
+
f"({p.get('provider_name', '?')} {p.get('class_name', '')})",
|
|
127
|
+
)
|
|
128
|
+
events.progress("test", "")
|
|
129
|
+
events.progress(
|
|
130
|
+
"test",
|
|
131
|
+
f"── capture-all WOULD dump {len(all_pkgs)} DriverStore package(s) "
|
|
132
|
+
f"(everything, incl. inbox / co-installers) ──",
|
|
133
|
+
)
|
|
134
|
+
events.progress(
|
|
135
|
+
"test",
|
|
136
|
+
f" Why the gap: capture-delta uploads ONLY OEM drivers backing the repo "
|
|
137
|
+
f"delta (not_found ∪ stale) = {len(to_harvest)}; capture-all dumps all "
|
|
138
|
+
f"{len(all_pkgs)} regardless. Devices marked CURRENT/COVERED or inbox are "
|
|
139
|
+
f"intentionally NOT harvested by delta.",
|
|
140
|
+
)
|
|
141
|
+
events.done("test", "=" * 64)
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
"scan": {
|
|
145
|
+
"devices": len(scan_result.devices),
|
|
146
|
+
"with_driver": len(scan_result.has_driver),
|
|
147
|
+
"installed_versions": len(scan_result.installed_versions),
|
|
148
|
+
},
|
|
149
|
+
"resolve": {
|
|
150
|
+
"to_install": len(drivers),
|
|
151
|
+
"already_current": resolve_result.already_current,
|
|
152
|
+
"not_found": len(not_found),
|
|
153
|
+
"stale": len(stale),
|
|
154
|
+
},
|
|
155
|
+
"verdicts": {k: len(v) for k, v in buckets.items()},
|
|
156
|
+
"harvest_delta_packages": len(to_harvest),
|
|
157
|
+
"capture_all_packages": len(all_pkgs),
|
|
158
|
+
}
|
|
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
|