From 1563a8ffa2804c731e679b704c83e88f0e994b7f Mon Sep 17 00:00:00 2001 From: "kebler.net" Date: Mon, 17 Jan 2022 19:31:45 -0800 Subject: [PATCH] 0.6.2 ingore .goutputstream files during atomic writes --- .npmignore | 0 example/example.js | 3 ++- package.json | 4 ++-- readme.md | 32 +++++++++++++++++++++++++++++++- src/watcher.js | 14 +++++++++----- 5 files changed, 44 insertions(+), 9 deletions(-) mode change 100644 => 100755 .npmignore mode change 100644 => 100755 package.json mode change 100644 => 100755 src/watcher.js diff --git a/.npmignore b/.npmignore old mode 100644 new mode 100755 diff --git a/example/example.js b/example/example.js index 933ded5..fab52a8 100644 --- a/example/example.js +++ b/example/example.js @@ -1,7 +1,7 @@ import Watcher from '../src/watcher.js' import onDeath from 'ondeath' -const USE_CUSTOM_HANDLER = true +const USE_CUSTOM_HANDLER = false const DEBOUNCE = 0 const READY_TIMEOUT = null @@ -11,6 +11,7 @@ const READY_TIMEOUT = null source: './example/repo/**', ignored: ['**/dontwatch.js'], ignoreList: ['./example/repo/.gitignore'], + // ignore_goutputstream: false, debounce: DEBOUNCE, readyTimeout: READY_TIMEOUT } diff --git a/package.json b/package.json old mode 100644 new mode 100755 index eeb3c52..deeb086 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uci-utils/watcher", - "version": "0.6.1", + "version": "0.6.2", "description": "File System Watcher Class that emits events", "main": "src/watcher.js", "type": "module", @@ -30,7 +30,7 @@ }, "homepage": "https://github.com/uCOMmandIt/uci-utils#readme", "dependencies": { - "@uci-utils/logger": "0.1.0", + "@uci-utils/logger": "^0.2.0", "@uci-utils/read-lines": "^0.3.0", "chokidar": "^3.5.1", "debounce-fn": "^5.0.0" diff --git a/readme.md b/readme.md index 6228699..5fc3ad6 100644 --- a/readme.md +++ b/readme.md @@ -27,7 +27,7 @@ opts = { } ``` **plus any options supported by chokidar** -[chokidar options](https://github.com/paulmillr/chokidar#persistence) +[chokidar options](https://github.com/paulmillr/chokidar) ## API @@ -78,3 +78,33 @@ function _handler (type, f) { #### custom one can use a custom handler by passing such a function in options or using registerHandler. The handler is passed two arguments the type of the change and the file changed. + + +#### atomic issues + +Several type of editors write atomically. They typically write a `.gpoutputstream` file temporily that "trick" choikdar. So by default this watcher ignores these files. Can you included them by passing false for `ignore_gpoutputstream`. If you still don't get a modified event using these apps (e.g. gedit) you might look at the `atomic` option and if all else fails `usePolling` + +#### Chokidar Options + +chokidar.watch('file', { + persistent: true, + ignored: '*.txt', + ignoreInitial: false, + followSymlinks: true, + cwd: '.', + disableGlobbing: false, + usePolling: false, + interval: 100, + binaryInterval: 300, + alwaysStat: false, + depth: 99, + awaitWriteFinish: { + stabilityThreshold: 2000, + pollInterval: 100 + }, + ignorePermissionErrors: false, + atomic: true // or a custom 'atomicity delay', in milliseconds (default 100) +}); + +details here +https://github.com/paulmillr/chokidar#api \ No newline at end of file diff --git a/src/watcher.js b/src/watcher.js old mode 100644 new mode 100755 index 83e82ea..cfe8e4e --- a/src/watcher.js +++ b/src/watcher.js @@ -23,6 +23,8 @@ class Watcher extends Emitter { this.handler = opts.handler || _handler this._ready = false this._watching = false + // .goutputstream files arise during atomic writes, ignore them by default + this.ignore_goutputstream = opts.ignore_goutputstream === false ? false : true return this } @@ -55,6 +57,7 @@ class Watcher extends Emitter { if (opts.delDir) this._watcher.on('unlinkDir', handler.bind(this, 'dir-deleted')) if (opts.addDir) this._watcher.on('addDir', handler.bind(this, 'dir-added')) + // these are watched by default, one can take action or not in the handler this._watcher .on('add', handler.bind(this, 'added')) .on('change', handler.bind(this, 'modified')) @@ -79,8 +82,8 @@ class Watcher extends Emitter { log.trace({ watching: this._watcher.getWatched(), msg: 'initial files watched' }) log.info(`now watching ${opts.source || this.opts.source}`) if (this.registerHandler(opts)) { - log.fatal('watcher was not initialzed so could not register handler') - return new Error('watcher was not initialzed so could not register handler') + log.fatal('watcher was not initialized so could not register handler') + return new Error('watcher was not initialized so could not register handler') } this._watching = true this.emit('watching', true, opts) @@ -122,7 +125,7 @@ class Watcher extends Emitter { } // private methods - + // set up chokidar async _init(opts = {}) { if (!opts.overwrite) { await this._fetchIgnoreLists(this.opts.excludeFrom) @@ -133,9 +136,10 @@ class Watcher extends Emitter { if (!opts.ignored) opts.ignored = [] opts.ignored = Array.isArray(opts.ignored) ? opts.ignored : opts.ignored.split(',') opts.ignored = opts.overwrite ? opts.ignored : [...this._ignored, ...opts.ignored] - opts = Object.assign({}, this.opts, opts) // now that ingnore arrays are dealt with merge options + if (this.ignore_goutputstream) opts.ignored.push('**/.goutputstream*') + opts = Object.assign({}, this.opts, opts) // now that ignore arrays are dealt with merge options return new Promise(async (resolve, reject) => { - log.debug({ options: opts, msg: 'intializing watch with options' }) + log.debug({ options: opts, msg: 'initializing watch with options' }) if (opts.source) { // create chokidar watcher this._watcher = watch(opts.source, opts)