@take-out/scripts 0.1.38-1772433507984 → 0.1.38-1772439111798

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@take-out/scripts",
3
- "version": "0.1.38-1772433507984",
3
+ "version": "0.1.38-1772439111798",
4
4
  "type": "module",
5
5
  "main": "./src/run.ts",
6
6
  "sideEffects": false,
@@ -20,7 +20,6 @@
20
20
  }
21
21
  },
22
22
  "scripts": {
23
- "postinstall": "cd src/run-group && (clang -O2 -o run-group run-group.c 2>/dev/null || gcc -O2 -o run-group run-group.c 2>/dev/null || true)",
24
23
  "lint": "oxlint src",
25
24
  "lint:fix": "oxfmt src && oxlint --fix --fix-suggestions src",
26
25
  "typecheck": "tko run typecheck"
@@ -31,7 +30,7 @@
31
30
  "dependencies": {
32
31
  "@clack/prompts": "^0.8.2",
33
32
  "@lydell/node-pty": "^1.2.0-beta.3",
34
- "@take-out/helpers": "0.1.38-1772433507984",
33
+ "@take-out/helpers": "0.1.38-1772439111798",
35
34
  "picocolors": "^1.1.1"
36
35
  },
37
36
  "peerDependencies": {
@@ -1,39 +1,8 @@
1
1
  import { spawn, type ChildProcess } from 'node:child_process'
2
- import { existsSync } from 'node:fs'
3
2
  import { cpus } from 'node:os'
4
- import { dirname, resolve } from 'node:path'
5
- import { fileURLToPath } from 'node:url'
6
3
 
7
4
  import type { Timer } from '@take-out/helpers'
8
5
 
9
- // find run-group binary for proper process group management
10
- let _runGroupBin: string | null | undefined
11
- function findRunGroupBinary(): string | null {
12
- if (_runGroupBin !== undefined) return _runGroupBin
13
-
14
- // check relative to this file (in packages/scripts/bin/)
15
- try {
16
- const __dirname = dirname(fileURLToPath(import.meta.url))
17
- const localBin = resolve(__dirname, '..', 'bin', 'run-group')
18
- if (existsSync(localBin)) {
19
- _runGroupBin = localBin
20
- return _runGroupBin
21
- }
22
- } catch {}
23
-
24
- // check in node_modules
25
- try {
26
- const nmBin = resolve(process.cwd(), 'node_modules', '@take-out', 'scripts', 'bin', 'run-group')
27
- if (existsSync(nmBin)) {
28
- _runGroupBin = nmBin
29
- return _runGroupBin
30
- }
31
- } catch {}
32
-
33
- _runGroupBin = null
34
- return null
35
- }
36
-
37
6
  export type ProcessType = ChildProcess
38
7
  export type ProcessHandler = (process: ProcessType) => void
39
8
 
@@ -50,39 +19,6 @@ export function getIsExiting() {
50
19
 
51
20
  const processHandlers = new Set<ProcessHandler>()
52
21
 
53
- // track all spawned child processes for cleanup on exit
54
- const activeProcesses = new Set<ChildProcess>()
55
-
56
- // install cleanup handlers once
57
- let cleanupInstalled = false
58
- function installCleanupHandlers() {
59
- if (cleanupInstalled) return
60
- cleanupInstalled = true
61
-
62
- const cleanup = () => {
63
- for (const proc of activeProcesses) {
64
- try {
65
- // kill the process group to ensure child processes are also killed
66
- if (proc.pid) {
67
- process.kill(-proc.pid, 'SIGTERM')
68
- }
69
- } catch {
70
- // process may already be dead
71
- }
72
- }
73
- }
74
-
75
- process.on('exit', cleanup)
76
- process.on('SIGINT', () => {
77
- cleanup()
78
- process.exit(130)
79
- })
80
- process.on('SIGTERM', () => {
81
- cleanup()
82
- process.exit(143)
83
- })
84
- }
85
-
86
22
  const colors = [
87
23
  '\x1b[36m', // cyan
88
24
  '\x1b[35m', // magenta
@@ -157,22 +93,13 @@ export async function run(
157
93
  let timeoutId: Timer | undefined
158
94
  let didTimeOut = false
159
95
 
160
- // find run-group binary (handles process group cleanup properly)
161
- const runGroupBin = findRunGroupBinary()
162
-
163
96
  try {
164
- // use run-group to wrap the command - it handles process groups and cleanup
165
- const shell = runGroupBin
166
- ? spawn(runGroupBin, ['bash', '-c', command], {
167
- env: { ...process.env, ...env },
168
- cwd,
169
- stdio: ['ignore', 'pipe', 'pipe'],
170
- })
171
- : spawn('bash', ['-c', command], {
172
- env: { ...process.env, ...env },
173
- cwd,
174
- stdio: ['ignore', 'pipe', 'pipe'],
175
- })
97
+ const shell = spawn('bash', ['-c', command], {
98
+ env: { ...process.env, ...env },
99
+ cwd,
100
+ stdio: ['ignore', 'pipe', 'pipe'],
101
+ detached: detached ?? false,
102
+ })
176
103
 
177
104
  if (detached) {
178
105
  shell.unref()
package/src/run-pty.mjs CHANGED
@@ -258,7 +258,7 @@ function handleInput(data) {
258
258
  pendingAction = null
259
259
  console.log(match.shortcut)
260
260
  match.killed = true
261
- match.terminal.kill()
261
+ killProcessTree(match.terminal.pid)
262
262
  setTimeout(() => {
263
263
  spawnScript(match.name, match.cwd, match.label, match.extraArgs, match.index)
264
264
  console.log(`${getPrefix(match.index)} restarted`)
@@ -268,7 +268,7 @@ function handleInput(data) {
268
268
  console.log(match.shortcut)
269
269
  if (!match.killed) {
270
270
  match.killed = true
271
- match.terminal.kill()
271
+ killProcessTree(match.terminal.pid)
272
272
  console.log(`${getPrefix(match.index)} killed`)
273
273
  }
274
274
  } else {
@@ -286,6 +286,24 @@ function handleInput(data) {
286
286
  }
287
287
  }
288
288
 
289
+ // kill entire process group to prevent orphans
290
+ function killProcessTree(pid) {
291
+ if (!pid) return
292
+ // try killing process group first (negative pid)
293
+ try {
294
+ process.kill(-pid, 'SIGTERM')
295
+ } catch {}
296
+ // also kill direct process
297
+ try {
298
+ process.kill(pid, 'SIGTERM')
299
+ } catch {}
300
+ // schedule force kill
301
+ setTimeout(() => {
302
+ try { process.kill(-pid, 'SIGKILL') } catch {}
303
+ try { process.kill(pid, 'SIGKILL') } catch {}
304
+ }, 100)
305
+ }
306
+
289
307
  function cleanup() {
290
308
  // restore terminal to cooked mode before exiting
291
309
  if (process.stdin.isTTY && process.stdin.setRawMode) {
@@ -299,10 +317,12 @@ function cleanup() {
299
317
  for (const p of processes) {
300
318
  if (!p.killed) {
301
319
  p.killed = true
302
- p.terminal.kill()
320
+ killProcessTree(p.terminal.pid)
303
321
  }
304
322
  }
305
- process.exit(0)
323
+
324
+ // wait for kills to complete before exit
325
+ setTimeout(() => process.exit(0), 150)
306
326
  }
307
327
 
308
328
  async function main() {
package/src/run.ts CHANGED
@@ -1,14 +1,32 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  /**
4
- * @description Run multiple scripts in parallel using run-group for proper process management
4
+ * @description Run multiple scripts in parallel
5
5
  */
6
6
 
7
+ import { spawn } from 'node:child_process'
7
8
  import fs from 'node:fs'
8
- import { dirname, join, relative, resolve } from 'node:path'
9
- import { fileURLToPath } from 'node:url'
9
+ import { join, relative, resolve } from 'node:path'
10
10
 
11
- const __dirname = dirname(fileURLToPath(import.meta.url))
11
+ import { handleProcessExit } from '@take-out/scripts/helpers/handleProcessExit'
12
+
13
+ import { getIsExiting } from './helpers/run'
14
+ import { checkNodeVersion } from './node-version-check'
15
+
16
+ const colors = [
17
+ '\x1b[38;5;245m',
18
+ '\x1b[38;5;240m',
19
+ '\x1b[38;5;250m',
20
+ '\x1b[38;5;243m',
21
+ '\x1b[38;5;248m',
22
+ '\x1b[38;5;238m',
23
+ '\x1b[38;5;252m',
24
+ ]
25
+
26
+ const reset = '\x1b[0m'
27
+
28
+ // eslint-disable-next-line no-control-regex
29
+ const ansiPattern = /\x1b\[[0-9;]*m/g
12
30
 
13
31
  const args = process.argv.slice(2)
14
32
  const ownFlags = ['--no-root', '--bun', '--watch', '--flags=last']
@@ -32,22 +50,40 @@ for (let i = 0; i < args.length; i++) {
32
50
  }
33
51
 
34
52
  const noRoot = args.includes('--no-root')
53
+ const runBun = args.includes('--bun')
54
+ const watch = args.includes('--watch')
35
55
  const flagsLast = args.includes('--flags=last')
36
56
 
57
+ const MAX_RESTARTS = 3
58
+
37
59
  const parentRunningScripts = process.env.BUN_RUN_SCRIPTS
38
60
  ? process.env.BUN_RUN_SCRIPTS.split(',')
39
61
  : []
40
62
 
41
- if (runCommands.length === 0) {
42
- console.error('Please provide at least one script name to run')
43
- process.exit(1)
44
- }
45
-
46
- interface ResolvedCommand {
63
+ interface ManagedProcess {
64
+ proc: ReturnType<typeof spawn>
47
65
  name: string
48
- command: string
49
66
  cwd: string
50
- args: string[]
67
+ prefixLabel: string
68
+ extraArgs: string[]
69
+ index: number
70
+ shortcut: string
71
+ }
72
+
73
+ const managedProcesses: ManagedProcess[] = []
74
+ const { addChildProcess, exit } = handleProcessExit()
75
+
76
+ function getPrefix(index: number): string {
77
+ const managed = managedProcesses[index]
78
+ if (!managed) return ''
79
+ const color = colors[index % colors.length]
80
+ const sc = managed.shortcut || String(index + 1)
81
+ return `${color}${sc} ${managed.prefixLabel}${reset}`
82
+ }
83
+
84
+ if (runCommands.length === 0) {
85
+ console.error('Please provide at least one script name to run')
86
+ exit(1)
51
87
  }
52
88
 
53
89
  async function readPackageJson(directoryPath: string) {
@@ -143,15 +179,6 @@ async function findWorkspaceDirectories(): Promise<string[]> {
143
179
  })
144
180
  }
145
181
 
146
- async function getScriptCommand(
147
- directoryPath: string,
148
- scriptName: string
149
- ): Promise<string | null> {
150
- const packageJson = await readPackageJson(directoryPath)
151
- if (!packageJson?.scripts?.[scriptName]) return null
152
- return packageJson.scripts[scriptName]
153
- }
154
-
155
182
  async function findAvailableScripts(
156
183
  directoryPath: string,
157
184
  scriptNames: string[]
@@ -167,180 +194,218 @@ async function findAvailableScripts(
167
194
  )
168
195
  }
169
196
 
170
- async function resolveAllCommands(): Promise<ResolvedCommand[]> {
171
- const commands: ResolvedCommand[] = []
172
- const lastScript = runCommands[runCommands.length - 1]
173
-
174
- // root scripts
175
- if (!noRoot) {
176
- const filteredCommands = runCommands.filter(
177
- (name) => !parentRunningScripts.includes(name)
178
- )
179
-
180
- for (const name of filteredCommands) {
181
- const command = await getScriptCommand('.', name)
182
- if (command) {
183
- const scriptArgs = !flagsLast || name === lastScript ? forwardArgs : []
184
- commands.push({
185
- name,
186
- command,
187
- cwd: '.',
188
- args: scriptArgs,
189
- })
190
- }
191
- }
192
- }
193
-
194
- // workspace scripts
197
+ async function mapWorkspacesToScripts(
198
+ scriptNames: string[]
199
+ ): Promise<Map<string, { scripts: string[]; packageName: string }>> {
195
200
  const workspaceDirs = await findWorkspaceDirectories()
201
+ const workspaceScriptMap = new Map<string, { scripts: string[]; packageName: string }>()
196
202
 
197
203
  for (const dir of workspaceDirs) {
198
- const availableScripts = await findAvailableScripts(dir, runCommands)
199
- const filteredScripts = availableScripts.filter(
200
- (scriptName) => !parentRunningScripts.includes(scriptName)
201
- )
202
-
203
- for (const scriptName of filteredScripts) {
204
- const command = await getScriptCommand(dir, scriptName)
205
- if (command) {
206
- const packageJson = await readPackageJson(dir)
207
- const packageName = packageJson?.name || dir
208
- const scriptArgs = !flagsLast || scriptName === lastScript ? forwardArgs : []
209
-
210
- commands.push({
211
- name: `${packageName} ${scriptName}`,
212
- command,
213
- cwd: dir,
214
- args: scriptArgs,
215
- })
216
- }
204
+ const availableScripts = await findAvailableScripts(dir, scriptNames)
205
+
206
+ if (availableScripts.length > 0) {
207
+ const packageJson = await readPackageJson(dir)
208
+ const packageName = packageJson?.name || dir
209
+ workspaceScriptMap.set(dir, {
210
+ scripts: availableScripts,
211
+ packageName,
212
+ })
217
213
  }
218
214
  }
219
215
 
220
- return commands
216
+ return workspaceScriptMap
221
217
  }
222
218
 
223
- function findRunGroup(): string | null {
224
- // check local first (in takeout monorepo)
225
- const localPath = join(__dirname, 'run-group', 'run-group')
226
- if (fs.existsSync(localPath)) return localPath
219
+ const runScript = async (
220
+ name: string,
221
+ cwd = '.',
222
+ prefixLabel: string = name,
223
+ restarts = 0,
224
+ extraArgs: string[] = [],
225
+ managedIndex?: number
226
+ ) => {
227
+ const index = managedIndex ?? managedProcesses.length
228
+
229
+ const runArgs = ['run', '--silent', runBun ? '--bun' : '', name, ...extraArgs].filter(
230
+ Boolean
231
+ )
227
232
 
228
- // check installed package
229
- const installedPath = join(__dirname, '..', 'run-group', 'run-group')
230
- if (fs.existsSync(installedPath)) return installedPath
233
+ const allRunningScripts = [...parentRunningScripts, ...runCommands].join(',')
234
+
235
+ const proc = spawn('bun', runArgs, {
236
+ stdio: ['ignore', 'pipe', 'pipe'],
237
+ shell: false,
238
+ detached: true,
239
+ env: {
240
+ ...process.env,
241
+ FORCE_COLOR: '3',
242
+ BUN_RUN_PARENT_SCRIPT: name,
243
+ BUN_RUN_SCRIPTS: allRunningScripts,
244
+ TKO_SILENT: '1',
245
+ } as any,
246
+ cwd: resolve(cwd),
247
+ })
231
248
 
232
- return null
233
- }
249
+ const managed: ManagedProcess = {
250
+ proc,
251
+ name,
252
+ cwd,
253
+ prefixLabel,
254
+ extraArgs,
255
+ index,
256
+ shortcut: '',
257
+ }
234
258
 
235
- // fallback: use node spawn when run-group binary not available
236
- async function runWithNodeFallback(commands: ResolvedCommand[]) {
237
- const { spawn } = await import('node:child_process')
238
- const { handleProcessExit } = await import('@take-out/scripts/helpers/handleProcessExit')
239
-
240
- const colors = [
241
- '\x1b[36m', '\x1b[35m', '\x1b[32m', '\x1b[33m', '\x1b[34m', '\x1b[31m',
242
- ]
243
- const reset = '\x1b[0m'
244
-
245
- const { addChildProcess } = handleProcessExit()
246
- let exitCode = 0
247
-
248
- const procs = commands.map((cmd, i) => {
249
- const color = colors[i % colors.length]
250
- const prefix = `${color}[${cmd.name}]${reset}`
251
- const fullCwd = resolve(cmd.cwd)
252
- const fullCommand = cmd.args.length > 0
253
- ? `${cmd.command} ${cmd.args.join(' ')}`
254
- : cmd.command
255
-
256
- const proc = spawn('sh', ['-c', fullCommand], {
257
- cwd: fullCwd,
258
- stdio: ['ignore', 'pipe', 'pipe'],
259
- env: {
260
- ...process.env,
261
- FORCE_COLOR: '3',
262
- TKO_SILENT: '1',
263
- BUN_RUN_SCRIPTS: runCommands.join(','),
264
- },
265
- })
259
+ if (managedIndex !== undefined) {
260
+ managedProcesses[managedIndex] = managed
261
+ } else {
262
+ managedProcesses.push(managed)
263
+ }
266
264
 
267
- addChildProcess(proc)
265
+ addChildProcess(proc)
268
266
 
269
- proc.stdout?.on('data', (data) => {
270
- for (const line of data.toString().split('\n')) {
271
- if (line) console.log(`${prefix} ${line}`)
272
- }
273
- })
267
+ proc.stdout!.on('data', (data) => {
268
+ if (getIsExiting()) return
269
+ const lines = data.toString().split('\n')
270
+ for (const line of lines) {
271
+ const stripped = line.replace(ansiPattern, '')
272
+ if (stripped.startsWith('$ ')) continue
273
+ if (line) console.info(`${getPrefix(index)} ${line}`)
274
+ }
275
+ })
274
276
 
275
- proc.stderr?.on('data', (data) => {
276
- for (const line of data.toString().split('\n')) {
277
- if (line) console.error(`${prefix} ${line}`)
278
- }
279
- })
277
+ proc.stderr!.on('data', (data) => {
278
+ if (getIsExiting()) return
279
+ const lines = data.toString().split('\n')
280
+ for (const line of lines) {
281
+ const stripped = line.replace(ansiPattern, '')
282
+ if (stripped.startsWith('$ ')) continue
283
+ if (line) console.error(`${getPrefix(index)} ${line}`)
284
+ }
285
+ })
280
286
 
281
- return new Promise<number>((resolve) => {
282
- proc.on('close', (code) => resolve(code || 0))
283
- })
287
+ proc.on('error', (error) => {
288
+ console.error(`${getPrefix(index)} Failed to start: ${error.message}`)
284
289
  })
285
290
 
286
- const codes = await Promise.all(procs)
287
- exitCode = Math.max(...codes)
288
- process.exit(exitCode)
289
- }
291
+ proc.on('close', (code) => {
292
+ if (getIsExiting()) return
290
293
 
291
- async function main() {
292
- const commands = await resolveAllCommands()
294
+ if (code && code !== 0) {
295
+ console.error(`${getPrefix(index)} Process exited with code ${code}`)
293
296
 
294
- if (commands.length === 0) {
295
- console.error('No matching scripts found')
296
- process.exit(0)
297
- }
297
+ if (watch && restarts < MAX_RESTARTS) {
298
+ const newRestarts = restarts + 1
299
+ console.info(`Restarting process ${name} (${newRestarts}/${MAX_RESTARTS} times)`)
300
+ runScript(name, cwd, prefixLabel, newRestarts, extraArgs, index)
301
+ } else {
302
+ exit(1)
303
+ }
304
+ }
305
+ })
298
306
 
299
- const runGroupPath = findRunGroup()
307
+ return proc
308
+ }
300
309
 
301
- // fallback to node if binary not available
302
- if (!runGroupPath) {
303
- return runWithNodeFallback(commands)
304
- }
310
+ function computeShortcuts() {
311
+ const initials = managedProcesses.map((p) => {
312
+ const words = p.prefixLabel
313
+ .toLowerCase()
314
+ .split(/[^a-z]+/)
315
+ .filter(Boolean)
316
+ return words.map((w) => w[0]).join('')
317
+ })
305
318
 
306
- // build run-group command
307
- // format: run-group -p -t @name <cmd1> --- @name2 <cmd2> --- ...
308
- const runGroupArgs: string[] = ['-p', '-t']
319
+ const lengths = new Array(managedProcesses.length).fill(1) as number[]
309
320
 
310
- for (let i = 0; i < commands.length; i++) {
311
- const cmd = commands[i]!
312
- const fullCwd = resolve(cmd.cwd)
321
+ for (let round = 0; round < 5; round++) {
322
+ const shortcuts = initials.map((init, i) => init.slice(0, lengths[i]) || init)
313
323
 
314
- // wrap command with cd and env setup
315
- // use sh -c to handle complex commands with &&, ||, etc
316
- const envSetup = `FORCE_COLOR=3 TKO_SILENT=1 BUN_RUN_SCRIPTS=${runCommands.join(',')}`
317
- const fullCommand = cmd.args.length > 0
318
- ? `${cmd.command} ${cmd.args.join(' ')}`
319
- : cmd.command
324
+ let hasCollision = false
325
+ const groups = new Map<string, number[]>()
326
+ for (let i = 0; i < shortcuts.length; i++) {
327
+ const key = shortcuts[i]!
328
+ if (!groups.has(key)) groups.set(key, [])
329
+ groups.get(key)!.push(i)
330
+ }
320
331
 
321
- // use @name prefix for display name in parallel mode
322
- runGroupArgs.push(`@${cmd.name}`)
323
- runGroupArgs.push('sh', '-c', `cd "${fullCwd}" && ${envSetup} ${fullCommand}`)
332
+ for (const [, indices] of groups) {
333
+ if (indices.length <= 1) continue
334
+ hasCollision = true
335
+ for (const idx of indices) {
336
+ lengths[idx]!++
337
+ }
338
+ }
324
339
 
325
- if (i < commands.length - 1) {
326
- runGroupArgs.push('---')
340
+ if (!hasCollision) {
341
+ for (let i = 0; i < managedProcesses.length; i++) {
342
+ managedProcesses[i]!.shortcut = shortcuts[i]!
343
+ }
344
+ return
327
345
  }
328
346
  }
329
347
 
330
- // exec run-group (replaces this process)
331
- const { execFileSync } = await import('node:child_process')
348
+ for (let i = 0; i < managedProcesses.length; i++) {
349
+ const sc = initials[i]!.slice(0, lengths[i]) || initials[i]!
350
+ managedProcesses[i]!.shortcut = sc || String(i + 1)
351
+ }
352
+ }
353
+
354
+ async function main() {
355
+ checkNodeVersion().catch((err) => {
356
+ console.error(err.message)
357
+ exit(1)
358
+ })
332
359
 
333
360
  try {
334
- execFileSync(runGroupPath, runGroupArgs, {
335
- stdio: 'inherit',
336
- env: process.env,
337
- })
338
- } catch (error: any) {
339
- process.exit(error.status || 1)
361
+ if (runCommands.length > 0) {
362
+ const lastScript = runCommands[runCommands.length - 1]
363
+
364
+ if (!noRoot) {
365
+ const filteredCommands = runCommands.filter(
366
+ (name) => !parentRunningScripts.includes(name)
367
+ )
368
+ const scriptPromises = filteredCommands.map((name) => {
369
+ const scriptArgs = !flagsLast || name === lastScript ? forwardArgs : []
370
+ return runScript(name, '.', name, 0, scriptArgs)
371
+ })
372
+
373
+ await Promise.all(scriptPromises)
374
+ }
375
+
376
+ const workspaceScriptMap = await mapWorkspacesToScripts(runCommands)
377
+
378
+ for (const [workspace, { scripts, packageName }] of workspaceScriptMap.entries()) {
379
+ const filteredScripts = scripts.filter(
380
+ (scriptName) => !parentRunningScripts.includes(scriptName)
381
+ )
382
+ const workspaceScriptPromises = filteredScripts.map((scriptName) => {
383
+ const scriptArgs = !flagsLast || scriptName === lastScript ? forwardArgs : []
384
+ return runScript(
385
+ scriptName,
386
+ workspace,
387
+ `${packageName} ${scriptName}`,
388
+ 0,
389
+ scriptArgs
390
+ )
391
+ })
392
+
393
+ await Promise.all(workspaceScriptPromises)
394
+ }
395
+ }
396
+
397
+ if (managedProcesses.length === 0) {
398
+ exit(0)
399
+ } else {
400
+ computeShortcuts()
401
+ }
402
+ } catch (error) {
403
+ console.error(`Error running scripts: ${error}`)
404
+ exit(1)
340
405
  }
341
406
  }
342
407
 
343
408
  main().catch((error) => {
344
409
  console.error(`Error running scripts: ${error}`)
345
- process.exit(1)
410
+ exit(1)
346
411
  })
package/bin/run-group DELETED
Binary file
@@ -1,24 +0,0 @@
1
- const std = @import("std");
2
-
3
- pub fn build(b: *std.Build) void {
4
- const target = b.standardTargetOptions(.{});
5
- const optimize = b.standardOptimizeOption(.{});
6
-
7
- const exe = b.addExecutable(.{
8
- .name = "run-group",
9
- .root_source_file = b.path("main.zig"),
10
- .target = target,
11
- .optimize = optimize,
12
- });
13
-
14
- b.installArtifact(exe);
15
-
16
- const run_cmd = b.addRunArtifact(exe);
17
- run_cmd.step.dependOn(b.getInstallStep());
18
- if (b.args) |args| {
19
- run_cmd.addArgs(args);
20
- }
21
-
22
- const run_step = b.step("run", "Run the app");
23
- run_step.dependOn(&run_cmd.step);
24
- }