Merge pull request #870 from ing-bank/feat/providenceWhitelistMode

feat(providence-analytics): add --allowlist-mode option
This commit is contained in:
Thijs Louisse 2020-08-12 10:03:02 +02:00 committed by GitHub
commit e374608c95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 198 additions and 63 deletions

View file

@ -0,0 +1,15 @@
---
'providence-analytics': minor
---
Allowlist modes
#### Features
- Allowlist mode: autodetects whether analyzed repository is a "git" or "npm" (published artifact) repository.
Via the cli `--allowlist-mode 'npm|git|all'` and `--allowlist-mode-reference 'npm|git|all'` can be
configured to override the autodetected mode.
#### Bugfixes
- Clean output extend-docs: strings like '[no-dependency]' will not end up in aggregated result

View file

@ -178,4 +178,5 @@ module.exports = {
spawnProcess, spawnProcess,
installDeps, installDeps,
pathsArrayFromCollectionName, pathsArrayFromCollectionName,
flatten,
}; };

View file

@ -116,11 +116,13 @@ async function cli({ cwd } = {}) {
providenceModule.providence(queryConfig, { providenceModule.providence(queryConfig, {
gatherFilesConfig: { gatherFilesConfig: {
extensions: commander.extensions, extensions: commander.extensions,
filter: commander.whitelist, allowlistMode: commander.allowlistMode,
filter: commander.allowlist,
}, },
gatherFilesConfigReference: { gatherFilesConfigReference: {
extensions: commander.extensions, extensions: commander.extensions,
filter: commander.whitelistReference, allowlistMode: commander.allowlistModeReference,
filter: commander.allowlistReference,
}, },
debugEnabled: commander.debug, debugEnabled: commander.debug,
queryMethod, queryMethod,
@ -172,12 +174,12 @@ async function cli({ cwd } = {}) {
v => cliHelpers.pathsArrayFromCs(v, cwd), v => cliHelpers.pathsArrayFromCs(v, cwd),
InputDataService.referenceProjectPaths, InputDataService.referenceProjectPaths,
) )
.option('-w, --whitelist [whitelist]', `whitelisted paths, like './src, ./packages/*'`, v => .option('-a, --allowlist [allowlist]', `allowlisted paths, like './src, ./packages/*'`, v =>
cliHelpers.pathsArrayFromCs(v, cwd), cliHelpers.pathsArrayFromCs(v, cwd),
) )
.option( .option(
'--whitelist-reference [whitelist-reference]', '--allowlist-reference [allowlist-reference]',
`whitelisted paths for reference, like './src, ./packages/*'`, `allowed paths for reference, like './src, ./packages/*'`,
v => cliHelpers.pathsArrayFromCs(v, cwd), v => cliHelpers.pathsArrayFromCs(v, cwd),
) )
.option( .option(
@ -201,6 +203,19 @@ async function cli({ cwd } = {}) {
without argument, it will act as boolean and include all dependencies. without argument, it will act as boolean and include all dependencies.
When a regex is supplied like --target-dependencies /^my-brand-/, it will filter When a regex is supplied like --target-dependencies /^my-brand-/, it will filter
all packages that comply with the regex`, all packages that comply with the regex`,
)
.option(
'--allowlist-mode [allowlist-mode]',
`Depending on whether we are dealing with a published artifact
(a dependency installed via npm) or a git repository, different paths will be
automatically put in the appropiate mode.
A mode of 'npm' will look at the package.json "files" entry and a mode of
'git' will look at '.gitignore' entry. The mode will be auto detected, but can be overridden
via this option.`,
)
.option(
'--allowlist-mode-reference [allowlist-mode-reference]',
`allowlist mode applied to refernce project`,
); );
commander commander
@ -286,8 +301,8 @@ async function cli({ cwd } = {}) {
prefixCfg, prefixCfg,
outputFolder: options.outputFolder, outputFolder: options.outputFolder,
extensions: commander.extensions, extensions: commander.extensions,
whitelist: commander.whitelist, allowlist: commander.allowlist,
whitelistReference: commander.whitelistReference, allowlistReference: commander.allowlistReference,
}) })
.then(resolveCli) .then(resolveCli)
.catch(rejectCli); .catch(rejectCli);

View file

@ -5,14 +5,15 @@ const { performance } = require('perf_hooks');
const { providence } = require('../program/providence.js'); const { providence } = require('../program/providence.js');
const { QueryService } = require('../program/services/QueryService.js'); const { QueryService } = require('../program/services/QueryService.js');
const { LogService } = require('../program/services/LogService.js'); const { LogService } = require('../program/services/LogService.js');
const { flatten } = require('./cli-helpers.js');
async function launchProvidenceWithExtendDocs({ async function launchProvidenceWithExtendDocs({
referenceProjectPaths, referenceProjectPaths,
prefixCfg, prefixCfg,
outputFolder, outputFolder,
extensions, extensions,
whitelist, allowlist,
whitelistReference, allowlistReference,
}) { }) {
const t0 = performance.now(); const t0 = performance.now();
@ -21,11 +22,11 @@ async function launchProvidenceWithExtendDocs({
{ {
gatherFilesConfig: { gatherFilesConfig: {
extensions: extensions || ['.js'], extensions: extensions || ['.js'],
filter: whitelist || ['!coverage', '!test'], filter: allowlist || ['!coverage', '!test'],
}, },
gatherFilesConfigReference: { gatherFilesConfigReference: {
extensions: extensions || ['.js'], extensions: extensions || ['.js'],
filter: whitelistReference || ['!coverage', '!test'], filter: allowlistReference || ['!coverage', '!test'],
}, },
queryMethod: 'ast', queryMethod: 'ast',
report: false, report: false,
@ -35,11 +36,13 @@ async function launchProvidenceWithExtendDocs({
); );
const outputFilePath = pathLib.join(outputFolder, 'providence-extend-docs-data.json'); const outputFilePath = pathLib.join(outputFolder, 'providence-extend-docs-data.json');
const queryOutputs = results.map(result => result.queryOutput).flat(); const queryOutputs = flatten(
results.map(result => result.queryOutput).filter(o => typeof o !== 'string'), // filter out '[no-dependency]' etc.
);
if (fs.existsSync(outputFilePath)) { if (fs.existsSync(outputFilePath)) {
fs.unlinkSync(outputFilePath); fs.unlinkSync(outputFilePath);
} }
fs.writeFile(outputFilePath, JSON.stringify(queryOutputs), err => { fs.writeFile(outputFilePath, JSON.stringify(queryOutputs, null, 2), err => {
if (err) { if (err) {
throw err; throw err;
} }

View file

@ -12,11 +12,17 @@ const { LogService } = require('./LogService.js');
const { AstService } = require('./AstService.js'); const { AstService } = require('./AstService.js');
const { getFilePathRelativeFromRoot } = require('../utils/get-file-path-relative-from-root.js'); const { getFilePathRelativeFromRoot } = require('../utils/get-file-path-relative-from-root.js');
function getGitIgnorePaths(rootPath) { function getGitignoreFile(rootPath) {
let fileContent;
try { try {
fileContent = fs.readFileSync(`${rootPath}/.gitignore`, 'utf8'); return fs.readFileSync(`${rootPath}/.gitignore`, 'utf8');
} catch (_) { } catch (_) {
return undefined;
}
}
function getGitIgnorePaths(rootPath) {
const fileContent = getGitignoreFile(rootPath);
if (!fileContent) {
return []; return [];
} }
@ -25,9 +31,28 @@ function getGitIgnorePaths(rootPath) {
if (entry.startsWith('#')) { if (entry.startsWith('#')) {
return false; return false;
} }
if (entry.startsWith('!')) {
return false; // negated folders will be kept
}
return entry.trim().length; return entry.trim().length;
}); });
return entries;
// normalize entries to be compatible with anymatch
const normalizedEntries = entries.map(e => {
let entry = e;
if (entry.startsWith('/')) {
entry = entry.slice(1);
}
const isFile = entry.indexOf('.') > 0; // index of 0 means hidden file.
if (entry.endsWith('/')) {
entry += '**';
} else if (!isFile) {
entry += '/**';
}
return entry;
});
return normalizedEntries;
} }
/** /**
@ -290,10 +315,27 @@ class InputDataService {
if (!customConfig.omitDefaultFilter) { if (!customConfig.omitDefaultFilter) {
cfg.filter = [...this.defaultGatherFilesConfig.filter, ...(customConfig.filter || [])]; cfg.filter = [...this.defaultGatherFilesConfig.filter, ...(customConfig.filter || [])];
} }
const allowlistModes = ['npm', 'git', 'all'];
if (customConfig.allowlistMode && !allowlistModes.includes(customConfig.allowlistMode)) {
throw new Error(
`[gatherFilesConfig] Please provide a valid allowListMode like "${allowlistModes.join(
'|',
)}". Found: "${customConfig.allowlistMode}"`,
);
}
const gitIgnorePaths = getGitIgnorePaths(startPath); let gitIgnorePaths = [];
const npmPackagePaths = getNpmPackagePaths(startPath); let npmPackagePaths = [];
const removeFilter = gitIgnorePaths.map(p => `!${p}`);
const hasGitIgnore = getGitignoreFile(startPath);
const allowlistMode = cfg.allowlistMode || (hasGitIgnore ? 'git' : 'npm');
if (allowlistMode === 'git') {
gitIgnorePaths = getGitIgnorePaths(startPath);
} else if (allowlistMode === 'npm') {
npmPackagePaths = getNpmPackagePaths(startPath);
}
const removeFilter = gitIgnorePaths;
const keepFilter = npmPackagePaths; const keepFilter = npmPackagePaths;
cfg.filter.forEach(filterEntry => { cfg.filter.forEach(filterEntry => {
@ -322,11 +364,9 @@ class InputDataService {
} }
return anymatch(keepFilter, localFilePath); return anymatch(keepFilter, localFilePath);
}); });
if (!filteredGlobRes || !filteredGlobRes.length) { if (!filteredGlobRes || !filteredGlobRes.length) {
LogService.warn(`No files found for path '${startPath}'`); LogService.warn(`No files found for path '${startPath}'`);
} }
return filteredGlobRes; return filteredGlobRes;
} }

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "find-classes", "name": "find-classes",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock__-297820780", "identifier": "importing-target-project_0.0.2-target-mock__1364353669",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "find-customelements", "name": "find-customelements",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock__-2006922104", "identifier": "importing-target-project_0.0.2-target-mock__-1063914889",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "find-exports", "name": "find-exports",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "exporting-ref-project_1.0.0__-1083884764", "identifier": "exporting-ref-project_1.0.0__309114983",
"targetProject": { "targetProject": {
"mainEntry": "./index.js", "mainEntry": "./index.js",
"name": "exporting-ref-project", "name": "exporting-ref-project",
@ -12,7 +12,7 @@
"commitHash": "[not-a-git-root]" "commitHash": "[not-a-git-root]"
}, },
"configuration": { "configuration": {
"metaConfig": null, "skipFileImports": false,
"gatherFilesConfig": {} "gatherFilesConfig": {}
} }
} }

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "find-imports", "name": "find-imports",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock__139587347", "identifier": "importing-target-project_0.0.2-target-mock__-1398544254",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "match-imports", "name": "match-imports",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__453069400", "identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__1498484172",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",
@ -18,7 +18,9 @@
"commitHash": "[not-a-git-root]" "commitHash": "[not-a-git-root]"
}, },
"configuration": { "configuration": {
"gatherFilesConfig": {} "gatherFilesConfig": {},
"targetProjectResult": null,
"referenceProjectResult": null
} }
} }
}, },

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "match-paths", "name": "match-paths",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__-238486383", "identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__1241369081",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",

View file

@ -4,7 +4,7 @@
"analyzerMeta": { "analyzerMeta": {
"name": "match-subclasses", "name": "match-subclasses",
"requiredAst": "babel", "requiredAst": "babel",
"identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__453069400", "identifier": "importing-target-project_0.0.2-target-mock_+_exporting-ref-project_1.0.0__-933483072",
"targetProject": { "targetProject": {
"mainEntry": "./target-src/match-imports/root-level-imports.js", "mainEntry": "./target-src/match-imports/root-level-imports.js",
"name": "importing-target-project", "name": "importing-target-project",

View file

@ -9,4 +9,4 @@ Whenever new Analyzers are added, please make sure the needed ingredients for a
end to end test are added to one of the above projects (or both). end to end test are added to one of the above projects (or both).
Be sure to update 'test-helpers/project-mocks-analyzer-output'. Be sure to update 'test-helpers/project-mocks-analyzer-output'.
This can be done by running `npm run test:e2e -- --generate-e2e-mode` once. This can be done by running `yarn test:node:e2e --generate-e2e-mode` once.

View file

@ -5,7 +5,7 @@ import MyCompMixin from './internalProxy.js';
export class ExtendedComp extends MyCompMixin(RefClass) { export class ExtendedComp extends MyCompMixin(RefClass) {
/** /**
* Whitelisted members * allowed members
*/ */
get getterSetter() {} get getterSetter() {}
set getterSetter(v) {} set getterSetter(v) {}

View file

@ -226,8 +226,8 @@ describe('Providence CLI', () => {
]); ]);
}); });
it('"-w --whitelist"', async () => { it('"-a --allowlist"', async () => {
await runCli(`${analyzeCmd} -w /mocked/path/example-project`, rootDir); await runCli(`${analyzeCmd} -a /mocked/path/example-project`, rootDir);
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project'); expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
expect(providenceStub.args[0][1].gatherFilesConfig.filter).to.eql([ expect(providenceStub.args[0][1].gatherFilesConfig.filter).to.eql([
'/mocked/path/example-project', '/mocked/path/example-project',
@ -236,21 +236,31 @@ describe('Providence CLI', () => {
pathsArrayFromCsStub.resetHistory(); pathsArrayFromCsStub.resetHistory();
providenceStub.resetHistory(); providenceStub.resetHistory();
await runCli(`${analyzeCmd} --whitelist /mocked/path/example-project`, rootDir); await runCli(`${analyzeCmd} --allowlist /mocked/path/example-project`, rootDir);
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project'); expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
expect(providenceStub.args[0][1].gatherFilesConfig.filter).to.eql([ expect(providenceStub.args[0][1].gatherFilesConfig.filter).to.eql([
'/mocked/path/example-project', '/mocked/path/example-project',
]); ]);
}); });
it('"--whitelist-reference"', async () => { it('"--allowlist-reference"', async () => {
await runCli(`${analyzeCmd} --whitelist-reference /mocked/path/example-project`, rootDir); await runCli(`${analyzeCmd} --allowlist-reference /mocked/path/example-project`, rootDir);
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project'); expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
expect(providenceStub.args[0][1].gatherFilesConfigReference.filter).to.eql([ expect(providenceStub.args[0][1].gatherFilesConfigReference.filter).to.eql([
'/mocked/path/example-project', '/mocked/path/example-project',
]); ]);
}); });
it('--allowlist-mode', async () => {
await runCli(`${analyzeCmd} --allowlist-mode git`, rootDir);
expect(providenceStub.args[0][1].gatherFilesConfig.allowlistMode).to.equal('git');
});
it('--allowlist-mode-reference', async () => {
await runCli(`${analyzeCmd} --allowlist-mode-reference npm`, rootDir);
expect(providenceStub.args[0][1].gatherFilesConfigReference.allowlistMode).to.equal('npm');
});
it('"-D --debug"', async () => { it('"-D --debug"', async () => {
await runCli(`${analyzeCmd} -D`, rootDir); await runCli(`${analyzeCmd} -D`, rootDir);
expect(providenceStub.args[0][1].debugEnabled).to.equal(true); expect(providenceStub.args[0][1].debugEnabled).to.equal(true);
@ -356,7 +366,7 @@ describe('Providence CLI', () => {
'--prefix-from pfrom --prefix-to pto', '--prefix-from pfrom --prefix-to pto',
'--output-folder /outp', '--output-folder /outp',
'--extensions bla', '--extensions bla',
'--whitelist wl --whitelist-reference wlr', '--allowlist al --allowlist-reference alr',
].join(' '), ].join(' '),
rootDir, rootDir,
); );
@ -369,8 +379,8 @@ describe('Providence CLI', () => {
}, },
outputFolder: '/outp', outputFolder: '/outp',
extensions: ['.bla'], extensions: ['.bla'],
whitelist: [`${rootDir}/wl`], allowlist: [`${rootDir}/al`],
whitelistReference: [`${rootDir}/wlr`], allowlistReference: [`${rootDir}/alr`],
}); });
}); });
}); });

