#!/usr/bin/env node import hardRejection from 'hard-rejection' import sade from 'sade' import { version } from '../package.json' import { clearCacheDirectory } from './cache-clear' import { showCacheDirectory } from './cache-dir' import { runCommand } from './run' hardRejection() const program = sade('cache-cmd') program .version(version) .describe('Run and cache a command based on various factors') .option( '-c, --cache-dir', 'Cache directory to use (default: .cache/cache-cmd in nearest node_modules)' ) program .command( 'run ', 'Run cached command (if no provided, this is the default)', { default: true } ) .option('-f, --file', 'Run command only when file content changes') .option('-t, --time', 'Run command only after specified time (unit with s,m,h,d,w,mo,y)') .option('--cache-on-error', 'Cache command run even when command exits with non-zero exit code') .example('run "echo ran this command" --time 20s') .example('run "./may-fail" --time 20s --cache-on-error') .example('run "yarn install" --file yarn.lock') .example('run "yarn install" --file yarn.lock --cache-dir .config/cache') .example('run "yarn install" --time 1mo --file yarn.lock --file package.json') .action((command: unknown, options: Record) => { const cacheDirectory = options['cache-dir'] const time = options.time const file = options.file const shouldCacheOnError = options['cache-on-error'] const files: unknown[] = file === undefined ? [] : Array.isArray(file) ? file : [file] if (typeof command !== 'string') { throw Error('Invalid supplied') } if (cacheDirectory !== undefined && typeof cacheDirectory !== 'string') { throw Error('Invalid --cache-dir supplied') } if (time !== undefined && typeof time !== 'string') { throw Error('Invalid --time supplied') } if (files.some((file) => typeof file !== 'string')) { throw Error('Invalid --file supplied') } if (shouldCacheOnError !== undefined && typeof shouldCacheOnError !== 'boolean') { throw Error('Invalid --cache-on-error supplied') } runCommand({ relativeCacheDirectory: cacheDirectory, command, cacheByTime: time, cacheByFiles: files as string[], shouldCacheOnError, }) }) program .command('cache dir', 'Show cache directory path used by cache-cmd') .action((options: Record) => { const cacheDirectory = options['cache-dir'] if (cacheDirectory !== undefined && typeof cacheDirectory !== 'string') { throw Error('Invalid --cache-dir supplied') } showCacheDirectory(cacheDirectory) }) program .command('cache clear', 'Clear cache used by cache-cmd') .action((options: Record) => { const cacheDirectory = options['cache-dir'] if (cacheDirectory !== undefined && typeof cacheDirectory !== 'string') { throw Error('Invalid --cache-dir supplied') } clearCacheDirectory(cacheDirectory) }) program.parse(process.argv)