diff --git a/README.md b/README.md index a18971cd..20cb1195 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,8 @@ By default, `fastify-cli` loads environment variables from `.env` in your curren The default value for `--plugin-timeout` is 10 seconds. By default,`--ignore-watch` flag is set to ignore `node_modules build dist .git bower_components logs .swp .nyc_output` files. +The `.git` entry matches a complete path segment, so Git metadata remains ignored +while projects in directories such as `fastify.git/main` can reload normally. #### Containerization diff --git a/lib/watch/utils.js b/lib/watch/utils.js index 6f49c3c6..5afa4088 100644 --- a/lib/watch/utils.js +++ b/lib/watch/utils.js @@ -5,6 +5,7 @@ const path = require('node:path') const arrayToRegExp = (arr) => { const reg = arr.map((file) => { + if (file === '.git') { return '(?:^|[/\\\\])\\.git(?:[/\\\\]|$)' } if (/^\./.test(file)) { return `\\${file}` } return file }).join('|') diff --git a/test/watch.test.js b/test/watch.test.js index 135be9ec..e33d1756 100644 --- a/test/watch.test.js +++ b/test/watch.test.js @@ -41,8 +41,76 @@ test('followWatch parameter should set watchDir correctly', async (t) => { test('should equal expect RegExp', t => { t.plan(1) - const expectRegExp = /(node_modules|build|dist|\.git|bower_components|logs)/ + const expectRegExp = /(node_modules|build|dist|(?:^|[/\\])\.git(?:[/\\]|$)|bower_components|logs)/ const regExp = arrayToRegExp(['node_modules', 'build', 'dist', '.git', 'bower_components', 'logs']) t.assert.deepStrictEqual(regExp, expectRegExp) }) + +test('.git ignore should only match complete path segments', t => { + const regExp = arrayToRegExp(['.git']) + + for (const separator of ['/', '\\']) { + for (const filepath of [ + '.git', + '.git/', + '.git/HEAD', + 'app/.git', + '/work/app/.git/objects/pack', + 'C:/work/app/.git/HEAD', + '//server/share/app/.git/HEAD', + '/work/fastify.git/main/.git' + ]) { + const filename = filepath.replaceAll('/', separator) + t.assert.strictEqual(regExp.test(filename), true, filename) + } + + for (const filepath of [ + 'fastify.git', + 'fastify.git/main', + '/work/fastify.git/main/app.js', + 'C:/work/ordinary.git/app.js', + '//server/share/ordinary.git/app.js', + '/work/.github/app.js', + '/work/app/.gitignore', + '/work/app/.gitconfig', + '/work/app/.git-backup/app.js' + ]) { + const filename = filepath.replaceAll('/', separator) + t.assert.strictEqual(regExp.test(filename), false, filename) + } + } +}) + +test('default ignores should allow compiled apps in .git-suffixed directories', t => { + const { ignoreWatch } = require('../args')(['--ignore-watch=.ts$']) + const regExp = arrayToRegExp(ignoreWatch.split(' ').filter(Boolean)) + + for (const separator of ['/', '\\']) { + const filename = filepath => filepath.replaceAll('/', separator) + t.assert.strictEqual(regExp.test(filename('/work/fastify.git/main')), false) + t.assert.strictEqual(regExp.test(filename('/work/fastify.git/main/dist/app.js')), false) + t.assert.strictEqual(regExp.test(filename('/work/ordinary.git/dist/app.js')), false) + t.assert.strictEqual(regExp.test(filename('/work/fastify.git/main/.git')), true) + t.assert.strictEqual(regExp.test(filename('/work/ordinary.git/.git/HEAD')), true) + t.assert.strictEqual(regExp.test(filename('/work/fastify.git/main/app.ts')), true) + + for (const entry of ['node_modules', 'build', 'bower_components', 'logs', '.swp', '.nyc_output']) { + t.assert.strictEqual(regExp.test(filename(`/work/app/${entry}/file`)), true) + } + } +}) + +test('custom ignore expressions should retain their matching behavior', t => { + const expressions = ['\\.git', '.ts$', 'logs/error.log', '^generated[/\\\\]'] + const expected = /(\.git|\.ts$|logs\/error.log|^generated[/\\])/ + const regExp = arrayToRegExp(expressions) + + t.assert.deepStrictEqual(regExp, expected) + t.assert.strictEqual(regExp.test('/work/fastify.git/main/app.js'), true) + t.assert.strictEqual(regExp.test('/work/app/app.ts'), true) + t.assert.strictEqual(regExp.test('/work/app/app.tsx'), false) + t.assert.strictEqual(regExp.test('/work/app/logs/error.log'), true) + t.assert.strictEqual(regExp.test('generated/app.js'), true) + t.assert.strictEqual(regExp.test('generated\\app.js'), true) +})