react-doctor 0.9.11-dev.f1899d2 → 0.9.12-dev.05ef989
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.
- package/README.md +1 -1
- package/bin/react-doctor.js +1 -9
- package/dist/{build-section-divider-4ZztYtZV.js → build-section-divider-BNQmYjME.js} +9 -10
- package/dist/{ci-B04VkLj2.js → ci-B9ir-2Up.js} +12 -12
- package/dist/cli.js +30 -31
- package/dist/{design-AAjcvExu.js → design-DrPr5wfS.js} +4 -4
- package/dist/{devtools-DPRVRu3S.js → devtools-D8NTVj81.js} +4 -4
- package/dist/{exit-gracefully-B7v9PIJk.js → exit-gracefully-C-_jVMT3.js} +6 -6
- package/dist/index.d.ts +38 -61
- package/dist/index.js +54842 -54698
- package/dist/{inspect-CdQJI2XI.js → inspect-BfdplEq6.js} +24 -23
- package/dist/{install-BRU4jf-Y.js → install-CcPaQeBb.js} +8 -8
- package/dist/{install-doctor-script-Dn69YqKG.js → install-doctor-script-BlIhuJW6.js} +4 -4
- package/dist/{install-github-workflow-BwELZAhu.js → install-github-workflow-DbnsoR9k.js} +6 -6
- package/dist/{install-react-doctor-CcDiKPfC.js → install-react-doctor-COZnJROS.js} +47 -45
- package/dist/{print-branded-header-_kkHIAUd.js → print-branded-header-B_Cgff5S.js} +4 -4
- package/dist/project-analysis-worker.d.ts +1 -0
- package/dist/project-analysis-worker.js +51900 -0
- package/dist/{read-object-file-Bsov5R1-.js → read-object-file-NNLnIQKt.js} +4 -4
- package/dist/{record-metric-CeygoJWT.js → record-metric-fdCvvcjz.js} +2628 -5681
- package/dist/{report-error-uffmJocy.js → report-error-BH7DfHGY.js} +5 -5
- package/dist/{report-workflow-result-CMtcy7Eb.js → report-workflow-result-B3YeoXsK.js} +5 -5
- package/dist/{resolve-scope-CFro-KQO.js → resolve-scope-gLUuBxjI.js} +6 -6
- package/dist/{rules-BkLea4GL.js → rules-B5VC89MR.js} +6 -6
- package/dist/{run-scan-app-Befn2abh.js → run-scan-app-Cl2mqLLB.js} +137 -121
- package/dist/{scan-C00HPxuL.js → scan-7OBudBct.js} +8 -8
- package/dist/semver-DFtnEmN-.js +3219 -0
- package/dist/{should-fail-scan-gate-BEoC3SoQ.js → should-fail-scan-gate-Dch9vbPz.js} +151 -83
- package/dist/{should-skip-prompts-De37OlfL.js → should-skip-prompts-CyNdARgB.js} +4 -4
- package/dist/{unref-stdin-DklpxlNQ.js → unref-stdin-Cynhx9N1.js} +6 -12
- package/dist/{version-CRfqT5pV.js → version-axnZCkCZ.js} +4 -4
- package/dist/{why-BTbl-alh.js → why-Ducgj7Hu.js} +4 -4
- package/package.json +5 -9
- package/dist/chunk-q7NCDQ7-.js +0 -28
- package/dist/lsp.js +0 -81125
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { $
|
|
4
|
-
import { a as setActiveRunTrace, i as recordRunTraceId, o as getTelemetryContext } from "./unref-stdin-
|
|
5
|
-
import { n as buildFooterLinkLines, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-
|
|
6
|
-
import { D as getPackageJsonPath, L as cliLogger, O as isRecord, P as runGit, a as installReactDoctorScriptStep, c as spinner, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-
|
|
7
|
-
import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-
|
|
8
|
-
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-
|
|
9
|
-
import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="19bff337-5a1f-5558-b6b7-bd4274f53f38")}catch(e){}}();
|
|
3
|
+
import { $ as Maintainability, $t as listSourceFiles, An as makeSpan, At as filterDiagnosticsForSurface, Bn as try_, Ct as computeConfigFingerprint, Dn as decodeUnknownSync, Dt as createOxlintSpawnSlots, E as NANOSECONDS_PER_MILLISECOND, En as Diagnostic, Et as createNodeReadFileLinesSync, Fn as provideContext, G as isCiOrCodingAgentEnvironment, Gn as succeed, Gt as highlighter, H as ACTION_INPUT_ENVIRONMENT_VARIABLES, Ht as hasPublishedFixRecipe, In as provideService, J as Files, Jn as fail, Kt as isMonorepoRoot, Ln as runPromise, Mn as orElseSucceed, Mt as filterSourceFiles, Nn as promise, Pn as provide, Q as Linter, R as CliInputError, Rn as runSync, Rt as getDiagnosticRuleIdentity, Sn as error, St as collectSourceFileCountsByDirectory, Tn as warn, Tt as countOptInProjectRuleSelections, U as detectRunnerOs, Un as mergeAll, Vt as groupBy, W as isCiEnvironment, Wt as hashFileContents, Xn as ParentSpan, Y as Git, Yn as void_, Yt as isReactDoctorError, Z as LintPartialFailures, Zt as isScanComplete, _ as makeNoopConsole, _n as summarizeDiagnostics, _t as buildSkippedChecks, an as mergeReactDoctorConfigs, at as Project, bn as yieldToEventLoop, br as isFile, bt as classifyFileContext, c as setSentryProjectInfo, cn as resolveLintBatchOrdering, cr as GIT_SHOW_MAX_BUFFER_BYTES, ct as SidecarLintCacheEnabled, d as isJsonModeActive, dn as resolveScanTarget, dr as JSX_FILE_PATTERN, en as listSourceFilesCooperative, er as CI_URL, et as NodeResolver, fn as restoreLegacyThrow, fr as MILLISECONDS_PER_SECOND, g as VERSION, gn as shouldUseMaintainabilityLayer, gt as buildRuleSeverityControls, ht as buildRuleDocsUrl, in as materializeSourceTree, ir as DIAGNOSTIC_CATEGORY_BUCKETS, it as Progress, jn as map, jt as filterPathsOutsideDirectories, k as SCAN_RESULT_CACHE_FILENAME, kn as gen, kt as discoverSupportedSubprojects, l as getRunId, ln as resolveReactDoctorCacheDir, lr as HTML_FILE_PATTERN, mr as SHARE_BASE_URL, n as recordDistribution, nt as OxlintSpawnSlots, o as buildSentryScope, on as remainingDeadlineBudgetMs, or as ENTERPRISE_CONTACT_URL, ot as Reporter, pn as runInspect, pr as OXLINT_NODE_REQUIREMENT, pt as atomicWriteJson, q as Config, qt as isPathInsideDirectory, r as toSpanAttributes, rn as mapWithConcurrency, rt as PerFileLintCacheEnabled, s as buildSentryProjectContext, sn as resolveGithubActionsScoreMetadata, st as Score, t as recordCount, tn as listWorkspacePackages, tt as OxlintConcurrency, un as resolveScanConcurrency, ur as JSX_DUPLICATION_SOURCE_FILE_PATTERN, ut as SupplyChain, vr as isDirectory, vt as calculateScore, w as METRIC, wn as log, wt as computeDiagnosticDelta, x as BASELINE_FILES_TEMP_DIR_PREFIX, xn as Console, yt as canonicalizeUserRuleKey, z as isNonInteractiveEnvironment, zn as sync } from "./record-metric-fdCvvcjz.js";
|
|
4
|
+
import { a as setActiveRunTrace, i as recordRunTraceId, o as getTelemetryContext } from "./unref-stdin-Cynhx9N1.js";
|
|
5
|
+
import { n as buildFooterLinkLines, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-BNQmYjME.js";
|
|
6
|
+
import { D as getPackageJsonPath, L as cliLogger, O as isRecord, P as runGit, a as installReactDoctorScriptStep, c as spinner, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-BlIhuJW6.js";
|
|
7
|
+
import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-DbnsoR9k.js";
|
|
8
|
+
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-gLUuBxjI.js";
|
|
9
|
+
import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-B3YeoXsK.js";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
12
12
|
import * as path$1 from "node:path";
|
|
13
13
|
import path from "node:path";
|
|
14
|
-
import * as fs$
|
|
14
|
+
import * as fs$2 from "node:fs";
|
|
15
15
|
import fs, { mkdtempSync, rmSync } from "node:fs";
|
|
16
|
-
import crypto, { randomUUID } from "node:crypto";
|
|
17
16
|
import ts from "typescript";
|
|
17
|
+
import crypto, { randomUUID } from "node:crypto";
|
|
18
18
|
import { tmpdir } from "node:os";
|
|
19
|
+
import * as fs$1 from "node:fs/promises";
|
|
19
20
|
import { performance } from "node:perf_hooks";
|
|
20
21
|
//#region src/cli/utils/apply-observability.ts
|
|
21
22
|
/**
|
|
@@ -83,7 +84,10 @@ const buildSpinnerProgressHandle = (text) => {
|
|
|
83
84
|
*/
|
|
84
85
|
const buildRuntimeLayers = (input) => {
|
|
85
86
|
const linterLayer = input.shouldSkipLint ? Linter.layerOf([]) : Linter.layerOxlint;
|
|
86
|
-
const
|
|
87
|
+
const maintainabilityLayer = shouldUseMaintainabilityLayer({
|
|
88
|
+
shouldRunDuplicateJsx: input.shouldRunDeadCode,
|
|
89
|
+
userConfig: input.userConfig
|
|
90
|
+
}) ? Maintainability.layerNode : Maintainability.layerOf([]);
|
|
87
91
|
const scoreLayer = input.shouldComputeScore ? Score.layerHttp : Score.layerOf(null);
|
|
88
92
|
const supplyChainLayer = input.shouldRunSupplyChain ? SupplyChain.layerNode : SupplyChain.layerOf([]);
|
|
89
93
|
const projectLayer = input.projectInfoOverride === void 0 ? Project.layerNode : Project.layerOf(input.projectInfoOverride);
|
|
@@ -93,7 +97,7 @@ const buildRuntimeLayers = (input) => {
|
|
|
93
97
|
config: input.userConfig,
|
|
94
98
|
resolvedDirectory: input.directory,
|
|
95
99
|
configSourceDirectory: input.configSourceDirectory
|
|
96
|
-
}) : Config.layerNode, Files.layerNode, Git.layerNode, linterLayer, LintPartialFailures.layerLive,
|
|
100
|
+
}) : Config.layerNode, Files.layerNode, Git.layerNode, linterLayer, LintPartialFailures.layerLive, maintainabilityLayer, progressLayer, reporterLayer, scoreLayer, supplyChainLayer);
|
|
97
101
|
const layersWithConcurrency = input.oxlintConcurrency === void 0 ? baseLayers : mergeAll(baseLayers, succeed(OxlintConcurrency, input.oxlintConcurrency));
|
|
98
102
|
return input.oxlintSpawnSlots === void 0 ? layersWithConcurrency : mergeAll(layersWithConcurrency, succeed(OxlintSpawnSlots, input.oxlintSpawnSlots));
|
|
99
103
|
};
|
|
@@ -309,7 +313,7 @@ const recordScanMetrics = (input) => {
|
|
|
309
313
|
recordCount(METRIC.scanCompleted, 1, {
|
|
310
314
|
mode: input.mode,
|
|
311
315
|
lint: input.lint,
|
|
312
|
-
|
|
316
|
+
maintainability: input.deadCode,
|
|
313
317
|
parallel: input.parallel,
|
|
314
318
|
scoreOnly: input.scoreOnly,
|
|
315
319
|
didLintFail: input.didLintFail,
|
|
@@ -349,7 +353,7 @@ const recordScanMetrics = (input) => {
|
|
|
349
353
|
else if (!input.noScore && !input.didLintFail && !input.didDeadCodeFail) recordCount(METRIC.scoreUnavailable, 1, { mode: input.mode });
|
|
350
354
|
if (input.baselineDegraded) recordCount(METRIC.baselineDegraded, 1);
|
|
351
355
|
if (input.didLintFail) recordCount(METRIC.lintFailed, 1, { reasonKind: input.lintFailureReasonKind });
|
|
352
|
-
if (input.didDeadCodeFail) recordCount(METRIC.
|
|
356
|
+
if (input.didDeadCodeFail) recordCount(METRIC.maintainabilityFailed, 1);
|
|
353
357
|
for (const check of result.skippedChecks) recordCount(METRIC.scanCheckSkipped, 1, {
|
|
354
358
|
check,
|
|
355
359
|
reason: result.skippedCheckReasons?.[check] ?? null
|
|
@@ -493,10 +497,16 @@ const CACHE_DISABLED_VALUES = new Set(["1", "true"]);
|
|
|
493
497
|
const TOOLCHAIN_PACKAGE_SPECIFIERS = [
|
|
494
498
|
"oxlint/package.json",
|
|
495
499
|
"oxlint-plugin-react-doctor/package.json",
|
|
496
|
-
"deslop-js/package.json",
|
|
497
500
|
"eslint-plugin-react-hooks/package.json"
|
|
498
501
|
];
|
|
499
502
|
const bundledRequire = createRequire(import.meta.url);
|
|
503
|
+
const RULE_PLUGIN_CONTENT_FINGERPRINT = (() => {
|
|
504
|
+
try {
|
|
505
|
+
return `oxlint-plugin-react-doctor#fingerprint=${hashFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor")) ?? "unreadable"}`;
|
|
506
|
+
} catch {
|
|
507
|
+
return "oxlint-plugin-react-doctor#fingerprint=unresolved";
|
|
508
|
+
}
|
|
509
|
+
})();
|
|
500
510
|
const normalizeForStableJson = (value) => {
|
|
501
511
|
if (value === null) return null;
|
|
502
512
|
if (value === void 0) return void 0;
|
|
@@ -632,12 +642,12 @@ const resolveCacheFilePath = (projectDirectory) => path.join(resolveReactDoctorC
|
|
|
632
642
|
const readPersistedCache = (cacheFilePath) => {
|
|
633
643
|
try {
|
|
634
644
|
const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
|
|
635
|
-
if (!isRecord(parsed) || parsed.version !==
|
|
636
|
-
version:
|
|
645
|
+
if (!isRecord(parsed) || parsed.version !== 7) return {
|
|
646
|
+
version: 7,
|
|
637
647
|
entries: []
|
|
638
648
|
};
|
|
639
649
|
if (!Array.isArray(parsed.entries)) return {
|
|
640
|
-
version:
|
|
650
|
+
version: 7,
|
|
641
651
|
entries: []
|
|
642
652
|
};
|
|
643
653
|
const entries = [];
|
|
@@ -652,12 +662,12 @@ const readPersistedCache = (cacheFilePath) => {
|
|
|
652
662
|
});
|
|
653
663
|
}
|
|
654
664
|
return {
|
|
655
|
-
version:
|
|
665
|
+
version: 7,
|
|
656
666
|
entries
|
|
657
667
|
};
|
|
658
668
|
} catch {
|
|
659
669
|
return {
|
|
660
|
-
version:
|
|
670
|
+
version: 7,
|
|
661
671
|
entries: []
|
|
662
672
|
};
|
|
663
673
|
}
|
|
@@ -665,7 +675,7 @@ const readPersistedCache = (cacheFilePath) => {
|
|
|
665
675
|
/**
|
|
666
676
|
* The global cache off-switch (`REACT_DOCTOR_NO_CACHE`), which disables every
|
|
667
677
|
* cache subsystem: this whole-repo scan cache plus core's per-file lint,
|
|
668
|
-
* sidecar
|
|
678
|
+
* sidecar caches (their `Context.Reference` defaults read the
|
|
669
679
|
* same variable). Exported for the wide event's `cache.temperature`
|
|
670
680
|
* derivation, which reports `"disabled"` instead of `"cold"` when the switch
|
|
671
681
|
* is on. Granular knobs (`REACT_DOCTOR_NO_FILE_CACHE`, …) are deliberately
|
|
@@ -688,7 +698,7 @@ const fileFingerprint = (filePath) => {
|
|
|
688
698
|
return null;
|
|
689
699
|
}
|
|
690
700
|
};
|
|
691
|
-
const
|
|
701
|
+
const resolveScanResultToolchainFingerprint = (nodeBinaryPath) => {
|
|
692
702
|
const fingerprints = [];
|
|
693
703
|
if (nodeBinaryPath !== null) fingerprints.push(nodeBinaryPath === process.execPath ? `node=${process.version}` : `node=${fileFingerprint(nodeBinaryPath) ?? "unreadable"}`);
|
|
694
704
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
|
|
@@ -698,6 +708,7 @@ const resolveToolchainFingerprint = (nodeBinaryPath) => {
|
|
|
698
708
|
} catch {
|
|
699
709
|
fingerprints.push(`${specifier}=missing`);
|
|
700
710
|
}
|
|
711
|
+
fingerprints.push(RULE_PLUGIN_CONTENT_FINGERPRINT);
|
|
701
712
|
return fingerprints;
|
|
702
713
|
};
|
|
703
714
|
const buildScanResultCacheKey = (input) => {
|
|
@@ -707,14 +718,14 @@ const buildScanResultCacheKey = (input) => {
|
|
|
707
718
|
if (repositoryIdentity === null) return null;
|
|
708
719
|
if (stringifyStableJson(input.userConfig) === null) return null;
|
|
709
720
|
const cacheKeyJson = stringifyStableJson({
|
|
710
|
-
schemaVersion:
|
|
721
|
+
schemaVersion: 7,
|
|
711
722
|
projectIdentity: resolveProjectIdentity(input.projectDirectory),
|
|
712
723
|
headSha: repositoryIdentity.headSha,
|
|
713
724
|
worktreeFingerprint: repositoryIdentity.worktreeFingerprint,
|
|
714
725
|
dotenvFingerprint: resolveDotenvFingerprint(input.projectDirectory),
|
|
715
726
|
reactDoctorVersion: input.version,
|
|
716
727
|
nodeVersion: process.version,
|
|
717
|
-
toolchainFingerprint:
|
|
728
|
+
toolchainFingerprint: resolveScanResultToolchainFingerprint(input.nodeBinaryPath),
|
|
718
729
|
configFingerprint: computeConfigFingerprint(input.projectDirectory, input.version),
|
|
719
730
|
hasConfigOverride: input.hasConfigOverride,
|
|
720
731
|
configSourceDirectory: input.configSourceDirectory,
|
|
@@ -755,7 +766,7 @@ const createScanResultCache = (projectDirectory) => {
|
|
|
755
766
|
for (const entry of readPersistedCache(cacheFilePath).entries) mergedEntries.set(entry.key, entry);
|
|
756
767
|
for (const entry of entries.values()) mergedEntries.set(entry.key, entry);
|
|
757
768
|
atomicWriteJson(cacheFilePath, {
|
|
758
|
-
version:
|
|
769
|
+
version: 7,
|
|
759
770
|
entries: [...mergedEntries.values()].sort((firstEntry, secondEntry) => secondEntry.createdAtMs - firstEntry.createdAtMs).slice(0, 20)
|
|
760
771
|
});
|
|
761
772
|
};
|
|
@@ -790,8 +801,7 @@ const shouldBlockCi = (diagnostics, blockingLevel) => {
|
|
|
790
801
|
/**
|
|
791
802
|
* Lowercase, key-safe form of a rule category for the `diag.category.*`
|
|
792
803
|
* telemetry attribute namespace (categories carry spaces / capitals, e.g.
|
|
793
|
-
* "Performance" → `performance`, "Dead Code" → `dead_code`).
|
|
794
|
-
* CLI run event and the editor LSP wide event so both namespace identically.
|
|
804
|
+
* "Performance" → `performance`, "Dead Code" → `dead_code`).
|
|
795
805
|
*/
|
|
796
806
|
const toCategoryKey = (category) => category.toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
797
807
|
//#endregion
|
|
@@ -821,12 +831,6 @@ const readEnvBoolean = (name) => {
|
|
|
821
831
|
return value.toLowerCase() === "true" || value === "1";
|
|
822
832
|
};
|
|
823
833
|
const ratioOf = (numerator, denominator) => denominator != null && denominator > 0 ? (numerator ?? 0) / denominator : null;
|
|
824
|
-
const resolveDeadCodeReuseRatio = (result) => {
|
|
825
|
-
if (result.deadCodeCacheHit === true) return 1;
|
|
826
|
-
const summaryTotal = (result.deadCodeSummaryCacheHits ?? 0) + (result.deadCodeSummaryCacheMisses ?? 0);
|
|
827
|
-
if (summaryTotal > 0) return (result.deadCodeSummaryCacheHits ?? 0) / summaryTotal;
|
|
828
|
-
return result.deadCodeCacheHit === false ? 0 : null;
|
|
829
|
-
};
|
|
830
834
|
/**
|
|
831
835
|
* One queryable cache temperature per scan, derived from the whole stack:
|
|
832
836
|
*
|
|
@@ -834,8 +838,7 @@ const resolveDeadCodeReuseRatio = (result) => {
|
|
|
834
838
|
* `wholeRepoCacheHit` flag from the CLI's cachedPayload
|
|
835
839
|
* branch; no scan work ran).
|
|
836
840
|
* - `"warm"` — any incremental reuse: per-file lint hits, sidecar
|
|
837
|
-
* replays
|
|
838
|
-
* summary-cache hits.
|
|
841
|
+
* replays.
|
|
839
842
|
* - `"disabled"` — zero reuse because the global `REACT_DOCTOR_NO_CACHE`
|
|
840
843
|
* off-switch is on. Granular per-cache opt-outs
|
|
841
844
|
* (`REACT_DOCTOR_NO_FILE_CACHE`, …) still read warm/cold,
|
|
@@ -844,7 +847,7 @@ const resolveDeadCodeReuseRatio = (result) => {
|
|
|
844
847
|
*
|
|
845
848
|
* `cache.warmth` is the headline reuse magnitude in [0, 1]: the plain mean of
|
|
846
849
|
* the subsystem reuse fractions known this run (lint hit ratio, sidecar
|
|
847
|
-
* replay ratio
|
|
850
|
+
* replay ratio), skipping subsystems that never consulted a
|
|
848
851
|
* cache; `1` on turbo, dropped when nothing consulted any cache. Deliberately
|
|
849
852
|
* unweighted — the per-subsystem dims stay the precise signal; warmth is the
|
|
850
853
|
* p50/p90-able summary. Emitted only on the success path.
|
|
@@ -857,11 +860,7 @@ const buildCacheAttributes = (input) => {
|
|
|
857
860
|
warmth: 1
|
|
858
861
|
});
|
|
859
862
|
const result = input.result;
|
|
860
|
-
const subsystemReuseRatios = [
|
|
861
|
-
ratioOf(result.lintCacheHitFileCount, result.lintCacheTotalFileCount),
|
|
862
|
-
ratioOf(result.lintSidecarReplayedFileCount, result.lintSidecarTotalFileCount),
|
|
863
|
-
resolveDeadCodeReuseRatio(result)
|
|
864
|
-
];
|
|
863
|
+
const subsystemReuseRatios = [ratioOf(result.lintCacheHitFileCount, result.lintCacheTotalFileCount), ratioOf(result.lintSidecarReplayedFileCount, result.lintSidecarTotalFileCount)];
|
|
865
864
|
let knownSubsystemCount = 0;
|
|
866
865
|
let reuseRatioSum = 0;
|
|
867
866
|
for (const reuseRatio of subsystemReuseRatios) {
|
|
@@ -1013,13 +1012,7 @@ const buildOutcomeAttributes = (input) => {
|
|
|
1013
1012
|
sidecarTotalFiles: result.lintSidecarTotalFileCount,
|
|
1014
1013
|
sidecarReplayRatio: ratioOf(result.lintSidecarReplayedFileCount, result.lintSidecarTotalFileCount)
|
|
1015
1014
|
}),
|
|
1016
|
-
...withNamespace("
|
|
1017
|
-
failed: input.didDeadCodeFail,
|
|
1018
|
-
overlapped: input.deadCodeOverlapped,
|
|
1019
|
-
cacheHit: result.deadCodeCacheHit,
|
|
1020
|
-
summaryCacheHits: result.deadCodeSummaryCacheHits,
|
|
1021
|
-
summaryCacheMisses: result.deadCodeSummaryCacheMisses
|
|
1022
|
-
}),
|
|
1015
|
+
...withNamespace("maintainability", { failed: input.didDeadCodeFail }),
|
|
1023
1016
|
...withNamespace("supplyChain", { overlapTimedOut: input.supplyChainOverlapTimedOut }),
|
|
1024
1017
|
...withNamespace("securityScan", { failed: input.securityScanFailed }),
|
|
1025
1018
|
...withNamespace("timing", {
|
|
@@ -1062,7 +1055,7 @@ const buildScanAttributes = (input) => {
|
|
|
1062
1055
|
workerCount: input.workerCount,
|
|
1063
1056
|
maxDurationMs: input.maxDurationMs,
|
|
1064
1057
|
lint: input.lint,
|
|
1065
|
-
|
|
1058
|
+
maintainability: input.deadCode,
|
|
1066
1059
|
supplyChain: input.supplyChain,
|
|
1067
1060
|
scoreOnly: input.scoreOnly,
|
|
1068
1061
|
noScore: input.noScore,
|
|
@@ -1073,6 +1066,7 @@ const buildScanAttributes = (input) => {
|
|
|
1073
1066
|
hasCustomConfig: input.hasCustomConfig,
|
|
1074
1067
|
rulesConfigured: ruleKeys.length,
|
|
1075
1068
|
rulesDisabled: ruleKeys.filter((key) => ruleOverrides[key] === "off").length,
|
|
1069
|
+
projectAnalysisRuleCount: countOptInProjectRuleSelections(buildRuleSeverityControls(input.userConfig)),
|
|
1076
1070
|
fileCount: input.result?.scannedFileCount,
|
|
1077
1071
|
nonJsxFileCount: input.result?.analyzedFiles?.filter((filePath) => !JSX_FILE_PATTERN.test(filePath)).length,
|
|
1078
1072
|
htmlFileCount: input.result?.analyzedFiles?.filter((filePath) => HTML_FILE_PATTERN.test(filePath)).length,
|
|
@@ -1083,7 +1077,7 @@ const buildScanAttributes = (input) => {
|
|
|
1083
1077
|
* Projects a scan into the namespaced attribute set for its root span — the
|
|
1084
1078
|
* canonical per-scan "wide event". Every attribute carries a dotted namespace
|
|
1085
1079
|
* that groups it by concept (`scan.*` config, `action.*` CI knobs, `outcome.*`
|
|
1086
|
-
* verdict, `diag.*` findings, `score.*`, `lint.*`, `
|
|
1080
|
+
* verdict, `diag.*` findings, `score.*`, `lint.*`, `maintainability.*`, `cache.*`,
|
|
1087
1081
|
* `supplyChain.*`, `timing.*`, `migration.*`, `baseline.*`) so the attributes
|
|
1088
1082
|
* tree up in Sentry's attribute browser and stay filter-/group-/aggregate-able
|
|
1089
1083
|
* in the Spans dataset. Pure and exported so the projection (outcome
|
|
@@ -1322,7 +1316,7 @@ const buildNoScoreMessage = (input) => {
|
|
|
1322
1316
|
reason = input.disabledMessage ?? "Score disabled by --no-score.";
|
|
1323
1317
|
break;
|
|
1324
1318
|
case "analysis-incomplete":
|
|
1325
|
-
reason = "Score not shown because lint or
|
|
1319
|
+
reason = "Score not shown because lint or maintainability analysis could not complete.";
|
|
1326
1320
|
break;
|
|
1327
1321
|
case "api-unavailable":
|
|
1328
1322
|
reason = "Score unavailable (could not reach the score API).";
|
|
@@ -1370,7 +1364,7 @@ const formatRuleSummary = (ruleKey, ruleDiagnostics) => {
|
|
|
1370
1364
|
const ruleDumpFileName = (ruleKey) => ruleKey.replace(/\//g, "--") + ".txt";
|
|
1371
1365
|
const readPreviousRuleDumpFileNames = (directory) => {
|
|
1372
1366
|
try {
|
|
1373
|
-
const previous = JSON.parse(fs$
|
|
1367
|
+
const previous = JSON.parse(fs$2.readFileSync(path$1.join(directory, "diagnostics.json"), "utf8"));
|
|
1374
1368
|
return new Set(previous.filter((d) => typeof d?.plugin === "string" && typeof d?.rule === "string").map((d) => ruleDumpFileName(`${d.plugin}/${d.rule}`)));
|
|
1375
1369
|
} catch {
|
|
1376
1370
|
return /* @__PURE__ */ new Set();
|
|
@@ -1378,10 +1372,10 @@ const readPreviousRuleDumpFileNames = (directory) => {
|
|
|
1378
1372
|
};
|
|
1379
1373
|
const writeDiagnosticsDirectory = (diagnostics, outputDirectory) => {
|
|
1380
1374
|
const directory = outputDirectory ? path$1.resolve(outputDirectory) : path$1.join(tmpdir(), `react-doctor-${randomUUID()}`);
|
|
1381
|
-
if (outputDirectory) for (const fileName of readPreviousRuleDumpFileNames(directory)) fs$
|
|
1382
|
-
fs$
|
|
1383
|
-
for (const [ruleKey, ruleDiagnostics] of buildSortedRuleGroups(diagnostics)) fs$
|
|
1384
|
-
fs$
|
|
1375
|
+
if (outputDirectory) for (const fileName of readPreviousRuleDumpFileNames(directory)) fs$2.rmSync(path$1.join(directory, fileName), { force: true });
|
|
1376
|
+
fs$2.mkdirSync(directory, { recursive: true });
|
|
1377
|
+
for (const [ruleKey, ruleDiagnostics] of buildSortedRuleGroups(diagnostics)) fs$2.writeFileSync(path$1.join(directory, ruleDumpFileName(ruleKey)), formatRuleSummary(ruleKey, ruleDiagnostics));
|
|
1378
|
+
fs$2.writeFileSync(path$1.join(directory, "diagnostics.json"), JSON.stringify(diagnostics));
|
|
1385
1379
|
return directory;
|
|
1386
1380
|
};
|
|
1387
1381
|
//#endregion
|
|
@@ -1425,6 +1419,9 @@ const formatElapsedTime = (elapsedMilliseconds) => {
|
|
|
1425
1419
|
return `${(elapsedMilliseconds / MILLISECONDS_PER_SECOND).toFixed(1)}s`;
|
|
1426
1420
|
};
|
|
1427
1421
|
//#endregion
|
|
1422
|
+
//#region src/cli/utils/format-skipped-check-label.ts
|
|
1423
|
+
const formatSkippedCheckLabel = (skippedCheck) => skippedCheck === "dead-code" ? "maintainability" : skippedCheck;
|
|
1424
|
+
//#endregion
|
|
1428
1425
|
//#region src/cli/utils/pluralize.ts
|
|
1429
1426
|
const pluralize = (count, singularNoun) => `${count} ${singularNoun}${count === 1 ? "" : "s"}`;
|
|
1430
1427
|
//#endregion
|
|
@@ -1473,7 +1470,7 @@ const printHeadlessReport = (input) => gen(function* () {
|
|
|
1473
1470
|
}
|
|
1474
1471
|
if (input.skippedChecks.length > 0) {
|
|
1475
1472
|
yield* log("");
|
|
1476
|
-
yield* warn(highlighter.warn(`Results are incomplete: ${input.skippedChecks.join(" and ")} checks failed.`));
|
|
1473
|
+
yield* warn(highlighter.warn(`Results are incomplete: ${input.skippedChecks.map(formatSkippedCheckLabel).join(" and ")} checks failed.`));
|
|
1477
1474
|
}
|
|
1478
1475
|
});
|
|
1479
1476
|
//#endregion
|
|
@@ -1673,12 +1670,39 @@ const renderAndRecordScan = async (input) => {
|
|
|
1673
1670
|
didDeadCodeFail: input.payload.didDeadCodeFail,
|
|
1674
1671
|
supplyChainOverlapTimedOut: input.payload.supplyChainOverlapTimedOut,
|
|
1675
1672
|
securityScanFailed: input.payload.securityScanFailed,
|
|
1676
|
-
deadCodeOverlapped: input.payload.deadCodeOverlapped,
|
|
1677
1673
|
suppressedRuleCounts: input.payload.suppressedRuleCounts ?? []
|
|
1678
1674
|
});
|
|
1679
1675
|
return result;
|
|
1680
1676
|
};
|
|
1681
1677
|
//#endregion
|
|
1678
|
+
//#region src/cli/utils/copy-unchanged-baseline-sources.ts
|
|
1679
|
+
const copyUnchangedBaselineSources = async (input) => {
|
|
1680
|
+
const baseMaterializedFiles = new Set(input.baseMaterializedFiles.map(toForwardSlashes));
|
|
1681
|
+
const headChangedFiles = new Set(input.headChangedFiles.map(toForwardSlashes));
|
|
1682
|
+
const untrackedFiles = new Set(input.untrackedFiles.map(toForwardSlashes));
|
|
1683
|
+
const sourceDirectory = path$1.resolve(input.directory);
|
|
1684
|
+
const targetDirectory = path$1.resolve(input.tempDirectory);
|
|
1685
|
+
return (await mapWithConcurrency(input.sourceFiles.filter((filePath) => {
|
|
1686
|
+
const normalizedPath = toForwardSlashes(filePath);
|
|
1687
|
+
return !baseMaterializedFiles.has(normalizedPath) && !headChangedFiles.has(normalizedPath) && !untrackedFiles.has(normalizedPath);
|
|
1688
|
+
}), 32, async (filePath) => {
|
|
1689
|
+
input.signal?.throwIfAborted();
|
|
1690
|
+
if (input.deadlineEpochMs !== null && Date.now() >= input.deadlineEpochMs) return false;
|
|
1691
|
+
const sourcePath = path$1.resolve(sourceDirectory, filePath);
|
|
1692
|
+
const targetPath = path$1.resolve(targetDirectory, filePath);
|
|
1693
|
+
if (!isPathInsideDirectory(sourcePath, sourceDirectory) || !isPathInsideDirectory(targetPath, targetDirectory)) return false;
|
|
1694
|
+
try {
|
|
1695
|
+
if (!(await fs$1.lstat(sourcePath)).isFile()) return false;
|
|
1696
|
+
await fs$1.mkdir(path$1.dirname(targetPath), { recursive: true });
|
|
1697
|
+
await fs$1.copyFile(sourcePath, targetPath);
|
|
1698
|
+
return true;
|
|
1699
|
+
} catch {
|
|
1700
|
+
input.signal?.throwIfAborted();
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
})).every(Boolean);
|
|
1704
|
+
};
|
|
1705
|
+
//#endregion
|
|
1682
1706
|
//#region src/cli/utils/read-diagnostic-evidence.ts
|
|
1683
1707
|
const SOURCE_EXTENSIONS = [
|
|
1684
1708
|
".ts",
|
|
@@ -2096,7 +2120,6 @@ const resolveMergeBaseRef = async (directory, ref) => {
|
|
|
2096
2120
|
const silentConsole$1 = makeNoopConsole();
|
|
2097
2121
|
const countIncompleteLintFiles = (lintPartialFailures) => countDroppedLintFiles(lintPartialFailures) + countDeadlineSkippedFiles(lintPartialFailures);
|
|
2098
2122
|
const runBaselineComparison = async (input) => {
|
|
2099
|
-
const temporaryDirectory = mkdtempSync(path.join(tmpdir(), BASELINE_FILES_TEMP_DIR_PREFIX));
|
|
2100
2123
|
const baselineIncludePaths = filterPathsOutsideDirectories({
|
|
2101
2124
|
rootDirectory: input.directory,
|
|
2102
2125
|
relativePaths: input.options.includePaths,
|
|
@@ -2112,12 +2135,24 @@ const runBaselineComparison = async (input) => {
|
|
|
2112
2135
|
relativePaths: input.headFiles,
|
|
2113
2136
|
excludedDirectories: input.options.excludedProjectDirectories
|
|
2114
2137
|
}) : void 0;
|
|
2138
|
+
const remainingBaselineBudgetMs = input.deadlineEpochMs === null ? null : remainingDeadlineBudgetMs(input.deadlineEpochMs);
|
|
2139
|
+
if (remainingBaselineBudgetMs === 0) return null;
|
|
2140
|
+
const baselineDeadlineSignal = remainingBaselineBudgetMs === null ? void 0 : AbortSignal.timeout(remainingBaselineBudgetMs);
|
|
2141
|
+
const baselineListingSignal = baselineDeadlineSignal === void 0 ? input.oxlintRuntime.abortSignal : input.oxlintRuntime.abortSignal === void 0 ? baselineDeadlineSignal : AbortSignal.any([input.oxlintRuntime.abortSignal, baselineDeadlineSignal]);
|
|
2142
|
+
let maintainabilitySourceFiles = [];
|
|
2143
|
+
if (input.options.deadCode) try {
|
|
2144
|
+
maintainabilitySourceFiles = (await listSourceFilesCooperative(input.directory, baselineListingSignal)).filter((filePath) => JSX_DUPLICATION_SOURCE_FILE_PATTERN.test(filePath) && classifyFileContext(filePath) === "production");
|
|
2145
|
+
} catch (error) {
|
|
2146
|
+
if (baselineDeadlineSignal?.aborted) return null;
|
|
2147
|
+
throw error;
|
|
2148
|
+
}
|
|
2149
|
+
const temporaryDirectory = mkdtempSync(path.join(tmpdir(), BASELINE_FILES_TEMP_DIR_PREFIX));
|
|
2115
2150
|
const snapshot = await materializeBaselineFiles({
|
|
2116
2151
|
directory: input.directory,
|
|
2117
2152
|
ref: input.baselineRef,
|
|
2118
|
-
files: baselineIncludePaths,
|
|
2119
|
-
baseFiles: baselineBaseFiles,
|
|
2120
|
-
headFiles: baselineHeadFiles,
|
|
2153
|
+
files: input.options.deadCode ? input.options.includePaths : baselineIncludePaths,
|
|
2154
|
+
baseFiles: input.options.deadCode ? input.baseFiles : baselineBaseFiles,
|
|
2155
|
+
headFiles: input.options.deadCode ? input.headFiles : baselineHeadFiles,
|
|
2121
2156
|
tempDirectory: temporaryDirectory
|
|
2122
2157
|
}).catch((error) => {
|
|
2123
2158
|
rmSync(temporaryDirectory, {
|
|
@@ -2135,22 +2170,47 @@ const runBaselineComparison = async (input) => {
|
|
|
2135
2170
|
}
|
|
2136
2171
|
try {
|
|
2137
2172
|
if (!snapshot.isComplete) return null;
|
|
2173
|
+
if (input.options.deadCode && !await copyUnchangedBaselineSources({
|
|
2174
|
+
directory: input.directory,
|
|
2175
|
+
sourceFiles: maintainabilitySourceFiles,
|
|
2176
|
+
baseMaterializedFiles: snapshot.materializedFiles,
|
|
2177
|
+
headChangedFiles: snapshot.headFiles,
|
|
2178
|
+
untrackedFiles: snapshot.untrackedFiles,
|
|
2179
|
+
tempDirectory: snapshot.tempDirectory,
|
|
2180
|
+
deadlineEpochMs: input.deadlineEpochMs,
|
|
2181
|
+
signal: input.oxlintRuntime.abortSignal
|
|
2182
|
+
})) return null;
|
|
2183
|
+
const filteredSnapshotBaseFiles = filterPathsOutsideDirectories({
|
|
2184
|
+
rootDirectory: input.directory,
|
|
2185
|
+
relativePaths: snapshot.baseFiles,
|
|
2186
|
+
excludedDirectories: input.options.excludedProjectDirectories
|
|
2187
|
+
});
|
|
2188
|
+
const filteredSnapshotHeadFiles = filterPathsOutsideDirectories({
|
|
2189
|
+
rootDirectory: input.directory,
|
|
2190
|
+
relativePaths: snapshot.headFiles,
|
|
2191
|
+
excludedDirectories: input.options.excludedProjectDirectories
|
|
2192
|
+
});
|
|
2138
2193
|
const analyzedHeadFiles = new Set(input.headAnalyzedFiles.map(toForwardSlashes));
|
|
2139
|
-
const baseFiles = new Set(
|
|
2140
|
-
const expectedHeadFiles = new Set(
|
|
2194
|
+
const baseFiles = new Set((baselineBaseFiles ?? filteredSnapshotBaseFiles).map(toForwardSlashes));
|
|
2195
|
+
const expectedHeadFiles = new Set((baselineHeadFiles ?? filteredSnapshotHeadFiles).map(toForwardSlashes));
|
|
2141
2196
|
for (const filePath of baselineIncludePaths) {
|
|
2142
2197
|
const normalizedFilePath = toForwardSlashes(filePath);
|
|
2143
2198
|
if (!baseFiles.has(normalizedFilePath)) expectedHeadFiles.add(normalizedFilePath);
|
|
2144
2199
|
}
|
|
2145
|
-
if (filterSourceFiles([...expectedHeadFiles]).some((filePath) => !analyzedHeadFiles.has(filePath))) return null;
|
|
2200
|
+
if (input.options.lint && filterSourceFiles([...expectedHeadFiles]).some((filePath) => !analyzedHeadFiles.has(filePath))) return null;
|
|
2201
|
+
const baselineLintPaths = new Set([...baselineIncludePaths, ...filteredSnapshotBaseFiles].map(toForwardSlashes));
|
|
2202
|
+
const materializedLintPaths = snapshot.materializedFiles.filter((filePath) => baselineLintPaths.has(toForwardSlashes(filePath)));
|
|
2203
|
+
const maintainabilityFocusPaths = [...new Set([...input.options.includePaths, ...snapshot.baseFiles].map(toForwardSlashes))];
|
|
2204
|
+
const baselineExcludedProjectDirectories = input.options.excludedProjectDirectories.map((excludedDirectory) => path.resolve(excludedDirectory)).filter((excludedDirectory) => isPathInsideDirectory(excludedDirectory, input.directory)).map((excludedDirectory) => path.resolve(snapshot.tempDirectory, path.relative(input.directory, excludedDirectory)));
|
|
2205
|
+
const baseIncludePaths = materializedLintPaths.length > 0 ? materializedLintPaths : maintainabilityFocusPaths;
|
|
2146
2206
|
const runtimeLayers = buildRuntimeLayers({
|
|
2147
2207
|
directory: snapshot.tempDirectory,
|
|
2148
2208
|
hasConfigOverride: true,
|
|
2149
2209
|
userConfig: input.userConfig,
|
|
2150
2210
|
configSourceDirectory: input.configSourceDirectory,
|
|
2151
2211
|
projectInfoOverride: input.headProjectInfo,
|
|
2152
|
-
shouldSkipLint: !input.options.lint || !input.resolvedNodeBinaryPath,
|
|
2153
|
-
shouldRunDeadCode:
|
|
2212
|
+
shouldSkipLint: !input.options.lint || !input.resolvedNodeBinaryPath || materializedLintPaths.length === 0,
|
|
2213
|
+
shouldRunDeadCode: input.options.deadCode,
|
|
2154
2214
|
shouldRunSupplyChain: input.options.supplyChain,
|
|
2155
2215
|
shouldComputeScore: false,
|
|
2156
2216
|
shouldShowProgressSpinners: false,
|
|
@@ -2159,7 +2219,8 @@ const runBaselineComparison = async (input) => {
|
|
|
2159
2219
|
});
|
|
2160
2220
|
const baseOutput = await runPromise(restoreLegacyThrow(runInspect({
|
|
2161
2221
|
directory: snapshot.tempDirectory,
|
|
2162
|
-
includePaths:
|
|
2222
|
+
includePaths: baseIncludePaths,
|
|
2223
|
+
maintainabilityFocusPaths,
|
|
2163
2224
|
customRulesOnly: input.options.customRulesOnly,
|
|
2164
2225
|
respectInlineDisables: input.options.respectInlineDisables,
|
|
2165
2226
|
warnings: input.options.warnings,
|
|
@@ -2168,7 +2229,7 @@ const runBaselineComparison = async (input) => {
|
|
|
2168
2229
|
includedTags: input.options.includedTags,
|
|
2169
2230
|
includeTagDefaults: input.options.includeTagDefaults,
|
|
2170
2231
|
nodeBinaryPath: input.resolvedNodeBinaryPath ?? void 0,
|
|
2171
|
-
runDeadCode:
|
|
2232
|
+
runDeadCode: input.options.deadCode,
|
|
2172
2233
|
isCi: input.options.isCi,
|
|
2173
2234
|
doctorVersion: VERSION,
|
|
2174
2235
|
runId: getRunId(),
|
|
@@ -2176,10 +2237,16 @@ const runBaselineComparison = async (input) => {
|
|
|
2176
2237
|
suppressScanSummary: true,
|
|
2177
2238
|
supplyChainManifestChanged: input.options.supplyChainManifestChanged,
|
|
2178
2239
|
deadlineEpochMs: input.deadlineEpochMs ?? void 0,
|
|
2179
|
-
signal: input.oxlintRuntime.abortSignal
|
|
2240
|
+
signal: input.oxlintRuntime.abortSignal,
|
|
2241
|
+
excludedProjectDirectories: baselineExcludedProjectDirectories,
|
|
2242
|
+
retainExcludedProjectDeadCodeDiagnostics: input.options.retainExcludedProjectDeadCodeDiagnostics
|
|
2180
2243
|
}, {}).pipe(provide(runtimeLayers), provideService(PerFileLintCacheEnabled, false), provideService(SidecarLintCacheEnabled, false), provideService(Console, silentConsole$1))), { signal: input.oxlintRuntime.abortSignal });
|
|
2181
|
-
if (baseOutput.didLintFail || countIncompleteLintFiles(baseOutput.lintPartialFailures) > 0) return null;
|
|
2182
|
-
const hasUnscannedUntrackedSourceFiles = filterSourceFiles(
|
|
2244
|
+
if (baseOutput.didLintFail || baseOutput.didDeadCodeFail || countIncompleteLintFiles(baseOutput.lintPartialFailures) > 0) return null;
|
|
2245
|
+
const hasUnscannedUntrackedSourceFiles = filterSourceFiles(filterPathsOutsideDirectories({
|
|
2246
|
+
rootDirectory: input.directory,
|
|
2247
|
+
relativePaths: snapshot.untrackedFiles,
|
|
2248
|
+
excludedDirectories: input.options.excludedProjectDirectories
|
|
2249
|
+
}).map(toForwardSlashes)).some((filePath) => !analyzedHeadFiles.has(filePath));
|
|
2183
2250
|
const diagnosticDelta = computeDiagnosticDelta({
|
|
2184
2251
|
headDiagnostics: input.headDiagnostics,
|
|
2185
2252
|
baseDiagnostics: baseOutput.diagnostics,
|
|
@@ -2352,6 +2419,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
2352
2419
|
directory,
|
|
2353
2420
|
precomputedSourceFileCount: options.precomputedSourceFileCount,
|
|
2354
2421
|
includePaths: options.includePaths,
|
|
2422
|
+
changedLineRanges: options.changedLineRanges ?? void 0,
|
|
2355
2423
|
customRulesOnly: options.customRulesOnly,
|
|
2356
2424
|
respectInlineDisables: options.respectInlineDisables,
|
|
2357
2425
|
warnings: options.warnings,
|
|
@@ -2382,7 +2450,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
2382
2450
|
else runSync(error(highlighter.error(lintFailureReason)));
|
|
2383
2451
|
let inspectDiagnostics = output.diagnostics;
|
|
2384
2452
|
let baselineDelta;
|
|
2385
|
-
if (options.baseline && isDiffMode && !didLintFail && countIncompleteLintFiles(output.lintPartialFailures) === 0) {
|
|
2453
|
+
if (options.baseline && isDiffMode && !didLintFail && !output.didDeadCodeFail && countIncompleteLintFiles(output.lintPartialFailures) === 0) {
|
|
2386
2454
|
const comparison = await runBaselineComparison({
|
|
2387
2455
|
directory,
|
|
2388
2456
|
options,
|
|
@@ -2535,13 +2603,13 @@ const resolveCursorBundledNode = () => {
|
|
|
2535
2603
|
if (!localAppData) return null;
|
|
2536
2604
|
const cursorAgentRoot = path$1.join(localAppData, "cursor-agent", "versions");
|
|
2537
2605
|
try {
|
|
2538
|
-
const versions = fs$
|
|
2606
|
+
const versions = fs$2.readdirSync(cursorAgentRoot);
|
|
2539
2607
|
if (versions.length === 0) return null;
|
|
2540
2608
|
const sortedVersions = versions.sort((a, b) => b.localeCompare(a, void 0, { numeric: true }));
|
|
2541
2609
|
for (const version of sortedVersions) try {
|
|
2542
2610
|
const bundledNodePath = path$1.join(cursorAgentRoot, version, "node.exe");
|
|
2543
2611
|
const entryScriptPath = path$1.join(cursorAgentRoot, version, "index.js");
|
|
2544
|
-
if (fs$
|
|
2612
|
+
if (fs$2.statSync(bundledNodePath).isFile() && fs$2.statSync(entryScriptPath).isFile()) return {
|
|
2545
2613
|
command: bundledNodePath,
|
|
2546
2614
|
args: [entryScriptPath]
|
|
2547
2615
|
};
|
|
@@ -2555,15 +2623,15 @@ const resolveWindowsCmdEntryScript = (command) => {
|
|
|
2555
2623
|
for (const directory of pathDirectories) {
|
|
2556
2624
|
const cmdFilePath = path$1.join(directory, `${command}.cmd`);
|
|
2557
2625
|
try {
|
|
2558
|
-
if (!fs$
|
|
2626
|
+
if (!fs$2.statSync(cmdFilePath).isFile()) continue;
|
|
2559
2627
|
} catch {
|
|
2560
2628
|
continue;
|
|
2561
2629
|
}
|
|
2562
2630
|
try {
|
|
2563
|
-
const entryScriptMatch = fs$
|
|
2631
|
+
const entryScriptMatch = fs$2.readFileSync(cmdFilePath, "utf8").match(/"%(?:~dp0|dp0%)\\([^"]+\.(?:m?js|cjs))"/);
|
|
2564
2632
|
if (!entryScriptMatch) continue;
|
|
2565
2633
|
const resolvedScriptPath = path$1.resolve(directory, entryScriptMatch[1]);
|
|
2566
|
-
if (fs$
|
|
2634
|
+
if (fs$2.statSync(resolvedScriptPath).isFile()) return resolvedScriptPath;
|
|
2567
2635
|
} catch {}
|
|
2568
2636
|
}
|
|
2569
2637
|
return null;
|
|
@@ -2889,7 +2957,7 @@ const buildCodeFrame = (input) => {
|
|
|
2889
2957
|
const absolutePath = resolveAbsolutePath(input.filePath, input.rootDirectory);
|
|
2890
2958
|
let source;
|
|
2891
2959
|
try {
|
|
2892
|
-
source = fs$
|
|
2960
|
+
source = fs$2.readFileSync(absolutePath, "utf8");
|
|
2893
2961
|
} catch {
|
|
2894
2962
|
return null;
|
|
2895
2963
|
}
|
|
@@ -2910,7 +2978,7 @@ const buildCodeFrame = (input) => {
|
|
|
2910
2978
|
const discoverWorkspacePackages = (rootDirectory) => {
|
|
2911
2979
|
const hasRootPackageJson = isFile(path$1.join(rootDirectory, "package.json"));
|
|
2912
2980
|
const packages = listWorkspacePackages(rootDirectory);
|
|
2913
|
-
if (packages.length === 0 && (!hasRootPackageJson || isMonorepoRoot(rootDirectory))) return
|
|
2981
|
+
if (packages.length === 0 && (!hasRootPackageJson || isMonorepoRoot(rootDirectory))) return discoverSupportedSubprojects(rootDirectory);
|
|
2914
2982
|
return packages;
|
|
2915
2983
|
};
|
|
2916
2984
|
const selectProjects = async (rootDirectory, projectFlag, skipPrompts, configProjects) => {
|
|
@@ -3026,7 +3094,7 @@ const shouldFailScanGate = (input) => {
|
|
|
3026
3094
|
return shouldBlockCi(filterScansForSurface(input.scans, "ciFailure"), input.blockingLevel);
|
|
3027
3095
|
};
|
|
3028
3096
|
//#endregion
|
|
3029
|
-
export { resolveMergeBaseRef as A,
|
|
3097
|
+
export { resolveMergeBaseRef as A, buildNoScoreMessage as B, copyToClipboard as C, deduplicateProjectScans as D, collectProjectSourceFileCounts as E, printFooter as F, formatFixRecipeLine as G, hasLintHardFailure as H, printDiagnosticsDump as I, formatLearnMoreLine as K, formatDiagnosticSite as L, pluralize as M, formatSkippedCheckLabel as N, createInvocationInspect as O, formatElapsedTime as P, hasIncompleteScoreAnalysis as R, CLI_AGENT_BINARIES as S, buildHandoffPayload as T, buildRulePriorityMap as U, buildEmptyReportMessage as V, buildSortedRuleGroups as W, resolveCliInspectOptions as _, projectManifestChanged as a, setUpGitHubActions as b, selectProjects as c, resolveProjectChangedLineRanges as d, resolveProjectDiffIncludePaths as f, resolveWorkspaceDeadCodeOwner as g, retryMissingProjectScores as h, validateModeFlags as i, printHeadlessReport as j, inspect as k, buildCodeFrame as l, resolveProjectRelativeDirectory as m, formatSkippedProjectsMessage as n, partitionProjectScanOutcomes as o, resolveProjectSourceFilePaths as p, validateIncludeUntrackedScope as r, discoverWorkspacePackages as s, shouldFailScanGate as t, resolveProjectScan as u, filterScansForSurface as v, launchCliAgent as w, detectLaunchableAgents as x, countUniqueScannedFiles as y, filterDiagnosticsByCategories as z };
|
|
3030
3098
|
|
|
3031
|
-
//# sourceMappingURL=should-fail-scan-gate-
|
|
3032
|
-
//# debugId=
|
|
3099
|
+
//# sourceMappingURL=should-fail-scan-gate-Dch9vbPz.js.map
|
|
3100
|
+
//# debugId=19bff337-5a1f-5558-b6b7-bd4274f53f38
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { z as isNonInteractiveEnvironment } from "./record-metric-
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1835ead5-8913-5fe5-a0fa-4de3e400bee0")}catch(e){}}();
|
|
3
|
+
import { z as isNonInteractiveEnvironment } from "./record-metric-fdCvvcjz.js";
|
|
4
4
|
//#region src/cli/utils/should-skip-prompts.ts
|
|
5
5
|
const shouldSkipPrompts = (input = {}) => Boolean(input.yes) || Boolean(input.json) || isNonInteractiveEnvironment() || !process.stdin.isTTY;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { shouldSkipPrompts as t };
|
|
8
8
|
|
|
9
|
-
//# sourceMappingURL=should-skip-prompts-
|
|
10
|
-
//# debugId=
|
|
9
|
+
//# sourceMappingURL=should-skip-prompts-CyNdARgB.js.map
|
|
10
|
+
//# debugId=1835ead5-8913-5fe5-a0fa-4de3e400bee0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import {
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9c17a65b-1eeb-5572-8f88-8abf23cb6ab2")}catch(e){}}();
|
|
3
|
+
import { Hn as buildWithScope, Jt as isProjectDiscoveryError, Kn as close, Ln as runPromise, On as make, Qt as layerObservability, R as CliInputError, Rn as runSync, Sr as messageFromUnknown, Yn as void_, Yt as isReactDoctorError, g as VERSION, i as isTelemetryEnabled, qn as makeUnsafe, yr as isErrnoException } from "./record-metric-fdCvvcjz.js";
|
|
4
4
|
//#region src/cli/utils/is-environment-error.ts
|
|
5
5
|
const ENVIRONMENT_ERROR_CODES = new Set([
|
|
6
6
|
"EACCES",
|
|
@@ -153,11 +153,8 @@ let pendingShutdown = null;
|
|
|
153
153
|
*
|
|
154
154
|
* Returns `null` when telemetry is disabled or unconfigured, which is what keeps
|
|
155
155
|
* `--no-telemetry` and unconfigured builds from opening a scope at all.
|
|
156
|
-
*
|
|
157
|
-
* `exportIntervalMs` lets a long-running process (the language server) ship
|
|
158
|
-
* telemetry periodically instead of only at shutdown.
|
|
159
156
|
*/
|
|
160
|
-
const getTelemetryContext = (
|
|
157
|
+
const getTelemetryContext = () => {
|
|
161
158
|
if (isBuilt) return telemetryContext;
|
|
162
159
|
isBuilt = true;
|
|
163
160
|
if (!isTelemetryEnabled()) return null;
|
|
@@ -165,10 +162,7 @@ const getTelemetryContext = (overrides = {}) => {
|
|
|
165
162
|
if (options === null && !isUserOtlpConfigured()) return null;
|
|
166
163
|
try {
|
|
167
164
|
const scope = makeUnsafe();
|
|
168
|
-
telemetryContext = runSync(buildWithScope(layerObservability(options
|
|
169
|
-
...options,
|
|
170
|
-
...overrides
|
|
171
|
-
}), scope));
|
|
165
|
+
telemetryContext = runSync(buildWithScope(layerObservability(options), scope));
|
|
172
166
|
telemetryScope = scope;
|
|
173
167
|
} catch {
|
|
174
168
|
telemetryContext = null;
|
|
@@ -223,5 +217,5 @@ const unrefStdin = () => {
|
|
|
223
217
|
//#endregion
|
|
224
218
|
export { setActiveRunTrace as a, isExpectedUserError as c, recordRunTraceId as i, formatEnvironmentError as l, getActiveRunTrace as n, getTelemetryContext as o, getLastRunTraceId as r, shutdownTelemetry as s, unrefStdin as t, isEnvironmentError as u };
|
|
225
219
|
|
|
226
|
-
//# sourceMappingURL=unref-stdin-
|
|
227
|
-
//# debugId=
|
|
220
|
+
//# sourceMappingURL=unref-stdin-Cynhx9N1.js.map
|
|
221
|
+
//# debugId=9c17a65b-1eeb-5572-8f88-8abf23cb6ab2
|