pinokiod 7.5.30 → 7.5.31

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.
@@ -14,6 +14,61 @@ const MINIFORGE_RELEASE = "26.3.2-3"
14
14
  const MINIFORGE_BASE_URL = `https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_RELEASE}`
15
15
  const CONDA_ROOT_DIR = "miniforge"
16
16
  const LEGACY_CONDA_ROOT_DIR = "miniconda"
17
+ const WINDOWS_OPENSSL_HOOKS = {
18
+ activate: {
19
+ "openssl_activate-win.bat": [
20
+ "@echo off",
21
+ 'if "%SSL_CERT_FILE%"=="" (',
22
+ ' set "SSL_CERT_FILE=%CONDA_PREFIX%\\Library\\ssl\\cacert.pem"',
23
+ ' set "__CONDA_OPENSSL_CERT_FILE_SET=1"',
24
+ ")",
25
+ "",
26
+ ].join("\r\n"),
27
+ "openssl_activate-win.ps1": [
28
+ "if (-not $Env:SSL_CERT_FILE) {",
29
+ ' $Env:SSL_CERT_FILE = "$Env:CONDA_PREFIX\\Library\\ssl\\cacert.pem"',
30
+ ' $Env:__CONDA_OPENSSL_CERT_FILE_SET = "1"',
31
+ "}",
32
+ "",
33
+ ].join("\r\n"),
34
+ "openssl_activate-win.sh": [
35
+ 'if [[ "${SSL_CERT_FILE:-}" == "" ]]; then',
36
+ ' export SSL_CERT_FILE="${CONDA_PREFIX}\\\\Library\\\\ssl\\\\cacert.pem"',
37
+ ' export __CONDA_OPENSSL_CERT_FILE_SET="1"',
38
+ "fi",
39
+ "",
40
+ ].join("\n"),
41
+ },
42
+ deactivate: {
43
+ "openssl_deactivate-win.bat": [
44
+ "@echo off",
45
+ 'if "%__CONDA_OPENSSL_CERT_FILE_SET%" == "1" (',
46
+ " set SSL_CERT_FILE=",
47
+ " set __CONDA_OPENSSL_CERT_FILE_SET=",
48
+ ")",
49
+ "",
50
+ ].join("\r\n"),
51
+ "openssl_deactivate-win.ps1": [
52
+ 'if ($Env:__CONDA_OPENSSL_CERT_FILE_SET -eq "1") {',
53
+ " Remove-Item -Path Env:\\SSL_CERT_FILE",
54
+ " Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_FILE_SET",
55
+ "}",
56
+ "",
57
+ ].join("\r\n"),
58
+ "openssl_deactivate-win.sh": [
59
+ 'if [[ "${__CONDA_OPENSSL_CERT_FILE_SET:-}" == "1" ]]; then',
60
+ " unset SSL_CERT_FILE",
61
+ " unset __CONDA_OPENSSL_CERT_FILE_SET",
62
+ "fi",
63
+ "",
64
+ ].join("\n"),
65
+ },
66
+ }
67
+ const LEGACY_SSL_CERT_DIR_HOOK_FILES = [
68
+ "zz_pinokio_unset_ssl_cert_dir-win.bat",
69
+ "zz_pinokio_unset_ssl_cert_dir-win.ps1",
70
+ "zz_pinokio_unset_ssl_cert_dir-win.sh",
71
+ ]
17
72
 
18
73
  class Conda {
19
74
  description = "Pinokio uses Conda to install various useful programs in an isolated manner."
@@ -69,7 +124,7 @@ class Conda {
69
124
  }
70
125
  return base
71
126
  }
