pinokiod 7.5.35 → 7.5.36
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/kernel/bin/conda.js +99 -121
- package/package.json +1 -1
- package/test/conda-bin.test.js +34 -125
package/kernel/bin/conda.js
CHANGED
|
@@ -69,79 +69,98 @@ const LEGACY_SSL_CERT_DIR_HOOK_FILES = [
|
|
|
69
69
|
"zz_pinokio_unset_ssl_cert_dir-win.ps1",
|
|
70
70
|
"zz_pinokio_unset_ssl_cert_dir-win.sh",
|
|
71
71
|
]
|
|
72
|
-
const
|
|
73
|
-
"
|
|
74
|
-
"site-packages",
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
'
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
72
|
+
const WINDOWS_CONDA_ACTIVATE_RELATIVE_PATHS = [
|
|
73
|
+
path.join("condabin", "_conda_activate.bat"),
|
|
74
|
+
path.join("Lib", "site-packages", "conda", "shell", "condabin", "_conda_activate.bat"),
|
|
75
|
+
]
|
|
76
|
+
const WINDOWS_CONDA_ACTIVATE_BAT = [
|
|
77
|
+
":: Copyright (C) 2012 Anaconda, Inc",
|
|
78
|
+
":: SPDX-License-Identifier: BSD-3-Clause",
|
|
79
|
+
":: Helper routine for activation, deactivation, and reactivation.",
|
|
80
|
+
"@ECHO OFF",
|
|
81
|
+
"SETLOCAL",
|
|
82
|
+
"",
|
|
83
|
+
":: Generate a unique temporary filename using a GUID to support parallel workflows",
|
|
84
|
+
":: (e.g., `start /b conda run ...`). %RANDOM% is insufficient because processes",
|
|
85
|
+
":: started simultaneously get identical time-based seeds, producing collisions.",
|
|
86
|
+
":: See: https://devblogs.microsoft.com/oldnewthing/20100617-00/?p=13673",
|
|
87
|
+
"FOR /F \"delims=\" %%G IN ('powershell -NoProfile -Command \"[guid]::NewGuid()\"') DO SET \"__conda_guid=%%G\"",
|
|
88
|
+
"SET \"__conda_tmp=%TEMP%\\__conda_tmp_%__conda_guid%.txt\"",
|
|
89
|
+
"",
|
|
90
|
+
":: Run conda command and get its output",
|
|
91
|
+
":: WARNING: This cannot be simplified into a FOR /F parsing loop because of the way",
|
|
92
|
+
":: MSDOS associates the outer quotes for usebackq. E.g., the following:",
|
|
93
|
+
":: `\"%CONDA_EXE%\" shell.cmd.exe activate \"name\"`",
|
|
94
|
+
":: Which results in the following gibberish being run:",
|
|
95
|
+
":: %CONDA_EXE%\" shell.cmd.exe activate \"environment",
|
|
96
|
+
":: Producing an error like:",
|
|
97
|
+
":: The filename, directory name, or volume label syntax is incorrect.",
|
|
98
|
+
":: Instead we run the command and store the output for subsequent processing.",
|
|
99
|
+
"\"%CONDA_EXE%\" %_CE_M% %_CE_CONDA% shell.cmd.exe %* > \"%__conda_tmp%\"",
|
|
100
|
+
"IF NOT EXIST \"%__conda_tmp%\" (",
|
|
101
|
+
" ECHO ERROR: Failed to create temp file for 'conda %*'.>&2",
|
|
102
|
+
" ECHO.>&2",
|
|
103
|
+
" ECHO This is likely a TEMP directory issue>&2",
|
|
104
|
+
" ECHO ^(permissions, disk space, or invalid path^).>&2",
|
|
105
|
+
" ECHO.>&2",
|
|
106
|
+
" ECHO Ensure TEMP or TMP environment variables point to a writable location.>&2",
|
|
107
|
+
" ECHO See: https://docs.conda.io/projects/conda/en/stable/user-guide/troubleshooting.html#temp-file-errors>&2",
|
|
108
|
+
" ENDLOCAL & EXIT /B 1",
|
|
109
|
+
") ELSE IF %ERRORLEVEL% NEQ 0 (",
|
|
110
|
+
" ECHO ERROR: 'conda %*' exited with code %ERRORLEVEL%.>&2",
|
|
111
|
+
" CALL :DELETE \"%__conda_tmp%\"",
|
|
112
|
+
" ENDLOCAL & EXIT /B 2",
|
|
113
|
+
")",
|
|
114
|
+
"",
|
|
115
|
+
":: Check if conda produced output",
|
|
116
|
+
"FOR /F \"delims=\" %%T IN (%__conda_tmp%) DO (",
|
|
117
|
+
" :: T = \"%TEMP%\\<uuid>.env\"",
|
|
118
|
+
" IF NOT EXIST \"%%T\" (",
|
|
119
|
+
" ECHO ERROR: Activation file missing for 'conda %*'.>&2",
|
|
120
|
+
" CALL :DELETE \"%__conda_tmp%\"",
|
|
121
|
+
" ENDLOCAL & EXIT /B 3",
|
|
122
|
+
" ) ELSE ENDLOCAL & @CALL :PINOKIO_APPLY_CONDA_ENV \"%%T\" \"%__conda_tmp%\" & @GOTO :EOF",
|
|
123
|
+
")",
|
|
124
|
+
"",
|
|
125
|
+
":: If we get here, the FOR loop never ran which means no output",
|
|
126
|
+
"ECHO ERROR: No output from 'conda %*'.>&2",
|
|
127
|
+
"CALL :DELETE \"%__conda_tmp%\"",
|
|
128
|
+
"ENDLOCAL & EXIT /B 5",
|
|
129
|
+
"",
|
|
130
|
+
":PINOKIO_APPLY_CONDA_ENV",
|
|
131
|
+
"@ECHO OFF",
|
|
132
|
+
"@FOR /F \"tokens=1,* delims==\" %%A IN (%~1) DO (",
|
|
133
|
+
"@IF \"%CONDA_DEBUG%\" == \"1\" ECHO DEBUG: \"%%A=%%B\">&2",
|
|
134
|
+
"@IF \"%%A\"==\"_CONDA_SCRIPT\" (",
|
|
135
|
+
"@CALL \"%%B\" || (",
|
|
136
|
+
"@ECHO ERROR: Activation script \"%%B\" failed with code %ERRORLEVEL%.>&2",
|
|
137
|
+
"@CALL :DELETE \"%~1\"",
|
|
138
|
+
"@CALL :DELETE \"%~2\"",
|
|
139
|
+
"@ECHO ON",
|
|
140
|
+
"@EXIT /B 4",
|
|
141
|
+
")",
|
|
142
|
+
") ELSE IF \"%%B\"==\"\" (",
|
|
143
|
+
"@SET \"%%A=\"",
|
|
144
|
+
") ELSE (",
|
|
145
|
+
"@SET \"%%A=%%B\"",
|
|
146
|
+
")",
|
|
147
|
+
")",
|
|
148
|
+
"@CALL :DELETE \"%~1\"",
|
|
149
|
+
"@CALL :DELETE \"%~2\"",
|
|
150
|
+
"@ECHO ON",
|
|
151
|
+
"@EXIT /B 0",
|
|
152
|
+
"",
|
|
153
|
+
":: Routine to delete a temp file if CONDA_DEBUG is not set",
|
|
154
|
+
":: usage: call :DELETE \"path/to/file\"",
|
|
155
|
+
":DELETE",
|
|
156
|
+
"IF \"%CONDA_DEBUG%\" == \"1\" (",
|
|
157
|
+
" ECHO DEBUG: Retaining temporary file \"%~1\".>&2",
|
|
158
|
+
") ELSE IF EXIST \"%~1\" (",
|
|
159
|
+
" DEL /F /Q \"%~1\" 2>NUL",
|
|
160
|
+
")",
|
|
161
|
+
"GOTO :EOF",
|
|
162
|
+
"",
|
|
163
|
+
].join("\r\n")
|
|
145
164
|
|
|
146
165
|
class Conda {
|
|
147
166
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
@@ -234,56 +253,15 @@ class Conda {
|
|
|
234
253
|
}
|
|
235
254
|
}
|
|
236
255
|
}
|
|
237
|
-
async
|
|
256
|
+
async ensureWindowsCondaActivateBat() {
|
|
238
257
|
if (this.kernel.platform !== "win32" || !(await this.hasCondaMeta())) {
|
|
239
258
|
return
|
|
240
259
|
}
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
} catch (error) {
|
|
246
|
-
if (error && error.code === "ENOENT") {
|
|
247
|
-
return
|
|
248
|
-
}
|
|
249
|
-
throw error
|
|
250
|
-
}
|
|
251
|
-
const eol = content.includes("\r\n") ? "\r\n" : "\n"
|
|
252
|
-
const routineAnchor = `${eol}:: Routine to delete a temp file if CONDA_DEBUG is not set`
|
|
253
|
-
if (!content.includes(routineAnchor)) {
|
|
254
|
-
console.warn("Could not patch Conda CMD activation echo leak; missing _conda_activate.bat routine anchor")
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
if (content.includes(WINDOWS_CONDA_ACTIVATE_PINOKIO_MARKER)) {
|
|
258
|
-
if (content.includes(`${WINDOWS_CONDA_ACTIVATE_PINOKIO_MARKER}${eol}@ECHO OFF`)) {
|
|
259
|
-
return
|
|
260
|
-
}
|
|
261
|
-
const routineStart = content.indexOf(WINDOWS_CONDA_ACTIVATE_PINOKIO_MARKER)
|
|
262
|
-
const routineAnchorIndex = content.indexOf(routineAnchor, routineStart)
|
|
263
|
-
if (routineAnchorIndex < 0) {
|
|
264
|
-
console.warn("Could not update Conda CMD activation echo patch; missing _conda_activate.bat routine anchor")
|
|
265
|
-
return
|
|
266
|
-
}
|
|
267
|
-
const patched = [
|
|
268
|
-
content.slice(0, routineStart),
|
|
269
|
-
windowsCondaActivatePatchRoutines(eol),
|
|
270
|
-
content.slice(routineAnchorIndex + eol.length),
|
|
271
|
-
].join("")
|
|
272
|
-
await fs.promises.writeFile(activatePath, patched)
|
|
273
|
-
return
|
|
260
|
+
for (const relativePath of WINDOWS_CONDA_ACTIVATE_RELATIVE_PATHS) {
|
|
261
|
+
const activatePath = this.kernel.bin.path(CONDA_ROOT_DIR, relativePath)
|
|
262
|
+
await fs.promises.mkdir(path.dirname(activatePath), { recursive: true })
|
|
263
|
+
await fs.promises.writeFile(activatePath, WINDOWS_CONDA_ACTIVATE_BAT)
|
|
274
264
|
}
|
|
275
|
-
const originalBlock = windowsCondaActivateOriginalBlock(eol)
|
|
276
|
-
if (!content.includes(originalBlock)) {
|
|
277
|
-
console.warn("Could not patch Conda CMD activation echo leak; unexpected _conda_activate.bat")
|
|
278
|
-
return
|
|
279
|
-
}
|
|
280
|
-
const patched = content
|
|
281
|
-
.replace(originalBlock, windowsCondaActivatePatchedBlock(eol))
|
|
282
|
-
.replace(
|
|
283
|
-
routineAnchor,
|
|
284
|
-
`${eol}${windowsCondaActivatePatchRoutines(eol)}:: Routine to delete a temp file if CONDA_DEBUG is not set`
|
|
285
|
-
)
|
|
286
|
-
await fs.promises.writeFile(activatePath, patched)
|
|
287
265
|
}
|
|
288
266
|
async init() {
|
|
289
267
|
if (this.kernel.homedir) {
|
|
@@ -307,7 +285,7 @@ report_errors: false`)
|
|
|
307
285
|
await this.ensureCompatibilityAlias()
|
|
308
286
|
}
|
|
309
287
|
await this.ensureWindowsOpenSslHooks()
|
|
310
|
-
await this.
|
|
288
|
+
await this.ensureWindowsCondaActivateBat()
|
|
311
289
|
}
|
|
312
290
|
}
|
|
313
291
|
async check() {
|
|
@@ -456,7 +434,7 @@ report_errors: false`)
|
|
|
456
434
|
)
|
|
457
435
|
}
|
|
458
436
|
await this.ensureWindowsOpenSslHooks()
|
|
459
|
-
await this.
|
|
437
|
+
await this.ensureWindowsCondaActivateBat()
|
|
460
438
|
await this.ensureCompatibilityAlias()
|
|
461
439
|
ondata({ raw: `Install finished\r\n` })
|
|
462
440
|
await this.kernel.bin.rm(installer, ondata)
|
package/package.json
CHANGED
package/test/conda-bin.test.js
CHANGED
|
@@ -125,56 +125,22 @@ const EXPECTED_WINDOWS_OPENSSL_HOOKS = {
|
|
|
125
125
|
].join('\n'),
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
const
|
|
129
|
-
'bin',
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
128
|
+
const WINDOWS_CONDA_ACTIVATE_PATHS = [
|
|
129
|
+
path.join('bin', 'miniforge', 'condabin', '_conda_activate.bat'),
|
|
130
|
+
path.join(
|
|
131
|
+
'bin',
|
|
132
|
+
'miniforge',
|
|
133
|
+
'Lib',
|
|
134
|
+
'site-packages',
|
|
135
|
+
'conda',
|
|
136
|
+
'shell',
|
|
137
|
+
'condabin',
|
|
138
|
+
'_conda_activate.bat'
|
|
139
|
+
),
|
|
140
|
+
]
|
|
141
|
+
const WINDOWS_CONDA_ACTIVATE_LEAK_BLOCK = [
|
|
139
142
|
' ) ELSE ENDLOCAL & (',
|
|
140
143
|
' FOR /F "tokens=1,* delims==" %%A IN (%%T) DO (',
|
|
141
|
-
' :: A, B = "key", "value"',
|
|
142
|
-
' IF "%CONDA_DEBUG%" == "1" ECHO DEBUG: "%%A=%%B">&2',
|
|
143
|
-
' IF "%%A"=="_CONDA_SCRIPT" (',
|
|
144
|
-
' :: Script execution, fast exit if activation scripts fail',
|
|
145
|
-
' CALL "%%B" || (',
|
|
146
|
-
' ECHO ERROR: Activation script "%%B" failed with code %ERRORLEVEL%.>&2',
|
|
147
|
-
' CALL :DELETE "%%T"',
|
|
148
|
-
' CALL :DELETE "%__conda_tmp%"',
|
|
149
|
-
' EXIT /B 4',
|
|
150
|
-
' )',
|
|
151
|
-
' ) ELSE IF "%%B"=="" (',
|
|
152
|
-
' :: Unset variable',
|
|
153
|
-
' SET "%%A="',
|
|
154
|
-
' ) ELSE (',
|
|
155
|
-
' :: Set variable',
|
|
156
|
-
' SET "%%A=%%B"',
|
|
157
|
-
' )',
|
|
158
|
-
' )',
|
|
159
|
-
' :: Clean up',
|
|
160
|
-
' CALL :DELETE "%%T"',
|
|
161
|
-
' CALL :DELETE "%__conda_tmp%"',
|
|
162
|
-
' EXIT /B 0',
|
|
163
|
-
' )',
|
|
164
|
-
].join('\r\n')
|
|
165
|
-
const WINDOWS_CONDA_ACTIVATE_SCRIPT = [
|
|
166
|
-
'@ECHO OFF',
|
|
167
|
-
'SETLOCAL',
|
|
168
|
-
'FOR /F "delims=" %%T IN (%__conda_tmp%) DO (',
|
|
169
|
-
' IF NOT EXIST "%%T" (',
|
|
170
|
-
' ENDLOCAL & EXIT /B 3',
|
|
171
|
-
WINDOWS_CONDA_ACTIVATE_ORIGINAL_BLOCK,
|
|
172
|
-
')',
|
|
173
|
-
'',
|
|
174
|
-
':: Routine to delete a temp file if CONDA_DEBUG is not set',
|
|
175
|
-
':DELETE',
|
|
176
|
-
'GOTO :EOF',
|
|
177
|
-
'',
|
|
178
144
|
].join('\r\n')
|
|
179
145
|
|
|
180
146
|
async function seedWindowsOpenSslHooks(root, condaRootName) {
|
|
@@ -195,11 +161,13 @@ async function seedWindowsOpenSslHooks(root, condaRootName) {
|
|
|
195
161
|
}
|
|
196
162
|
}
|
|
197
163
|
|
|
198
|
-
async function
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
164
|
+
async function seedWindowsCondaActivateScripts(root, content = 'corrupted helper\r\n') {
|
|
165
|
+
const activatePaths = WINDOWS_CONDA_ACTIVATE_PATHS.map((activatePath) => path.join(root, activatePath))
|
|
166
|
+
for (const activatePath of activatePaths) {
|
|
167
|
+
await fs.mkdir(path.dirname(activatePath), { recursive: true })
|
|
168
|
+
await fs.writeFile(activatePath, content)
|
|
169
|
+
}
|
|
170
|
+
return activatePaths
|
|
203
171
|
}
|
|
204
172
|
|
|
205
173
|
async function assertWindowsOpenSslHooksPatched(root, condaRootName) {
|
|
@@ -262,81 +230,22 @@ test('Conda init patches Windows OpenSSL hooks for legacy Miniconda roots', asyn
|
|
|
262
230
|
await assertWindowsOpenSslHooksPatched(root, 'miniconda')
|
|
263
231
|
})
|
|
264
232
|
|
|
265
|
-
test('Conda init
|
|
266
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-cmd-activate-
|
|
233
|
+
test('Conda init replaces Windows CMD activation helper files', async () => {
|
|
234
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-cmd-activate-replace-'))
|
|
267
235
|
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
268
|
-
const
|
|
236
|
+
const activatePaths = await seedWindowsCondaActivateScripts(root)
|
|
269
237
|
const conda = createConda(createKernel(root))
|
|
270
238
|
|
|
271
239
|
await conda.init()
|
|
272
|
-
const patched = await fs.readFile(activatePath, 'utf8')
|
|
273
|
-
await conda.init()
|
|
274
|
-
|
|
275
|
-
assert.equal(await fs.readFile(activatePath, 'utf8'), patched)
|
|
276
|
-
assert.equal(patched.includes(WINDOWS_CONDA_ACTIVATE_ORIGINAL_BLOCK), false)
|
|
277
|
-
assert.match(patched, /ENDLOCAL & @CALL :PINOKIO_APPLY_CONDA_ENV "%%T" "%__conda_tmp%" & @GOTO :EOF/)
|
|
278
|
-
assert.match(patched, /:PINOKIO_APPLY_CONDA_ENV\r\n@ECHO OFF/)
|
|
279
|
-
assert.match(patched, /@CALL "%%B" \|\| \(/)
|
|
280
|
-
assert.match(patched, /@ECHO ON\r\n@EXIT \/B 0/)
|
|
281
|
-
assert.match(patched, /:: Routine to delete a temp file if CONDA_DEBUG is not set/)
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
test('Conda init updates the earlier Windows CMD activation echo patch', async () => {
|
|
285
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-cmd-activate-update-patch-'))
|
|
286
|
-
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
287
|
-
const oldPatch = WINDOWS_CONDA_ACTIVATE_SCRIPT
|
|
288
|
-
.replace(
|
|
289
|
-
WINDOWS_CONDA_ACTIVATE_ORIGINAL_BLOCK,
|
|
290
|
-
' ) ELSE ENDLOCAL & @CALL :PINOKIO_APPLY_CONDA_ENV "%%T" "%__conda_tmp%" & @GOTO :EOF'
|
|
291
|
-
)
|
|
292
|
-
.replace(
|
|
293
|
-
'\r\n:: Routine to delete a temp file if CONDA_DEBUG is not set',
|
|
294
|
-
[
|
|
295
|
-
'\r\n:PINOKIO_APPLY_CONDA_ENV',
|
|
296
|
-
'@FOR /F "tokens=1,* delims==" %%A IN (%~1) DO (',
|
|
297
|
-
'@IF "%CONDA_DEBUG%" == "1" ECHO DEBUG: "%%A=%%B">&2',
|
|
298
|
-
')',
|
|
299
|
-
'@CALL :DELETE "%~1"',
|
|
300
|
-
'@CALL :DELETE "%~2"',
|
|
301
|
-
'@EXIT /B 0',
|
|
302
|
-
':: Routine to delete a temp file if CONDA_DEBUG is not set',
|
|
303
|
-
].join('\r\n')
|
|
304
|
-
)
|
|
305
|
-
const activatePath = await seedWindowsCondaActivateScript(root, oldPatch)
|
|
306
|
-
const conda = createConda(createKernel(root))
|
|
307
|
-
|
|
308
240
|
await conda.init()
|
|
309
241
|
|
|
310
|
-
const
|
|
311
|
-
assert.
|
|
312
|
-
assert.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
318
|
-
const unexpected = '@ECHO OFF\r\nREM unexpected upstream script\r\n'
|
|
319
|
-
const activatePath = await seedWindowsCondaActivateScript(root, unexpected)
|
|
320
|
-
const conda = createConda(createKernel(root))
|
|
321
|
-
|
|
322
|
-
await conda.init()
|
|
323
|
-
|
|
324
|
-
assert.equal(await fs.readFile(activatePath, 'utf8'), unexpected)
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
test('Conda init leaves Windows CMD activation script unchanged when patch anchor is missing', async () => {
|
|
328
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-cmd-activate-missing-anchor-'))
|
|
329
|
-
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
330
|
-
const missingAnchor = WINDOWS_CONDA_ACTIVATE_SCRIPT.replace(
|
|
331
|
-
'\r\n:: Routine to delete a temp file if CONDA_DEBUG is not set',
|
|
332
|
-
'\r\n:: unexpected routine header'
|
|
333
|
-
)
|
|
334
|
-
const activatePath = await seedWindowsCondaActivateScript(root, missingAnchor)
|
|
335
|
-
const conda = createConda(createKernel(root))
|
|
336
|
-
|
|
337
|
-
await conda.init()
|
|
338
|
-
|
|
339
|
-
assert.equal(await fs.readFile(activatePath, 'utf8'), missingAnchor)
|
|
242
|
+
const contents = await Promise.all(activatePaths.map((activatePath) => fs.readFile(activatePath, 'utf8')))
|
|
243
|
+
assert.equal(contents[0], contents[1])
|
|
244
|
+
assert.equal(contents[0].includes(WINDOWS_CONDA_ACTIVATE_LEAK_BLOCK), false)
|
|
245
|
+
assert.match(contents[0], /ENDLOCAL & @CALL :PINOKIO_APPLY_CONDA_ENV "%%T" "%__conda_tmp%" & @GOTO :EOF/)
|
|
246
|
+
assert.match(contents[0], /:PINOKIO_APPLY_CONDA_ENV\r\n@ECHO OFF/)
|
|
247
|
+
assert.match(contents[0], /@CALL "%%B" \|\| \(/)
|
|
248
|
+
assert.match(contents[0], /@ECHO ON\r\n@EXIT \/B 0/)
|
|
340
249
|
})
|
|
341
250
|
|
|
342
251
|
test('Conda pins Python 3.10.20 consistently across platforms', async () => {
|
|
@@ -381,7 +290,6 @@ test('Conda install keeps the Windows Python 3.10.20 SSL-fixed build pin', async
|
|
|
381
290
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-python-pin-win32-'))
|
|
382
291
|
const kernel = createKernel(root, 'win32')
|
|
383
292
|
const calls = []
|
|
384
|
-
let activatePath
|
|
385
293
|
|
|
386
294
|
kernel.bin.mods = []
|
|
387
295
|
kernel.bin.download = async () => {}
|
|
@@ -392,7 +300,6 @@ test('Conda install keeps the Windows Python 3.10.20 SSL-fixed build pin', async
|
|
|
392
300
|
const miniforge = path.join(root, 'bin', 'miniforge')
|
|
393
301
|
await fs.mkdir(path.join(miniforge, 'conda-meta'), { recursive: true })
|
|
394
302
|
await fs.writeFile(path.join(miniforge, 'python.exe'), 'fake python\n')
|
|
395
|
-
activatePath = await seedWindowsCondaActivateScript(root)
|
|
396
303
|
}
|
|
397
304
|
}
|
|
398
305
|
|
|
@@ -405,7 +312,9 @@ test('Conda install keeps the Windows Python 3.10.20 SSL-fixed build pin', async
|
|
|
405
312
|
condaInstall.message[1],
|
|
406
313
|
'conda install -y --override-channels -c conda-forge "python=3.10.20=*_1_cpython" "conda-libmamba-solver>=25.4.0"'
|
|
407
314
|
)
|
|
408
|
-
|
|
315
|
+
for (const activatePath of WINDOWS_CONDA_ACTIVATE_PATHS.map((activatePath) => path.join(root, activatePath))) {
|
|
316
|
+
assert.match(await fs.readFile(activatePath, 'utf8'), /:PINOKIO_APPLY_CONDA_ENV/)
|
|
317
|
+
}
|
|
409
318
|
})
|
|
410
319
|
|
|
411
320
|
test('Conda install replaces legacy miniconda with a compatibility alias to miniforge', async () => {
|