@rip-lang/swarm 1.2.5 → 1.2.7
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/README.md +16 -0
- package/package.json +1 -1
- package/swarm.rip +44 -22
package/README.md
CHANGED
|
@@ -214,3 +214,19 @@ swarm { setup, perform }
|
|
|
214
214
|
rip download-tests.rip tests.txt -w 40
|
|
215
215
|
# 15,000 tests across 40 workers — finishes in minutes
|
|
216
216
|
```
|
|
217
|
+
|
|
218
|
+
## Troubleshooting
|
|
219
|
+
|
|
220
|
+
### Progress bar text appears black in VS Code / Cursor
|
|
221
|
+
|
|
222
|
+
VS Code's terminal has a "minimum contrast ratio" feature that overrides
|
|
223
|
+
foreground colors. This can turn white progress text black. To fix it,
|
|
224
|
+
add this to your VS Code or Cursor settings:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
"terminal.integrated.minimumContrastRatio": 1
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This disables the contrast adjustment and lets ANSI colors render as
|
|
231
|
+
intended. The progress display works correctly in standard terminals
|
|
232
|
+
(iTerm2, Terminal.app, etc.) without any changes.
|
package/package.json
CHANGED
package/swarm.rip
CHANGED
|
@@ -87,8 +87,9 @@ hex = (str) ->
|
|
|
87
87
|
[parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)].join(';')
|
|
88
88
|
_hex[str] = result
|
|
89
89
|
|
|
90
|
-
fg
|
|
91
|
-
bg
|
|
90
|
+
fg = (rgb) -> if rgb then "\x1b[38;2;#{hex(rgb)}m" else "\x1b[39m"
|
|
91
|
+
bg = (rgb) -> if rgb then "\x1b[48;2;#{hex(rgb)}m" else "\x1b[49m"
|
|
92
|
+
fgw =! fg("fff")
|
|
92
93
|
|
|
93
94
|
# ==============================================================================
|
|
94
95
|
# Progress display
|
|
@@ -113,13 +114,14 @@ draw = (state) ->
|
|
|
113
114
|
ppct = (done + died) / jobs
|
|
114
115
|
most = Math.max(...Object.values(info), 1)
|
|
115
116
|
|
|
116
|
-
# worker bars
|
|
117
|
+
# worker bars — set colors once, just move cursor per row
|
|
118
|
+
write fgw + bg("5383ec")
|
|
117
119
|
for slot, count of info
|
|
118
120
|
tpct = count / most
|
|
119
121
|
cols = Math.floor(ppct * tpct * wide)
|
|
120
|
-
write go(parseInt(slot) + 1, len + 5) +
|
|
122
|
+
write go(parseInt(slot) + 1, len + 5) + char.repeat(cols)
|
|
121
123
|
|
|
122
|
-
# summary bar
|
|
124
|
+
# summary bar — one atomic write
|
|
123
125
|
dpct = done / jobs
|
|
124
126
|
lpct = live / jobs
|
|
125
127
|
gcol = Math.floor(dpct * wide)
|
|
@@ -129,12 +131,11 @@ draw = (state) ->
|
|
|
129
131
|
|
|
130
132
|
out = [
|
|
131
133
|
go(row, len + 5)
|
|
132
|
-
|
|
133
|
-
bg("
|
|
134
|
-
bg("
|
|
135
|
-
bg("d85140") + " ".repeat(rcol) # red (rest)
|
|
134
|
+
bg("58a65c") + char.repeat(gcol) # green (done)
|
|
135
|
+
bg("f1bf42") + char.repeat(ycol) # yellow (live)
|
|
136
|
+
bg("d85140") + " ".repeat(rcol) # red (rest)
|
|
136
137
|
go(row, len + 5 + wide + 3)
|
|
137
|
-
bg("5383ec") + " #{(ppct * 100).toFixed(1)}% "
|
|
138
|
+
bg("5383ec") + " #{(ppct * 100).toFixed(1)}% " # blue (pct)
|
|
138
139
|
if done > 0 then bg() + " " + bg("58a65c") + " #{done}/#{jobs} done "
|
|
139
140
|
if died > 0 then bg() + " " + bg("d85140") + " #{died} died "
|
|
140
141
|
].filter(Boolean).join('') + fg() + bg()
|
|
@@ -166,17 +167,17 @@ export swarm = (opts = {}) ->
|
|
|
166
167
|
|
|
167
168
|
if workers < 1
|
|
168
169
|
console.error 'error: workers must be at least 1'
|
|
169
|
-
|
|
170
|
+
exit(1)
|
|
170
171
|
|
|
171
172
|
if doreset
|
|
172
173
|
rmSync(_dir, { recursive: true, force: true })
|
|
173
174
|
console.log 'removed .swarm directory'
|
|
174
|
-
|
|
175
|
+
exit(0)
|
|
175
176
|
|
|
176
177
|
# run setup
|
|
177
178
|
unless typeof opts.perform is 'function'
|
|
178
179
|
console.error 'error: perform() function is required'
|
|
179
|
-
|
|
180
|
+
exit(1)
|
|
180
181
|
|
|
181
182
|
context = {}
|
|
182
183
|
if typeof opts.setup is 'function'
|
|
@@ -187,13 +188,13 @@ export swarm = (opts = {}) ->
|
|
|
187
188
|
# read task list
|
|
188
189
|
unless existsSync(_todo)
|
|
189
190
|
console.error 'error: no .swarm/todo directory found (did setup run?)'
|
|
190
|
-
|
|
191
|
+
exit(1)
|
|
191
192
|
|
|
192
193
|
tasks = readdirSync(_todo).sort().map (f) -> join(_todo, f)
|
|
193
194
|
|
|
194
195
|
if tasks.length is 0
|
|
195
196
|
console.log 'no tasks to process'
|
|
196
|
-
|
|
197
|
+
exit(0)
|
|
197
198
|
|
|
198
199
|
jobs = tasks.length
|
|
199
200
|
|
|
@@ -213,12 +214,28 @@ export swarm = (opts = {}) ->
|
|
|
213
214
|
catch
|
|
214
215
|
null
|
|
215
216
|
|
|
217
|
+
# pre-flight: check workers can resolve modules from script directory
|
|
218
|
+
dir = dirname(scriptPath)
|
|
219
|
+
found = false
|
|
220
|
+
loop
|
|
221
|
+
if existsSync(join(dir, 'node_modules', '@rip-lang', 'swarm'))
|
|
222
|
+
found = true
|
|
223
|
+
break
|
|
224
|
+
parent = dirname(dir)
|
|
225
|
+
break if parent is dir
|
|
226
|
+
dir = parent
|
|
227
|
+
unless found
|
|
228
|
+
console.error "swarm: no node_modules found — workers won't be able to load modules"
|
|
229
|
+
console.error "hint: run 'bun add @rip-lang/all' in your project directory"
|
|
230
|
+
exit 1
|
|
231
|
+
|
|
216
232
|
# state
|
|
217
|
-
live
|
|
218
|
-
done
|
|
219
|
-
died
|
|
220
|
-
info
|
|
221
|
-
taskIdx
|
|
233
|
+
live = 0
|
|
234
|
+
done = 0
|
|
235
|
+
died = 0
|
|
236
|
+
info = {}
|
|
237
|
+
taskIdx = 0
|
|
238
|
+
fatal = false
|
|
222
239
|
inflight = {} # slot → taskPath (track in-flight tasks for crash recovery)
|
|
223
240
|
lastTask = {} # slot → last completed task name (for display)
|
|
224
241
|
|
|
@@ -226,7 +243,7 @@ export swarm = (opts = {}) ->
|
|
|
226
243
|
process.on 'SIGINT', ->
|
|
227
244
|
cursor(true) unless quiet
|
|
228
245
|
write go(workers + 5, 1) + "\n" unless quiet
|
|
229
|
-
|
|
246
|
+
exit(1)
|
|
230
247
|
unless quiet
|
|
231
248
|
process.on 'SIGWINCH', ->
|
|
232
249
|
drawFrame(workers)
|
|
@@ -276,6 +293,11 @@ export swarm = (opts = {}) ->
|
|
|
276
293
|
w.on 'message', (msg) ->
|
|
277
294
|
switch msg.type
|
|
278
295
|
when 'error'
|
|
296
|
+
unless fatal
|
|
297
|
+
fatal = true
|
|
298
|
+
cursor(true) unless quiet
|
|
299
|
+
console.error "\nswarm: #{msg.error}"
|
|
300
|
+
console.error "hint: run 'bun add @rip-lang/all' in your project directory" if msg.error.includes('Cannot find module')
|
|
279
301
|
writeFileSync('.swarm/errors.log', "worker #{slot} startup: #{msg.error}\n", { flag: 'a' }) if existsSync(_dir)
|
|
280
302
|
when 'ready'
|
|
281
303
|
dispatchNext(w, slot)
|
|
@@ -332,7 +354,7 @@ export swarm = (opts = {}) ->
|
|
|
332
354
|
s = parseInt(slot)
|
|
333
355
|
n = info[slot]
|
|
334
356
|
rate = if secs > 0 then (n / secs).toFixed(1) else '—'
|
|
335
|
-
write go(s + 1, len + 5) +
|
|
357
|
+
write go(s + 1, len + 5) + fgw + bg("5383ec") + char.repeat(wide) + fg() + bg() + " │ #{n} jobs @ #{rate}/sec" + clear(true)
|
|
336
358
|
draw({ live: 0, done, died, jobs, workers, info })
|
|
337
359
|
cursor(true)
|
|
338
360
|
write go(workers + 5, 1)
|