View file

@ -3,26 +3,13 @@ const { expect } = require('chai');
const { providence } = require('../../../../src/program/providence.js'); const { providence } = require('../../../../src/program/providence.js');
const { QueryService } = require('../../../../src/program/services/QueryService.js'); const { QueryService } = require('../../../../src/program/services/QueryService.js');
const { ReportService } = require('../../../../src/program/services/ReportService.js'); const { ReportService } = require('../../../../src/program/services/ReportService.js');
const { LogService } = require('../../../../src/program/services/LogService.js');
const { const {
mockWriteToJson, mockWriteToJson,
restoreWriteToJson, restoreWriteToJson,
} = require('../../../../test-helpers/mock-report-service-helpers.js'); } = require('../../../../test-helpers/mock-report-service-helpers.js');
const {
suppressNonCriticalLogs,
restoreSuppressNonCriticalLogs,
} = require('../../../../test-helpers/mock-log-service-helpers.js');
describe('Analyzers file-system integration', () => { describe('Analyzers file-system integration', () => {
before(() => {
suppressNonCriticalLogs();
});
after(() => {
restoreSuppressNonCriticalLogs();
});
const generateE2eMode = process.argv.includes('--generate-e2e-mode'); const generateE2eMode = process.argv.includes('--generate-e2e-mode');
const queryResults = []; const queryResults = [];
@ -116,15 +103,16 @@ describe('Analyzers file-system integration', () => {
const findExportsQueryConfig = QueryService.getQueryConfigFromAnalyzer(analyzerName); const findExportsQueryConfig = QueryService.getQueryConfigFromAnalyzer(analyzerName);
await providence(findExportsQueryConfig, providenceConfig); await providence(findExportsQueryConfig, providenceConfig);
if (generateE2eMode) { if (generateE2eMode) {
LogService.info( console.info(
'Successfully created mocks. Do not forget to rerun tests now without "--generate-e2e-mode"', 'Successfully created mocks. Do not forget to rerun tests now without "--generate-e2e-mode"',
); );
return; return;
} }
// eslint-disable-next-line import/no-dynamic-require, global-require // eslint-disable-next-line import/no-dynamic-require, global-require
const expectedOutput = require(`../../../../test-helpers/project-mocks-analyzer-outputs/${analyzerName}.json`); const expectedOutput = require(`../../../../test-helpers/project-mocks-analyzer-outputs/${analyzerName}.json`);
const queryResult = JSON.parse(JSON.stringify(queryResults[0])).queryOutput; const { queryOutput } = JSON.parse(JSON.stringify(queryResults[0]));
expect(queryResult).to.eql(expectedOutput.queryOutput); expect(queryOutput).not.to.eql([]);
expect(queryOutput).to.eql(expectedOutput.queryOutput);
}); });
} }
}); });

