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.
@@ -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(condaRootPath, useCondaList) {
5
+ async function buildCondaListFromMeta(minicondaPath, useCondaList) {
6
6
  if (!useCondaList) {
7
- const metaOutput = await readFromMeta(condaRootPath)
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(condaRootPath)
12
+ return await runCondaList(minicondaPath)
13
13
  }
14
14
 
15
- async function readFromMeta(condaRootPath) {
16
- if (!condaRootPath) {
15
+ async function readFromMeta(minicondaPath) {
16
+ if (!minicondaPath) {
17
17
  return null
18
18
  }
19
- const metaDir = path.join(condaRootPath, 'conda-meta')
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(condaRootPath) {
57
- const condaBinary = resolveCondaBinary(condaRootPath)
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(condaRootPath) {
72
+ function resolveCondaBinary(minicondaPath) {
73
73
  if (process.platform === 'win32') {
74
- if (condaRootPath) {
75
- const scriptPath = path.join(condaRootPath, 'Scripts', 'conda.exe')
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 (condaRootPath) {
83
- const binPath = path.join(condaRootPath, 'bin', 'conda')
82
+ if (minicondaPath) {
83
+ const binPath = path.join(minicondaPath, 'bin', 'conda')
84
84
  if (fs.existsSync(binPath)) {
85
85
  return binPath
86
86
  }
@@ -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 CONDA_COMPAT_ROOT_DIR = "miniconda"
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
- runtimeStampPath() {
58
- return this.kernel.bin.path(CONDA_ROOT_DIR, ".pinokio-runtime.json")
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.kernel.exists(`bin/${CONDA_ROOT_DIR}/conda-meta`)
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 compat_path = this.kernel.bin.path(CONDA_COMPAT_ROOT_DIR)
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 compat_path_exists = await this.kernel.exists(`bin/${CONDA_COMPAT_ROOT_DIR}`)
234
- if (install_path_exists || compat_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
- compat_path_exists = await this.kernel.exists(`bin/${CONDA_COMPAT_ROOT_DIR}`)
244
- if (compat_path_exists) {
245
- console.log("Removing compatibility install path...", compat_path)
246
- await this.removeInstallPath(compat_path)
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(CONDA_COMPAT_ROOT_DIR)
350
- const targetExists = await fs.promises.access(target).then(() => true).catch(() => false)
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(CONDA_COMPAT_ROOT_DIR, ondata)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "7.5.0",
3
+ "version": "7.5.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
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")
@@ -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)