diff --git a/README.md b/README.md index fd77b00..708ca58 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,6 @@ _Run a command on each file in a folder and its subfolders (CLI tool designed fo **recursive-exec** is `find -type f -exec` for use in your project's **package.json** file. -screenshot - ## A) Setup Install package for node: ```shell diff --git a/dist/recursive-exec.d.ts b/dist/recursive-exec.d.ts new file mode 100644 index 0000000..87d1878 --- /dev/null +++ b/dist/recursive-exec.d.ts @@ -0,0 +1,18 @@ +//! recursive-exec v0.0.1 ~~ https://github.com/center-key/recursive-exec ~~ MIT License + +export type Settings = { + extensions: string[] | null; + quiet: boolean; +}; +export type Result = { + folder: string; + file: string; + path: string; + filename: string; + basename: string; + command: string; +}; +declare const recursiveExec: { + find(folder: string, command: string, options?: Partial): Result[]; +}; +export { recursiveExec }; diff --git a/dist/recursive-exec.js b/dist/recursive-exec.js new file mode 100644 index 0000000..1d1f042 --- /dev/null +++ b/dist/recursive-exec.js @@ -0,0 +1,65 @@ +//! recursive-exec v0.0.1 ~~ https://github.com/center-key/recursive-exec ~~ MIT License + +import { globSync } from 'glob'; +import { spawnSync } from 'node:child_process'; +import chalk from 'chalk'; +import fs from 'fs'; +import log from 'fancy-log'; +import path from 'path'; +import slash from 'slash'; +const recursiveExec = { + find(folder, command, options) { + const defaults = { + extensions: null, + quiet: false, + }; + const settings = { ...defaults, ...options }; + const errorMessage = !folder ? 'Must specify the folder path.' : + !fs.existsSync(folder) ? 'Folder does not exist: ' + folder : + !fs.statSync(folder).isDirectory() ? 'Folder is not a folder: ' + folder : + !command ? 'Command template missing.' : + null; + if (errorMessage) + throw Error('[recursive-exec] ' + errorMessage); + const startTime = Date.now(); + const source = slash(path.normalize(folder)).replace(/\/$/, ''); + const logName = chalk.gray('recursive-exec'); + const getExts = () => settings.extensions.join(',').replaceAll('.', ''); + const extensions = !settings.extensions ? '' : `.{${getExts()}}`; + const files = globSync(source + '/**/*' + extensions, { ignore: '**/node_modules/**/*', nodir: true }).sort(); + if (!settings.quiet) + log(logName, chalk.magenta(source)); + const calcResult = (file) => { + const filename = file.substring(source.length + 1); + const relPath = file.substring(source.length + 1, file.length - path.basename(file).length - 1); + const basename = filename.substring(0, filename.length - path.extname(filename).length); + const interpolate = (template) => template + .replaceAll('{{basename}}', basename) + .replaceAll('{{file}}', file) + .replaceAll('{{filename}}', filename) + .replaceAll('{{path}}', relPath); + return { + folder: source, + file: file, + path: relPath, + filename: filename, + basename: basename, + command: interpolate(command), + }; + }; + const results = files.map(calcResult); + const execCommand = (result) => { + if (!settings.quiet) + log(logName, chalk.blue.bold('command:'), chalk.cyanBright(result.command)); + const task = spawnSync(result.command, { shell: true, stdio: 'inherit' }); + if (task.status !== 0) + throw Error(`[recursive-exec] Status: ${task.status}\nCommand: ${result.command}`); + }; + results.forEach(execCommand); + const summary = `(files: ${results.length}, ${Date.now() - startTime}ms)`; + if (!settings.quiet) + log(logName, chalk.green('done'), chalk.white(summary)); + return results; + }, +}; +export { recursiveExec }; diff --git a/package.json b/package.json index 30f4523..999f3f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "recursive-exec", - "version": "0.0.0", + "version": "0.0.1", "description": "Run a command on each file in a folder and its subfolders (CLI tool designed for use in npm scripts)", "license": "MIT", "type": "module",