@snyk/code-client
Advanced tools
Comparing version 4.20.5 to 4.21.0
@@ -190,3 +190,3 @@ "use strict"; | ||
// Scan for custom ignore rules | ||
const fileIgnores = await files_1.collectIgnoreRules(options.paths, options.symlinksEnabled, options.defaultFileIgnores); | ||
const filePolicies = await files_1.collectFilePolicies(options.paths, options.symlinksEnabled, options.defaultFileIgnores); | ||
const baseDir = files_1.determineBaseDir(options.paths); | ||
@@ -200,3 +200,3 @@ emitter_1.emitter.scanFilesProgress(0); | ||
baseDir, | ||
fileIgnores, | ||
filePolicies, | ||
supportedFiles, | ||
@@ -224,3 +224,3 @@ }); | ||
supportedFiles, | ||
fileIgnores, | ||
fileIgnores: [...filePolicies.excludes, ...filePolicies.ignores], | ||
skippedOversizedFiles, | ||
@@ -227,0 +227,0 @@ }; |
import { Cache } from './cache'; | ||
import { CollectBundleFilesOptions } from './interfaces/analysis-options.interface'; | ||
import { CollectBundleFilesOptions, FilePolicies } from './interfaces/analysis-options.interface'; | ||
import { SupportedFiles, FileInfo } from './interfaces/files.interface'; | ||
@@ -7,3 +7,9 @@ export declare function notEmpty<T>(value: T | null | undefined): value is T; | ||
export declare function getGlobPatterns(supportedFiles: SupportedFiles): string[]; | ||
export declare function collectIgnoreRules(dirs: string[], symlinksEnabled?: boolean, fileIgnores?: string[]): Promise<string[]>; | ||
/** | ||
* Recursively collect all exclude and ignore rules from "dirs". | ||
* | ||
* Exclude rules from .snyk files and ignore rules from .[*]ignore files are collected separately. | ||
* Any .[*]ignore files in paths excluded by .snyk exclude rules are ignored. | ||
*/ | ||
export declare function collectFilePolicies(dirs: string[], symlinksEnabled?: boolean, fileIgnores?: string[]): Promise<FilePolicies>; | ||
export declare function determineBaseDir(paths: string[]): string; | ||
@@ -14,3 +20,3 @@ /** | ||
* */ | ||
export declare function collectBundleFiles({ symlinksEnabled, baseDir, fileIgnores, paths, supportedFiles, }: CollectBundleFilesOptions): AsyncGenerator<FileInfo | string>; | ||
export declare function collectBundleFiles({ symlinksEnabled, baseDir, filePolicies, paths, supportedFiles, }: CollectBundleFilesOptions): AsyncGenerator<FileInfo | string>; | ||
export declare function prepareExtendingBundle(baseDir: string, supportedFiles: SupportedFiles, fileIgnores: string[] | undefined, files: string[], symlinksEnabled?: boolean): Promise<{ | ||
@@ -17,0 +23,0 @@ files: FileInfo[]; |
@@ -25,3 +25,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isMatch = exports.composeFilePayloads = exports.resolveBundleFilePath = exports.resolveBundleFiles = exports.getFileInfo = exports.calcHash = exports.getBundleFilePath = exports.prepareExtendingBundle = exports.collectBundleFiles = exports.determineBaseDir = exports.collectIgnoreRules = exports.getGlobPatterns = exports.parseFileIgnores = exports.notEmpty = void 0; | ||
exports.isMatch = exports.composeFilePayloads = exports.resolveBundleFilePath = exports.resolveBundleFiles = exports.getFileInfo = exports.calcHash = exports.getBundleFilePath = exports.prepareExtendingBundle = exports.collectBundleFiles = exports.determineBaseDir = exports.collectFilePolicies = exports.getGlobPatterns = exports.parseFileIgnores = exports.notEmpty = void 0; | ||
const nodePath = __importStar(require("path")); | ||
@@ -181,10 +181,20 @@ const fs = __importStar(require("fs")); | ||
} | ||
async function collectIgnoreRules(dirs, symlinksEnabled = false, fileIgnores = constants_1.IGNORES_DEFAULT) { | ||
/** | ||
* Recursively collect all exclude and ignore rules from "dirs". | ||
* | ||
* Exclude rules from .snyk files and ignore rules from .[*]ignore files are collected separately. | ||
* Any .[*]ignore files in paths excluded by .snyk exclude rules are ignored. | ||
*/ | ||
async function collectFilePolicies(dirs, symlinksEnabled = false, fileIgnores = constants_1.IGNORES_DEFAULT) { | ||
const tasks = dirs.map(async (folder) => { | ||
const fileStats = await lStat(folder); | ||
// Check if symlink and exclude if requested | ||
if (!fileStats || (fileStats.isSymbolicLink() && !symlinksEnabled) || fileStats.isFile()) | ||
return []; | ||
// Find ignore files inside this directory | ||
const localIgnoreFiles = await fast_glob_1.default(constants_1.IGNORE_FILES_NAMES.map(i => `*${i}`), { | ||
if (!fileStats || (fileStats.isSymbolicLink() && !symlinksEnabled) || fileStats.isFile()) { | ||
return { | ||
excludes: [], | ||
ignores: [], | ||
}; | ||
} | ||
// Find .snyk and .[*]ignore files inside this directory. | ||
const allIgnoredFiles = await fast_glob_1.default(constants_1.IGNORE_FILES_NAMES.map(i => `*${i}`), { | ||
...fgOptions, | ||
@@ -194,9 +204,22 @@ cwd: folder, | ||
}); | ||
// Read ignore files and merge new patterns | ||
return lodash_union_1.default(...localIgnoreFiles.map(parseFileIgnores)); | ||
// Parse rules from all .snyk files inside this directory. | ||
const snykFiles = allIgnoredFiles.filter(f => f.endsWith(constants_1.DOTSNYK_FILENAME)); | ||
const snykExcludeRules = lodash_union_1.default(...snykFiles.map(parseFileIgnores)); | ||
// Parse rules from relevant .[*]ignore files inside this directory. | ||
// Exclude ignore files under paths excluded by .snyk files. | ||
const ignoreFiles = allIgnoredFiles.filter(f => !f.endsWith(constants_1.DOTSNYK_FILENAME) && multimatch_1.default([nodePath.dirname(f)], snykExcludeRules).length === 0); | ||
const ignoreFileRules = lodash_union_1.default(...ignoreFiles.map(parseFileIgnores)); | ||
return { | ||
excludes: snykExcludeRules, | ||
ignores: ignoreFileRules, | ||
}; | ||
}); | ||
const customRules = await Promise.all(tasks); | ||
return lodash_union_1.default(fileIgnores, ...customRules); | ||
const collectedRules = await Promise.all(tasks); | ||
return { | ||
excludes: lodash_union_1.default(...collectedRules.map(policies => policies.excludes)), | ||
// Merge external and collected ignore rules | ||
ignores: lodash_union_1.default(fileIgnores, ...collectedRules.map(policies => policies.ignores)), | ||
}; | ||
} | ||
exports.collectIgnoreRules = collectIgnoreRules; | ||
exports.collectFilePolicies = collectFilePolicies; | ||
function determineBaseDir(paths) { | ||
@@ -214,5 +237,5 @@ if (paths.length === 1) { | ||
exports.determineBaseDir = determineBaseDir; | ||
async function* searchFiles(patterns, cwd, symlinksEnabled, ignores) { | ||
const positiveIgnores = ignores.filter(rule => !rule.startsWith('!')); | ||
const negativeIgnores = ignores.filter(rule => rule.startsWith('!')).map(rule => rule.substring(1)); | ||
async function* searchFiles(patterns, cwd, symlinksEnabled, policies) { | ||
const positiveIgnores = [...policies.excludes, ...policies.ignores.filter(rule => !rule.startsWith('!'))]; | ||
const negativeIgnores = policies.ignores.filter(rule => rule.startsWith('!')).map(rule => rule.substring(1)); | ||
// We need to use the ignore rules directly in the stream. Otherwise we would expand all the branches of the file system | ||
@@ -234,2 +257,3 @@ // that should be ignored, leading to performance issues (the parser would look stuck while analyzing each ignored file). | ||
} | ||
const deepPatterns = patterns.map(p => `**/${p}`); | ||
// TODO: This is incorrect because the .gitignore format allows to specify exceptions to previous rules, therefore | ||
@@ -246,5 +270,7 @@ // the separation between positive and negative ignores is incorrect in a scenario with 2+ exeptions like the one below: | ||
baseNameMatch: false, | ||
// Exclude rules should still be respected | ||
ignore: policies.excludes, | ||
}); | ||
for await (const filePath of negativeSearcher) { | ||
if (isMatch(filePath.toString(), patterns.map(p => `**/${p}`))) | ||
if (isMatch(filePath.toString(), deepPatterns)) | ||
yield filePath; | ||
@@ -258,3 +284,3 @@ } | ||
* */ | ||
async function* collectBundleFiles({ symlinksEnabled = false, baseDir, fileIgnores, paths, supportedFiles, }) { | ||
async function* collectBundleFiles({ symlinksEnabled = false, baseDir, filePolicies, paths, supportedFiles, }) { | ||
const cache = new cache_1.Cache(constants_1.CACHE_KEY, baseDir); | ||
@@ -280,3 +306,3 @@ const files = []; | ||
for (const folder of dirs) { | ||
const searcher = searchFiles(globPatterns, folder, symlinksEnabled, fileIgnores); | ||
const searcher = searchFiles(globPatterns, folder, symlinksEnabled, filePolicies); | ||
// eslint-disable-next-line no-await-in-loop | ||
@@ -293,3 +319,3 @@ for await (const filePath of searcher) { | ||
if (files.length) { | ||
const searcher = searchFiles(filterSupportedFiles(files, supportedFiles), baseDir, symlinksEnabled, fileIgnores); | ||
const searcher = searchFiles(filterSupportedFiles(files, supportedFiles), baseDir, symlinksEnabled, filePolicies); | ||
for await (const filePath of searcher) { | ||
@@ -296,0 +322,0 @@ const fileInfo = await getFileInfo(filePath.toString(), baseDir, false, cache); |
@@ -42,6 +42,10 @@ import { SupportedFiles } from '..'; | ||
} | ||
export interface FilePolicies { | ||
excludes: string[]; | ||
ignores: string[]; | ||
} | ||
export interface CollectBundleFilesOptions extends AnalyzeFoldersOptions { | ||
supportedFiles: SupportedFiles; | ||
baseDir: string; | ||
fileIgnores: string[]; | ||
filePolicies: FilePolicies; | ||
} | ||
@@ -48,0 +52,0 @@ export interface ReportOptions { |
@@ -94,3 +94,3 @@ { | ||
}, | ||
"version": "4.20.5" | ||
"version": "4.21.0" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
175174
2471