⚝
One Hat Cyber Team
⚝
Your IP:
172.22.0.1
Server IP:
151.80.20.34
Server:
Linux 794f04d97d5e 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64
Server Software:
Apache/2.4.62 (Debian)
PHP Version:
8.2.28
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
node_modules
/
tap
/
lib
/
View File Name :
watch.js
const proc = typeof process === 'object' && process ? process : null const chokidar = require('chokidar') const Minipass = require('minipass') const bin = require.resolve('../bin/run.js') const {spawn} = require('child_process') const onExit = require('signal-exit') const fs = require('fs') const {writeFileSync, readFileSync} = fs const {stringify} = require('tap-yaml') const {resolve} = require('path') class Watch extends Minipass { constructor (options) { if (!options.coverage) throw new Error('--watch requires coverage to be enabled') if (!proc) throw new Error('--watch requires working node.js process object') super() this.args = [bin, ...options._.parsed, '--no-watch'] this.positionals = [...options._] this.log('initial test run', this.args) this.proc = spawn(proc.execPath, this.args, { stdio: 'inherit' }) this.proc.on('close', () => this.main()) const saveFolder = 'node_modules/.cache/tap' require('../settings.js').mkdirRecursiveSync(saveFolder) this.saveFile = saveFolder + '/watch-' + proc.pid /* istanbul ignore next */ onExit(() => require('../settings.js').rmdirRecursiveSync(this.saveFile)) this.index = null this.indexFile = '.nyc_output/processinfo/index.json' this.fileList = [] this.queue = [] this.watcher = null this.env = { ...proc.env } } readIndex () { this.index = JSON.parse(readFileSync(this.indexFile, 'utf8')) } kill (signal) { if (this.proc) this.proc.kill(signal) } watchList () { if (!this.index) this.readIndex() // externalIds are the relative path to a test file // the files object keys are fully resolved. // If a test is covered, it'll show up in both! // Since a covered test was definitely included in its own // test run, don't add it a second time, so we don't get // two chokidar events for the same file change. const fileSet = new Set(Object.keys(this.index.files)) Object.keys(this.index.externalIds) .filter(f => !fileSet.has(resolve(f))) .forEach(f => fileSet.add(f)) return [...fileSet] } pause () { if (this.watcher) this.watcher.close() this.watcher = null } resume () { if (!this.watcher) this.watch() } main () { this.emit('main') this.proc = null this.fileList = this.watchList() this.watch() } watch () { this.pause() const sawAdd = new Map() const watcher = this.watcher = chokidar.watch(this.fileList) // ignore the first crop of add events, since we already ran the tests watcher.on('all', (ev, file) => { if (ev === 'add' && !sawAdd.get(file)) sawAdd.set(file, true) else this.onChange(ev, file) }) return watcher } onChange (ev, file) { const tests = this.testsFromChange(file) this.queue.push(...tests) this.log(ev + ' ' + file) if (this.proc) return this.log('test in progress, queuing for next run') this.run() } run () { const set = [...new Set(this.queue)] this.log('running tests', set) writeFileSync(this.saveFile, set.join('\n') + '\n') this.queue.length = 0 this.proc = spawn(proc.execPath, [ ...this.args, '--save=' + this.saveFile, '--nyc-arg=--no-clean' ], { stdio: 'inherit', env: this.env, }) this.proc.on('close', (code, signal) => this.onClose(code, signal)) this.emit('process', this.proc) } onClose (code, signal) { this.readIndex() this.proc = null // only add if it's not already there as either a test or included file const newFileList = this.watchList().filter(f => !this.fileList.includes(f) && !this.fileList.includes(resolve(f))) this.fileList.push(...newFileList) this.resume() newFileList.forEach(f => this.watcher.add(f)) // if there are any failures (especially, from a bail out) // then add those, but ignore if it's not there. const leftover = (() => { try { return fs.readFileSync(this.saveFile, 'utf8').trim().split('\n') } catch (er) { return [] } })() // run again if something was added during the process const runAgain = this.queue.length this.queue.push(...leftover) if (runAgain) this.run() else this.emit('afterProcess', {code, signal}) } log (msg, arg) { if (arg && typeof arg !== 'string') msg += '\n' + stringify(arg) this.write(msg + '\n') } testsFromChange (file) { return this.index.externalIds[file] ? [file] : this.testsFromFile(file) } testsFromFile (file) { const reducer = (set, uuid) => { for (let process = this.index.processes[uuid]; process; process = process.parent && this.index.processes[process.parent]) { if (process.externalId) set.add(process.externalId) } return set } const procs = this.index.files[file] || /* istanbul ignore next */ [] return [...procs.reduce(reducer, new Set())] } } module.exports = {Watch}