snyk-docker-plugin
Version:
Snyk CLI docker plugin
183 lines • 6.57 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.groupNodeModulesFilesByDirectory = exports.groupNodeAppFilesByDirectory = exports.cleanupAppNodeModules = exports.persistNodeModules = void 0;
const Debug = require("debug");
const promises_1 = require("fs/promises");
const path = require("path");
const debug = Debug("snyk");
const nodeModulesRegex = /^(.*?)(?:[\\\/]node_modules)/;
async function createTempProjectDir(projectDir) {
const tmpDir = await (0, promises_1.mkdtemp)("snyk");
const tempProjectRoot = path.join(tmpDir, projectDir);
await (0, promises_1.mkdir)(tempProjectRoot, { recursive: true });
return {
tmpDir,
tempProjectRoot,
};
}
const manifestName = "package.json";
async function fileExists(path) {
return await (0, promises_1.stat)(path)
.then(() => true)
.catch(() => false);
}
async function createSyntheticManifest(tempRootManifestDir) {
const tempRootManifestPath = path.join(tempRootManifestDir, manifestName);
debug(`Creating an empty synthetic manifest file: ${tempRootManifestPath}`);
try {
await (0, promises_1.writeFile)(tempRootManifestPath, "{}", "utf-8");
}
catch (error) {
debug(`Error while writing file ${tempRootManifestPath} : ${error.message}`);
}
}
async function saveOnDisk(tempDir, modules, filePathToContent) {
for (const module of modules) {
const manifestContent = filePathToContent[module];
if (!manifestContent) {
continue;
}
await createFile(path.join(tempDir, module), manifestContent);
}
}
async function persistNodeModules(project, filePathToContent, fileNamesGroupedByDirectory) {
const modules = fileNamesGroupedByDirectory.get(project);
const tmpDir = "";
const tempProjectRoot = "";
if (!modules || modules.size === 0) {
debug(`Empty application directory tree.`);
return {
tempDir: tmpDir,
tempProjectPath: tempProjectRoot,
};
}
try {
const { tmpDir, tempProjectRoot } = await createTempProjectDir(project);
await saveOnDisk(tmpDir, modules, filePathToContent);
const result = {
tempDir: tmpDir,
tempProjectPath: tempProjectRoot,
manifestPath: path.join(tempProjectRoot.substring(tmpDir.length), manifestName),
};
const manifestFileExists = await fileExists(path.join(tempProjectRoot, manifestName));
if (!manifestFileExists) {
await createSyntheticManifest(tempProjectRoot);
delete result.manifestPath;
}
return result;
}
catch (error) {
debug(`Failed to copy the application manifest files locally: ${error.message}`);
return {
tempDir: tmpDir,
tempProjectPath: tempProjectRoot,
};
}
}
exports.persistNodeModules = persistNodeModules;
async function createFile(filePath, fileContent) {
try {
await (0, promises_1.mkdir)(path.dirname(filePath), { recursive: true });
await (0, promises_1.writeFile)(filePath, fileContent, "utf-8");
}
catch (error) {
debug(`Error while creating file ${filePath} : ${error.message}`);
}
}
function isYarnCacheDependency(filePath) {
if (filePath.includes(".yarn/cache") ||
filePath.includes(".cache/yarn") ||
filePath.includes("yarn\\cache") ||
filePath.includes("cache\\yarn") ||
filePath.includes("Cache\\Yarn") ||
filePath.includes("Yarn\\Cache")) {
return true;
}
return false;
}
function isNpmCacheDependency(filePath) {
if (filePath.includes(".npm/") || filePath.includes("\\npm-cache")) {
return true;
}
return false;
}
// TODO: Enable custom cache filtering if needed
// function isCustomCache(filePath: string): boolean {
// return (filePath.includes("cache") || filePath.includes("Cache"));
// }
function isPnpmCacheDependency(filePath) {
if (filePath.includes("pnpm-store") ||
filePath.includes("pnpm/store") ||
filePath.includes("pnpm\\store")) {
return true;
}
return false;
}
function getNodeModulesParentDir(filePath) {
const nodeModulesParentDirMatch = nodeModulesRegex.exec(filePath);
if (nodeModulesParentDirMatch && nodeModulesParentDirMatch.length > 1) {
const nodeModulesParentDir = nodeModulesParentDirMatch[1];
if (nodeModulesParentDir === "") {
return "/"; // ensuring the same behavior of path.dirname for '/' dir
}
return nodeModulesParentDir;
}
return null;
}
function groupNodeAppFilesByDirectory(filePathToContent) {
var _a;
const filesByDir = new Map();
const filePaths = Object.keys(filePathToContent);
for (const filePath of filePaths) {
const directory = path.dirname(filePath);
if (!filesByDir.has(directory)) {
filesByDir.set(directory, new Set());
}
(_a = filesByDir.get(directory)) === null || _a === void 0 ? void 0 : _a.add(filePath);
}
return filesByDir;
}
exports.groupNodeAppFilesByDirectory = groupNodeAppFilesByDirectory;
function getGroupingDir(filePath) {
const nodeModulesParentDir = getNodeModulesParentDir(filePath);
if (nodeModulesParentDir) {
return nodeModulesParentDir;
}
return path.dirname(filePath);
}
function groupNodeModulesFilesByDirectory(filePathToContent) {
var _a;
const filesByDir = new Map();
const filePaths = Object.keys(filePathToContent);
for (const filePath of filePaths) {
if (isNpmCacheDependency(filePath)) {
continue;
}
if (isYarnCacheDependency(filePath)) {
continue;
}
if (isPnpmCacheDependency(filePath)) {
continue;
}
const directory = getGroupingDir(filePath);
if (!filesByDir.has(directory)) {
filesByDir.set(directory, new Set());
}
(_a = filesByDir.get(directory)) === null || _a === void 0 ? void 0 : _a.add(filePath);
}
return filesByDir;
}
exports.groupNodeModulesFilesByDirectory = groupNodeModulesFilesByDirectory;
async function cleanupAppNodeModules(appRootDir) {
if (!appRootDir) {
return;
}
try {
await (0, promises_1.rm)(appRootDir, { recursive: true });
}
catch (error) {
debug(`Error while removing ${appRootDir} : ${error.message}`);
}
}
exports.cleanupAppNodeModules = cleanupAppNodeModules;
//# sourceMappingURL=node-modules-utils.js.map
;