pinokiod 7.5.0 → 7.5.1
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-meta.js +13 -13
- package/kernel/bin/conda.js +19 -45
- package/package.json +1 -1
- package/server/index.js +2 -1
- package/test/conda-bin.test.js +14 -19
package/kernel/bin/conda-meta.js
CHANGED
|
@@ -2,21 +2,21 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const { execFile } = require('child_process')
|
|
4
4
|
|
|
5
|
-
async function buildCondaListFromMeta(
|
|
5
|
+
async function buildCondaListFromMeta(minicondaPath, useCondaList) {
|
|
6
6
|
if (!useCondaList) {
|
|
7
|
-
const metaOutput = await readFromMeta(
|
|
7
|
+
const metaOutput = await readFromMeta(minicondaPath)
|
|
8
8
|
if (metaOutput) {
|
|
9
9
|
return { response: metaOutput, source: 'conda-meta' }
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
return await runCondaList(
|
|
12
|
+
return await runCondaList(minicondaPath)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
async function readFromMeta(
|
|
16
|
-
if (!
|
|
15
|
+
async function readFromMeta(minicondaPath) {
|
|
16
|
+
if (!minicondaPath) {
|
|
17
17
|
return null
|
|
18
18
|
}
|
|
19
|
-
const metaDir = path.join(
|
|
19
|
+
const metaDir = path.join(minicondaPath, 'conda-meta')
|
|
20
20
|
let entries
|
|
21
21
|
try {
|
|
22
22
|
entries = await fs.promises.readdir(metaDir, { withFileTypes: true })
|
|
@@ -53,8 +53,8 @@ async function readFromMeta(condaRootPath) {
|
|
|
53
53
|
return lines.join('\n')
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
async function runCondaList(
|
|
57
|
-
const condaBinary = resolveCondaBinary(
|
|
56
|
+
async function runCondaList(minicondaPath) {
|
|
57
|
+
const condaBinary = resolveCondaBinary(minicondaPath)
|
|
58
58
|
if (!condaBinary) {
|
|
59
59
|
return { response: '', source: 'conda-list' }
|
|
60
60
|
}
|
|
@@ -69,18 +69,18 @@ async function runCondaList(condaRootPath) {
|
|
|
69
69
|
})
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function resolveCondaBinary(
|
|
72
|
+
function resolveCondaBinary(minicondaPath) {
|
|
73
73
|
if (process.platform === 'win32') {
|
|
74
|
-
if (
|
|
75
|
-
const scriptPath = path.join(
|
|
74
|
+
if (minicondaPath) {
|
|
75
|
+
const scriptPath = path.join(minicondaPath, 'Scripts', 'conda.exe')
|
|
76
76
|
if (fs.existsSync(scriptPath)) {
|
|
77
77
|
return scriptPath
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
return 'conda'
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
83
|
-
const binPath = path.join(
|
|
82
|
+
if (minicondaPath) {
|
|
83
|
+
const binPath = path.join(minicondaPath, 'bin', 'conda')
|
|
84
84
|
if (fs.existsSync(binPath)) {
|
|
85
85
|
return binPath
|
|
86
86
|
}
|
package/kernel/bin/conda.js
CHANGED
|
@@ -16,12 +16,7 @@ const {
|
|
|
16
16
|
const MINIFORGE_RELEASE = "26.3.2-3"
|
|
17
17
|
const MINIFORGE_BASE_URL = `https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_RELEASE}`
|
|
18
18
|
const CONDA_ROOT_DIR = "miniforge"
|
|
19
|
-
const
|
|
20
|
-
const PINOKIO_CONDA_RUNTIME = {
|
|
21
|
-
distribution: "miniforge",
|
|
22
|
-
release: MINIFORGE_RELEASE,
|
|
23
|
-
epoch: 1,
|
|
24
|
-
}
|
|
19
|
+
const LEGACY_CONDA_ROOT_DIR = "miniconda"
|
|
25
20
|
|
|
26
21
|
class Conda {
|
|
27
22
|
description = "Pinokio uses Conda to install various useful programs in an isolated manner."
|
|
@@ -54,26 +49,8 @@ class Conda {
|
|
|
54
49
|
sqlitePinnedSpec(this.kernel.platform),
|
|
55
50
|
].join("\n")
|
|
56
51
|
}
|
|
57
|
-
|
|
58
|
-
return this.kernel.bin
|
|
59
|
-
}
|
|
60
|
-
async hasCurrentRuntimeStamp() {
|
|
61
|
-
try {
|
|
62
|
-
const value = await fs.promises.readFile(this.runtimeStampPath(), "utf8")
|
|
63
|
-
const runtime = JSON.parse(value)
|
|
64
|
-
return !!(runtime &&
|
|
65
|
-
runtime.distribution === PINOKIO_CONDA_RUNTIME.distribution &&
|
|
66
|
-
runtime.release === PINOKIO_CONDA_RUNTIME.release &&
|
|
67
|
-
runtime.epoch === PINOKIO_CONDA_RUNTIME.epoch)
|
|
68
|
-
} catch (e) {
|
|
69
|
-
return false
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async writeRuntimeStamp() {
|
|
73
|
-
await fs.promises.writeFile(
|
|
74
|
-
this.runtimeStampPath(),
|
|
75
|
-
`${JSON.stringify(PINOKIO_CONDA_RUNTIME, null, 2)}\n`
|
|
76
|
-
)
|
|
52
|
+
async hasCondaMeta() {
|
|
53
|
+
return await this.kernel.exists(`bin/${CONDA_ROOT_DIR}/conda-meta`)
|
|
77
54
|
}
|
|
78
55
|
env() {
|
|
79
56
|
let base = {
|
|
@@ -100,6 +77,9 @@ class Conda {
|
|
|
100
77
|
if (this.kernel.platform !== "win32") {
|
|
101
78
|
return
|
|
102
79
|
}
|
|
80
|
+
if (!(await this.hasCondaMeta())) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
103
83
|
const activateDir = this.kernel.bin.path(`${CONDA_ROOT_DIR}/etc/conda/activate.d`)
|
|
104
84
|
await fs.promises.mkdir(activateDir, { recursive: true }).catch(() => {})
|
|
105
85
|
await fs.promises.writeFile(
|
|
@@ -141,12 +121,12 @@ remote_connect_timeout_secs: 20.0
|
|
|
141
121
|
remote_read_timeout_secs: 300.0
|
|
142
122
|
remote_max_retries: 6
|
|
143
123
|
report_errors: false`)
|
|
144
|
-
let pinned_exists = await this.
|
|
124
|
+
let pinned_exists = await this.hasCondaMeta()
|
|
145
125
|
if (pinned_exists) {
|
|
146
126
|
await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
|
|
127
|
+
await this.ensureSslCertDirOverride()
|
|
128
|
+
await this.ensureCompatibilityAlias()
|
|
147
129
|
}
|
|
148
|
-
await this.ensureSslCertDirOverride()
|
|
149
|
-
await this.ensureCompatibilityAlias()
|
|
150
130
|
}
|
|
151
131
|
}
|
|
152
132
|
async check() {
|
|
@@ -228,10 +208,10 @@ report_errors: false`)
|
|
|
228
208
|
const installer_url = this.urls[this.kernel.platform][this.kernel.arch]
|
|
229
209
|
const installer = this.installer[this.kernel.platform]
|
|
230
210
|
const install_path = this.kernel.bin.path(CONDA_ROOT_DIR)
|
|
231
|
-
const
|
|
211
|
+
const legacy_path = this.kernel.bin.path(LEGACY_CONDA_ROOT_DIR)
|
|
232
212
|
let install_path_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}`)
|
|
233
|
-
let
|
|
234
|
-
if (install_path_exists ||
|
|
213
|
+
let legacy_path_exists = await this.kernel.exists(`bin/${LEGACY_CONDA_ROOT_DIR}`)
|
|
214
|
+
if (install_path_exists || legacy_path_exists) {
|
|
235
215
|
console.log("Install path already exists. Will replace after installer download...", install_path)
|
|
236
216
|
} else {
|
|
237
217
|
console.log("Install path does not exist. Installing...")
|
|
@@ -240,10 +220,10 @@ report_errors: false`)
|
|
|
240
220
|
ondata({ raw: `downloading installer: ${installer_url}...\r\n` })
|
|
241
221
|
await this.kernel.bin.download(installer_url, installer, ondata)
|
|
242
222
|
|
|
243
|
-
|
|
244
|
-
if (
|
|
245
|
-
console.log("Removing
|
|
246
|
-
await this.removeInstallPath(
|
|
223
|
+
legacy_path_exists = await this.kernel.exists(`bin/${LEGACY_CONDA_ROOT_DIR}`)
|
|
224
|
+
if (legacy_path_exists) {
|
|
225
|
+
console.log("Removing legacy install path...", legacy_path)
|
|
226
|
+
await this.removeInstallPath(legacy_path)
|
|
247
227
|
}
|
|
248
228
|
install_path_exists = await this.kernel.exists(`bin/${CONDA_ROOT_DIR}`)
|
|
249
229
|
if (install_path_exists) {
|
|
@@ -309,7 +289,6 @@ report_errors: false`)
|
|
|
309
289
|
)
|
|
310
290
|
}
|
|
311
291
|
await this.ensureSslCertDirOverride()
|
|
312
|
-
await this.writeRuntimeStamp()
|
|
313
292
|
await this.ensureCompatibilityAlias()
|
|
314
293
|
ondata({ raw: `Install finished\r\n` })
|
|
315
294
|
await this.kernel.bin.rm(installer, ondata)
|
|
@@ -346,9 +325,8 @@ report_errors: false`)
|
|
|
346
325
|
}
|
|
347
326
|
async ensureCompatibilityAlias() {
|
|
348
327
|
const target = this.kernel.bin.path(CONDA_ROOT_DIR)
|
|
349
|
-
const alias = this.kernel.bin.path(
|
|
350
|
-
|
|
351
|
-
if (!targetExists) {
|
|
328
|
+
const alias = this.kernel.bin.path(LEGACY_CONDA_ROOT_DIR)
|
|
329
|
+
if (!(await this.hasCondaMeta())) {
|
|
352
330
|
return
|
|
353
331
|
}
|
|
354
332
|
const aliasExists = await fs.promises.lstat(alias).then(() => true).catch(() => false)
|
|
@@ -378,10 +356,6 @@ report_errors: false`)
|
|
|
378
356
|
for(let p of this.paths[this.kernel.platform]) {
|
|
379
357
|
let e = await this.kernel.bin.exists(p)
|
|
380
358
|
if (e && this.kernel.bin.correct_conda) {
|
|
381
|
-
if (!(await this.hasCurrentRuntimeStamp())) {
|
|
382
|
-
console.log("Pinokio Conda runtime changed; marking Conda invalid")
|
|
383
|
-
return false
|
|
384
|
-
}
|
|
385
359
|
return true
|
|
386
360
|
}
|
|
387
361
|
}
|
|
@@ -389,7 +363,7 @@ report_errors: false`)
|
|
|
389
363
|
}
|
|
390
364
|
|
|
391
365
|
async uninstall(req, ondata) {
|
|
392
|
-
await this.kernel.bin.rm(
|
|
366
|
+
await this.kernel.bin.rm(LEGACY_CONDA_ROOT_DIR, ondata)
|
|
393
367
|
return this.kernel.bin.rm(CONDA_ROOT_DIR, ondata)
|
|
394
368
|
}
|
|
395
369
|
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -6013,7 +6013,7 @@ class Server {
|
|
|
6013
6013
|
this.kernel.store.set("version", this.version.pinokiod)
|
|
6014
6014
|
console.log("[DONE] Updating to the new version")
|
|
6015
6015
|
console.log("not up to date. update py.")
|
|
6016
|
-
// remove ~/bin/py
|
|
6016
|
+
// remove ~/bin/miniconda/py
|
|
6017
6017
|
let p = path.resolve(home, "bin/py")
|
|
6018
6018
|
console.log(`[TRY] reset ${p}`)
|
|
6019
6019
|
await fse.remove(p)
|
|
@@ -10034,6 +10034,7 @@ class Server {
|
|
|
10034
10034
|
return
|
|
10035
10035
|
}
|
|
10036
10036
|
// check bin folder
|
|
10037
|
+
// let bin_path = this.kernel.path("bin/miniconda")
|
|
10037
10038
|
// let bin_exists = await this.exists(bin_path)
|
|
10038
10039
|
// if (!bin_exists) {
|
|
10039
10040
|
// res.redirect("/setup")
|
package/test/conda-bin.test.js
CHANGED
|
@@ -46,17 +46,6 @@ async function createLegacyMiniconda(root) {
|
|
|
46
46
|
return createCondaRoot(root, 'miniconda')
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
async function writeCurrentRuntimeStamp(root) {
|
|
50
|
-
await fs.writeFile(
|
|
51
|
-
path.join(root, 'bin', 'miniforge', '.pinokio-runtime.json'),
|
|
52
|
-
`${JSON.stringify({
|
|
53
|
-
distribution: 'miniforge',
|
|
54
|
-
release: '26.3.2-3',
|
|
55
|
-
epoch: 1,
|
|
56
|
-
}, null, 2)}\n`
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
49
|
function createConda(kernel) {
|
|
61
50
|
const conda = new Conda()
|
|
62
51
|
conda.kernel = kernel
|
|
@@ -81,6 +70,20 @@ test('Conda uses Miniforge assets and writes conda-forge-only config', async ()
|
|
|
81
70
|
assert.doesNotMatch(condarc, /bin\/miniconda\/envs/)
|
|
82
71
|
assert.doesNotMatch(condarc, /\bdefaults\b/)
|
|
83
72
|
assert.doesNotMatch(condarc, /auto_accept_tos/)
|
|
73
|
+
assert.equal(await pathExists(path.join(root, 'bin', 'miniforge')), false)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('Conda init writes activation hooks only after Miniforge exists', async () => {
|
|
77
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-init-hooks-'))
|
|
78
|
+
await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
|
|
79
|
+
const conda = createConda(createKernel(root))
|
|
80
|
+
|
|
81
|
+
await conda.init()
|
|
82
|
+
|
|
83
|
+
assert.equal(
|
|
84
|
+
await pathExists(path.join(root, 'bin', 'miniforge', 'etc', 'conda', 'activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat')),
|
|
85
|
+
true
|
|
86
|
+
)
|
|
84
87
|
})
|
|
85
88
|
|
|
86
89
|
test('Conda pins Python 3.10.20 consistently across platforms', async () => {
|
|
@@ -204,14 +207,6 @@ test('Conda installed stays false when metadata check already marked Conda inval
|
|
|
204
207
|
assert.equal(await createConda(kernel).installed(), false)
|
|
205
208
|
})
|
|
206
209
|
|
|
207
|
-
test('Conda installed returns false for old Conda runtimes without the Miniforge stamp', async () => {
|
|
208
|
-
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-runtime-stale-'))
|
|
209
|
-
await createMiniforge(root)
|
|
210
|
-
const kernel = createKernel(root)
|
|
211
|
-
|
|
212
|
-
assert.equal(await createConda(kernel).installed(), false)
|
|
213
|
-
})
|
|
214
|
-
|
|
215
210
|
test('Conda install keeps the old runtime when the replacement installer download fails', async () => {
|
|
216
211
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-download-fails-'))
|
|
217
212
|
const miniconda = await createLegacyMiniconda(root)
|