pinokiod 3.8.1 → 3.8.5
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/api/fs/index.js +6 -4
- package/kernel/api/index.js +102 -31
- package/kernel/bin/index.js +143 -4
- package/kernel/bin/node.js +9 -0
- package/kernel/index.js +32 -1
- package/kernel/info.js +1 -0
- package/kernel/prototype.js +47 -0
- package/kernel/shell.js +110 -54
- package/kernel/shells.js +16 -7
- package/kernel/store.js +58 -0
- package/kernel/util.js +106 -35
- package/package.json +1 -1
- package/script/index.js +12 -0
- package/server/index.js +466 -250
- package/server/public/SpaceMono-Bold.ttf +0 -0
- package/server/public/SpaceMono-BoldItalic.ttf +0 -0
- package/server/public/SpaceMono-Italic.ttf +0 -0
- package/server/public/SpaceMono-Regular.ttf +0 -0
- package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
- package/server/public/filepond-plugin-image-crop.min.js +9 -0
- package/server/public/filepond-plugin-image-edit.min.css +8 -0
- package/server/public/filepond-plugin-image-edit.min.js +9 -0
- package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
- package/server/public/filepond-plugin-image-preview.min.css +8 -0
- package/server/public/filepond-plugin-image-preview.min.js +9 -0
- package/server/public/filepond-plugin-image-resize.min.js +9 -0
- package/server/public/filepond-plugin-image-transform.min.js +9 -0
- package/server/public/filepond.min.css +8 -0
- package/server/public/filepond.min.js +9 -0
- package/server/public/fscreator.js +160 -0
- package/server/public/fseditor.js +189 -0
- package/server/public/github.png +0 -0
- package/server/public/opener.js +3 -1
- package/server/public/pinokio-black.png +0 -0
- package/server/public/pinokio-black2.png +0 -0
- package/server/public/style.css +131 -9
- package/server/socket.js +123 -37
- package/server/views/app.ejs +184 -11
- package/server/views/editor.ejs +12 -2
- package/server/views/explore.ejs +4 -3
- package/server/views/help.ejs +4 -2
- package/server/views/index.ejs +218 -80
- package/server/views/install.ejs +1 -1
- package/server/views/local_editor.ejs +282 -0
- package/server/views/minterm.ejs +687 -0
- package/server/views/partials/menu.ejs +7 -1
- package/server/views/prototypes.ejs +463 -0
- package/server/views/proxy.ejs +10 -4
- package/server/views/settings.ejs +4 -3
- package/server/views/terminal.ejs +99 -15
package/kernel/shell.js
CHANGED
|
@@ -13,7 +13,6 @@ const pty = require('@homebridge/node-pty-prebuilt-multiarch')
|
|
|
13
13
|
const path = require("path")
|
|
14
14
|
const sudo = require("sudo-prompt-programfiles-x86");
|
|
15
15
|
const unparse = require('yargs-unparser-custom-flag');
|
|
16
|
-
const shellPath = require('shell-path');
|
|
17
16
|
const Util = require('./util')
|
|
18
17
|
const Environment = require('./environment')
|
|
19
18
|
const home = os.homedir()
|
|
@@ -60,36 +59,9 @@ class Shell {
|
|
|
60
59
|
}, 1)
|
|
61
60
|
|
|
62
61
|
}
|
|
63
|
-
async
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
params := {
|
|
67
|
-
group: <group id>,
|
|
68
|
-
id: <shell id>,
|
|
69
|
-
path: <shell cwd (always absolute path)>,
|
|
70
|
-
env: <environment value key pairs>
|
|
71
|
-
}
|
|
72
|
-
*/
|
|
73
|
-
this.cols = params.cols ? params.cols : 100;
|
|
74
|
-
this.rows = params.rows ? params.rows : 30;
|
|
75
|
-
|
|
76
|
-
this.vt = new Terminal({
|
|
77
|
-
allowProposedApi: true,
|
|
78
|
-
cols: this.cols,
|
|
79
|
-
rows: this.rows,
|
|
80
|
-
})
|
|
81
|
-
this.vts = new SerializeAddon()
|
|
82
|
-
this.vt.loadAddon(this.vts)
|
|
83
|
-
|
|
84
|
-
// 1. id
|
|
85
|
-
this.id = (params.id ? params.id : uuidv4())
|
|
86
|
-
|
|
87
|
-
// 2. group id
|
|
88
|
-
this.group = params.group
|
|
89
|
-
|
|
90
|
-
// 2. env
|
|
91
|
-
// default env
|
|
92
|
-
|
|
62
|
+
async init_env(params) {
|
|
63
|
+
console.log({ params })
|
|
64
|
+
console.time("> 1")
|
|
93
65
|
this.env = Object.assign({}, process.env)
|
|
94
66
|
// If the user has set PYTHONPATH, unset it.
|
|
95
67
|
if (this.env.PYTHONPATH) {
|
|
@@ -103,6 +75,15 @@ class Shell {
|
|
|
103
75
|
if (this.env.CMAKE_GENERATOR) {
|
|
104
76
|
delete this.env.CMAKE_GENERATOR
|
|
105
77
|
}
|
|
78
|
+
|
|
79
|
+
//this.env.PNPM_CONFIG_PREFIX = this.kernel.path("bin/npm")
|
|
80
|
+
//this.env.pnpm_config_prefix = this.kernel.path("bin/npm")
|
|
81
|
+
// this.env.PNPM_HOME = this.kernel.path("bin/npm")
|
|
82
|
+
// this.env.pnpm_home = this.kernel.path("bin/npm")
|
|
83
|
+
|
|
84
|
+
// this.env.NPM_CONFIG_PREFIX = this.kernel.path("bin/npm")
|
|
85
|
+
// this.env.npm_config_prefix = this.kernel.path("bin/npm")
|
|
86
|
+
|
|
106
87
|
|
|
107
88
|
// if (this.env.CUDA_HOME) {
|
|
108
89
|
// delete this.env.CUDA_HOME
|
|
@@ -117,16 +98,12 @@ class Shell {
|
|
|
117
98
|
delete this.env[key]
|
|
118
99
|
}
|
|
119
100
|
}
|
|
101
|
+
console.timeEnd("> 1")
|
|
102
|
+
console.time("> 2")
|
|
120
103
|
|
|
121
104
|
this.env.CMAKE_OBJECT_PATH_MAX = 1024
|
|
122
105
|
this.env.PYTORCH_ENABLE_MPS_FALLBACK = 1
|
|
123
106
|
this.env.TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD = 1
|
|
124
|
-
// if (this.platform === 'win32') {
|
|
125
|
-
// this.env.USERPROFILE = this.kernel.homedir
|
|
126
|
-
// } else {
|
|
127
|
-
// this.env.HOME = this.kernel.homedir
|
|
128
|
-
// }
|
|
129
|
-
|
|
130
107
|
// this.env.PIP_REQUIRE_VIRTUALENV = "true"
|
|
131
108
|
// this.env.NPM_CONFIG_USERCONFIG = this.kernel.path("user_npmrc")
|
|
132
109
|
// this.env.NPM_CONFIG_GLOBALCONFIG = this.kernel.path("global_npmrc")
|
|
@@ -136,7 +113,9 @@ class Shell {
|
|
|
136
113
|
// First override this.env with system env
|
|
137
114
|
let system_env = await Environment.get(this.kernel.homedir)
|
|
138
115
|
this.env = Object.assign(this.env, system_env)
|
|
116
|
+
console.timeEnd("> 2")
|
|
139
117
|
|
|
118
|
+
console.time("> 3")
|
|
140
119
|
// if the shell is running from a script file, the params.$parent will include the path to the parent script
|
|
141
120
|
// this means we need to apply app environment as well
|
|
142
121
|
if (params.$parent) {
|
|
@@ -158,7 +137,7 @@ class Shell {
|
|
|
158
137
|
if (this.platform === 'win32') {
|
|
159
138
|
// ignore
|
|
160
139
|
} else {
|
|
161
|
-
this.env[PATH_KEY]=
|
|
140
|
+
this.env[PATH_KEY]= this.kernel.shellpath || [
|
|
162
141
|
'./node_modules/.bin',
|
|
163
142
|
'/.nodebrew/current/bin',
|
|
164
143
|
'/usr/local/bin',
|
|
@@ -177,6 +156,8 @@ class Shell {
|
|
|
177
156
|
this.env[PATH_KEY] = this.env[PATH_KEY] + path.delimiter + path.resolve(this.kernel.homedir, 'bin')
|
|
178
157
|
|
|
179
158
|
|
|
159
|
+
console.timeEnd("> 3")
|
|
160
|
+
console.time("> 4")
|
|
180
161
|
if (params.env) {
|
|
181
162
|
for(let key in params.env) {
|
|
182
163
|
// iterate through the env attributes
|
|
@@ -210,8 +191,10 @@ class Shell {
|
|
|
210
191
|
}
|
|
211
192
|
}
|
|
212
193
|
}
|
|
194
|
+
console.timeEnd("> 4")
|
|
213
195
|
|
|
214
196
|
|
|
197
|
+
console.time("> 5")
|
|
215
198
|
for(let key in this.env) {
|
|
216
199
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) && key !== "ProgramFiles(x86)") {
|
|
217
200
|
delete this.env[key]
|
|
@@ -230,6 +213,61 @@ class Shell {
|
|
|
230
213
|
delete this.env[key]
|
|
231
214
|
}
|
|
232
215
|
}
|
|
216
|
+
console.timeEnd("> 5")
|
|
217
|
+
}
|
|
218
|
+
async start(params, ondata) {
|
|
219
|
+
console.log("shell start", params)
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
params := {
|
|
223
|
+
group: <group id>,
|
|
224
|
+
id: <shell id>,
|
|
225
|
+
path: <shell cwd (always absolute path)>,
|
|
226
|
+
env: <environment value key pairs>
|
|
227
|
+
}
|
|
228
|
+
*/
|
|
229
|
+
|
|
230
|
+
this.cols = 100
|
|
231
|
+
this.rows = 30
|
|
232
|
+
|
|
233
|
+
if (params.cols) {
|
|
234
|
+
this.cols = params.cols
|
|
235
|
+
}
|
|
236
|
+
if (params.rows) {
|
|
237
|
+
this.rows = params.rows
|
|
238
|
+
}
|
|
239
|
+
if (params.client && params.client.cols) {
|
|
240
|
+
this.cols = params.client.cols
|
|
241
|
+
}
|
|
242
|
+
if (params.client && params.client.rows) {
|
|
243
|
+
this.rows = params.client.rows
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
console.log({ cols: this.cols, rows: this.rows })
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
this.vt = new Terminal({
|
|
250
|
+
allowProposedApi: true,
|
|
251
|
+
cols: this.cols,
|
|
252
|
+
rows: this.rows,
|
|
253
|
+
})
|
|
254
|
+
this.vts = new SerializeAddon()
|
|
255
|
+
this.vt.loadAddon(this.vts)
|
|
256
|
+
|
|
257
|
+
// 1. id
|
|
258
|
+
this.id = (params.id ? params.id : uuidv4())
|
|
259
|
+
|
|
260
|
+
// 2. group id
|
|
261
|
+
this.group = params.group
|
|
262
|
+
|
|
263
|
+
// 2. env
|
|
264
|
+
// default env
|
|
265
|
+
await this.init_env(params)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
233
271
|
// 3. path => path can be http, relative, absolute
|
|
234
272
|
this.path = params.path
|
|
235
273
|
|
|
@@ -281,11 +319,12 @@ class Shell {
|
|
|
281
319
|
return response
|
|
282
320
|
} else {
|
|
283
321
|
let response = await this.request(params, async (stream) => {
|
|
284
|
-
if (stream
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
322
|
+
if (ondata) ondata(stream)
|
|
323
|
+
// if (stream.prompt) {
|
|
324
|
+
// this.resolve()
|
|
325
|
+
// } else {
|
|
326
|
+
// if (ondata) ondata(stream)
|
|
327
|
+
// }
|
|
289
328
|
})
|
|
290
329
|
return response
|
|
291
330
|
}
|
|
@@ -293,8 +332,13 @@ class Shell {
|
|
|
293
332
|
// return this.id
|
|
294
333
|
}
|
|
295
334
|
emit(message) {
|
|
335
|
+
console.log("> 1", { message, input: this.input })
|
|
296
336
|
if (this.ptyProcess) {
|
|
297
|
-
|
|
337
|
+
console.log("> 2")
|
|
338
|
+
if (this.input) {
|
|
339
|
+
console.log("> 3")
|
|
340
|
+
this.ptyProcess.write(message)
|
|
341
|
+
}
|
|
298
342
|
}
|
|
299
343
|
}
|
|
300
344
|
send(message, newline, cb) {
|
|
@@ -370,12 +414,16 @@ class Shell {
|
|
|
370
414
|
return r
|
|
371
415
|
}
|
|
372
416
|
async request(params, cb) {
|
|
417
|
+
console.log("shell.request", params)
|
|
373
418
|
// create the path if it doesn't exist
|
|
374
419
|
await fs.promises.mkdir(params.path, { recursive: true }).catch((e) => { })
|
|
375
420
|
|
|
376
421
|
|
|
377
422
|
// not connected => make a new connection => which means get a new prompt
|
|
378
423
|
// if already connected => no need for a new prompt
|
|
424
|
+
if (params.input) {
|
|
425
|
+
this.input = params.input
|
|
426
|
+
}
|
|
379
427
|
if (params.persistent) {
|
|
380
428
|
this.persistent = params.persistent
|
|
381
429
|
}
|
|
@@ -907,6 +955,7 @@ class Shell {
|
|
|
907
955
|
}
|
|
908
956
|
}
|
|
909
957
|
kill(message, force) {
|
|
958
|
+
console.log("KILL")
|
|
910
959
|
|
|
911
960
|
this.done = true
|
|
912
961
|
this.ready = false
|
|
@@ -1014,6 +1063,11 @@ ${cleaned}
|
|
|
1014
1063
|
|
|
1015
1064
|
}
|
|
1016
1065
|
stream(msg, callback) {
|
|
1066
|
+
if (msg === "\u0007") {
|
|
1067
|
+
// Ignore bell sound escape character because it slows down everything and makes redundant sound
|
|
1068
|
+
callback()
|
|
1069
|
+
return
|
|
1070
|
+
}
|
|
1017
1071
|
this.vt.write(msg, () => {
|
|
1018
1072
|
let buf = this.vts.serialize()
|
|
1019
1073
|
let cleaned = this.stripAnsi(buf)
|
|
@@ -1021,8 +1075,10 @@ ${cleaned}
|
|
|
1021
1075
|
id: this.id,
|
|
1022
1076
|
raw: msg,
|
|
1023
1077
|
cleaned,
|
|
1024
|
-
state: cleaned
|
|
1078
|
+
state: cleaned,
|
|
1079
|
+
shell_id: this.id
|
|
1025
1080
|
}
|
|
1081
|
+
this.state = cleaned
|
|
1026
1082
|
if (this.cb) this.cb(response)
|
|
1027
1083
|
|
|
1028
1084
|
// Decide whether to kill or continue
|
|
@@ -1037,15 +1093,15 @@ ${cleaned}
|
|
|
1037
1093
|
// todo: may need to handle cases when the command returns immediately with no output (example: 'which brew' returns immediately with no text if brew doesn't exist)
|
|
1038
1094
|
setTimeout(() => {
|
|
1039
1095
|
if (cache === cleaned) {
|
|
1040
|
-
if (this.persistent) {
|
|
1041
|
-
if (this.cb) this.cb({
|
|
1042
|
-
//raw: cached_msg,
|
|
1043
|
-
//raw: msg,
|
|
1044
|
-
//raw: "",
|
|
1045
|
-
cleaned,
|
|
1046
|
-
state: cleaned,
|
|
1047
|
-
prompt: true
|
|
1048
|
-
})
|
|
1096
|
+
if (this.input || this.persistent) {
|
|
1097
|
+
// if (this.cb) this.cb({
|
|
1098
|
+
// //raw: cached_msg,
|
|
1099
|
+
// //raw: msg,
|
|
1100
|
+
// //raw: "",
|
|
1101
|
+
// cleaned,
|
|
1102
|
+
// state: cleaned,
|
|
1103
|
+
// prompt: true
|
|
1104
|
+
// })
|
|
1049
1105
|
callback()
|
|
1050
1106
|
} else {
|
|
1051
1107
|
callback()
|
package/kernel/shells.js
CHANGED
|
@@ -35,15 +35,20 @@ class Shells {
|
|
|
35
35
|
} else {
|
|
36
36
|
m = "ls"
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
console.time("init_env")
|
|
39
|
+
await sh.init_env({
|
|
40
40
|
env: this.kernel.bin.envs({}),
|
|
41
|
-
conda: {
|
|
42
|
-
skip: true
|
|
43
|
-
}
|
|
44
|
-
}, async (stream) => {
|
|
45
|
-
process.stdout.write(stream.raw)
|
|
46
41
|
})
|
|
42
|
+
console.timeEnd("init_env")
|
|
43
|
+
// let response = await sh.start({
|
|
44
|
+
// message: m,
|
|
45
|
+
// env: this.kernel.bin.envs({}),
|
|
46
|
+
// conda: {
|
|
47
|
+
// skip: true
|
|
48
|
+
// }
|
|
49
|
+
// }, async (stream) => {
|
|
50
|
+
// process.stdout.write(stream.raw)
|
|
51
|
+
// })
|
|
47
52
|
|
|
48
53
|
this.kernel.envs = sh.env
|
|
49
54
|
// also set the uppercase variables if they're not set
|
|
@@ -76,6 +81,7 @@ class Shells {
|
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
async _launch(params, options, ondata) {
|
|
84
|
+
console.log("_launch", { params, options })
|
|
79
85
|
// iterate through all the envs
|
|
80
86
|
params.env = this.kernel.bin.envs(params.env)
|
|
81
87
|
|
|
@@ -267,6 +273,7 @@ class Shells {
|
|
|
267
273
|
}
|
|
268
274
|
*/
|
|
269
275
|
let session = this.get(params.id)
|
|
276
|
+
console.log("EMIT", { session, params })
|
|
270
277
|
if (session) {
|
|
271
278
|
session.emit(params.emit)
|
|
272
279
|
}
|
|
@@ -341,6 +348,7 @@ class Shells {
|
|
|
341
348
|
}
|
|
342
349
|
}
|
|
343
350
|
async run(req, options, ondata) {
|
|
351
|
+
console.log("shells.run",req)
|
|
344
352
|
let response = await this.launch(req, options, ondata)
|
|
345
353
|
// req.id = id
|
|
346
354
|
// let sh = this.get(id)
|
|
@@ -429,6 +437,7 @@ class Shells {
|
|
|
429
437
|
}
|
|
430
438
|
}
|
|
431
439
|
rm(id) {
|
|
440
|
+
console.log("SHELL RM", id)
|
|
432
441
|
for(let i=0; i<this.shells.length; i++) {
|
|
433
442
|
let shell = this.shells[i]
|
|
434
443
|
if (shell.id === id) {
|
package/kernel/store.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const os = require('os')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
class Store {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.root = path.resolve(os.homedir(), ".pinokio")
|
|
7
|
+
if (!fs.existsSync(path.resolve(this.root))) {
|
|
8
|
+
fs.mkdirSync(path.resolve(this.root))
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exists() {
|
|
12
|
+
let p = path.resolve(this.root, "config.json")
|
|
13
|
+
return fs.existsSync(p)
|
|
14
|
+
}
|
|
15
|
+
clone(old) {
|
|
16
|
+
console.log("clone", old)
|
|
17
|
+
let p = path.resolve(this.root, "config.json")
|
|
18
|
+
fs.writeFileSync(p, JSON.stringify(old, null, 2))
|
|
19
|
+
}
|
|
20
|
+
set(key, val) {
|
|
21
|
+
let o
|
|
22
|
+
try {
|
|
23
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
24
|
+
o = JSON.parse(str)
|
|
25
|
+
} catch(e) {
|
|
26
|
+
o = {}
|
|
27
|
+
}
|
|
28
|
+
o[key] = val
|
|
29
|
+
fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
|
|
30
|
+
}
|
|
31
|
+
get(key) {
|
|
32
|
+
try {
|
|
33
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
34
|
+
let o = JSON.parse(str)
|
|
35
|
+
return o[key]
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
delete(key) {
|
|
41
|
+
try {
|
|
42
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
43
|
+
let o = JSON.parse(str)
|
|
44
|
+
delete o[key]
|
|
45
|
+
fs.writeFileSync(path.resolve(this.root, "config.json"), JSON.stringify(o, null, 2))
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
store() {
|
|
50
|
+
try {
|
|
51
|
+
let str = fs.readFileSync(path.resolve(this.root, "config.json"), "utf8")
|
|
52
|
+
let o = JSON.parse(str)
|
|
53
|
+
return o
|
|
54
|
+
} catch (e) {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
module.exports = Store
|
package/kernel/util.js
CHANGED
|
@@ -14,6 +14,9 @@ const groupReplacement = "$$$";
|
|
|
14
14
|
const h = "[^\\S\\r\\n]"; // simulate `\h`
|
|
15
15
|
const returnPattern = /\r/g;
|
|
16
16
|
const returnReplacement = "\\r";
|
|
17
|
+
const {
|
|
18
|
+
glob
|
|
19
|
+
} = require('glob')
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
// asar handling for go-get-folder-size
|
|
@@ -36,26 +39,20 @@ const du = async (folderpath) => {
|
|
|
36
39
|
const is_port_available = async (port) => {
|
|
37
40
|
return new Promise((resolve) => {
|
|
38
41
|
const server = http.createServer();
|
|
39
|
-
console.log("> Checking port availability", port)
|
|
40
42
|
try {
|
|
41
43
|
server.listen(port, (err) => {
|
|
42
44
|
if (err) {
|
|
43
|
-
console.log("> [1 port not available]", err)
|
|
44
45
|
resolve(false); // Port is occupied
|
|
45
46
|
} else {
|
|
46
|
-
console.log("> [2 port available] test server started. closing test server now.")
|
|
47
47
|
server.close(() => {
|
|
48
|
-
console.log("> Test server closed.")
|
|
49
48
|
resolve(true); // Port is free
|
|
50
49
|
}); // Close the server immediately after testing
|
|
51
50
|
}
|
|
52
51
|
});
|
|
53
52
|
server.on('error', (err) => {
|
|
54
|
-
console.log("> [3 port not available]", err);
|
|
55
53
|
resolve(false); // Port is occupied
|
|
56
54
|
});
|
|
57
55
|
} catch (e) {
|
|
58
|
-
console.log("> [4 port not available]", err)
|
|
59
56
|
resolve(false) // port not available
|
|
60
57
|
}
|
|
61
58
|
});
|
|
@@ -94,39 +91,89 @@ const parse_env = async (filename) => {
|
|
|
94
91
|
return {}
|
|
95
92
|
}
|
|
96
93
|
}
|
|
97
|
-
const openfs = (dirPath, options) => {
|
|
94
|
+
const openfs = (dirPath, options, kernel) => {
|
|
98
95
|
let command = '';
|
|
99
96
|
const platform = os.platform()
|
|
100
|
-
|
|
101
|
-
if (options && options.
|
|
102
|
-
mode =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
97
|
+
console.log("openfs", dirPath, options)
|
|
98
|
+
if (options && options.command) {
|
|
99
|
+
let mode = "view"
|
|
100
|
+
if (options && options.command) {
|
|
101
|
+
mode = options.command
|
|
102
|
+
}
|
|
103
|
+
console.log("> mode", mode)
|
|
104
|
+
if (mode === "view") {
|
|
105
|
+
switch (platform) {
|
|
106
|
+
case 'darwin':
|
|
107
|
+
command = `open -R "${dirPath}"`;
|
|
108
|
+
break;
|
|
109
|
+
case 'win32':
|
|
110
|
+
command = `explorer /select,"${dirPath}" & timeout /t 1 >nul`;
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
command = `xdg-open "${dirPath}"`;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
child_process.exec(command)
|
|
117
|
+
} else if (mode === "open") {
|
|
118
|
+
switch (platform) {
|
|
119
|
+
case 'darwin':
|
|
120
|
+
command = `open "${dirPath}"`;
|
|
121
|
+
break;
|
|
122
|
+
case 'win32':
|
|
123
|
+
command = `explorer "${dirPath}"`;
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
command = `xdg-open "${dirPath}"`;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
child_process.exec(command)
|
|
130
|
+
} else {
|
|
131
|
+
command = `${mode} "${dirPath}"`
|
|
132
|
+
console.log("> command", command)
|
|
133
|
+
if (kernel) {
|
|
134
|
+
kernel.exec({
|
|
135
|
+
message: command,
|
|
136
|
+
}, (e) => {
|
|
137
|
+
process.stdout.write(e.raw)
|
|
138
|
+
}).then(() => {
|
|
139
|
+
console.log("DONE")
|
|
140
|
+
})
|
|
141
|
+
} else {
|
|
142
|
+
child_process.exec(command)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
let mode = "view"
|
|
147
|
+
if (options && options.mode) {
|
|
148
|
+
mode = options.mode
|
|
115
149
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
150
|
+
if (mode === "view") {
|
|
151
|
+
switch (platform) {
|
|
152
|
+
case 'darwin':
|
|
153
|
+
command = `open -R "${dirPath}"`;
|
|
154
|
+
break;
|
|
155
|
+
case 'win32':
|
|
156
|
+
command = `explorer /select,"${dirPath}" & timeout /t 1 >nul`;
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
command = `xdg-open "${dirPath}"`;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
} else if (mode === "open") {
|
|
163
|
+
switch (platform) {
|
|
164
|
+
case 'darwin':
|
|
165
|
+
command = `open "${dirPath}"`;
|
|
166
|
+
break;
|
|
167
|
+
case 'win32':
|
|
168
|
+
command = `explorer "${dirPath}"`;
|
|
169
|
+
break;
|
|
170
|
+
default:
|
|
171
|
+
command = `xdg-open "${dirPath}"`;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
127
174
|
}
|
|
175
|
+
child_process.exec(command)
|
|
128
176
|
}
|
|
129
|
-
child_process.exec(command)
|
|
130
177
|
}
|
|
131
178
|
const parse_env_detail = async (filename) => {
|
|
132
179
|
// takes env and returns an array
|
|
@@ -199,6 +246,30 @@ const escapeStringRegexp = (string) => {
|
|
|
199
246
|
.replace(/-/g, '\\x2d');
|
|
200
247
|
}
|
|
201
248
|
|
|
249
|
+
const find_python = async (root) => {
|
|
250
|
+
let python_pattern
|
|
251
|
+
if (os.platform() === "win32") {
|
|
252
|
+
python_pattern = "**/python.exe";
|
|
253
|
+
} else {
|
|
254
|
+
python_pattern = "**/python"; // Matches python, python3, python3.x
|
|
255
|
+
}
|
|
256
|
+
const pythonBinaries = await glob(python_pattern, { nodir: true, cwd: root });
|
|
257
|
+
return pythonBinaries
|
|
258
|
+
}
|
|
259
|
+
const find_venv = async (root) => {
|
|
260
|
+
let python_pattern
|
|
261
|
+
if (os.platform() === "win32") {
|
|
262
|
+
python_pattern = "**/python.exe";
|
|
263
|
+
} else {
|
|
264
|
+
python_pattern = "**/python"; // Matches python, python3, python3.x
|
|
265
|
+
}
|
|
266
|
+
const pythonBinaries = await glob(python_pattern, { nodir: true, cwd: root, absolute: true });
|
|
267
|
+
const venvs = pythonBinaries.map((p) => {
|
|
268
|
+
return path.resolve(p, "../..")
|
|
269
|
+
})
|
|
270
|
+
return venvs
|
|
271
|
+
}
|
|
272
|
+
|
|
202
273
|
const update_env = async (filepath, changes) => {
|
|
203
274
|
console.log("UPDATE_ENV", { filepath, changes })
|
|
204
275
|
const env = await fs.promises.readFile(filepath, "utf8")
|
|
@@ -237,5 +308,5 @@ const update_env = async (filepath, changes) => {
|
|
|
237
308
|
await fs.promises.writeFile(filepath, newval)
|
|
238
309
|
};
|
|
239
310
|
module.exports = {
|
|
240
|
-
parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available
|
|
311
|
+
parse_env, log_path, api_path, update_env, parse_env_detail, openfs, port_running, du, is_port_available, find_python, find_venv
|
|
241
312
|
}
|
package/package.json
CHANGED
package/script/index.js
CHANGED
|
@@ -4,6 +4,16 @@ const os = require('os')
|
|
|
4
4
|
const platform = os.platform()
|
|
5
5
|
const Server = require('../server')
|
|
6
6
|
class Store {
|
|
7
|
+
constructor() {
|
|
8
|
+
let o
|
|
9
|
+
try {
|
|
10
|
+
let str = fs.readFileSync(path.resolve(__dirname, "pinokio.json"), "utf8")
|
|
11
|
+
o = JSON.parse(str)
|
|
12
|
+
} catch(e) {
|
|
13
|
+
o = {}
|
|
14
|
+
}
|
|
15
|
+
this.store = o
|
|
16
|
+
}
|
|
7
17
|
set(key, val) {
|
|
8
18
|
let o
|
|
9
19
|
try {
|
|
@@ -13,6 +23,7 @@ class Store {
|
|
|
13
23
|
o = {}
|
|
14
24
|
}
|
|
15
25
|
o[key] = val
|
|
26
|
+
this.store = o
|
|
16
27
|
fs.writeFileSync(path.resolve(__dirname, "pinokio.json"), JSON.stringify(o, null, 2))
|
|
17
28
|
}
|
|
18
29
|
get(key) {
|
|
@@ -31,6 +42,7 @@ class Store {
|
|
|
31
42
|
console.log("before delete", o)
|
|
32
43
|
delete o[key]
|
|
33
44
|
console.log("after delete", o)
|
|
45
|
+
this.store = o
|
|
34
46
|
fs.writeFileSync(path.resolve(__dirname, "pinokio.json"), JSON.stringify(o, null, 2))
|
|
35
47
|
} catch (e) {
|
|
36
48
|
}
|