@naanlang/naan 1.6.0 → 1.7.0
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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/bin/index.js +2 -2
- package/dist/env_web.js +3 -31
- package/dist/naan.min.js +10 -10
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +44 -122
- package/frameworks/browser/worker.nlg +64 -24
- package/frameworks/browser/workers.nlg +1 -1
- package/frameworks/client/apiclient.nlg +73 -43
- package/frameworks/client/psm_client.nlg +10 -14
- package/frameworks/common/common.nlg +2 -0
- package/frameworks/node/apiserver.nlg +0 -1
- package/frameworks/node/node.nlg +1 -0
- package/frameworks/node/pty.nlg +21 -21
- package/frameworks/node/shell.nlg +26 -3
- package/frameworks/node/worker.nlg +153 -79
- package/frameworks/project/build.nlg +55 -13
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/debugcom.nlg +20 -3
- package/frameworks/running/debugnub.nlg +16 -7
- package/frameworks/running/executors.nlg +14 -12
- package/frameworks/running/instances.nlg +1 -0
- package/frameworks/running/remote_req.nlg +4 -8
- package/frameworks/running/remote_res.nlg +1 -1
- package/frameworks/running/sourcecode.nlg +3 -2
- package/frameworks/running/taskexec.nlg +14 -57
- package/frameworks/service/imp.nlg +15 -0
- package/frameworks/service/nubnode.nlg +35 -4
- package/frameworks/service/nubweb.nlg +22 -4
- package/frameworks/storage/file_manager.nlg +3 -2
- package/lib/browser/env_web.js +10 -38
- package/lib/browser/env_webworker.js +1 -30
- package/lib/core/naanlib.js +10 -10
- package/lib/env_node.js +5 -22
- package/lib/env_nodeworker.js +8 -43
- package/lib/node_server_init.nlg +149 -0
- package/lib/node_worker.js +36 -0
- package/lib/node_worker_init.nlg +43 -0
- package/package.json +1 -1
- package/plugins/openSearch/openSearch.nlg +3 -2
- package/plugins/openSearch/os_dynamo.nlg +3 -2
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +44 -2
- package/plugins/serviceAws/aws_dynamo.nlg +144 -63
- package/plugins/serviceAws/aws_utils.nlg +6 -11
- package/plugins/serviceAws/serviceAws.nlg +3 -2
- package/test/test_01_core.nlg +2 -2
- package/test/test_02_context.nlg +8 -8
- package/test/test_03_jsinterop.nlg +3 -3
- package/test/test_07_lingo.nlg +1 -1
|
@@ -10,13 +10,6 @@
|
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
/*
|
|
14
|
-
* globals
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
gWorkerController = false;
|
|
19
|
-
|
|
20
13
|
|
|
21
14
|
/*
|
|
22
15
|
* CurBot
|
|
@@ -46,7 +39,6 @@ closure CurBot(options, local curbot) {
|
|
|
46
39
|
debugtext: ONdebugText.proc
|
|
47
40
|
status: ONstatus.proc
|
|
48
41
|
debugout: ONdebugOut.proc
|
|
49
|
-
messageout: ONmessageOut.proc
|
|
50
42
|
ioctl: ONioctl.proc
|
|
51
43
|
})
|
|
52
44
|
curbot.guid = 1
|
|
@@ -86,12 +78,46 @@ closure CurBot(options, local curbot) {
|
|
|
86
78
|
//
|
|
87
79
|
// Send the message to all our subscribers.
|
|
88
80
|
//
|
|
89
|
-
function notifyAll(message, exceptID, local topDestID) {
|
|
81
|
+
curbot.notifyAll = function notifyAll(message, exceptID, local topDestID) {
|
|
90
82
|
for topDestID in curbot.topsubs
|
|
91
83
|
if topDestID != exceptID
|
|
92
84
|
curbot.sender(topDestID, message)
|
|
93
85
|
}
|
|
94
86
|
|
|
87
|
+
// textEntry
|
|
88
|
+
//
|
|
89
|
+
// Simulate text entry for subprocess support.
|
|
90
|
+
//
|
|
91
|
+
curbot.textEntry = function textEntry(text) {
|
|
92
|
+
curbot.host.DispatchMessage({
|
|
93
|
+
id: "keyline"
|
|
94
|
+
text: text
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// rawStart
|
|
99
|
+
//
|
|
100
|
+
// Configure ioctls for raw terminal operation using the spawned PTY process.
|
|
101
|
+
//
|
|
102
|
+
curbot.rawStart = closure rawStart(ptySpawned, local dokey, doresize, doattach) {
|
|
103
|
+
dokey = xnew(function(msg, arg) { ptySpawned.write(arg.key) })
|
|
104
|
+
js.t.ioctl_add_listener("raw-key", dokey)
|
|
105
|
+
doresize = xnew(function(msg, dim) { ptySpawned.resize(dim.cols, dim.rows) })
|
|
106
|
+
js.t.ioctl_add_listener("term-resize", doresize)
|
|
107
|
+
js.t.ioctl("raw", true)
|
|
108
|
+
doattach = xnew(function(msg, arg) { js.t.ioctl("raw", true) }) // restore raw mode when we are attached
|
|
109
|
+
js.t.ioctl_add_listener("term-attach", doattach)
|
|
110
|
+
|
|
111
|
+
curbot.rawStop = function rawStop() {
|
|
112
|
+
js.t.ioctl("raw")
|
|
113
|
+
js.t.ioctl_remove_listener("raw-key", dokey)
|
|
114
|
+
js.t.ioctl_remove_listener("term-resize", doresize)
|
|
115
|
+
js.t.ioctl_remove_listener("term-attach", doattach)
|
|
116
|
+
dokey = doresize = doattach = false
|
|
117
|
+
curbot.rawStop = undefined
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
95
121
|
// impReceive
|
|
96
122
|
//
|
|
97
123
|
// Received a payload.
|
|
@@ -104,11 +130,14 @@ closure CurBot(options, local curbot) {
|
|
|
104
130
|
subscribe(sourceID)
|
|
105
131
|
else if message.id == "unsubscribe"
|
|
106
132
|
unsubscribe(sourceID)
|
|
107
|
-
else if message.id == "typed"
|
|
108
|
-
notifyAll(message, sourceID)
|
|
109
133
|
else {
|
|
110
|
-
|
|
111
|
-
|
|
134
|
+
subscribe(sourceID) // auto-subscribe
|
|
135
|
+
if message.id == "typed"
|
|
136
|
+
notifyAll(message, sourceID)
|
|
137
|
+
else if message.id == "keyline" && curbot.keyin
|
|
138
|
+
curbot.keyin(message.text) // terminal keyboard -> pty subprocess
|
|
139
|
+
else
|
|
140
|
+
curbot.host.DispatchMessage(message)
|
|
112
141
|
}
|
|
113
142
|
}
|
|
114
143
|
|
|
@@ -117,7 +146,7 @@ closure CurBot(options, local curbot) {
|
|
|
117
146
|
// Received an unknown destination notice.
|
|
118
147
|
//
|
|
119
148
|
curbot.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
120
|
-
if curbot.topsubs
|
|
149
|
+
if curbot.topsubs.indexOf(unknownID) >= 0 { // did not have courtesy to unsubscribe!
|
|
121
150
|
unsubscribe(unknownID)
|
|
122
151
|
return
|
|
123
152
|
}
|
|
@@ -125,28 +154,15 @@ closure CurBot(options, local curbot) {
|
|
|
125
154
|
debuglog("CurBot.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
126
155
|
}
|
|
127
156
|
|
|
128
|
-
// replyHook
|
|
129
|
-
//
|
|
130
|
-
// Intercept the ReplyMessage function to see if we should handle it.
|
|
131
|
-
//
|
|
132
|
-
function replyHook(data) {
|
|
133
|
-
// js.g.console.log("CurBot.replyHook:\n", Dialect.print(new(data)))
|
|
134
|
-
// debuglog("CurBot.replyHook:\n", Dialect.print(new(data)))
|
|
135
|
-
/* ###
|
|
136
|
-
if data._guid
|
|
137
|
-
workco.uworkers[data._guid].msgport.postMessage({
|
|
138
|
-
id: "targetreceive"
|
|
139
|
-
data: data
|
|
140
|
-
})
|
|
141
|
-
*/
|
|
142
|
-
}
|
|
143
|
-
curbot.host.OnReplyHook(replyHook.proc)
|
|
144
|
-
|
|
145
157
|
// ONtextOut
|
|
146
158
|
//
|
|
147
159
|
// Process console text output by Naan.
|
|
148
160
|
//
|
|
149
161
|
function ONtextOut(text) {
|
|
162
|
+
if curbot.naanin {
|
|
163
|
+
curbot.naanin(text) // naan output -> pty subprocess
|
|
164
|
+
return
|
|
165
|
+
}
|
|
150
166
|
notifyAll({
|
|
151
167
|
id: "textout",
|
|
152
168
|
text: text,
|
|
@@ -187,22 +203,6 @@ closure CurBot(options, local curbot) {
|
|
|
187
203
|
})
|
|
188
204
|
}
|
|
189
205
|
|
|
190
|
-
// ONmessageOut
|
|
191
|
-
//
|
|
192
|
-
// Process message output.
|
|
193
|
-
//
|
|
194
|
-
function ONmessageOut(data, local _guid) {
|
|
195
|
-
if data._guid {
|
|
196
|
-
_guid = data._guid
|
|
197
|
-
data._guid = undefined
|
|
198
|
-
curbot.sender(_guid, {
|
|
199
|
-
id: "targetout",
|
|
200
|
-
data: data
|
|
201
|
-
})
|
|
202
|
-
return
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
206
|
// ONioctl
|
|
207
207
|
//
|
|
208
208
|
// Process ioctl.
|
|
@@ -236,11 +236,17 @@ closure CurBot(options, local curbot) {
|
|
|
236
236
|
* type: <string> // target category, e.g. "Local"
|
|
237
237
|
* startup: <dictionary> // startup options
|
|
238
238
|
* topOriginID: <string> // so top can route to us through IMP
|
|
239
|
+
* rootPath: <string> // root path of worker's folder, must have lib/node_worker_init.nlg
|
|
240
|
+
* node: {
|
|
241
|
+
* // see NodeJS docs
|
|
242
|
+
* workerData: { // passed to node_worker.js
|
|
243
|
+
* }
|
|
244
|
+
* }
|
|
239
245
|
* }
|
|
240
246
|
*
|
|
241
247
|
*/
|
|
242
248
|
|
|
243
|
-
closure NowBot(options, local nowbot, subChannel) {
|
|
249
|
+
closure NowBot(options, local nowbot, nodeops, subChannel, ptySpawned) {
|
|
244
250
|
global(App, js, threads, JSpath)
|
|
245
251
|
nowbot = new(object, this)
|
|
246
252
|
nowbot.topsubs = []
|
|
@@ -248,8 +254,14 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
248
254
|
type: "node-worker"
|
|
249
255
|
}, options)
|
|
250
256
|
|
|
251
|
-
|
|
252
|
-
|
|
257
|
+
nodeops = merge({
|
|
258
|
+
// execArgv: ["--inspect-brk"] // unfortunately doesn't work; use VS Code instead
|
|
259
|
+
}, options.node)
|
|
260
|
+
if options.rootPath
|
|
261
|
+
nodeops.workerData = merge({
|
|
262
|
+
rootPath: options.rootPath
|
|
263
|
+
}, nodeops.workerData)
|
|
264
|
+
nowbot.thread = xnew(threads.Worker, JSpath.resolve(js.d, "lib/node_worker.js"), nodeops)
|
|
253
265
|
subChannel = xnew(threads.MessageChannel)
|
|
254
266
|
nowbot.thread.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1])
|
|
255
267
|
nowbot.msgport = subChannel.port2
|
|
@@ -303,6 +315,43 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
303
315
|
nowbot.sender(topDestID, message)
|
|
304
316
|
}
|
|
305
317
|
|
|
318
|
+
// textEntry
|
|
319
|
+
//
|
|
320
|
+
// Simulate text entry for subprocess support.
|
|
321
|
+
//
|
|
322
|
+
nowbot.textEntry = function textEntry(text) {
|
|
323
|
+
nowbot.msgport.postMessage({
|
|
324
|
+
id: "keyline"
|
|
325
|
+
text: text
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ioctl
|
|
330
|
+
//
|
|
331
|
+
// Send an ioctl to the terminal.
|
|
332
|
+
//
|
|
333
|
+
nowbot.ioctl = function ioctl(op, arg) {
|
|
334
|
+
notifyAll({
|
|
335
|
+
id: "ioctl"
|
|
336
|
+
op: op
|
|
337
|
+
arg: arg
|
|
338
|
+
})
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// rawMode
|
|
342
|
+
//
|
|
343
|
+
// Configure ioctls for raw terminal operation using the spawned PTY process.
|
|
344
|
+
//
|
|
345
|
+
nowbot.rawStart = function rawStart(ptys) {
|
|
346
|
+
ptySpawned = ptys
|
|
347
|
+
ioctl("raw", true)
|
|
348
|
+
nowbot.rawStop = function rawStop() {
|
|
349
|
+
ioctl("raw", false)
|
|
350
|
+
nowbot.rawStop = undefined
|
|
351
|
+
ptySpawned = false
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
306
355
|
// impReceive
|
|
307
356
|
//
|
|
308
357
|
// Received a payload.
|
|
@@ -314,22 +363,35 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
314
363
|
subscribe(sourceID)
|
|
315
364
|
else if message.id == "unsubscribe"
|
|
316
365
|
unsubscribe(sourceID)
|
|
317
|
-
else if message.id == "typed"
|
|
318
|
-
notifyAll(message, sourceID)
|
|
319
366
|
else {
|
|
367
|
+
subscribe(sourceID) // auto-subscribe
|
|
368
|
+
if message.id == "typed" {
|
|
369
|
+
notifyAll(message, sourceID)
|
|
370
|
+
return
|
|
371
|
+
}
|
|
372
|
+
if ptySpawned { // raw mode: kludgey, but works
|
|
373
|
+
if message.id == "ioctl-event" {
|
|
374
|
+
if message.msg == "raw-key"
|
|
375
|
+
ptySpawned.write(message.arg.key)
|
|
376
|
+
else if message.msg == "term-resize"
|
|
377
|
+
ptySpawned.resize(message.arg.cols, message.arg.rows)
|
|
378
|
+
}
|
|
379
|
+
if (message.id == "attached")
|
|
380
|
+
ioctl("raw", true) // restore raw mode after terminal attach
|
|
381
|
+
}
|
|
320
382
|
if message.id == "keyline" && nowbot.keyin
|
|
321
383
|
nowbot.keyin(message.text) // terminal keyboard -> pty subprocess
|
|
322
384
|
else
|
|
323
385
|
nowbot.msgport.postMessage(message)
|
|
324
386
|
}
|
|
325
387
|
}
|
|
326
|
-
|
|
388
|
+
|
|
327
389
|
// impUnknown
|
|
328
390
|
//
|
|
329
391
|
// Received an unknown destination notice.
|
|
330
392
|
//
|
|
331
393
|
nowbot.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
332
|
-
if nowbot.topsubs
|
|
394
|
+
if nowbot.topsubs.indexOf(unknownID) >= 0 { // did not have courtesy to unsubscribe!
|
|
333
395
|
unsubscribe(unknownID)
|
|
334
396
|
return
|
|
335
397
|
}
|
|
@@ -348,9 +410,11 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
348
410
|
id: "terminated"
|
|
349
411
|
error: error
|
|
350
412
|
})
|
|
413
|
+
nowbot.dispatchEvent("terminated", nowbot.instanceID, { error: error })
|
|
414
|
+
nowbot.thread = false
|
|
351
415
|
destroy()
|
|
352
416
|
})
|
|
353
|
-
|
|
417
|
+
|
|
354
418
|
// onexit
|
|
355
419
|
//
|
|
356
420
|
// Note that the worker thread has terminated.
|
|
@@ -360,9 +424,11 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
360
424
|
id: "terminated"
|
|
361
425
|
exitCode: exitCode
|
|
362
426
|
})
|
|
427
|
+
nowbot.dispatchEvent("terminated", nowbot.instanceID, { exitCode: exitCode })
|
|
428
|
+
nowbot.thread = false
|
|
363
429
|
destroy()
|
|
364
430
|
})
|
|
365
|
-
|
|
431
|
+
|
|
366
432
|
// destroy
|
|
367
433
|
//
|
|
368
434
|
// Ensure the worker is destroyed.
|
|
@@ -370,7 +436,7 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
370
436
|
nowbot.destroy = function destroy() {
|
|
371
437
|
terminate()
|
|
372
438
|
nowbot.thread = false
|
|
373
|
-
nowbot.impconn.
|
|
439
|
+
nowbot.impconn.destroy()
|
|
374
440
|
nowbot.impconn = false
|
|
375
441
|
App.imp.unregister(nowbot.instanceID)
|
|
376
442
|
}
|
|
@@ -387,35 +453,28 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
387
453
|
startmsg = {
|
|
388
454
|
id: "start"
|
|
389
455
|
state: false // resume state, if we have any
|
|
390
|
-
altcmd:
|
|
456
|
+
altcmd: options.startup.initcmds
|
|
391
457
|
dirpath: js.d
|
|
392
458
|
workerID: workerID
|
|
393
|
-
workerGUID: worker.guid
|
|
394
459
|
metadata: {
|
|
395
460
|
mainInstanceID: App.imp.us.instanceID
|
|
396
461
|
name: options.name
|
|
462
|
+
maintext: options.startup.maintext.concat("\n")
|
|
397
463
|
}
|
|
398
464
|
}
|
|
399
|
-
if options.startup.initcmds
|
|
400
|
-
startmsg.altcmd = options.startup.initcmds.concat("\n")
|
|
401
465
|
if options.startup.dirpath
|
|
402
466
|
startmsg.dirpath = options.startup.dirpath
|
|
403
467
|
nowbot.msgport.postMessage(startmsg)
|
|
404
468
|
notifyAll({
|
|
405
469
|
id: "started"
|
|
406
470
|
})
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
js.t.DispatchMessage({
|
|
410
|
-
id: "targetin"
|
|
411
|
-
data: msg.data
|
|
412
|
-
}) }
|
|
413
|
-
else if msg.id == "textout" && nowbot.naanin
|
|
471
|
+
nowbot.dispatchEvent("started", nowbot.instanceID)
|
|
472
|
+
} else if msg.id == "textout" && nowbot.naanin
|
|
414
473
|
nowbot.naanin(msg.text) // naan output -> pty subprocess
|
|
415
474
|
else
|
|
416
475
|
notifyAll(msg)
|
|
417
476
|
})
|
|
418
|
-
|
|
477
|
+
|
|
419
478
|
// terminate
|
|
420
479
|
//
|
|
421
480
|
// Terminate this worker asap.
|
|
@@ -440,6 +499,7 @@ closure NowBot(options, local nowbot, subChannel) {
|
|
|
440
499
|
}
|
|
441
500
|
|
|
442
501
|
nowbot.subprocess = MakeSubProcessor(nowbot) // Enable PTY subprocesses on our terminal
|
|
502
|
+
Events(nowbot)
|
|
443
503
|
|
|
444
504
|
// finis
|
|
445
505
|
|
|
@@ -518,7 +578,9 @@ closure NobBot(options, local nobbot)
|
|
|
518
578
|
* return value is a result tuple with an object that can be used to kill or monitor the
|
|
519
579
|
* subprocess.
|
|
520
580
|
*
|
|
521
|
-
*
|
|
581
|
+
* exec.subprocess(executable, args, options)
|
|
582
|
+
*
|
|
583
|
+
* The subprocess can be connected to the terminal raw, or in a variety of ways:
|
|
522
584
|
*
|
|
523
585
|
* term-keyboard | term-display | worker-in | worker-out
|
|
524
586
|
* -------------------------------------|---------------|------------|-----------
|
|
@@ -527,29 +589,28 @@ closure NobBot(options, local nobbot)
|
|
|
527
589
|
*
|
|
528
590
|
* Options:
|
|
529
591
|
* {
|
|
530
|
-
* input:
|
|
531
|
-
* output:
|
|
532
|
-
*
|
|
592
|
+
* input: false | "keyboard" | "pipe"
|
|
593
|
+
* output: false | "display" | "pipe" | "tee"
|
|
594
|
+
* raw: <boolean>
|
|
595
|
+
* spawn: <PtyManager.spawn options>
|
|
533
596
|
* }
|
|
534
597
|
*
|
|
535
598
|
*/
|
|
536
599
|
|
|
537
600
|
closure MakeSubProcessor(execbot) {
|
|
601
|
+
global()
|
|
538
602
|
closure subprocess(
|
|
539
603
|
executable, args, options, local error, pty) {
|
|
540
604
|
|
|
541
605
|
// ptyData - text has been returned from the subprocess
|
|
542
606
|
function ptyData(text) {
|
|
543
607
|
if options.output == "display" || options.output == "tee"
|
|
544
|
-
notifyAll({
|
|
608
|
+
execbot.notifyAll({ // send to display
|
|
545
609
|
id: "textout",
|
|
546
610
|
text: text
|
|
547
611
|
})
|
|
548
612
|
if options.output == "pipe" || options.output == "tee"
|
|
549
|
-
|
|
550
|
-
id: "keyline"
|
|
551
|
-
text: text
|
|
552
|
-
})
|
|
613
|
+
execbot.textEntry(text) // send to NaaN worker
|
|
553
614
|
}
|
|
554
615
|
|
|
555
616
|
// ptyKilled - the subprocess has terminated
|
|
@@ -558,6 +619,10 @@ closure MakeSubProcessor(execbot) {
|
|
|
558
619
|
execbot.keyin = false
|
|
559
620
|
if execbot.naanin === naanin
|
|
560
621
|
execbot.naanin = false
|
|
622
|
+
if options.raw {
|
|
623
|
+
execbot.rawStop()
|
|
624
|
+
execbot.textEntry("\x15mu();;\n") // send to NaaN worker
|
|
625
|
+
}
|
|
561
626
|
}
|
|
562
627
|
|
|
563
628
|
// keyin - the terminal has generated text for the subprocess
|
|
@@ -570,6 +635,7 @@ closure MakeSubProcessor(execbot) {
|
|
|
570
635
|
pty.write(text)
|
|
571
636
|
}
|
|
572
637
|
|
|
638
|
+
require("./pty.nlg") // load on demand
|
|
573
639
|
`(error, pty) = PtyManager().spawn(executable, args, {
|
|
574
640
|
ptyData: ptyData
|
|
575
641
|
ptyKilled: ptyKilled
|
|
@@ -577,9 +643,17 @@ closure MakeSubProcessor(execbot) {
|
|
|
577
643
|
if error
|
|
578
644
|
return (list(error))
|
|
579
645
|
if options.input == "keyboard"
|
|
580
|
-
|
|
646
|
+
execbot.keyin = keyin // replace existing
|
|
581
647
|
else if options.input == "pipe"
|
|
582
648
|
execbot.naanin = naanin // replace existing
|
|
649
|
+
if options.raw
|
|
650
|
+
execbot.rawStart(pty)
|
|
651
|
+
|
|
652
|
+
// our worker has terminated
|
|
653
|
+
execbot.addEventListener("terminated", function() {
|
|
654
|
+
pty.kill()
|
|
655
|
+
})
|
|
656
|
+
|
|
583
657
|
list(false, pty)
|
|
584
658
|
}
|
|
585
659
|
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -426,7 +426,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
426
426
|
// autoquoted to itself, a symbol. This can be used to detect build time vs. runtime.
|
|
427
427
|
|
|
428
428
|
function parseAndPack1(text, fpath, options, operation,
|
|
429
|
-
local util, lib, penv, naansym, dlogsym, pmod, pcomp, output, textout, annerror, annotations, package)
|
|
429
|
+
local util, lib, penv, naansym, dlogsym, pmod, pcomp, ournn, output, textout, annerror, annotations, package)
|
|
430
430
|
{
|
|
431
431
|
//
|
|
432
432
|
// textline
|
|
@@ -445,20 +445,39 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
445
445
|
lib = Naan.module.modlist().Lib.exports
|
|
446
446
|
if !util || !lib
|
|
447
447
|
return (list("Build packager cannot access support functions"))
|
|
448
|
+
//
|
|
449
|
+
// The following crazy rigmarole is about customizing the ParsEnvironment so we can glean
|
|
450
|
+
// enough information to build a package without actually executing the code. To do this we
|
|
451
|
+
// replace the entire Naan.module collection of functions with just build, so the others do
|
|
452
|
+
// nothing. From that we collect the module and component names, plus the manifest. This
|
|
453
|
+
// also sets up a benign "exports" dictionary so module build can "go through the mtions"
|
|
454
|
+
// without modification.
|
|
455
|
+
//
|
|
448
456
|
penv = lib.ParsEnvironment(Dialect, "build-".concat(operation))
|
|
449
457
|
penv.evalq(letlocal(App)) // make local copy of App
|
|
450
458
|
penv.evalq(letlocal(js)) // make local copy of js
|
|
451
|
-
|
|
452
|
-
penv.evalq(assign(naansym,new(Naan))) // make it modifiable
|
|
459
|
+
ournn = new(Naan) // get modifiable Naan
|
|
453
460
|
pmod = { } // our module object
|
|
454
461
|
pcomp = { } // our component object
|
|
455
|
-
|
|
462
|
+
ournn.module = {
|
|
456
463
|
build: function(modname, compname, proc) {
|
|
457
|
-
pmod.id = module
|
|
464
|
+
pmod.id = module.id
|
|
465
|
+
pmod.exports = { }
|
|
458
466
|
pcomp.name = compname
|
|
459
467
|
call(proc, pmod, pcomp) // obtain manifest
|
|
460
468
|
}
|
|
461
469
|
}
|
|
470
|
+
naansym = penv.evalq(function(nn) {
|
|
471
|
+
assign(letlocal(Naan).0,nn)
|
|
472
|
+
`Naan
|
|
473
|
+
}(ournn)) // make Naan modifiable
|
|
474
|
+
penv.evalq(assign(letlocal(module).0, { // make local copy of module
|
|
475
|
+
exports: { }
|
|
476
|
+
}))
|
|
477
|
+
//
|
|
478
|
+
// Here we make a custom debuglog function that identifies the text without color and will
|
|
479
|
+
// write the output to the build log.
|
|
480
|
+
//
|
|
462
481
|
dlogsym = penv.evalq(letlocal(debuglog).0) // make local copy of debuglog
|
|
463
482
|
penv.evalq(function \.debuglog args { // redefine debuglog for capture
|
|
464
483
|
let (arg, spaced) {
|
|
@@ -471,8 +490,19 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
471
490
|
apply(textline, reverse(spaced))
|
|
472
491
|
} () })
|
|
473
492
|
penv.evalq(putproc(car(dlogsym), \.debuglog.proc))
|
|
493
|
+
//
|
|
494
|
+
// The NideBuild symbol is "debug" or "release", etc. or is simply autoquoted as the symbol
|
|
495
|
+
// itself when not building. This is used if the source needs different behavior at build
|
|
496
|
+
// time or run time.
|
|
497
|
+
//
|
|
474
498
|
penv.eval(append(quote(assign(compress("NideBuild"))), operation)) // NideBuild symbol is operation name string
|
|
499
|
+
//
|
|
500
|
+
// This is the actual meat of the matter, the parsing of the program text.
|
|
501
|
+
//
|
|
475
502
|
output = penv.parse(text) // parse and evaluate
|
|
503
|
+
//
|
|
504
|
+
// Output processing and error logging
|
|
505
|
+
//
|
|
476
506
|
textout = ""
|
|
477
507
|
try {
|
|
478
508
|
if !pcomp.name
|
|
@@ -507,20 +537,30 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
507
537
|
}
|
|
508
538
|
if output.errors.length > 0
|
|
509
539
|
return (list("errors in ".concat(fpath), false, annotations, textout))
|
|
540
|
+
//
|
|
541
|
+
// Build the package, if not just doing syntax checking
|
|
542
|
+
//
|
|
510
543
|
if options.naanpack || options.jspack { // actually building a package?
|
|
511
544
|
if !pcomp.name {
|
|
512
|
-
|
|
545
|
+
//
|
|
546
|
+
// Some components cannot use a build function because they are too early in the
|
|
547
|
+
// boot process, but we still need a component. We look for NaanBuildComponent
|
|
548
|
+
// to define a dictionary with filename, name and manifest fields. For example,
|
|
549
|
+
// see Util:Module.nlg
|
|
550
|
+
//
|
|
551
|
+
pcomp = penv.evalq(car(compress(NaanBuildComponent)))
|
|
513
552
|
if !pcomp || !fpath.endsWith("/".concat(pcomp.filename))
|
|
514
553
|
return (list("Build cannot package without component in ".concat(fpath), false, annotations, textout))
|
|
515
554
|
}
|
|
516
|
-
package =
|
|
555
|
+
package = util.pkgSave(compress(pcomp.name), pcomp.manifest)
|
|
556
|
+
if string(package)
|
|
557
|
+
return (list("Build cannot generate package for ".concat(fpath), false, annotations, textout))
|
|
517
558
|
}
|
|
518
559
|
} catch {
|
|
519
560
|
if true
|
|
520
561
|
return (list("Packaging exception in ".concat(fpath, ": ", tostring(exception)), false, annotations, textout))
|
|
521
562
|
} finally {
|
|
522
563
|
penv.destroy() // remove the namespace
|
|
523
|
-
debuglog("parseAndPack1 done", fpath)
|
|
524
564
|
}
|
|
525
565
|
if options.naanpack
|
|
526
566
|
package = (js.w||js.s||js.g).JSON.stringify(package) // doesn't have frameworks/common available
|
|
@@ -546,7 +586,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
546
586
|
build.parallel = ExecutorParallel(track, { // create worker pool
|
|
547
587
|
basename: "build"
|
|
548
588
|
initeval: `(false, (parseAndPack1))
|
|
549
|
-
})
|
|
589
|
+
})
|
|
550
590
|
result = build.parallel.rpc(parseAndPack1, list(text, fpath, options, operation))
|
|
551
591
|
if !result.0 {
|
|
552
592
|
result = result.1 // unpeel RPC result
|
|
@@ -1211,17 +1251,19 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1211
1251
|
//
|
|
1212
1252
|
// Run the current build product by spawning a new worker.
|
|
1213
1253
|
//
|
|
1214
|
-
build.runSpawn = function runSpawn(local error, maintext, executor, vpath, site) {
|
|
1254
|
+
build.runSpawn = function runSpawn(local error, maintext, executor, vpath, site, dirpath) {
|
|
1215
1255
|
`(error, maintext) = fs.readFile(JSpath.join(build.destpath, build.runway.main))
|
|
1216
1256
|
if error
|
|
1217
1257
|
error = Error("Builder: cannot read main file", error)
|
|
1218
1258
|
else {
|
|
1259
|
+
dirpath = fs.path.resolve("/", fs.rootpath, build.destpath, build.runway.path || "")
|
|
1219
1260
|
`(error, executor) = track.spawn(build.runway.spawn.0, "${rules.name} ${build.version}", {
|
|
1220
1261
|
workerID: "Run-${build.version}+${build.buildnum}"
|
|
1221
1262
|
startup: {
|
|
1222
|
-
|
|
1223
|
-
dirpath:
|
|
1263
|
+
maintext: maintext
|
|
1264
|
+
dirpath: dirpath
|
|
1224
1265
|
}
|
|
1266
|
+
rootPath: dirpath
|
|
1225
1267
|
})
|
|
1226
1268
|
if error
|
|
1227
1269
|
error = Error("Builder: cannot spawn executor instance", error)
|
|
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
|
|
|
296
296
|
*
|
|
297
297
|
* Nide.proj/
|
|
298
298
|
* nide_cliser.cfg - JSON definition of the project (see below)
|
|
299
|
-
* NaanIDE_version.txt - [default] substitution file defining 1.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.7.0+1 etc.
|
|
300
300
|
* NaanIDE_version_builds.txt - [default] contains current build number as decimal string
|
|
301
301
|
* build/ - [optional] default build output location
|
|
302
302
|
* NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
|
|
@@ -19,9 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
closure DebugCommand(executor, notify, local decom, excon) {
|
|
21
21
|
decom = new(object, this)
|
|
22
|
-
executor.DebugCmd({
|
|
23
|
-
op: "attach"
|
|
24
|
-
})
|
|
25
22
|
decom.executor = executor
|
|
26
23
|
|
|
27
24
|
// debugData
|
|
@@ -96,6 +93,24 @@ closure DebugCommand(executor, notify, local decom, excon) {
|
|
|
96
93
|
status
|
|
97
94
|
}
|
|
98
95
|
|
|
96
|
+
// query
|
|
97
|
+
// Send a status update back.
|
|
98
|
+
//
|
|
99
|
+
decom.query = function query() {
|
|
100
|
+
decom.executor.DebugCmd({
|
|
101
|
+
op: "query"
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// attach
|
|
106
|
+
// Attach our GUI to the low-level debugger
|
|
107
|
+
//
|
|
108
|
+
decom.attach = function attach() {
|
|
109
|
+
executor.DebugCmd({
|
|
110
|
+
op: "attach"
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
//
|
|
100
115
|
// Run control.
|
|
101
116
|
//
|
|
@@ -138,6 +153,8 @@ closure DebugCommand(executor, notify, local decom, excon) {
|
|
|
138
153
|
notify.runState(debugStatus())
|
|
139
154
|
}
|
|
140
155
|
|
|
156
|
+
attach()
|
|
157
|
+
|
|
141
158
|
// finis
|
|
142
159
|
|
|
143
160
|
decom
|
|
@@ -35,6 +35,7 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
35
35
|
nub.watches = []
|
|
36
36
|
nub.stacks = { }
|
|
37
37
|
nub.usage = { }
|
|
38
|
+
paused = { }
|
|
38
39
|
|
|
39
40
|
// debugDepth
|
|
40
41
|
// Return the recursive debugging depth as an integer.
|
|
@@ -45,6 +46,18 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
45
46
|
curdepth = 0
|
|
46
47
|
curdepth
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
// sendStatus
|
|
51
|
+
// Send current status to the far end.
|
|
52
|
+
//
|
|
53
|
+
function sendStatus() {
|
|
54
|
+
js.t.ReplyDebugger({
|
|
55
|
+
op: "status"
|
|
56
|
+
depth: debugDepth()
|
|
57
|
+
bpenable: debug.bpenable
|
|
58
|
+
exenable: nub.exenable
|
|
59
|
+
})
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
// onDebugger proc
|
|
50
63
|
// Process an incoming debugger command.
|
|
@@ -52,17 +65,13 @@ closure DebugNub(local nub, debug, paused) {
|
|
|
52
65
|
function onDebugger(msg) {
|
|
53
66
|
if msg.op == "attach" {
|
|
54
67
|
debug.setCommander(nub)
|
|
55
|
-
|
|
56
|
-
op: "status"
|
|
57
|
-
depth: debugDepth()
|
|
58
|
-
bpenable: debug.bpenable
|
|
59
|
-
exenable: nub.exenable
|
|
60
|
-
})
|
|
68
|
+
sendStatus()
|
|
61
69
|
}
|
|
62
70
|
else if msg.op == "detach" {
|
|
63
71
|
debug.setCommander(false)
|
|
64
72
|
paused.wait = false // false: go back to ndb
|
|
65
|
-
}
|
|
73
|
+
} else if msg.op == "query"
|
|
74
|
+
sendStatus()
|
|
66
75
|
else if msg.op == "pause"
|
|
67
76
|
debugger()
|
|
68
77
|
else if msg.op == "resume" || msg.op == "stop"
|