@olegjs/on-change
Version:
Run a command when a file changes since last time the command was executed
54 lines (44 loc) • 1.49 kB
JavaScript
const { yellow, magenta } = require('chalk')
const { spawnSync } = require('child_process')
const { createHash } = require('crypto')
const { existsSync, readFileSync, writeFileSync } = require('fs')
const { basename, dirname, join } = require('path')
const argv = require('yargs')
.scriptName('on-file-change')
.usage('Usage: $0 --file [file] [command]')
.example(
'$0 --file package-lock.json npm ci',
'Reinstall dependencies on changed package-lock.json',
)
.option('file', {
alias: 'f',
demandOption: true,
describe: 'Path to file to check for changes',
type: 'string',
})
.demandCommand(1).argv
const UTF = 'utf8'
const getCheckSum = (s, algorithm = 'sha1', format = 'hex') =>
createHash(algorithm)
.update(s)
.digest(format)
const getPastCheckSum = path =>
existsSync(path)
? readFileSync(path, UTF)
.trim()
.split(/\s+/)[0]
: null
const checkSum = getCheckSum(readFileSync(argv.file, UTF))
const checkSumFileName = `.${basename(argv.file)}.sha`
const pastCheckSum = getPastCheckSum(join(dirname(argv.file), checkSumFileName))
const isSumChecksOut = checkSum === pastCheckSum
if (!isSumChecksOut) {
console.log(
`File "${magenta(argv.file)}" has changed.`,
`Running "${yellow(argv._.join(' '))}"...`,
)
const [command, ...args] = argv._
spawnSync(command, args, { encoding: UTF, stdio: 'inherit' })
writeFileSync(checkSumFileName, `${checkSum} ${argv.file}`)
}