72
- async ensureSslCertDirOverride() {
127
+ async ensureWindowsOpenSslHooks() {
73
128
  if (this.kernel.platform !== "win32") {
74
129
  return
75
130
  }
@@ -82,33 +137,26 @@ class Conda {
82
137
  if (condaRootDirs.length === 0) {
83
138
  return
84
139
  }
85
- const hookFiles = {
86
- "zz_pinokio_unset_ssl_cert_dir-win.bat": `@echo off
87
- if "%__CONDA_OPENSSL_CERT_DIR_SET%"=="1" (
88
- set "SSL_CERT_DIR="
89
- set "__CONDA_OPENSSL_CERT_DIR_SET="
90
- )
91
- `,
92
- "zz_pinokio_unset_ssl_cert_dir-win.ps1": `if ($Env:__CONDA_OPENSSL_CERT_DIR_SET -eq "1") {
93
- Remove-Item -Path Env:\\SSL_CERT_DIR -ErrorAction SilentlyContinue
94
- Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_DIR_SET -ErrorAction SilentlyContinue
95
- }
96
- `,
97
- "zz_pinokio_unset_ssl_cert_dir-win.sh": `if [[ "\${__CONDA_OPENSSL_CERT_DIR_SET:-}" == "1" ]]; then
98
- unset SSL_CERT_DIR
99
- unset __CONDA_OPENSSL_CERT_DIR_SET
100
- fi
101
- `,
102
- }
103
140
  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)
141
+ const activateDir = this.kernel.bin.path(`${rootDir}/etc/conda/activate.d`)
142
+ const deactivateDir = this.kernel.bin.path(`${rootDir}/etc/conda/deactivate.d`)
143
+ for (const hookDir of [activateDir, deactivateDir]) {
144
+ for (const filename of LEGACY_SSL_CERT_DIR_HOOK_FILES) {
145
+ await fs.promises.rm(path.resolve(hookDir, filename), { force: true }).catch(() => {})
146
+ }
147
+ }
148
+ for (const [filename, content] of Object.entries(WINDOWS_OPENSSL_HOOKS.activate)) {
149
+ const hookPath = path.resolve(activateDir, filename)
150
+ const exists = await fs.promises.access(hookPath).then(() => true).catch(() => false)
151
+ if (exists) {
152
+ await fs.promises.writeFile(hookPath, content)
153
+ }
154
+ }
155
+ for (const [filename, content] of Object.entries(WINDOWS_OPENSSL_HOOKS.deactivate)) {
156
+ const hookPath = path.resolve(deactivateDir, filename)
157
+ const exists = await fs.promises.access(hookPath).then(() => true).catch(() => false)
158
+ if (exists) {
159
+ await fs.promises.writeFile(hookPath, content)
112
160
  }
113
161
  }
114
162
  }
@@ -134,7 +182,7 @@ report_errors: false`)
134
182
  await fs.promises.writeFile(this.kernel.path(`bin/${CONDA_ROOT_DIR}/conda-meta/pinned`), this.pinnedPackages())
135
183
  await this.ensureCompatibilityAlias()
136
184
  }
137
- await this.ensureSslCertDirOverride()
185
+ await this.ensureWindowsOpenSslHooks()
138
186
  }
139
187
  }
140
188
  async check() {
@@ -282,7 +330,7 @@ report_errors: false`)
282
330
  this.kernel.bin.path(CONDA_ROOT_DIR, "python3.exe"),
283
331
  )
284
332
  }
285
- await this.ensureSslCertDirOverride()
333
+ await this.ensureWindowsOpenSslHooks()
286
334
  await this.ensureCompatibilityAlias()
287
335
  ondata({ raw: `Install finished\r\n` })
288
336
  await this.kernel.bin.rm(installer, ondata)
@@ -448,6 +448,9 @@ class Bin {
448
448
  break
449
449
  }
450
450
  }
451
+ if (this.mod && this.mod.conda && this.mod.conda.ensureWindowsOpenSslHooks) {
452
+ await this.mod.conda.ensureWindowsOpenSslHooks()
453
+ }
451
454
  }
452
455
 
453
456
  if (this.platform === "darwin") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "7.5.30",
