Skip to content

Commit

Permalink
feat: [OSM-1040] Added pnpm support under 'enablePnpmCli' feature flag (
Browse files Browse the repository at this point in the history
#5181)

* feat: [OSM-1040] Added pnpm support under 'enablePnpmCli' feature flag
  • Loading branch information
gemaxim committed May 10, 2024
1 parent 36e2460 commit 46769cc
Show file tree
Hide file tree
Showing 94 changed files with 16,898 additions and 242 deletions.
502 changes: 487 additions & 15 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -121,7 +121,8 @@
"snyk-gradle-plugin": "4.1.0",
"snyk-module": "3.1.0",
"snyk-mvn-plugin": "3.4.2",
"snyk-nodejs-lockfile-parser": "1.52.11",
"snyk-nodejs-lockfile-parser": "1.56.0",
"snyk-nodejs-plugin": "1.1.0",
"snyk-nuget-plugin": "2.4.5",
"snyk-php-plugin": "1.9.2",
"snyk-policy": "^1.25.0",
Expand Down
1 change: 1 addition & 0 deletions src/cli/args.ts
Expand Up @@ -44,6 +44,7 @@ const DEBUG_DEFAULT_NAMESPACES = [
'snyk-sbt-plugin',
'snyk-mvn-plugin',
'snyk-yarn-workspaces',
'snyk-pnpm-workspaces',
];

function dashToCamelCase(dash) {
Expand Down
27 changes: 21 additions & 6 deletions src/cli/commands/monitor/index.ts
Expand Up @@ -49,6 +49,7 @@ import { getEcosystem, monitorEcosystem } from '../../../lib/ecosystems';
import { getFormattedMonitorOutput } from '../../../lib/ecosystems/monitor';
import { processCommandArgs } from '../process-command-args';
import { hasFeatureFlag } from '../../../lib/feature-flags';
import { PNPM_FEATURE_FLAG } from '../../../lib/package-managers';

const SEPARATOR = '\n-------------------------------------------------------\n';
const debug = Debug('snyk');
Expand Down Expand Up @@ -158,6 +159,12 @@ export default async function monitor(...args0: MethodArgs): Promise<any> {
);
}

const hasPnpmSupport = await hasFeatureFlag(PNPM_FEATURE_FLAG, options);

const featureFlags = hasPnpmSupport
? new Set<string>([PNPM_FEATURE_FLAG])
: new Set<string>();

// Part 1: every argument is a scan target; process them sequentially
for (const path of paths) {
debug(`Processing ${path}...`);
Expand All @@ -170,7 +177,11 @@ export default async function monitor(...args0: MethodArgs): Promise<any> {
} else if (options.docker) {
analysisType = 'docker';
} else {
packageManager = detect.detectPackageManager(path, options);
packageManager = detect.detectPackageManager(
path,
options,
featureFlags,
);
}
const unsupportedPackageManagers: Array<{
label: string;
Expand All @@ -185,7 +196,7 @@ export default async function monitor(...args0: MethodArgs): Promise<any> {
const targetFile =
!options.scanAllUnmanaged && options.docker && !options.file // snyk monitor --docker (without --file)
? undefined
: options.file || detect.detectPackageFile(path);
: options.file || detect.detectPackageFile(path, featureFlags);

const displayPath = pathUtil.relative(
'.',
Expand All @@ -206,11 +217,15 @@ export default async function monitor(...args0: MethodArgs): Promise<any> {
// each plugin will be asked to scan once per path
// some return single InspectResult & newer ones return Multi
const inspectResult = await promiseOrCleanup(
getDepsFromPlugin(path, {
...options,
getDepsFromPlugin(
path,
packageManager,
}),
{
...options,
path,
packageManager,
},
featureFlags,
),
spinner.clear(analyzingDepsSpinnerLabel),
);
analytics.add('pluginName', inspectResult.plugin.name);
Expand Down
54 changes: 47 additions & 7 deletions src/lib/detect.ts
Expand Up @@ -5,11 +5,13 @@ import { NoSupportedManifestsFoundError } from './errors';
import {
SupportedPackageManagers,
SUPPORTED_MANIFEST_FILES,
PNPM_FEATURE_FLAG,
} from './package-managers';

const debug = debugLib('snyk-detect');

const DETECTABLE_FILES: string[] = [
'pnpm-lock.yaml',
'yarn.lock',
'package-lock.json',
'package.json',
Expand Down Expand Up @@ -38,6 +40,7 @@ const DETECTABLE_FILES: string[] = [
];

export const AUTO_DETECTABLE_FILES: string[] = [
'pnpm-lock.yaml',
'package-lock.json',
'yarn.lock',
'package.json',
Expand Down Expand Up @@ -81,6 +84,7 @@ const DETECTABLE_PACKAGE_MANAGERS: {
[SUPPORTED_MANIFEST_FILES.BUILD_GRADLE_KTS]: 'gradle',
[SUPPORTED_MANIFEST_FILES.BUILD_SBT]: 'sbt',
[SUPPORTED_MANIFEST_FILES.YARN_LOCK]: 'yarn',
[SUPPORTED_MANIFEST_FILES.PNPM_LOCK]: 'pnpm',
[SUPPORTED_MANIFEST_FILES.PACKAGE_JSON]: 'npm',
[SUPPORTED_MANIFEST_FILES.PIPFILE]: 'pip',
[SUPPORTED_MANIFEST_FILES.SETUP_PY]: 'pip',
Expand All @@ -102,16 +106,26 @@ const DETECTABLE_PACKAGE_MANAGERS: {
[SUPPORTED_MANIFEST_FILES.PACKAGE_SWIFT]: 'swift',
};

export function isPathToPackageFile(path: string) {
export function isPathToPackageFile(
path: string,
featureFlags: Set<string> = new Set<string>(),
) {
for (const fileName of DETECTABLE_FILES) {
if (path.endsWith(fileName)) {
if (!isFileCompatible(fileName, featureFlags)) {
continue;
}
return true;
}
}
return false;
}

export function detectPackageManager(root: string, options) {
export function detectPackageManager(
root: string,
options,
featureFlags: Set<string> = new Set<string>(),
) {
// If user specified a package manager let's use it.
if (options.packageManager) {
return options.packageManager;
Expand All @@ -133,14 +147,14 @@ export function detectPackageManager(root: string, options) {
);
}
file = options.file;
packageManager = detectPackageManagerFromFile(file);
packageManager = detectPackageManagerFromFile(file, featureFlags);
} else if (options.scanAllUnmanaged) {
packageManager = 'maven';
} else {
debug('no file specified. Trying to autodetect in base folder ' + root);
file = detectPackageFile(root);
file = detectPackageFile(root, featureFlags);
if (file) {
packageManager = detectPackageManagerFromFile(file);
packageManager = detectPackageManagerFromFile(file, featureFlags);
}
}
} else {
Expand Down Expand Up @@ -169,19 +183,41 @@ export function isLocalFolder(root: string) {
}
}

export function detectPackageFile(root) {
function isFileCompatible(
file: string,
featureFlags: Set<string> = new Set<string>(),
) {
if (
file === SUPPORTED_MANIFEST_FILES.PNPM_LOCK &&
!featureFlags.has(PNPM_FEATURE_FLAG)
) {
return false;
}
return true;
}

export function detectPackageFile(
root: string,
featureFlags: Set<string> = new Set<string>(),
) {
for (const file of DETECTABLE_FILES) {
if (fs.existsSync(pathLib.resolve(root, file))) {
if (!isFileCompatible(file, featureFlags)) {
debug(
`found pnpm lockfile ${file} in ${root}, but ${PNPM_FEATURE_FLAG} not enabled`,
);
continue;
}
debug('found package file ' + file + ' in ' + root);
return file;
}
}

debug('no package file found in ' + root);
}

export function detectPackageManagerFromFile(
file: string,
featureFlags: Set<string> = new Set<string>(),
): SupportedPackageManagers {
let key = pathLib.basename(file);

Expand All @@ -204,6 +240,10 @@ export function detectPackageManagerFromFile(
throw new Error('Could not detect package manager for file: ' + file);
}

if (!isFileCompatible(key, featureFlags)) {
throw new Error('Could not detect package manager for file: ' + file);
}

return DETECTABLE_PACKAGE_MANAGERS[key];
}

Expand Down

0 comments on commit 46769cc

Please sign in to comment.