pinokiod 7.5.29 → 7.5.30

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.
@@ -69,15 +69,27 @@ async function runCondaList(minicondaPath) {
69
69
  })
70
70
  }
71
71
 
72
- function resolveCondaBinary(minicondaPath) {
73
- if (process.platform === 'win32') {
72
+ async function managedCondaRuns(minicondaPath, platform = process.platform) {
73
+ const condaBinary = resolveCondaBinary(minicondaPath, platform, false)
74
+ if (!condaBinary) {
75
+ return false
76
+ }
77
+ return await new Promise((resolve) => {
78
+ execFile(condaBinary, ['--version'], { windowsHide: true, timeout: 15000 }, (err) => {
79
+ resolve(!err)
80
+ })
81
+ })
82
+ }
83
+
84
+ function resolveCondaBinary(minicondaPath, platform = process.platform, allowFallback = true) {
85
+ if (platform === 'win32') {
74
86
  if (minicondaPath) {
75
87
  const scriptPath = path.join(minicondaPath, 'Scripts', 'conda.exe')
76
88
  if (fs.existsSync(scriptPath)) {
77
89
  return scriptPath
78
90
  }
79
91
  }
80
- return 'conda'
92
+ return allowFallback ? 'conda' : null
81
93
  }
82
94
  if (minicondaPath) {
83
95
  const binPath = path.join(minicondaPath, 'bin', 'conda')
@@ -85,9 +97,10 @@ function resolveCondaBinary(minicondaPath) {
85
97
  return binPath
86
98
  }
87
99
  }
88
- return 'conda'
100
+ return allowFallback ? 'conda' : null
89
101
  }
90
102
 
91
103
  module.exports = {
92
- buildCondaListFromMeta
104
+ buildCondaListFromMeta,
105
+ managedCondaRuns,
93
106
  }
@@ -2,7 +2,7 @@ const fs = require('fs')
2
2
  const path = require('path')
3
3
  const { glob } = require('glob')
4
4
  const semver = require('semver')
5
- const { buildCondaListFromMeta } = require('./conda-meta')
5
+ const { buildCondaListFromMeta, managedCondaRuns } = require('./conda-meta')
6
6
  const {
7
7
  CONDA_PIN_VERSION,
8
8
  PYTHON_INSTALL_SPEC,
@@ -73,33 +73,45 @@ class Conda {
73
73
  if (this.kernel.platform !== "win32") {
74
74
  return
75
75
  }
76
- if (!(await this.hasCondaMeta())) {
76
+ const condaRootDirs = []
77
+ for (const rootDir of [CONDA_ROOT_DIR, LEGACY_CONDA_ROOT_DIR]) {
78
+ if (await this.kernel.exists(`bin/${rootDir}/conda-meta`)) {
79
+ condaRootDirs.push(rootDir)
80
+ }
81
+ }
82
+ if (condaRootDirs.length === 0) {
77
83
  return
78
84
  }
79
- const activateDir = this.kernel.bin.path(`${CONDA_ROOT_DIR}/etc/conda/activate.d`)
80
- await fs.promises.mkdir(activateDir, { recursive: true }).catch(() => {})
81
- await fs.promises.writeFile(
82
- path.resolve(activateDir, "zz_pinokio_unset_ssl_cert_dir-win.bat"),
83
- `@echo off
85
+ const hookFiles = {
86
+ "zz_pinokio_unset_ssl_cert_dir-win.bat": `@echo off
84
87
  if "%__CONDA_OPENSSL_CERT_DIR_SET%"=="1" (
85
88
  set "SSL_CERT_DIR="
89
+ set "__CONDA_OPENSSL_CERT_DIR_SET="
86
90
  )
87
- `
88
- )
89
- await fs.promises.writeFile(
90
- path.resolve(activateDir, "zz_pinokio_unset_ssl_cert_dir-win.ps1"),
91
- `if ($Env:__CONDA_OPENSSL_CERT_DIR_SET -eq "1") {
91
+ `,
92
+ "zz_pinokio_unset_ssl_cert_dir-win.ps1": `if ($Env:__CONDA_OPENSSL_CERT_DIR_SET -eq "1") {
92
93
  Remove-Item -Path Env:\\SSL_CERT_DIR -ErrorAction SilentlyContinue
94
+ Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_DIR_SET -ErrorAction SilentlyContinue
93
95
  }
94
- `
95
- )
96
- await fs.promises.writeFile(
97
- path.resolve(activateDir, "zz_pinokio_unset_ssl_cert_dir-win.sh"),
98
- `if [[ "\${__CONDA_OPENSSL_CERT_DIR_SET:-}" == "1" ]]; then
96
+ `,
97
+ "zz_pinokio_unset_ssl_cert_dir-win.sh": `if [[ "\${__CONDA_OPENSSL_CERT_DIR_SET:-}" == "1" ]]; then
99
98
  unset SSL_CERT_DIR
99
+ unset __CONDA_OPENSSL_CERT_DIR_SET
100
100
  fi
101
- `
102
- )
101
+ `,
102
+ }
103
+ for (const rootDir of condaRootDirs) {
104
+ const hookDirs = [
105
+ this.kernel.bin.path(`${rootDir}/etc/conda/activate.d`),
106
+ this.kernel.bin.path(`${rootDir}/etc/conda/deactivate.d`),
107
+ ]
108
+ for (const hookDir of hookDirs) {
109
+ await fs.promises.mkdir(hookDir, { recursive: true }).catch(() => {})
110
+ for (const [filename, content] of Object.entries(hookFiles)) {
111
+ await fs.promises.writeFile(path.resolve(hookDir, filename), content)
112
+ }
113
+ }
114
+ }
103
115
  }
104
116
  async init() {
105
117
  if (this.kernel.homedir) {
@@ -120,9 +132,9 @@ report_errors: false`)
120
132
  let pinned_exists = await this.hasCondaMeta()
121
133
  if (pinned_exists) {
122
134
  await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
123
- await this.ensureSslCertDirOverride()
124
135
  await this.ensureCompatibilityAlias()
125
136
  }
137
+ await this.ensureSslCertDirOverride()
126
138
  }
127
139
  }
128
140
  async check() {
@@ -170,7 +182,10 @@ report_errors: false`)
170
182
  this.kernel.bin.installed.conda = conda
171
183
  this.kernel.bin.installed.conda_versions = conda_versions
172
184
  this.kernel.bin.installed.conda_builds = conda_builds
173
- return conda_check.conda && conda_check.mamba && conda_check.python
185
+ if (!(conda_check.conda && conda_check.mamba && conda_check.python)) {
186
+ return false
187
+ }
188
+ return await managedCondaRuns(this.kernel.bin.path(CONDA_ROOT_DIR), this.kernel.platform)
174
189
  }
175
190
  async install(req, ondata) {
176
191
  for(let i=0; i<5; i++) {
@@ -21,7 +21,7 @@ const LLVM = require('./llvm')
21
21
  const VS = require("./vs")
22
22
  const Cuda = require("./cuda")
23
23
  const Torch = require("./torch")
24
- const { buildCondaListFromMeta } = require('./conda-meta')
24
+ const { buildCondaListFromMeta, managedCondaRuns } = require('./conda-meta')
25
25
  const {
26
26
  isExpectedPythonPinned,
27
27
  } = require('./conda-pins')
@@ -412,7 +412,7 @@ class Bin {
412
412
  }
413
413
 
414
414
  if (conda_check.conda && conda_check.mamba && conda_check.python) {
415
- this.correct_conda = true
415
+ this.correct_conda = await managedCondaRuns(this.kernel.bin.path("miniforge"), this.platform)
416
416
  }
417
417
  }
418
418
  this.installed.conda = conda
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "7.5.29",
3
+ "version": "7.5.30",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1284,6 +1284,10 @@ body.main-sidebar-page .navheader {
1284
1284
  box-shadow: none;
1285
1285
  isolation: isolate;
1286
1286
  }
1287
+ body.main-sidebar-page > header.navheader h1,
1288
+ body.app-page > header.navheader h1 {
1289
+ gap: 6px;
1290
+ }
1287
1291
  body.main-sidebar-page .navheader .sidebar-toggle {
1288
1292
  color: #0f172a;
1289
1293
  position: relative;
@@ -25,12 +25,38 @@ function createKernel(root, platform = 'win32') {
25
25
  exists: async (...parts) => pathExists(path.join(root, ...parts)),
26
26
  bin: {
27
27
  correct_conda: true,
28
+ installed: {},
28
29
  path: (...parts) => path.join(root, 'bin', ...parts),
29
30
  exists: async (target) => pathExists(path.join(root, 'bin', target)),
30
31
  },
31
32
  }
32
33
  }
33
34
 
35
+ async function writeCondaMeta(root, name, version, build = 'py_0') {
36
+ const metaDir = path.join(root, 'bin', 'miniforge', 'conda-meta')
37
+ await fs.mkdir(metaDir, { recursive: true })
38
+ await fs.writeFile(
39
+ path.join(metaDir, `${name}-${version}.json`),
40
+ JSON.stringify({ name, version, build_string: build, channel: 'conda-forge' })
41
+ )
42
+ }
43
+
44
+ async function writeHealthyCondaMeta(root, platform = 'win32') {
45
+ await writeCondaMeta(root, 'conda', '26.3.2', 'py310')
46
+ await writeCondaMeta(root, 'conda-libmamba-solver', '25.4.0', 'pyhd3eb1b0_0')
47
+ await writeCondaMeta(root, 'python', '3.10.20', platform === 'win32' ? 'h4de0772_1_cpython' : 'cpython')
48
+ }
49
+
50
+ async function writeFakeManagedConda(root, platform = 'win32') {
51
+ const condaPath = platform === 'win32'
52
+ ? path.join(root, 'bin', 'miniforge', 'Scripts', 'conda.exe')
53
+ : path.join(root, 'bin', 'miniforge', 'bin', 'conda')
54
+ await fs.mkdir(path.dirname(condaPath), { recursive: true })
55
+ await fs.copyFile(process.execPath, condaPath)
56
+ await fs.chmod(condaPath, 0o755)
57
+ return condaPath
58
+ }
59
+
34
60
  async function createCondaRoot(root, name) {
35
61
  const condaRoot = path.join(root, 'bin', name)
36
62
  await fs.mkdir(path.join(condaRoot, 'Scripts'), { recursive: true })
@@ -73,17 +99,59 @@ test('Conda uses Miniforge assets and writes conda-forge-only config', async ()
73
99
  assert.equal(await pathExists(path.join(root, 'bin', 'miniforge')), false)
74
100
  })
75
101
 
76
- test('Conda init writes activation hooks only after Miniforge exists', async () => {
102
+ test('Conda init writes SSL_CERT_DIR neutralizing hooks only after Miniforge exists', async () => {
77
103
  const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-init-hooks-'))
78
104
  await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
79
105
  const conda = createConda(createKernel(root))
80
106
 
81
107
  await conda.init()
82
108
 
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
109
+ const hookRelativePaths = [
110
+ path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
111
+ path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.ps1'),
112
+ path.join('activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.sh'),
113
+ path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
114
+ path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.ps1'),
115
+ path.join('deactivate.d', 'zz_pinokio_unset_ssl_cert_dir-win.sh'),
116
+ ]
117
+ for (const hookRelativePath of hookRelativePaths) {
118
+ assert.equal(
119
+ await pathExists(path.join(root, 'bin', 'miniforge', 'etc', 'conda', hookRelativePath)),
120
+ true
121
+ )
122
+ }
123
+
124
+ const batHook = await fs.readFile(
125
+ path.join(root, 'bin', 'miniforge', 'etc', 'conda', 'activate.d', 'zz_pinokio_unset_ssl_cert_dir-win.bat'),
126
+ 'utf8'
86
127
  )
128
+ assert.match(batHook, /set "SSL_CERT_DIR="/)
129
+ assert.match(batHook, /set "__CONDA_OPENSSL_CERT_DIR_SET="/)
130
+ assert.doesNotMatch(batHook, /SSL_CERT_FILE/)
131
+ })
132
+
133
+ test('Conda init writes SSL_CERT_DIR neutralizing hooks for legacy Miniconda roots', async () => {
134
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-legacy-init-hooks-'))
135
+ await fs.mkdir(path.join(root, 'bin', 'miniconda', 'conda-meta'), { recursive: true })
136
+ const conda = createConda(createKernel(root))
137
+
138
+ await conda.init()
139
+
140
+ const batHookPath = path.join(
141
+ root,
142
+ 'bin',
143
+ 'miniconda',
144
+ 'etc',
145
+ 'conda',
146
+ 'deactivate.d',
147
+ 'zz_pinokio_unset_ssl_cert_dir-win.bat'
148
+ )
149
+ assert.equal(await pathExists(batHookPath), true)
150
+
151
+ const batHook = await fs.readFile(batHookPath, 'utf8')
152
+ assert.match(batHook, /set "SSL_CERT_DIR="/)
153
+ assert.match(batHook, /set "__CONDA_OPENSSL_CERT_DIR_SET="/)
154
+ assert.doesNotMatch(batHook, /SSL_CERT_FILE/)
87
155
  })
88
156
 
89
157
  test('Conda pins Python 3.10.20 consistently across platforms', async () => {
@@ -207,6 +275,21 @@ test('Conda installed stays false when metadata check already marked Conda inval
207
275
  assert.equal(await createConda(kernel).installed(), false)
208
276
  })
209
277
 
278
+ test('Conda check rejects metadata-only Windows installs', async () => {
279
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-smoke-missing-'))
280
+ await writeHealthyCondaMeta(root, 'win32')
281
+
282
+ assert.equal(await createConda(createKernel(root, 'win32')).check(), false)
283
+ })
284
+
285
+ test('Conda check accepts a runnable managed Windows conda executable', async () => {
286
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-smoke-runnable-'))
287
+ await writeHealthyCondaMeta(root, 'win32')
288
+ await writeFakeManagedConda(root, 'win32')
289
+
290
+ assert.equal(await createConda(createKernel(root, 'win32')).check(), true)
291
+ })
292
+
210
293
  test('Conda install keeps the old runtime when the replacement installer download fails', async () => {
211
294
  const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-download-fails-'))
212
295
  const miniconda = await createLegacyMiniconda(root)