Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: snyk/cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: aaf9fbc45fd1ef91f612c49bc8a4acbe46442474
Choose a base ref
...
head repository: snyk/cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6e168de3f12b1d807a43a4221297fe537ea7c6ac
Choose a head ref
  • 7 commits
  • 14 files changed
  • 3 contributors

Commits on Aug 28, 2020

  1. fix: test dependencies scan result type

    Use scan result type when making request to test dependencies.
    Split out makeRequest to it's own file so that it can be mocked.
    gitphill committed Aug 28, 2020
    Copy the full SHA
    a3438c0 View commit details
  2. Merge pull request #1370 from snyk/fix/test-dependencies-scan-result-…

    …type
    
    fix: test dependencies scan result type
    gitphill authored Aug 28, 2020
    Copy the full SHA
    54409b0 View commit details
  3. Copy the full SHA
    801535a View commit details
  4. Merge pull request #1373 from snyk/fix/bump-snyk-cpp-plugin

    fix: ignore broken files during cpp scan
    gitphill authored Aug 28, 2020
    Copy the full SHA
    3d7b708 View commit details
  5. Copy the full SHA
    2780cac View commit details
  6. Copy the full SHA
    a234c41 View commit details
  7. Merge pull request #1372 from snyk/feat/handle-empty-package-json

    feat: handle empty package.json dependencies better
    lili2311 authored Aug 28, 2020
    Copy the full SHA
    6e168de View commit details
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@
"proxy-from-env": "^1.0.0",
"semver": "^6.0.0",
"snyk-config": "3.1.0",
"snyk-cpp-plugin": "1.4.0",
"snyk-cpp-plugin": "1.4.1",
"snyk-docker-plugin": "3.18.1",
"snyk-go-plugin": "1.16.0",
"snyk-gradle-plugin": "3.5.1",
1 change: 1 addition & 0 deletions src/cli/args.ts
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@ const DEBUG_DEFAULT_NAMESPACES = [
'snyk:find-files',
'snyk:run-test',
'snyk:prune',
'snyk-nodejs-plugin',
'snyk-gradle-plugin',
'snyk-sbt-plugin',
'snyk-mvn-plugin',
50 changes: 16 additions & 34 deletions src/lib/ecosystems.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import * as cppPlugin from 'snyk-cpp-plugin';
import { Options } from './types';
import { TestCommandResult } from '../cli/commands/types';
import { DepGraphData } from '@snyk/dep-graph';
import * as snyk from './index';
import * as config from './config';
import { isCI } from './is-ci';
import * as snyk from './';
import request = require('./request');
import { DepGraphData } from '@snyk/dep-graph';

interface Artifact {
import { makeRequest } from './request/promise';
import { Options } from './types';
import { TestCommandResult } from '../cli/commands/types';
export interface Artifact {
type: string;
data: any;
meta: { [key: string]: any };
}

interface ScanResult {
export interface ScanResult {
type: string;
artifacts: Artifact[];
meta: {
[key: string]: any;
};
}

interface TestResults {
export interface TestResult {
depGraph: DepGraphData;
affectedPkgs: {
[pkgId: string]: {
@@ -49,7 +48,7 @@ export interface EcosystemPlugin {
scan: (options: Options) => Promise<ScanResult[]>;
display: (
scanResults: ScanResult[],
testResults: TestResults[],
testResults: TestResult[],
errors: string[],
) => Promise<string>;
}
@@ -80,19 +79,19 @@ export async function testEcosystem(
): Promise<TestCommandResult> {
const plugin = getPlugin(ecosystem);
const scanResultsByPath: { [dir: string]: ScanResult[] } = {};
let scanResults: ScanResult[] = [];
for (const path of paths) {
options.path = path;
const results = await plugin.scan(options);
scanResultsByPath[path] = results;
scanResults = scanResults.concat(results);
}

const [testResults, errors] = await testDependencies(scanResultsByPath);
const stringifiedData = JSON.stringify(testResults, null, 2);
if (options.json) {
return TestCommandResult.createJsonTestCommandResult(stringifiedData);
}
const emptyResults: ScanResult[] = [];
const scanResults = emptyResults.concat(...Object.values(scanResultsByPath));
const readableResult = await plugin.display(scanResults, testResults, errors);

return TestCommandResult.createHumanReadableTestCommandResult(
@@ -103,8 +102,8 @@ export async function testEcosystem(

export async function testDependencies(scans: {
[dir: string]: ScanResult[];
}): Promise<[TestResults[], string[]]> {
const results: TestResults[] = [];
}): Promise<[TestResult[], string[]]> {
const results: TestResult[] = [];
const errors: string[] = [];
for (const [path, scanResults] of Object.entries(scans)) {
for (const scanResult of scanResults) {
@@ -117,16 +116,16 @@ export async function testDependencies(scans: {
authorization: 'token ' + snyk.api,
},
body: {
type: 'cpp',
type: scanResult.type,
artifacts: scanResult.artifacts,
meta: {},
},
};
try {
const response = await makeRequest(payload);
const response = await makeRequest<TestResult>(payload);
results.push(response);
} catch (error) {
if (error.code !== 200) {
if (error.code >= 400 && error.code < 500) {
throw new Error(error.message);
}
errors.push('Could not test dependencies in ' + path);
@@ -135,20 +134,3 @@ export async function testDependencies(scans: {
}
return [results, errors];
}

export async function makeRequest(payload: any): Promise<TestResults> {
return new Promise((resolve, reject) => {
request(payload, (error, res, body) => {
if (error) {
return reject(error);
}
if (res.statusCode !== 200) {
return reject({
code: res.statusCode,
message: res?.body?.message || 'Error testing dependencies',
});
}
resolve(body);
});
});
}
22 changes: 22 additions & 0 deletions src/lib/get-file-contents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as fs from 'fs';
import * as path from 'path';

export function getFileContents(
root: string,
fileName: string,
): {
content: string;
fileName: string;
} {
const fullPath = path.resolve(root, fileName);
if (!fs.existsSync(fullPath)) {
throw new Error(
'Manifest ' + fileName + ' not found at location: ' + fileName,
);
}
const content = fs.readFileSync(fullPath, 'utf-8');
return {
content,
fileName,
};
}
54 changes: 42 additions & 12 deletions src/lib/plugins/nodejs-plugin/npm-modules-parser.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,62 @@
import * as path from 'path';
import * as fs from 'fs';
import * as resolveNodeDeps from 'snyk-resolve-deps';
import * as baseDebug from 'debug';
import * as _ from '@snyk/lodash';

import * as spinner from '../../spinner';
import * as analytics from '../../analytics';
import { Options } from '../types';
import { getFileContents } from '../../get-file-contents';

const debug = baseDebug('snyk-nodejs-plugin');

export async function parse(
root: string,
targetFile: string,
options: Options,
): Promise<resolveNodeDeps.PackageExpanded> {
if (targetFile.endsWith('yarn.lock')) {
options.file =
options.file && options.file.replace('yarn.lock', 'package.json');
}

// package-lock.json falls back to package.json (used in wizard code)
if (targetFile.endsWith('package-lock.json')) {
options.file =
options.file && options.file.replace('package-lock.json', 'package.json');
}
// check if there any dependencies
const packageJsonFileName = path.resolve(root, options.file!);
const packageManager = options.packageManager || 'npm';

try {
const packageJson = JSON.parse(
getFileContents(root, packageJsonFileName).content,
);
let dependencies = packageJson.dependencies;
if (options.dev) {
dependencies = { ...dependencies, ...packageJson.devDependencies };
}
if (_.isEmpty(dependencies)) {
return new Promise((resolve) =>
resolve({
name: packageJson.name,
dependencies: {},
version: packageJson.version,
}),
);
}
} catch (e) {
debug(`Failed to read ${packageJsonFileName}: Error: ${e}`);
throw new Error(
`Failed to read ${packageJsonFileName}. Error: ${e.message}`,
);
}
const nodeModulesPath = path.join(
path.dirname(path.resolve(root, targetFile)),
'node_modules',
);
const packageManager = options.packageManager || 'npm';

if (!fs.existsSync(nodeModulesPath)) {
// throw a custom error
@@ -36,17 +77,6 @@ export async function parse(
try {
await spinner.clear<void>(resolveModuleSpinnerLabel)();
await spinner(resolveModuleSpinnerLabel);
if (targetFile.endsWith('yarn.lock')) {
options.file =
options.file && options.file.replace('yarn.lock', 'package.json');
}

// package-lock.json falls back to package.json (used in wizard code)
if (targetFile.endsWith('package-lock.json')) {
options.file =
options.file &&
options.file.replace('package-lock.json', 'package.json');
}
return resolveNodeDeps(
root,
Object.assign({}, options, { noFromArrays: true }),
28 changes: 4 additions & 24 deletions src/lib/plugins/nodejs-plugin/yarn-workspaces-parser.ts
Original file line number Diff line number Diff line change
@@ -3,14 +3,14 @@ import * as pathUtil from 'path';
import * as _ from '@snyk/lodash';

const debug = baseDebug('snyk:yarn-workspaces');
import * as fs from 'fs';
import * as lockFileParser from 'snyk-nodejs-lockfile-parser';
import * as path from 'path';
import { NoSupportedManifestsFoundError } from '../../errors';
import {
MultiProjectResultCustom,
ScannedProjectCustom,
} from '../get-multi-plugin-result';
import { getFileContents } from '../../get-file-contents';

export async function processYarnWorkspaces(
root: string,
@@ -89,7 +89,7 @@ export async function processYarnWorkspaces(
);
const project: ScannedProjectCustom = {
packageManager: 'yarn',
targetFile: path.relative(root, packageJson.name),
targetFile: path.relative(root, packageJson.fileName),
depTree: res as any,
plugin: {
name: 'snyk-nodejs-lockfile-parser',
@@ -102,26 +102,6 @@ export async function processYarnWorkspaces(
return result;
}

function getFileContents(
root: string,
fileName: string,
): {
content: string;
name: string;
} {
const fullPath = path.resolve(root, fileName);
if (!fs.existsSync(fullPath)) {
throw new Error(
'Manifest ' + fileName + ' not found at location: ' + fileName,
);
}
const content = fs.readFileSync(fullPath, 'utf-8');
return {
content,
name: fileName,
};
}

interface YarnWorkspacesMap {
[packageJsonName: string]: {
workspaces: string[];
@@ -130,7 +110,7 @@ interface YarnWorkspacesMap {

export function getWorkspacesMap(file: {
content: string;
name: string;
fileName: string;
}): YarnWorkspacesMap {
const yarnWorkspacesMap = {};
if (!file) {
@@ -143,7 +123,7 @@ export function getWorkspacesMap(file: {
);

if (rootFileWorkspacesDefinitions && rootFileWorkspacesDefinitions.length) {
yarnWorkspacesMap[file.name] = {
yarnWorkspacesMap[file.fileName] = {
workspaces: rootFileWorkspacesDefinitions,
};
}
18 changes: 18 additions & 0 deletions src/lib/request/promise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import request = require('./index');

export async function makeRequest<T>(payload: any): Promise<T> {
return new Promise((resolve, reject) => {
request(payload, (error, res, body) => {
if (error) {
return reject(error);
}
if (res.statusCode !== 200) {
return reject({
code: res.statusCode,
message: body?.message,
});
}
resolve(body);
});
});
}
Loading