devmap 0.2.5__py3-none-any.whl → 0.3.1__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.
- devmap/_devmap.mjs +266 -37
- {devmap-0.2.5.dist-info → devmap-0.3.1.dist-info}/METADATA +1 -1
- devmap-0.3.1.dist-info/RECORD +7 -0
- devmap-0.2.5.dist-info/RECORD +0 -7
- {devmap-0.2.5.dist-info → devmap-0.3.1.dist-info}/WHEEL +0 -0
- {devmap-0.2.5.dist-info → devmap-0.3.1.dist-info}/entry_points.txt +0 -0
- {devmap-0.2.5.dist-info → devmap-0.3.1.dist-info}/top_level.txt +0 -0
devmap/_devmap.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
var VERSION = "0.
|
|
4
|
+
// src/version.ts
|
|
5
|
+
var VERSION = "0.3.1";
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// src/install.ts
|
|
8
8
|
function isIsolated(i) {
|
|
9
9
|
return !i.onPath && !i.env;
|
|
10
10
|
}
|
|
@@ -21,7 +21,7 @@ function locationTag(i) {
|
|
|
21
21
|
return i.env ? `env: ${i.env}` : "off-path";
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
//
|
|
24
|
+
// src/detector/registry.ts
|
|
25
25
|
var registry = [];
|
|
26
26
|
function register(d) {
|
|
27
27
|
registry.push(d);
|
|
@@ -48,7 +48,7 @@ async function runDetectors(ctx, progress) {
|
|
|
48
48
|
return { byName, allChecks };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
//
|
|
51
|
+
// src/check/model.ts
|
|
52
52
|
function makeCheck(id, kind, severity, label, detail, path = [], fix) {
|
|
53
53
|
const c = { ID: id, Kind: kind, Severity: severity, Label: label, Detail: detail, Path: path };
|
|
54
54
|
if (fix)
|
|
@@ -56,7 +56,7 @@ function makeCheck(id, kind, severity, label, detail, path = [], fix) {
|
|
|
56
56
|
return c;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
//
|
|
59
|
+
// src/platform/exec.ts
|
|
60
60
|
import { spawnSync, spawn } from "node:child_process";
|
|
61
61
|
import { readdirSync, statSync, lstatSync, existsSync } from "node:fs";
|
|
62
62
|
import { join, basename } from "node:path";
|
|
@@ -319,7 +319,7 @@ function scanBrokenSymlinks(dirs) {
|
|
|
319
319
|
return ghosts;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
//
|
|
322
|
+
// src/platform/shells.ts
|
|
323
323
|
function shellName(s) {
|
|
324
324
|
return { current: "current", powershell: "PowerShell", gitbash: "Git Bash", wsl: "WSL" }[s];
|
|
325
325
|
}
|
|
@@ -349,7 +349,7 @@ function shellPathDirs(shell) {
|
|
|
349
349
|
return pathDirs();
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
-
//
|
|
352
|
+
// src/detector/conflicts.ts
|
|
353
353
|
function computeConflicts(groups, shells, disabled) {
|
|
354
354
|
const checks = [];
|
|
355
355
|
const multiVersionTools = [];
|
|
@@ -440,7 +440,220 @@ function isCheckDisabled(id, disabled) {
|
|
|
440
440
|
return isDisabled(id, disabled);
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
//
|
|
443
|
+
// src/security/runtimeAdvisories.ts
|
|
444
|
+
var RUNTIME_ADVISORIES = {
|
|
445
|
+
node: {
|
|
446
|
+
eolByVersion: {
|
|
447
|
+
"16": "2023-09-11",
|
|
448
|
+
"18": "2025-04-30",
|
|
449
|
+
"20": "2026-04-30",
|
|
450
|
+
"22": "2027-04-30",
|
|
451
|
+
"24": "2028-04-30",
|
|
452
|
+
"26": "2029-04-30"
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
python: {
|
|
456
|
+
eolByVersion: {
|
|
457
|
+
"3.7": "2023-06-27",
|
|
458
|
+
"3.8": "2024-10-07",
|
|
459
|
+
"3.9": "2025-10-31",
|
|
460
|
+
"3.10": "2026-10-31",
|
|
461
|
+
"3.11": "2027-10-31",
|
|
462
|
+
"3.12": "2028-10-31",
|
|
463
|
+
"3.13": "2029-10-31"
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
go: {
|
|
467
|
+
eolByVersion: {
|
|
468
|
+
"1.20": "2024-02-06",
|
|
469
|
+
"1.21": "2024-08-13",
|
|
470
|
+
"1.22": "2025-02-11",
|
|
471
|
+
"1.23": "2025-08-12",
|
|
472
|
+
"1.24": "2026-02-11"
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
// src/security/scan.ts
|
|
478
|
+
function eolKeys(version) {
|
|
479
|
+
const parts = version.split(".");
|
|
480
|
+
const maj = parts[0];
|
|
481
|
+
const min = parts[1] ?? "0";
|
|
482
|
+
return [maj, `${maj}.${min}`];
|
|
483
|
+
}
|
|
484
|
+
function computeSecurity(byName) {
|
|
485
|
+
const checks = [];
|
|
486
|
+
const runtimes = byName.runtimes || [];
|
|
487
|
+
const now = Date.now();
|
|
488
|
+
for (const g of runtimes) {
|
|
489
|
+
const adv = RUNTIME_ADVISORIES[g.id];
|
|
490
|
+
if (!adv)
|
|
491
|
+
continue;
|
|
492
|
+
for (const inst of g.installs) {
|
|
493
|
+
const v = inst.version;
|
|
494
|
+
if (!v)
|
|
495
|
+
continue;
|
|
496
|
+
for (const key of eolKeys(v)) {
|
|
497
|
+
const eol = adv.eolByVersion[key];
|
|
498
|
+
if (eol) {
|
|
499
|
+
const eolT = Date.parse(eol + "T00:00:00Z");
|
|
500
|
+
if (!isNaN(eolT) && eolT < now) {
|
|
501
|
+
checks.push(makeCheck(`security.eol.${g.id}`, "stale", "warn", `${g.id} ${v} is end-of-life (since ${eol})`, `${g.id} ${v} reached end-of-life on ${eol} and no longer receives security patches. Upgrade to a supported release. (${inst.path})`, [inst.path]));
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return checks;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/security/sca.ts
|
|
512
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
513
|
+
function whichTool(name) {
|
|
514
|
+
const isWin = process.platform === "win32";
|
|
515
|
+
const r = spawnSync2(isWin ? "where" : "command", isWin ? [name] : ["-v", name], { encoding: "utf-8" });
|
|
516
|
+
if (r.error)
|
|
517
|
+
return null;
|
|
518
|
+
const out = (r.stdout || "").split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
|
|
519
|
+
return out || null;
|
|
520
|
+
}
|
|
521
|
+
function getVersion(toolId) {
|
|
522
|
+
const r = spawnSync2(toolId, ["--version"], { encoding: "utf-8", timeout: 15000 });
|
|
523
|
+
if (r.error || !r.stdout)
|
|
524
|
+
return null;
|
|
525
|
+
const m = r.stdout.match(/(\d+\.\d+\.\d+)/);
|
|
526
|
+
return m ? m[1] : null;
|
|
527
|
+
}
|
|
528
|
+
function toSeverity(s) {
|
|
529
|
+
const t = (s || "").toUpperCase();
|
|
530
|
+
if (t === "CRITICAL" || t === "HIGH")
|
|
531
|
+
return "error";
|
|
532
|
+
return "warn";
|
|
533
|
+
}
|
|
534
|
+
var SCA_TOOLS = [
|
|
535
|
+
{
|
|
536
|
+
id: "osv-scanner",
|
|
537
|
+
label: "OSV-Scanner",
|
|
538
|
+
auditArgs: ["--format", "json", "."],
|
|
539
|
+
parse: (json) => {
|
|
540
|
+
const out = [];
|
|
541
|
+
for (const res of json?.results || []) {
|
|
542
|
+
for (const v of res?.vulnerabilities || []) {
|
|
543
|
+
const pkg = v?.package || {};
|
|
544
|
+
const sev = toSeverity(v?.severity || v?.database_specific?.severity);
|
|
545
|
+
const vid = v?.id || "UNKNOWN";
|
|
546
|
+
out.push(makeCheck(`security.deps.osv.${vid}`, "vuln", sev, `${pkg.name || "?"}@${pkg.version || "?"} affected by ${vid} (${sev === "error" ? "HIGH" : "MEDIUM"})`, `${vid}: ${v?.summary || v?.details || ""}. Package ${pkg.name}@${pkg.version}.`, [pkg.name || ""]));
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return out;
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
id: "pip-audit",
|
|
554
|
+
label: "pip-audit",
|
|
555
|
+
auditArgs: ["-f", "json"],
|
|
556
|
+
parse: (json) => {
|
|
557
|
+
const out = [];
|
|
558
|
+
for (const dep of json?.dependencies || []) {
|
|
559
|
+
for (const v of dep?.vulns || []) {
|
|
560
|
+
const sev = toSeverity(v?.severity);
|
|
561
|
+
const vid = v?.id || "UNKNOWN";
|
|
562
|
+
out.push(makeCheck(`security.deps.pipaudit.${vid}`, "vuln", sev, `${dep?.name || "?"}@${dep?.version || "?"} affected by ${vid} (${sev === "error" ? "HIGH" : "MEDIUM"})`, `${vid}: ${v?.description || ""}. Fix versions: ${(v?.fix_versions || []).join(", ") || "n/a"}.`, [dep?.name || ""]));
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
for (const v of json?.vulnerabilities || []) {
|
|
566
|
+
const sev = toSeverity(v?.severity);
|
|
567
|
+
const vid = v?.id || "UNKNOWN";
|
|
568
|
+
out.push(makeCheck(`security.deps.pipaudit.${vid}`, "vuln", sev, `${v?.name || "?"} affected by ${vid}`, `${vid}: ${v?.description || ""}.`, [v?.name || ""]));
|
|
569
|
+
}
|
|
570
|
+
return out;
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
id: "govulncheck",
|
|
575
|
+
label: "govulncheck",
|
|
576
|
+
auditArgs: ["-json", "."],
|
|
577
|
+
parse: (json) => {
|
|
578
|
+
const out = [];
|
|
579
|
+
for (const res of json?.Results || []) {
|
|
580
|
+
for (const v of res?.Vulnerabilities || []) {
|
|
581
|
+
const score = v?.Severity?.Score;
|
|
582
|
+
const sev = typeof score === "number" && score >= 9 ? "error" : "warn";
|
|
583
|
+
const vid = v?.OSV?.id || "UNKNOWN";
|
|
584
|
+
const pkg = v?.Package?.Path || v?.Package?.Name || "?";
|
|
585
|
+
out.push(makeCheck(`security.deps.govulncheck.${vid}`, "vuln", sev, `${pkg}@${v?.Version || "?"} affected by ${vid} (${sev === "error" ? "HIGH" : "MEDIUM"})`, `${vid}: ${v?.Details || ""}. Package ${pkg}@${v?.Version || "?"}.`, [pkg]));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return out;
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
id: "trivy",
|
|
593
|
+
label: "Trivy",
|
|
594
|
+
auditArgs: ["fs", "--format", "json", "."],
|
|
595
|
+
parse: (json) => {
|
|
596
|
+
const out = [];
|
|
597
|
+
for (const res of json?.Results || []) {
|
|
598
|
+
for (const v of res?.Vulnerabilities || []) {
|
|
599
|
+
const sev = toSeverity(v?.Severity);
|
|
600
|
+
const vid = v?.VulnerabilityID || "UNKNOWN";
|
|
601
|
+
out.push(makeCheck(`security.deps.trivy.${vid}`, "vuln", sev, `${v?.PkgName || "?"}@${v?.InstalledVersion || "?"} affected by ${vid} (${sev === "error" ? "HIGH" : "MEDIUM"})`, `${vid}: ${v?.Title || v?.Description || ""}. Fixed in ${v?.FixedVersion || "n/a"}.`, [v?.PkgName || ""]));
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return out;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
];
|
|
608
|
+
function detectScaTools() {
|
|
609
|
+
return SCA_TOOLS.map((t) => {
|
|
610
|
+
const p = whichTool(t.id);
|
|
611
|
+
return { id: t.id, label: t.label, path: p, version: p ? getVersion(t.id) : null };
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
function computeScaInventory() {
|
|
615
|
+
return detectScaTools().map((d) => {
|
|
616
|
+
const id = `security.scanner.${d.id}`;
|
|
617
|
+
if (d.path) {
|
|
618
|
+
return makeCheck(id, "vuln", "info", `${d.label} available (${d.version || "?"})`, `${d.label} is installed at ${d.path}. devmap can shell out to it for dependency CVE audit with --audit-deps.`, [d.path || ""]);
|
|
619
|
+
}
|
|
620
|
+
return makeCheck(id, "vuln", "info", `${d.label} not installed`, `${d.label} not found on PATH. Install it to enable dependency CVE scanning via devmap --audit-deps (it fetches vuln DBs over the network).`, []);
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
function runScaAudit(cwd) {
|
|
624
|
+
const present = detectScaTools().filter((d) => d.path);
|
|
625
|
+
if (present.length === 0) {
|
|
626
|
+
return [
|
|
627
|
+
makeCheck("security.deps.none", "vuln", "info", "no SCA tool installed — dependency CVE audit skipped", "Install osv-scanner / pip-audit / govulncheck / trivy to enable dependency CVE scanning via `devmap --audit-deps`.", [])
|
|
628
|
+
];
|
|
629
|
+
}
|
|
630
|
+
const checks = [];
|
|
631
|
+
for (const d of present) {
|
|
632
|
+
const tool = SCA_TOOLS.find((t) => t.id === d.id);
|
|
633
|
+
const r = spawnSync2(d.id, tool.auditArgs, { cwd, encoding: "utf-8", timeout: 120000, maxBuffer: 16 * 1024 * 1024 });
|
|
634
|
+
if (r.error || r.status === null) {
|
|
635
|
+
checks.push(makeCheck(`security.deps.${d.id}.error`, "vuln", "info", `${d.label} audit failed to start`, `${d.label} could not be launched: ${r.error?.message || "unknown error"}.`, []));
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
if (r.status !== 0 && !r.stdout.trim()) {
|
|
639
|
+
checks.push(makeCheck(`security.deps.${d.id}.skip`, "vuln", "info", `${d.label} audit produced no output (exit ${r.status})`, `${d.label} returned no scannable result in ${cwd} (no project / no lockfile / no module).`, []));
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
try {
|
|
643
|
+
const json = JSON.parse(r.stdout);
|
|
644
|
+
const parsed = tool.parse(json, d.label);
|
|
645
|
+
checks.push(...parsed);
|
|
646
|
+
if (parsed.length === 0) {
|
|
647
|
+
checks.push(makeCheck(`security.deps.${d.id}.clean`, "vuln", "info", `${d.label} audit: no vulnerabilities found`, `${d.label} found no known vulnerabilities in ${cwd}.`, []));
|
|
648
|
+
}
|
|
649
|
+
} catch (e) {
|
|
650
|
+
checks.push(makeCheck(`security.deps.${d.id}.parse`, "vuln", "info", `${d.label} audit output not JSON`, `${d.label} returned output that could not be parsed as JSON: ${e?.message || e}.`, []));
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return checks;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/output/json.ts
|
|
444
657
|
function buildManifest(byName, conflicts, checks, environments, shells) {
|
|
445
658
|
const sys = byName.system || {};
|
|
446
659
|
const runtimes = byName.runtimes || [];
|
|
@@ -487,7 +700,7 @@ function buildManifest(byName, conflicts, checks, environments, shells) {
|
|
|
487
700
|
};
|
|
488
701
|
}
|
|
489
702
|
|
|
490
|
-
//
|
|
703
|
+
// src/glyphs.ts
|
|
491
704
|
var WIN = process.platform === "win32";
|
|
492
705
|
var G = {
|
|
493
706
|
spinner: WIN ? ["|", "/", "-", "\\"] : ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
@@ -521,7 +734,7 @@ function clean(s) {
|
|
|
521
734
|
return out;
|
|
522
735
|
}
|
|
523
736
|
|
|
524
|
-
//
|
|
737
|
+
// src/progress.ts
|
|
525
738
|
var SPINNERS = G.spinner;
|
|
526
739
|
|
|
527
740
|
class ScanProgress {
|
|
@@ -609,7 +822,7 @@ class ScanProgress {
|
|
|
609
822
|
}
|
|
610
823
|
}
|
|
611
824
|
|
|
612
|
-
//
|
|
825
|
+
// src/scan.ts
|
|
613
826
|
async function runScan(shells, disabled, opts = {}) {
|
|
614
827
|
const progress = opts.silent ? undefined : new ScanProgress(0, process.stderr.isTTY);
|
|
615
828
|
const ctx = {
|
|
@@ -618,7 +831,8 @@ async function runScan(shells, disabled, opts = {}) {
|
|
|
618
831
|
projectRoots: opts.projectRoots,
|
|
619
832
|
progress,
|
|
620
833
|
checkOutdated: opts.checkOutdated,
|
|
621
|
-
wslDeep: opts.wslDeep
|
|
834
|
+
wslDeep: opts.wslDeep,
|
|
835
|
+
auditDeps: opts.auditDeps
|
|
622
836
|
};
|
|
623
837
|
const { byName, allChecks } = await runDetectors(ctx, progress);
|
|
624
838
|
const groups = [
|
|
@@ -627,7 +841,12 @@ async function runScan(shells, disabled, opts = {}) {
|
|
|
627
841
|
...byName.ides || []
|
|
628
842
|
];
|
|
629
843
|
const conflicts = computeConflicts(groups, shells, disabled);
|
|
630
|
-
const
|
|
844
|
+
const securityChecks = [
|
|
845
|
+
...computeSecurity(byName),
|
|
846
|
+
...computeScaInventory(),
|
|
847
|
+
...opts.auditDeps ? runScaAudit(process.cwd()) : []
|
|
848
|
+
];
|
|
849
|
+
const collected = [...allChecks, ...conflicts.checks, ...securityChecks].filter((c) => !isCheckDisabled(c.ID, disabled));
|
|
631
850
|
const environments = {
|
|
632
851
|
vcpkg: byName.vcpkg,
|
|
633
852
|
pip: byName.pip,
|
|
@@ -643,7 +862,7 @@ async function runScan(shells, disabled, opts = {}) {
|
|
|
643
862
|
return buildManifest(byName, conflicts, collected, environments, shells);
|
|
644
863
|
}
|
|
645
864
|
|
|
646
|
-
//
|
|
865
|
+
// src/query.ts
|
|
647
866
|
var CAT_ALIASES = {
|
|
648
867
|
runtimes: "runtime",
|
|
649
868
|
runtime: "runtime",
|
|
@@ -704,7 +923,7 @@ function queryManifest(m, opts) {
|
|
|
704
923
|
return { groups, checks, conflicts };
|
|
705
924
|
}
|
|
706
925
|
|
|
707
|
-
//
|
|
926
|
+
// src/diff.ts
|
|
708
927
|
var CAT_KEYS = [
|
|
709
928
|
["runtimes", "runtime"],
|
|
710
929
|
["packageManagers", "packageManager"],
|
|
@@ -777,7 +996,7 @@ function diffManifests(a, b) {
|
|
|
777
996
|
return { tools: toolList, issues, summary };
|
|
778
997
|
}
|
|
779
998
|
|
|
780
|
-
//
|
|
999
|
+
// src/detector/system.ts
|
|
781
1000
|
import os from "node:os";
|
|
782
1001
|
register({
|
|
783
1002
|
name: "system",
|
|
@@ -796,12 +1015,12 @@ register({
|
|
|
796
1015
|
}
|
|
797
1016
|
});
|
|
798
1017
|
|
|
799
|
-
//
|
|
1018
|
+
// src/detector/runtimes.ts
|
|
800
1019
|
import { homedir } from "node:os";
|
|
801
1020
|
import { join as join2 } from "node:path";
|
|
802
1021
|
import { existsSync as existsSync2, readdirSync as readdirSync2 } from "node:fs";
|
|
803
1022
|
|
|
804
|
-
//
|
|
1023
|
+
// src/detector/util.ts
|
|
805
1024
|
var CONCURRENCY = 12;
|
|
806
1025
|
var GENERIC_FLAGS = ["--version", "version", "-v", "-V"];
|
|
807
1026
|
function dedupe(paths, seen) {
|
|
@@ -868,7 +1087,7 @@ async function detectSimpleAsync(list, onProgress) {
|
|
|
868
1087
|
return out;
|
|
869
1088
|
}
|
|
870
1089
|
|
|
871
|
-
//
|
|
1090
|
+
// src/detector/runtimes.ts
|
|
872
1091
|
var HOME = homedir();
|
|
873
1092
|
async function condaPythonPaths() {
|
|
874
1093
|
const found = [];
|
|
@@ -939,7 +1158,7 @@ register({
|
|
|
939
1158
|
}
|
|
940
1159
|
});
|
|
941
1160
|
|
|
942
|
-
//
|
|
1161
|
+
// src/detector/pkgmgrs.ts
|
|
943
1162
|
var TOOLS = [
|
|
944
1163
|
"npm",
|
|
945
1164
|
"pip",
|
|
@@ -968,7 +1187,7 @@ register({
|
|
|
968
1187
|
}
|
|
969
1188
|
});
|
|
970
1189
|
|
|
971
|
-
//
|
|
1190
|
+
// src/detector/ides.ts
|
|
972
1191
|
register({
|
|
973
1192
|
name: "ides",
|
|
974
1193
|
async scan(ctx) {
|
|
@@ -979,7 +1198,7 @@ register({
|
|
|
979
1198
|
}
|
|
980
1199
|
});
|
|
981
1200
|
|
|
982
|
-
//
|
|
1201
|
+
// src/detector/vcpkg.ts
|
|
983
1202
|
import { join as join3 } from "node:path";
|
|
984
1203
|
var CANDIDATES = [
|
|
985
1204
|
"C:\\vcpkg\\vcpkg.exe",
|
|
@@ -1038,7 +1257,7 @@ register({
|
|
|
1038
1257
|
}
|
|
1039
1258
|
});
|
|
1040
1259
|
|
|
1041
|
-
//
|
|
1260
|
+
// src/detector/piputil.ts
|
|
1042
1261
|
function parseList2(raw) {
|
|
1043
1262
|
if (!raw)
|
|
1044
1263
|
return [];
|
|
@@ -1072,7 +1291,7 @@ async function pipPackagesAsync(pythonPath, timeout = 6000, withOutdated = false
|
|
|
1072
1291
|
}
|
|
1073
1292
|
}
|
|
1074
1293
|
|
|
1075
|
-
//
|
|
1294
|
+
// src/detector/pip.ts
|
|
1076
1295
|
import { basename as basename2 } from "node:path";
|
|
1077
1296
|
function shortName(pythonPath) {
|
|
1078
1297
|
const lower = pythonPath.toLowerCase();
|
|
@@ -1126,7 +1345,7 @@ register({
|
|
|
1126
1345
|
}
|
|
1127
1346
|
});
|
|
1128
1347
|
|
|
1129
|
-
//
|
|
1348
|
+
// src/detector/apt.ts
|
|
1130
1349
|
function parseApt(out) {
|
|
1131
1350
|
const pkgs = [];
|
|
1132
1351
|
for (const line of out.split(`
|
|
@@ -1156,7 +1375,7 @@ register({
|
|
|
1156
1375
|
}
|
|
1157
1376
|
});
|
|
1158
1377
|
|
|
1159
|
-
//
|
|
1378
|
+
// src/detector/condaenv.ts
|
|
1160
1379
|
import { join as join4 } from "node:path";
|
|
1161
1380
|
import { existsSync as existsSync3 } from "node:fs";
|
|
1162
1381
|
function pythonOf(envPath) {
|
|
@@ -1201,7 +1420,7 @@ register({
|
|
|
1201
1420
|
}
|
|
1202
1421
|
});
|
|
1203
1422
|
|
|
1204
|
-
//
|
|
1423
|
+
// src/detector/docker.ts
|
|
1205
1424
|
var DESKTOP = "C:\\Program Files\\Docker\\Docker\\resources\\bin\\docker.exe";
|
|
1206
1425
|
function findDocker() {
|
|
1207
1426
|
for (const p of whichInDirs("docker", pathDirs()))
|
|
@@ -1246,7 +1465,7 @@ register({
|
|
|
1246
1465
|
}
|
|
1247
1466
|
});
|
|
1248
1467
|
|
|
1249
|
-
//
|
|
1468
|
+
// src/detector/wsl.ts
|
|
1250
1469
|
var PROBE_SCRIPT = "echo py3=$(command -v python3); echo py=$(command -v python); echo node=$(command -v node); " + "echo go=$(command -v go); echo rustc=$(command -v rustc); echo gcc=$(command -v gcc); " + "echo git=$(command -v git); echo docker=$(command -v docker)";
|
|
1251
1470
|
var TOOL_KEYS = ["py3", "py", "node", "go", "rustc", "gcc", "git", "docker"];
|
|
1252
1471
|
async function probeDistro(name) {
|
|
@@ -1340,7 +1559,7 @@ register({
|
|
|
1340
1559
|
}
|
|
1341
1560
|
});
|
|
1342
1561
|
|
|
1343
|
-
//
|
|
1562
|
+
// src/detector/vsshells.ts
|
|
1344
1563
|
import { readdirSync as readdirSync3, existsSync as existsSync4, statSync as statSync2 } from "node:fs";
|
|
1345
1564
|
import { join as join5 } from "node:path";
|
|
1346
1565
|
var VS_BASES = [
|
|
@@ -1506,7 +1725,7 @@ register({
|
|
|
1506
1725
|
}
|
|
1507
1726
|
});
|
|
1508
1727
|
|
|
1509
|
-
//
|
|
1728
|
+
// src/detector/projects.ts
|
|
1510
1729
|
import { readdirSync as readdirSync4, existsSync as existsSync5, statSync as statSync3 } from "node:fs";
|
|
1511
1730
|
import { join as join6, basename as basename3, dirname } from "node:path";
|
|
1512
1731
|
function isVenv(dir) {
|
|
@@ -1580,7 +1799,7 @@ register({
|
|
|
1580
1799
|
}
|
|
1581
1800
|
});
|
|
1582
1801
|
|
|
1583
|
-
//
|
|
1802
|
+
// src/cli.ts
|
|
1584
1803
|
import { writeFileSync, mkdirSync, readFileSync, existsSync as existsSync6 } from "node:fs";
|
|
1585
1804
|
import { homedir as homedir2 } from "node:os";
|
|
1586
1805
|
import { join as join7 } from "node:path";
|
|
@@ -1617,7 +1836,7 @@ function tokenize(argv) {
|
|
|
1617
1836
|
const key = a.slice(2);
|
|
1618
1837
|
const nxt = argv[i + 1];
|
|
1619
1838
|
if (nxt !== undefined && !nxt.startsWith("--")) {
|
|
1620
|
-
opts[key] = nxt;
|
|
1839
|
+
opts[key] = opts[key] !== undefined ? `${opts[key]},${nxt}` : nxt;
|
|
1621
1840
|
i++;
|
|
1622
1841
|
} else
|
|
1623
1842
|
opts[key] = true;
|
|
@@ -1671,7 +1890,8 @@ async function cmdScan(opts, pos) {
|
|
|
1671
1890
|
projectRoots: roots,
|
|
1672
1891
|
silent: opts.quiet === true,
|
|
1673
1892
|
checkOutdated: opts.outdated === true,
|
|
1674
|
-
wslDeep: opts["wsl-deep"] === true
|
|
1893
|
+
wslDeep: opts["wsl-deep"] === true,
|
|
1894
|
+
auditDeps: opts["audit-deps"] === true
|
|
1675
1895
|
});
|
|
1676
1896
|
if (opts.json) {
|
|
1677
1897
|
emitText(JSON.stringify(manifest, null, 2), opts.bom === true);
|
|
@@ -1687,8 +1907,16 @@ async function cmdScan(opts, pos) {
|
|
|
1687
1907
|
} catch {}
|
|
1688
1908
|
}
|
|
1689
1909
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1910
|
+
if (opts.ci) {
|
|
1911
|
+
const hasError = (manifest.checks || []).some((c) => c.Severity === "error");
|
|
1912
|
+
if (hasError)
|
|
1913
|
+
return 1;
|
|
1914
|
+
const hasWarn = (manifest.checks || []).some((c) => c.Severity === "warn");
|
|
1915
|
+
if (hasWarn)
|
|
1916
|
+
return 2;
|
|
1917
|
+
return 0;
|
|
1918
|
+
}
|
|
1919
|
+
return 0;
|
|
1692
1920
|
}
|
|
1693
1921
|
async function cmdQuery(opts, pos) {
|
|
1694
1922
|
const selector = pos[1];
|
|
@@ -1948,7 +2176,8 @@ scan options:
|
|
|
1948
2176
|
--scan-root <dir> project-local environment scan root (comma-separated; default cwd). e.g. --scan-root C:\\src
|
|
1949
2177
|
--outdated check pip/conda upgradable packages online (off by default: requires PyPI access and slows the scan)
|
|
1950
2178
|
--wsl-deep probe inside stopped WSL distros (default probes only running ones to avoid waking distros)
|
|
1951
|
-
--ci any error
|
|
2179
|
+
--ci CI gate: clean → exit 0; any warn → exit 2; any error → exit 1
|
|
2180
|
+
--audit-deps dependency CVE audit via OSV-Scanner/pip-audit/govulncheck/Trivy (opt-in, uses network)
|
|
1952
2181
|
--quiet suppress scan progress feedback (for scripts/CI)
|
|
1953
2182
|
--bom prepend UTF-8 BOM for viewing in Notepad etc. (only on redirect/pipe)
|
|
1954
2183
|
--version / --help
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devmap
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Map your machine's dev environment and surface issues (PATH conflicts, ghost binaries, multi-version collisions). fastfetch-for-dev-tools. This PyPI package ships the real devmap CLI (a bundled JavaScript app launched via Node.js or Bun), so `pip install devmap && devmap` works standalone.
|
|
5
5
|
Author: devmap contributors
|
|
6
6
|
License: MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
devmap/__init__.py,sha256=4Ek7Di0FYYl76FKnHJ8VYiJPHlUTfoqyBB_hul_pFbk,1728
|
|
2
|
+
devmap/_devmap.mjs,sha256=kSUWJXXmxf2IPTM8aCs8kZtPBKbldAud1vpovK9spXk,79053
|
|
3
|
+
devmap-0.3.1.dist-info/METADATA,sha256=RgTgWOQdNjoIZa93ZBgs9F_F8z8D_vKObWdr_j2zfVE,1633
|
|
4
|
+
devmap-0.3.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
5
|
+
devmap-0.3.1.dist-info/entry_points.txt,sha256=FOQKZCLz0WGWemrTw0suYRqKWrUB4_XJ2Gkrw60ZEcg,39
|
|
6
|
+
devmap-0.3.1.dist-info/top_level.txt,sha256=QeomiD_JKcjSd_jTZv0WJF3darUb2sUsxmocjgYJ6Qc,7
|
|
7
|
+
devmap-0.3.1.dist-info/RECORD,,
|
devmap-0.2.5.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
devmap/__init__.py,sha256=4Ek7Di0FYYl76FKnHJ8VYiJPHlUTfoqyBB_hul_pFbk,1728
|
|
2
|
-
devmap/_devmap.mjs,sha256=slhroJM6F72Aot8jSwk9qdneL9NMfn3ISoeZoNg9BU8,70472
|
|
3
|
-
devmap-0.2.5.dist-info/METADATA,sha256=s6ULpjU01jRSAfXzEwE5nUPQnPGq5L2Vpxc0hLdr7cU,1633
|
|
4
|
-
devmap-0.2.5.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
5
|
-
devmap-0.2.5.dist-info/entry_points.txt,sha256=FOQKZCLz0WGWemrTw0suYRqKWrUB4_XJ2Gkrw60ZEcg,39
|
|
6
|
-
devmap-0.2.5.dist-info/top_level.txt,sha256=QeomiD_JKcjSd_jTZv0WJF3darUb2sUsxmocjgYJ6Qc,7
|
|
7
|
-
devmap-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|