3
+ "version": "7.5.31",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -6041,6 +6041,13 @@ class Server {
6041
6041
  if (version === this.version.pinokiod) {
6042
6042
  console.log("version up to date")
6043
6043
  } else if (!(await fse.pathExists(path.resolve(home, "bin/miniforge/conda-meta")))) {
6044
+ // if miniconda => miniforge migration hasn't happened yet
6045
+ if (!(await fse.pathExists(path.resolve(home, "bin/miniconda/conda-meta")))) {
6046
+ // if miniconda folder does NOT exist (new user), set version
6047
+ // if miniconda folder exists (existing user), don't set version yet
6048
+ // => version only set after miniconda => miniforge migration has happened
6049
+ this.kernel.store.set("version", this.version.pinokiod)
6050
+ }
6044
6051
  console.warn("[WARN] Managed home refresh deferred until Miniforge is installed")
6045
6052
  } else {
6046
6053
  // For every update, this gets triggered exactly once.
@@ -78,6 +78,88 @@ function createConda(kernel) {
78
78
  return conda
79
79
  }
80
80
 
81
+ const EXPECTED_WINDOWS_OPENSSL_HOOKS = {
82
+ [path.join('activate.d', 'openssl_activate-win.bat')]: [
83
+ '@echo off',
84
+ 'if "%SSL_CERT_FILE%"=="" (',
85
+ ' set "SSL_CERT_FILE=%CONDA_PREFIX%\\Library\\ssl\\cacert.pem"',
86
+ ' set "__CONDA_OPENSSL_CERT_FILE_SET=1"',
87
+ ')',
88
+ '',
89
+ ].join('\r\n'),
90
+ [path.join('activate.d', 'openssl_activate-win.ps1')]: [
91
+ 'if (-not $Env:SSL_CERT_FILE) {',
92
+ ' $Env:SSL_CERT_FILE = "$Env:CONDA_PREFIX\\Library\\ssl\\cacert.pem"',
93
+ ' $Env:__CONDA_OPENSSL_CERT_FILE_SET = "1"',
94
+ '}',
95
+ '',
96
+ ].join('\r\n'),
97
+ [path.join('activate.d', 'openssl_activate-win.sh')]: [
98
+ 'if [[ "${SSL_CERT_FILE:-}" == "" ]]; then',
99
+ ' export SSL_CERT_FILE="${CONDA_PREFIX}\\\\Library\\\\ssl\\\\cacert.pem"',
100
+ ' export __CONDA_OPENSSL_CERT_FILE_SET="1"',
101
+ 'fi',
102
+ '',
103
+ ].join('\n'),
104
+ [path.join('deactivate.d', 'openssl_deactivate-win.bat')]: [
105
+ '@echo off',
106
+ 'if "%__CONDA_OPENSSL_CERT_FILE_SET%" == "1" (',
107
+ ' set SSL_CERT_FILE=',
108
+ ' set __CONDA_OPENSSL_CERT_FILE_SET=',
109
+ ')',
110
+ '',
111
+ ].join('\r\n'),
112
+ [path.join('deactivate.d', 'openssl_deactivate-win.ps1')]: [
113
+ 'if ($Env:__CONDA_OPENSSL_CERT_FILE_SET -eq "1") {',
114
+ ' Remove-Item -Path Env:\\SSL_CERT_FILE',
115
+ ' Remove-Item -Path Env:\\__CONDA_OPENSSL_CERT_FILE_SET',
116
+ '}',
117
+ '',
118
+ ].join('\r\n'),
119
+ [path.join('deactivate.d', 'openssl_deactivate-win.sh')]: [
120
+ 'if [[ "${__CONDA_OPENSSL_CERT_FILE_SET:-}" == "1" ]]; then',
121
+ ' unset SSL_CERT_FILE',
122
+ ' unset __CONDA_OPENSSL_CERT_FILE_SET',
123
+ 'fi',
124
+ '',
125
+ ].join('\n'),
126
+ }
127
+
128
+ async function seedWindowsOpenSslHooks(root, condaRootName) {
129
+ const condaHookRoot = path.join(root, 'bin', condaRootName, 'etc', 'conda')
130
+ for (const hookRelativePath of Object.keys(EXPECTED_WINDOWS_OPENSSL_HOOKS)) {
131
+ const hookPath = path.join(condaHookRoot, hookRelativePath)
132
+ await fs.mkdir(path.dirname(hookPath), { recursive: true })
133
+ await fs.writeFile(hookPath, 'upstream hook with SSL_CERT_DIR\n')
134
+ }
135
+ for (const hookDirName of ['activate.d', 'deactivate.d']) {
136
+ for (const filename of [
137
+ 'zz_pinokio_unset_ssl_cert_dir-win.bat',
138
+ 'zz_pinokio_unset_ssl_cert_dir-win.ps1',
139
+ 'zz_pinokio_unset_ssl_cert_dir-win.sh',
140
+ ]) {
141
+ await fs.writeFile(path.join(condaHookRoot, hookDirName, filename), 'legacy hook\n')
142
+ }
143
+ }
144
+ }
145
+
146
+ async function assertWindowsOpenSslHooksPatched(root, condaRootName) {
147
+ const condaHookRoot = path.join(root, 'bin', condaRootName, 'etc', 'conda')
148
+ for (const [hookRelativePath, expectedContent] of Object.entries(EXPECTED_WINDOWS_OPENSSL_HOOKS)) {
149
+ const hookPath = path.join(condaHookRoot, hookRelativePath)
150
+ assert.equal(await fs.readFile(hookPath, 'utf8'), expectedContent)
151
+ }
152
+ for (const hookDirName of ['activate.d', 'deactivate.d']) {
153
+ for (const filename of [
154
+ 'zz_pinokio_unset_ssl_cert_dir-win.bat',
155
+ 'zz_pinokio_unset_ssl_cert_dir-win.ps1',
156
+ 'zz_pinokio_unset_ssl_cert_dir-win.sh',
157
+ ]) {
158
+ assert.equal(await pathExists(path.join(condaHookRoot, hookDirName, filename)), false)
159
+ }
160
+ }
161
+ }
162
+
81
163
  test('Conda uses Miniforge assets and writes conda-forge-only config', async () => {
82
164
  const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-miniforge-config-'))
83
165
  const conda = createConda(createKernel(root))
@@ -99,59 +181,26 @@ test('Conda uses Miniforge assets and writes conda-forge-only config', async ()
99
181
  assert.equal(await pathExists(path.join(root, 'bin', 'miniforge')), false)
100
182
  })
101
183
 
102
- test('Conda init writes SSL_CERT_DIR neutralizing hooks only after Miniforge exists', async () => {
103
- const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-init-hooks-'))
184
+ test('Conda init patches Windows OpenSSL hooks and removes legacy SSL_CERT_DIR hooks', async () => {
185
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-openssl-hooks-'))
104
186
  await fs.mkdir(path.join(root, 'bin', 'miniforge', 'conda-meta'), { recursive: true })
187
+ await seedWindowsOpenSslHooks(root, 'miniforge')
105
188
  const conda = createConda(createKernel(root))
106
189
 
107
190
  await conda.init()
108
191
 
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'
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/)
192
+ await assertWindowsOpenSslHooksPatched(root, 'miniforge')
131
193
  })
132
194
 
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-'))
195
+ test('Conda init patches Windows OpenSSL hooks for legacy Miniconda roots', async () => {
196
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'pinokio-conda-legacy-openssl-hooks-'))
135
197
  await fs.mkdir(path.join(root, 'bin', 'miniconda', 'conda-meta'), { recursive: true })
198
+ await seedWindowsOpenSslHooks(root, 'miniconda')
136
199
  const conda = createConda(createKernel(root))
137
200
 
138
201
  await conda.init()
139
202
 
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/)
203
+ await assertWindowsOpenSslHooksPatched(root, 'miniconda')
155
204
  })
156
205
 
157
206
  test('Conda pins Python 3.10.20 consistently across platforms', async () => {