diff --git a/packages/collector-extension/lib/index.js b/packages/collector-extension/lib/index.js index 883522c404ee2c332e3bfb63d63e5dd1ded08261..824cd59b2a27e32da7d5098fa70bed086e1057d0 100644 --- a/packages/collector-extension/lib/index.js +++ b/packages/collector-extension/lib/index.js @@ -35,7 +35,7 @@ module.exports.register = function () { const expandPathContext = { base: worktreeDir, cwd: worktreeDir, dot: ospath.join(worktreeDir, startPath) } const scanDirs = new Set() const collectors = (Array.isArray(collectorConfig) ? collectorConfig : [collectorConfig]).map((collector) => { - const { run: runConfig = {}, scan: scanConfig = [] } = collector + const { run: runConfig = {}, scan: scanConfig = [], untracked = false } = collector return { run: { ...runConfig, @@ -49,6 +49,7 @@ module.exports.register = function () { } return accum }, []), + untracked, } }) if (worktree) { @@ -57,7 +58,13 @@ module.exports.register = function () { const cache = gitCache[gitdir] || (gitCache[gitdir] = {}) const ref = `refs/${reftype === 'branch' ? 'head' : reftype}s/${refname}` // Q: if repo is local, should we operate on a clone instead? - await prepareWorktree({ fs, cache, dir: worktreeDir, gitdir, ref, remote, bare: worktree === undefined }) + const untracked = collectors + .map((collector) => collector.untracked) + .reduce((previous, current) => previous || current, false) + await prepareWorktree( + { fs, cache, dir: worktreeDir, gitdir, ref, remote, bare: worktree === undefined }, + untracked + ) } for (const { run, scan: scans } of collectors) { const { cwd, command, local } = run @@ -108,7 +115,7 @@ module.exports.register = function () { }) } -async function prepareWorktree (repo) { +async function prepareWorktree (repo, untrackedFiles) { const { dir, gitdir, ref, remote = 'origin', bare } = repo delete repo.remote const currentIndexPath = ospath.join(gitdir, 'index') @@ -121,7 +128,9 @@ async function prepareWorktree (repo) { try { await fsp.unlink(worktreeValidStatePath) await fsp.cp(worktreeIndexPath, currentIndexPath, { force }) - await removeUntrackedFiles(repo) + if (!untrackedFiles) { + await removeUntrackedFiles(repo) + } } catch { force = false if (currentIndex) await fsp.unlink(currentIndexPath) diff --git a/packages/collector-extension/test/collector-extension-test.js b/packages/collector-extension/test/collector-extension-test.js index 295da436bfb3a5a1281855582c46fc1ca3b8ee5a..5619a97c83218bf8627a50bec71a71b082a297d5 100644 --- a/packages/collector-extension/test/collector-extension-test.js +++ b/packages/collector-extension/test/collector-extension-test.js @@ -987,6 +987,37 @@ describe('collector extension', () => { }) }) + it('should not remove untracked changes if configuration allows untracked files', async () => { + const collectorConfig = { + run: { command: 'node .gen-dirty-worktree.js' }, + scan: { dir: 'build' }, + untracked: true, + } + await runScenario({ + repoName: 'test-at-root', + collectorConfig, + branches: ['v1.0.x', 'v2.0.x'], + before: (contentAggregate) => { + expect(contentAggregate).to.have.lengthOf(2) + const [bucket1, bucket2] = contentAggregate + expect(bucket1).to.have.property('version', 'v1.0.x') + expect(bucket2).to.have.property('version', 'v2.0.x') + }, + after: (contentAggregate) => { + expect(contentAggregate).to.have.lengthOf(2) + const [bucket1, bucket2] = contentAggregate + expect(bucket1).to.have.property('version', '1.0') + expect(bucket1.files).to.have.lengthOf(1) + expect(bucket1.files[0].path).to.equal('modules/ROOT/pages/v1.0.x-release.adoc') + expect(bucket2).to.have.property('version', '2.0') + expect(bucket2.files).to.have.lengthOf(3) + expect(bucket2.files[0].path).to.equal('modules/ROOT/pages/dirty-worktree.adoc') + expect(bucket2.files[1].path).to.equal('modules/ROOT/pages/v1.0.x-release.adoc') + expect(bucket2.files[2].path).to.equal('modules/ROOT/pages/v2.0.x-release.adoc') + }, + }) + }) + it('should not follow symlinks when removing untracked files in worktree', async () => { const collectorConfig = { run: { command: 'node .check-dirty-worktree.js' },