View file

@ -54,10 +54,10 @@ describe('InputDataService', () => {
'/test-helpers/project-mocks/importing-target-project', '/test-helpers/project-mocks/importing-target-project',
), ),
).to.equal(true); ).to.equal(true);
expect(inputDataPerProject[0].entries.length).to.equal(11); expect(inputDataPerProject[0].entries.length).to.equal(6);
expect(inputDataPerProject[0].entries[0].context.code).to.not.be.undefined; expect(inputDataPerProject[0].entries[0].context.code).to.not.be.undefined;
expect(inputDataPerProject[0].entries[0].file).to.equal( expect(inputDataPerProject[0].entries[0].file).to.equal(
'./node_modules/exporting-ref-project/index.js', './target-src/find-customelements/multiple.js',
); );
}); });
@ -215,7 +215,7 @@ describe('InputDataService', () => {
expect(globOutput).to.eql(['/fictional/project/index.js']); expect(globOutput).to.eql(['/fictional/project/index.js']);
}); });
it('filters npm files entries', async () => { it('filters npm "files" entries when allowlistMode is "npm"', async () => {
mockProject({ mockProject({
'./docs/x.js': '', './docs/x.js': '',
'./src/y.js': '', './src/y.js': '',
@ -225,7 +225,9 @@ describe('InputDataService', () => {
files: ['*.add.js', 'docs', 'src'], files: ['*.add.js', 'docs', 'src'],
}), }),
}); });
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project'); const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
allowlistMode: 'npm',
});
expect(globOutput).to.eql([ expect(globOutput).to.eql([
'/fictional/project/docs/x.js', '/fictional/project/docs/x.js',
'/fictional/project/file.add.js', '/fictional/project/file.add.js',
@ -233,21 +235,80 @@ describe('InputDataService', () => {
]); ]);
}); });
it('filters .gitignore entries', async () => { it('filters .gitignore entries when allowlistMode is "git"', async () => {
mockProject({ mockProject({
'./coverage/file.js': '', './coverage/file.js': '',
'./storybook-static/index.js': '', './storybook-static/index.js': '',
'./build/index.js': '', './build/index.js': '',
'./shall/pass.js': '',
'./keep/it.js': '',
'.gitignore': ` '.gitignore': `
/coverage /coverage
# comment # comment
/storybook-static/ /storybook-static/
build/ build/
!keep/
`,
});
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
allowlistMode: 'git',
});
expect(globOutput).to.eql([
'/fictional/project/keep/it.js',
'/fictional/project/shall/pass.js',
]);
});
it('filters no entries when allowlistMode is "all"', async () => {
mockProject({
'./dist/bundle.js': '',
'./src/file.js': '',
'./package.json': JSON.stringify({
files: ['dist', 'src'],
}),
'.gitignore': `
/dist
`,
});
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
allowlistMode: 'all',
});
expect(globOutput).to.eql([
'/fictional/project/dist/bundle.js',
'/fictional/project/src/file.js',
]);
});
it('autodetects allowlistMode', async () => {
mockProject({
'./dist/bundle.js': '',
'./package.json': JSON.stringify({
files: ['dist'],
}),
'.gitignore': `
/dist
`, `,
}); });
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project'); const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
expect(globOutput).to.eql([]); expect(globOutput).to.eql([
// This means allowlistMode is 'git'
]);
restoreOriginalInputDataPaths();
restoreMockedProjects();
mockProject({
'./dist/bundle.js': '',
'./package.json': JSON.stringify({
files: ['dist'],
}),
});
const globOutput2 = InputDataService.gatherFilesFromDir('/fictional/project');
expect(globOutput2).to.eql([
// This means allowlistMode is 'npm'
'/fictional/project/dist/bundle.js',
]);
}); });
describe('Default filter', () => { describe('Default filter', () => {