Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow watch for recursive not existing folder #897

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 27 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const {

const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);
const exists = promisify(fs.exists);

/**
* @typedef {String} Path
Expand Down Expand Up @@ -765,15 +766,37 @@ _isntIgnored(path, stat) {
* Provides a set of common helpers and properties relating to symlink and glob handling.
* @param {Path} path file, directory, or glob pattern being watched
* @param {Number=} depth at any depth > 0, this isn't a glob
* @returns {WatchHelper} object containing helpers for this path
* @returns {Promise<WatchHelper>} object containing helpers for this path
*/
_getWatchHelpers(path, depth) {
const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
async _getWatchHelpers(path, depth)
{
const baseWatchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
const follow = this.options.followSymlinks;
const existingWatchPath=await this._mostSpecifiedExistingAncestor(baseWatchPath);

return new WatchHelper(path, watchPath, follow, this);
return new WatchHelper(path, existingWatchPath, follow, this);
}

/**
* Find the most recent (specified ) ancestor path that exists.
* @param {Path} path file or directory
* @returns {Promise<String>} the most recent ancestor path that exists
* @private
*/
async _mostSpecifiedExistingAncestor(path)
{
const father = globParent(path);

if (father == path)
return path;

const doesExists = await exists(path);
if (doesExists)
return path;

return this._mostSpecifiedExistingAncestor(father);
}

// Directory helpers
// -----------------

Expand Down
2 changes: 1 addition & 1 deletion lib/fsevents-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ async _addToFsEvents(path, transform, forceAdd, priorDepth) {
const opts = this.fsw.options;
const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;

const wh = this.fsw._getWatchHelpers(path);
const wh = await this.fsw._getWatchHelpers(path);

// evaluate what is at the path we're being asked to watch
try {
Expand Down
2 changes: 1 addition & 1 deletion lib/nodefs-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
return false;
}

let wh = this.fsw._getWatchHelpers(path, depth);
let wh =await this.fsw._getWatchHelpers(path, depth);
if (!wh.hasGlob && priorWh) {
wh.hasGlob = priorWh.hasGlob;
wh.globFilter = priorWh.globFilter;
Expand Down
47 changes: 47 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,53 @@ const runTests = function(baseopts) {
spy.should.have.been.calledWith('add', testPath);
});
});

it('should watch glob path with non-existent dir and detect addDir/add', async () => {
const testDir = getFixturePath('subdir');
const testPathWithGlob=getFixturePath("subdir/*.txt")
const testPath = getFixturePath('subdir/add.txt');
let watcher = chokidar_watch(testPathWithGlob, options);
const spy = await aspy(watcher, 'all');
spy.should.not.have.been.called;

await delay();
await fs_mkdir(testDir, PERM_ARR);

await delay();
await write(testPath, 'hello');
await waitFor([spy.withArgs('add')]);
spy.should.not.have.been.calledWith('addDir', testDir);
spy.should.have.been.calledWith('add', testPath);
});

it('should watch glob path with non-existent dir and detect addDir/add', async function () {
function skipIfCantRun() {
let currentNodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1])
if (currentNodeVersion < 10.12)
this.skip("recursive mkdir is not supported before node 10.12")
}

skipIfCantRun.call(this);
const subPath = 'subdir0/subdir1/subdir2/subdir3';
const testDir = getFixturePath(subPath);
const testPathWithGlob=getFixturePath(subPath+"/*.txt")
const testPath = getFixturePath(subPath+'/add.txt');
let watcher = chokidar_watch(testPathWithGlob, options);
const spy = await aspy(watcher, 'all');
spy.should.not.have.been.called;

await delay();
await fs_mkdir(testDir, {recursive:true,mode:PERM_ARR});

await delay();
await write(testPath, 'hello');
await waitFor([spy.withArgs('add')]);
spy.should.not.have.been.calledWith('addDir');
spy.should.have.been.calledWith('add', testPath);
});



describe('watch glob patterns', () => {
it('should correctly watch and emit based on glob input', async () => {
const watchPath = getGlobPath('*a*.txt');
Expand Down