ttsc 0.31.0 → 0.31.2
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/cmd/platform/main.go +2 -2
- package/internal/sourceprocess/contain_windows.go +10 -13
- package/internal/sourceprocess/started_windows.go +41 -0
- package/internal/sourceprocess/windows_started_publication_distinguishes_pending_from_refusal_test.go +76 -0
- package/internal/watchhelper/run.go +30 -20
- package/internal/watchhelper/run_other.go +4 -4
- package/internal/watchhelper/run_windows.go +471 -0
- package/internal/watchhelper/watchhelper.go +8 -2
- package/internal/watchhelper/windows_notifications_preserve_mutations_without_access_noise_test.go +506 -0
- package/lib/compiler/internal/build/BuildExecution.d.ts +4 -2
- package/lib/compiler/internal/build/BuildExecution.js +40 -12
- package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
- package/lib/compiler/internal/startResidentTransform.js +5 -4
- package/lib/compiler/internal/startResidentTransform.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +9 -7
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/internal/javascriptRuntimeCapabilities.d.ts +13 -4
- package/lib/internal/javascriptRuntimeCapabilities.js +56 -6
- package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
- package/lib/internal/nativeBinary.d.ts +3 -3
- package/lib/internal/nativeBinary.js +3 -3
- package/lib/internal/pluginSource.d.ts +1 -0
- package/lib/internal/pluginSource.js +1 -0
- package/lib/internal/pluginSource.js.map +1 -1
- package/lib/internal/resolveNodeBinary.d.ts +6 -1
- package/lib/internal/resolveNodeBinary.js +6 -2
- package/lib/internal/resolveNodeBinary.js.map +1 -1
- package/lib/internal/runtimeExecutableIdentity.d.ts +22 -13
- package/lib/internal/runtimeExecutableIdentity.js +192 -102
- package/lib/internal/runtimeExecutableIdentity.js.map +1 -1
- package/lib/launcher/internal/runtime/installRuntimeHooks.js +58 -4
- package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.d.ts +5 -1
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js +7 -2
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js.map +1 -1
- package/lib/launcher/internal/ttscserver/runTtscserver.js +8 -1
- package/lib/launcher/internal/ttscserver/runTtscserver.js.map +1 -1
- package/lib/plugin/internal/CapabilityResolutionFormat.d.ts +21 -62
- package/lib/plugin/internal/CapabilityResolutionFormat.js +15 -106
- package/lib/plugin/internal/CapabilityResolutionFormat.js.map +1 -1
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +6 -0
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +4 -4
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
- package/lib/plugin/internal/load/loadProjectPlugins.d.ts +24 -14
- package/lib/plugin/internal/load/loadProjectPlugins.js +141 -56
- package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/internal/readCapabilityResolution.d.ts +6 -0
- package/lib/plugin/internal/readCapabilityResolution.js +8 -5
- package/lib/plugin/internal/readCapabilityResolution.js.map +1 -1
- package/lib/plugin/internal/source/GoEnvironmentReading.d.ts +48 -0
- package/lib/plugin/internal/source/GoEnvironmentReading.js +156 -0
- package/lib/plugin/internal/source/GoEnvironmentReading.js.map +1 -0
- package/lib/plugin/internal/source/NativeSourcePackages.d.ts +51 -13
- package/lib/plugin/internal/source/NativeSourcePackages.js +182 -27
- package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +42 -3
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +68 -7
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
- package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.d.ts +5 -3
- package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.js +14 -8
- package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.js.map +1 -1
- package/lib/plugin/internal/source/PluginContentIdentities.d.ts +265 -0
- package/lib/plugin/internal/source/PluginContentIdentities.js +452 -0
- package/lib/plugin/internal/source/PluginContentIdentities.js.map +1 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.d.ts +63 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.js +128 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.js.map +1 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.d.ts +10 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js +12 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js.map +1 -1
- package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +53 -19
- package/lib/plugin/internal/source/SourcePluginWorkspace.js +111 -22
- package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
- package/lib/plugin/internal/source/buildSourcePlugin.d.ts +34 -18
- package/lib/plugin/internal/source/buildSourcePlugin.js +52 -24
- package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/source/computeCacheKey.d.ts +25 -7
- package/lib/plugin/internal/source/computeCacheKey.js +85 -34
- package/lib/plugin/internal/source/computeCacheKey.js.map +1 -1
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +7 -3
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +75 -102
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildEnvironment.d.ts +8 -3
- package/lib/plugin/internal/source/pluginBuildEnvironment.js +8 -4
- package/lib/plugin/internal/source/pluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js +12 -2
- package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildVersions.d.ts +2 -2
- package/lib/plugin/internal/source/pluginBuildVersions.js +4 -17
- package/lib/plugin/internal/source/pluginBuildVersions.js.map +1 -1
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.d.ts +6 -5
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js +10 -17
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js.map +1 -1
- package/lib/plugin/internal/source/pluginSourceState.d.ts +6 -2
- package/lib/plugin/internal/source/pluginSourceState.js +20 -8
- package/lib/plugin/internal/source/pluginSourceState.js.map +1 -1
- package/lib/plugin/internal/source/pluginSourceStateHolds.d.ts +7 -2
- package/lib/plugin/internal/source/pluginSourceStateHolds.js +12 -7
- package/lib/plugin/internal/source/pluginSourceStateHolds.js.map +1 -1
- package/lib/plugin/internal/source/processPluginBuildEnvironment.d.ts +7 -2
- package/lib/plugin/internal/source/processPluginBuildEnvironment.js +8 -3
- package/lib/plugin/internal/source/processPluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/provenPluginSourceDigest.d.ts +28 -0
- package/lib/plugin/internal/source/provenPluginSourceDigest.js +41 -0
- package/lib/plugin/internal/source/provenPluginSourceDigest.js.map +1 -0
- package/lib/plugin/internal/source/pruneCacheFileRoot.d.ts +3 -2
- package/lib/plugin/internal/source/pruneCacheFileRoot.js +3 -2
- package/lib/plugin/internal/source/pruneCacheFileRoot.js.map +1 -1
- package/lib/plugin/internal/source/ttscPackageVersion.d.ts +26 -0
- package/lib/plugin/internal/source/ttscPackageVersion.js +47 -0
- package/lib/plugin/internal/source/ttscPackageVersion.js.map +1 -0
- package/lib/plugin/internal/writeCapabilityResolution.d.ts +6 -0
- package/lib/plugin/internal/writeCapabilityResolution.js +11 -7
- package/lib/plugin/internal/writeCapabilityResolution.js.map +1 -1
- package/lib/plugin/resolveCapabilityPlugins.js +67 -15
- package/lib/plugin/resolveCapabilityPlugins.js.map +1 -1
- package/package.json +8 -8
- package/src/compiler/internal/build/BuildExecution.ts +46 -13
- package/src/compiler/internal/startResidentTransform.ts +12 -3
- package/src/compiler/internal/transformProjectInMemory.ts +10 -2
- package/src/internal/javascriptRuntimeCapabilities.ts +71 -5
- package/src/internal/nativeBinary.ts +3 -3
- package/src/internal/pluginSource.ts +1 -0
- package/src/internal/resolveNodeBinary.ts +12 -1
- package/src/internal/runtimeExecutableIdentity.ts +227 -141
- package/src/launcher/internal/runtime/installRuntimeHooks.ts +68 -3
- package/src/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.ts +11 -2
- package/src/launcher/internal/ttscserver/runTtscserver.ts +18 -1
- package/src/plugin/internal/CapabilityResolutionFormat.ts +23 -107
- package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +14 -4
- package/src/plugin/internal/load/loadProjectPlugins.ts +421 -211
- package/src/plugin/internal/readCapabilityResolution.ts +17 -6
- package/src/plugin/internal/source/GoEnvironmentReading.ts +178 -0
- package/src/plugin/internal/source/NativeSourcePackages.ts +365 -48
- package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +83 -5
- package/src/plugin/internal/source/PluginBuildEnvironmentWitness.ts +18 -8
- package/src/plugin/internal/source/PluginContentIdentities.ts +563 -0
- package/src/plugin/internal/source/PluginLoadAnswers.ts +151 -0
- package/src/plugin/internal/source/SourceBuildCacheLayout.ts +14 -0
- package/src/plugin/internal/source/SourcePluginWorkspace.ts +148 -25
- package/src/plugin/internal/source/buildSourcePlugin.ts +104 -36
- package/src/plugin/internal/source/computeCacheKey.ts +129 -55
- package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +152 -105
- package/src/plugin/internal/source/pluginBuildEnvironment.ts +9 -2
- package/src/plugin/internal/source/pluginBuildEnvironmentWorker.ts +18 -2
- package/src/plugin/internal/source/pluginBuildVersions.ts +5 -26
- package/src/plugin/internal/source/pluginModuleReplaceDirectories.ts +13 -25
- package/src/plugin/internal/source/pluginSourceState.ts +28 -12
- package/src/plugin/internal/source/pluginSourceStateHolds.ts +15 -8
- package/src/plugin/internal/source/processPluginBuildEnvironment.ts +8 -2
- package/src/plugin/internal/source/provenPluginSourceDigest.ts +45 -0
- package/src/plugin/internal/source/pruneCacheFileRoot.ts +3 -2
- package/src/plugin/internal/source/ttscPackageVersion.ts +45 -0
- package/src/plugin/internal/writeCapabilityResolution.ts +29 -8
- package/src/plugin/resolveCapabilityPlugins.ts +87 -13
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
|
|
3
4
|
import { CapabilityResolutionFormat } from "./CapabilityResolutionFormat";
|
|
4
5
|
import type { ITtscCapabilityPluginSource } from "./ITtscCapabilityPluginSource";
|
|
5
6
|
import type { ITtscCapabilityResolutionEntry } from "./ITtscCapabilityResolutionEntry";
|
|
6
7
|
import { hashHostInputPaths } from "./load/hashHostInputPaths";
|
|
7
8
|
import { realpathHostInputPaths } from "./load/realpathHostInputPaths";
|
|
9
|
+
import { PluginContentIdentities } from "./source/PluginContentIdentities";
|
|
8
10
|
import { pluginSourceFilesSignature } from "./source/pluginSourceFilesSignature";
|
|
9
11
|
import { pluginSourceStateHolds } from "./source/pluginSourceStateHolds";
|
|
10
12
|
import { recordCacheFileUse } from "./source/recordCacheFileUse";
|
|
@@ -52,6 +54,12 @@ export function readCapabilityResolution(options: {
|
|
|
52
54
|
|
|
53
55
|
/** Environment selecting the cache root; ambient process env when omitted. */
|
|
54
56
|
env?: NodeJS.ProcessEnv;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Record store of the project's plugin cache, which proves the runtime and
|
|
60
|
+
* the plugin sources and SDK from metadata instead of their bytes (#1725).
|
|
61
|
+
*/
|
|
62
|
+
identities?: PluginContentIdentities.Store;
|
|
55
63
|
}): ITtscCapabilityResolutionEntry | null {
|
|
56
64
|
const file = CapabilityResolutionFormat.resolutionFile(options);
|
|
57
65
|
if (file === null) return null;
|
|
@@ -83,12 +91,14 @@ export function readCapabilityResolution(options: {
|
|
|
83
91
|
// old one still exists.
|
|
84
92
|
const sources = Object.entries(entry.pluginSources);
|
|
85
93
|
const evidence = sources.some(([, source]) => source.signature !== undefined)
|
|
86
|
-
?
|
|
87
|
-
|
|
94
|
+
? PluginContentIdentities.sourceEvidence(
|
|
95
|
+
PluginContentIdentities.mintReference(path.dirname(file)),
|
|
88
96
|
)
|
|
89
97
|
: undefined;
|
|
98
|
+
const projectRoot = path.resolve(options.cwd);
|
|
90
99
|
for (const [directory, source] of sources)
|
|
91
|
-
if (!pluginSourceProven(directory, source, evidence))
|
|
100
|
+
if (!pluginSourceProven(directory, source, evidence, projectRoot))
|
|
101
|
+
return null;
|
|
92
102
|
for (const plugin of entry.plugins)
|
|
93
103
|
if (!fs.existsSync(plugin.binary)) return null;
|
|
94
104
|
recordCacheFileUse(file);
|
|
@@ -108,8 +118,9 @@ function pluginSourceProven(
|
|
|
108
118
|
directory: string,
|
|
109
119
|
source: ITtscCapabilityPluginSource,
|
|
110
120
|
evidence:
|
|
111
|
-
| ReturnType<typeof
|
|
121
|
+
| ReturnType<typeof PluginContentIdentities.sourceEvidence>
|
|
112
122
|
| undefined,
|
|
123
|
+
projectRoot: string,
|
|
113
124
|
): boolean {
|
|
114
125
|
try {
|
|
115
126
|
const now =
|
|
@@ -123,8 +134,8 @@ function pluginSourceProven(
|
|
|
123
134
|
now.separable &&
|
|
124
135
|
now.signature === source.signature &&
|
|
125
136
|
source.digest !== undefined
|
|
126
|
-
? { sourceDigest: source.digest }
|
|
127
|
-
: {},
|
|
137
|
+
? { projectRoot, sourceDigest: source.digest }
|
|
138
|
+
: { projectRoot },
|
|
128
139
|
);
|
|
129
140
|
} catch {
|
|
130
141
|
return false;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { SidecarEnvironment } from "../../../compiler/internal/sharedHost/SidecarEnvironment";
|
|
4
|
+
import { GoSourceInputs } from "./GoSourceInputs";
|
|
5
|
+
import { PluginBuildEnvironmentWitness } from "./PluginBuildEnvironmentWitness";
|
|
6
|
+
import type { PluginContentIdentities } from "./PluginContentIdentities";
|
|
7
|
+
import { PluginLoadAnswers } from "./PluginLoadAnswers";
|
|
8
|
+
import { spawnGoTool } from "./spawnGoTool";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Acquire current Go values together with their environment-file evidence.
|
|
12
|
+
* Build digests and syntax readers share this owner; a file-location hint is
|
|
13
|
+
* never a retained positive environment verdict (#1516, #1712).
|
|
14
|
+
*
|
|
15
|
+
* @evidence contracts/common.md#principled-implementation The acquisition pairs actual Go output with native pre-read file evidence; callers retain their own completeness and reuse policy.
|
|
16
|
+
* @evidence contracts/common.md#clear-and-simple-design One namespace owns environment-file discovery and native acquisition for build and manifest clients.
|
|
17
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No handwritten default GOENV path or process-permanent environment success replaces native Go.
|
|
18
|
+
* @evidence contracts/common.md#meaningful-documentation Prose distinguishes observation from a discovery hint and identifies both consumers.
|
|
19
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation The read member owns native observation and execution.
|
|
20
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms The read member owns acquisition and identity costs.
|
|
21
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The read member owns hint sharing; no result cache is exposed.
|
|
22
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The read member describes the private hint map and delegated native lifetime.
|
|
23
|
+
*/
|
|
24
|
+
export namespace GoEnvironmentReading {
|
|
25
|
+
/**
|
|
26
|
+
* The Go environment file each Go tool and environment was last seen to name,
|
|
27
|
+
* which lets a reading witness that file before `go env` reads it.
|
|
28
|
+
*/
|
|
29
|
+
const goEnvironmentFiles = new Map<string, string | null>();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Answer family that carries the same location hint across processes, so a
|
|
33
|
+
* new process does not run `go env` once merely to learn it (#1722). A wrong
|
|
34
|
+
* or stale hint only costs the existing rediscovery run.
|
|
35
|
+
*/
|
|
36
|
+
const ENVIRONMENT_FILE_HINT = "go-environment-file";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* What chooses the file's location: `GOENV`, else `os.UserConfigDir()`
|
|
40
|
+
* (`%AppData%`, `$XDG_CONFIG_HOME`, `$HOME`, Plan 9's `$home`). The hint
|
|
41
|
+
* across processes is keyed by these alone, because a launch rarely repeats
|
|
42
|
+
* every unrelated variable, such as a per-run trace path, and a hint that
|
|
43
|
+
* misses costs the rediscovery run on every launch.
|
|
44
|
+
*/
|
|
45
|
+
const LOCATION_VARIABLES = [
|
|
46
|
+
"GOENV",
|
|
47
|
+
"APPDATA",
|
|
48
|
+
"XDG_CONFIG_HOME",
|
|
49
|
+
"HOME",
|
|
50
|
+
"home",
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Run `go env -json` for the requested keys and `GOENV`, the file `go env -w`
|
|
55
|
+
* writes, witnessing that file before the run reads it.
|
|
56
|
+
*
|
|
57
|
+
* The file decides the reading without being part of it, so only its metadata
|
|
58
|
+
* is kept, and it must be taken before the read: metadata taken after would
|
|
59
|
+
* describe an edit that landed between the two, and a reading of the old
|
|
60
|
+
* content would pass as proven. Which file `go env` reads is known only from
|
|
61
|
+
* its answer, so the file this Go tool and environment named last is
|
|
62
|
+
* witnessed first, and a reading that names another is taken again with that
|
|
63
|
+
* one witnessed. A file that keeps moving between runs leaves the reading
|
|
64
|
+
* unwitnessable, so a kept reading or a build keyed on it never holds.
|
|
65
|
+
*
|
|
66
|
+
* The location hint also comes from the record store when one is supplied, so
|
|
67
|
+
* a new process witnesses the right file on its first run instead of running
|
|
68
|
+
* `go env` once only to learn the name.
|
|
69
|
+
*
|
|
70
|
+
* @param identities Optional record store carrying the hint across processes.
|
|
71
|
+
* @returns The parsed object, or `undefined` when native acquisition or JSON
|
|
72
|
+
* object decoding failed.
|
|
73
|
+
* @evidence contracts/common.md#principled-implementation Actual Go supplies values and the environment-file path; pre-read metadata and bounded rediscovery preserve the earliest file witness instead of attaching a later state to an earlier read.
|
|
74
|
+
* @evidence contracts/common.md#clear-and-simple-design One acquisition serves build hashing and manifest syntax qualification; callers choose keys and own interpretation and cache admission.
|
|
75
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts A remembered file name is only a discovery hint. Every call executes Go, and unresolved movement marks its witness unproven rather than lending a historical positive verdict.
|
|
76
|
+
* @evidence contracts/common.md#meaningful-documentation Native paragraphs explain why file discovery can repeat and distinguish unavailable acquisition from current authority.
|
|
77
|
+
* @evidence contracts/portability.md#os-neutral-implementation Go reports its actual environment-file location; native path metadata and the existing Go process owner supply observation and execution semantics.
|
|
78
|
+
* @evidence contracts/performance.md#efficient-algorithms Hashing the complete tool/environment identity and up to three native Go queries process full name/value/output bytes. Requested keys contribute argument bytes; file discovery uses metadata rather than an SDK walk.
|
|
79
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Only file-location discovery hints are shared: in process across equal selected-tool/environment identities, and through the record store across equal selected tools and location variables, since the reading verifies any hint against the file Go reports. Current Go values and file authority are reacquired for every call.
|
|
80
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources The module retains one file-location hint per historical tool/environment identity, without eviction, but no positive reading or native handle; persisted hints belong to the single-file collector. Command capture/retirement belongs to spawnGoTool and the caller owns the transferred witness.
|
|
81
|
+
*/
|
|
82
|
+
export function read(
|
|
83
|
+
goBinary: string,
|
|
84
|
+
cwd: string,
|
|
85
|
+
env: NodeJS.ProcessEnv,
|
|
86
|
+
keys: readonly string[],
|
|
87
|
+
witness: PluginBuildEnvironmentWitness.Record | undefined,
|
|
88
|
+
identities?: PluginContentIdentities.Store,
|
|
89
|
+
): Record<string, unknown> | undefined {
|
|
90
|
+
const memo = crypto.createHash("sha256").update(goBinary);
|
|
91
|
+
for (const [key, value] of Object.entries(env).sort(([left], [right]) =>
|
|
92
|
+
left < right ? -1 : left > right ? 1 : 0,
|
|
93
|
+
)) {
|
|
94
|
+
if (value !== undefined)
|
|
95
|
+
memo.update(`\0${key.length}:${key}${value.length}:${value}`);
|
|
96
|
+
}
|
|
97
|
+
const memoKey = memo.digest("hex");
|
|
98
|
+
let named = goEnvironmentFiles.get(memoKey);
|
|
99
|
+
if (named === undefined) {
|
|
100
|
+
const hinted = PluginLoadAnswers.read(
|
|
101
|
+
identities,
|
|
102
|
+
ENVIRONMENT_FILE_HINT,
|
|
103
|
+
hintKey(goBinary, env),
|
|
104
|
+
);
|
|
105
|
+
if (hinted === null || typeof hinted === "string") named = hinted;
|
|
106
|
+
}
|
|
107
|
+
const remembered = named;
|
|
108
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
109
|
+
if (named !== undefined && named !== null)
|
|
110
|
+
PluginBuildEnvironmentWitness.add(witness, named);
|
|
111
|
+
const result = spawnGoTool(goBinary, ["env", "-json", ...keys, "GOENV"], {
|
|
112
|
+
cwd,
|
|
113
|
+
encoding: "utf8",
|
|
114
|
+
env: GoSourceInputs.goBuildEnv(goBinary, undefined, env),
|
|
115
|
+
windowsHide: true,
|
|
116
|
+
});
|
|
117
|
+
if (result.error !== undefined || result.status !== 0) return undefined;
|
|
118
|
+
let parsed: Record<string, unknown>;
|
|
119
|
+
try {
|
|
120
|
+
const decoded: unknown = JSON.parse(result.stdout);
|
|
121
|
+
if (
|
|
122
|
+
decoded === null ||
|
|
123
|
+
typeof decoded !== "object" ||
|
|
124
|
+
Array.isArray(decoded)
|
|
125
|
+
)
|
|
126
|
+
return undefined;
|
|
127
|
+
parsed = decoded as Record<string, unknown>;
|
|
128
|
+
} catch {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const reported =
|
|
132
|
+
typeof parsed.GOENV === "string" &&
|
|
133
|
+
parsed.GOENV !== "" &&
|
|
134
|
+
parsed.GOENV !== "off"
|
|
135
|
+
? parsed.GOENV
|
|
136
|
+
: null;
|
|
137
|
+
if (reported === named) {
|
|
138
|
+
goEnvironmentFiles.set(memoKey, named);
|
|
139
|
+
if (named !== remembered)
|
|
140
|
+
PluginLoadAnswers.write(
|
|
141
|
+
identities,
|
|
142
|
+
ENVIRONMENT_FILE_HINT,
|
|
143
|
+
hintKey(goBinary, env),
|
|
144
|
+
named,
|
|
145
|
+
);
|
|
146
|
+
return parsed;
|
|
147
|
+
}
|
|
148
|
+
if (named !== undefined && named !== null) witness?.delete(named);
|
|
149
|
+
named = reported;
|
|
150
|
+
goEnvironmentFiles.set(memoKey, named);
|
|
151
|
+
// No file to witness: the reading depends on none.
|
|
152
|
+
if (named === null || witness === undefined) {
|
|
153
|
+
if (named !== remembered)
|
|
154
|
+
PluginLoadAnswers.write(
|
|
155
|
+
identities,
|
|
156
|
+
ENVIRONMENT_FILE_HINT,
|
|
157
|
+
hintKey(goBinary, env),
|
|
158
|
+
named,
|
|
159
|
+
);
|
|
160
|
+
return parsed;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (named !== undefined && named !== null)
|
|
164
|
+
PluginBuildEnvironmentWitness.refuse(witness, named);
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// A wrong hint is safe: the reading compares it with the `GOENV` Go reports
|
|
169
|
+
// and runs again with the reported file witnessed.
|
|
170
|
+
function hintKey(goBinary: string, env: NodeJS.ProcessEnv): unknown {
|
|
171
|
+
return [
|
|
172
|
+
goBinary,
|
|
173
|
+
LOCATION_VARIABLES.map(
|
|
174
|
+
(name) => SidecarEnvironment.read(env, name) ?? null,
|
|
175
|
+
),
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
}
|