Skip to content

Commit

Permalink
feat(scripts): run scripts and bins
Browse files Browse the repository at this point in the history
  • Loading branch information
dangreen committed Feb 17, 2022
1 parent 9cc9d7a commit e093e94
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
6 changes: 4 additions & 2 deletions packages/scripts/src/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ import {
} from 'argue-cli'
import {
detectPackageManager,
readPackageJsonUpward,
readScripts,
runParallel,
runSerial
} from './utils/index.js'

const pm = detectPackageManager()
const pkg = await readPackageJsonUpward()
const { parallel } = readOptions(
option(alias('parallel', 'p'), Boolean),
)
const scripts = readScripts()

if (parallel) {
process.exit(await runParallel(pm, scripts))
process.exit(await runParallel(pm, scripts, pkg))
} else {
process.exit(await runSerial(pm, scripts))
process.exit(await runSerial(pm, scripts, pkg))
}
17 changes: 17 additions & 0 deletions packages/scripts/src/utils/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ export function getRunArgs(pm, args) {
]
}

/**
* Get args to run command.
* @param {string} pm - Package manager name.
* @param {string[]} args - Command args.
* @param {{ scripts?: Record<string, string> }} pkg - package.json
* @returns {[string, string[]]} - Bin and commands.
*/
export function getArgs(pm, args, pkg) {
if (pkg.scripts && (args[0] in pkg.scripts)) {
return [pm, getRunArgs(pm, args)]
}

const [bin, ...restArgs] = args

return [bin, restArgs]
}

/**
* Read scripts from argv to run with package manager.
* @returns Package manager scripts to run.
Expand Down
41 changes: 41 additions & 0 deletions packages/scripts/src/utils/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { resolve, dirname } from 'path'
import { constants, promises } from 'fs'

const { access, readFile } = promises

/**
* Find file starts from cwd ups to root.
* @param {string} filename
* @param {string} [dir]
* @returns {Promise<string>} Path to file.
*/
export async function findFileUpward(filename, dir = process.cwd()) {
const file = resolve(dir, filename)

try {
await access(file, constants.R_OK)

return file
} catch (err) {
if (dir === '.') {
throw err
}

return findFileUpward(filename, dirname(dir))
}
}

/**
* Find and read package.json file.
* @returns {Promise<object>} package.json
*/
export async function readPackageJsonUpward() {
try {
const path = await findFileUpward('package.json')
const pkg = JSON.parse(await readFile(path, 'utf8'))

return pkg
} catch (err) {
throw new Error(`Can't find package.json`)
}
}
1 change: 1 addition & 0 deletions packages/scripts/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './args.js'
export * from './files.js'
export * from './spawn.js'
export * from './run.js'
18 changes: 10 additions & 8 deletions packages/scripts/src/utils/run.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { cpus } from 'os'
import pLimit from 'p-limit'
import { spawn } from './spawn.js'
import { getRunArgs } from './args.js'
import { getArgs } from './args.js'

/**
* Run package manager scripts serial.
* @param {string} pm
* @param {string[][]} scripts
* @param {{ scripts?: Record<string, string> }} pkg - package.json
* @returns Exit code
*/
export async function runSerial(pm, scripts) {
const pmScripts = scripts.map(script => getRunArgs(pm, script))
export async function runSerial(pm, scripts, pkg) {
const cmds = scripts.map(script => getArgs(pm, script, pkg))
let exitCode = 0

for (const pmScript of pmScripts) {
exitCode = exitCode || (await spawn(pm, pmScript)).exitCode
for (const [bin, args] of cmds) {
exitCode = exitCode || (await spawn(bin, args)).exitCode
}

return exitCode
Expand All @@ -24,12 +25,13 @@ export async function runSerial(pm, scripts) {
* Run package manager scripts parallel.
* @param {string} pm
* @param {string[][]} scripts
* @param {{ scripts?: Record<string, string> }} pkg - package.json
* @returns Exit code.
*/
export async function runParallel(pm, scripts) {
export async function runParallel(pm, scripts, pkg) {
const limit = pLimit(cpus().length)
const pmScripts = scripts.map(script => getRunArgs(pm, script))
const tasks = pmScripts.map(pmScript => limit(() => spawn(pm, pmScript, false)))
const cmds = scripts.map(script => getArgs(pm, script, pkg))
const tasks = cmds.map(([bin, args]) => limit(() => spawn(bin, args, false)))
let exitCode = 0
/** @type {{ exitCode: number, output?: string | Error }} */
let result
Expand Down

0 comments on commit e093e94

Please sign in to comment.