Skip to content

Commit

Permalink
chore: refactor patch & split option types by command
Browse files Browse the repository at this point in the history
Refactor patch from js -> ts.
Convert to async / await
Split Options types by command + cli command base options
  • Loading branch information
lili2311 committed Jun 24, 2019
1 parent 7f8a635 commit 2db2107
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
const debug = require('debug')('snyk');
const snyk = require('../../../lib/');
const protect = require('../../../lib/protect');
const analytics = require('../../../lib/analytics');
const detect = require('../../../lib/detect');
const pm = require('../../../lib/package-managers');
import * as debugModule from 'debug';
import * as snyk from '../../../lib/';
import * as types from '../../../lib/types';
import * as protect from '../../../lib/protect';
import * as analytics from '../../../lib/analytics';
import * as detect from '../../../lib/detect';
import * as pm from '../../../lib/package-managers';
import { CustomError } from '../../../lib/errors';
import { Options } from '../../../lib/plugins/types';
import { LegacyVulnApiResult } from '../../../lib/snyk-test/legacy';

const debug = debugModule('snyk');

function protectFunc(options = {}) {
function protectFunc(options: types.ProtectOptions & types.Options & types.TestOptions) {
options.loose = true; // replace missing policies with empty ones
options.vulnEndpoint = '/vuln/npm/patches';
// TODO: fix this by providing better patch support for yarn
Expand All @@ -18,9 +23,8 @@ function protectFunc(options = {}) {
// bypass lockfile test for wizard
options.traverseNodeModules = true;


try {
const packageManager = detect.detectPackageManager(process.cwd(), options);
const packageManager: pm.SupportedPackageManagers = detect.detectPackageManager(process.cwd(), options);
const supportsProtect = pm.PROTECT_SUPPORTED_PACKAGE_MANAGERS
.includes(packageManager);
if (!supportsProtect) {
Expand Down Expand Up @@ -59,18 +63,22 @@ function protectFunc(options = {}) {
});
}

function patch(policy, options) {
return snyk.test(process.cwd(), options).then((res) => {
if (!res.vulnerabilities) {
const e = new Error('Code is already patched');
e.code = 'ALREADY_PATCHED';
async function patch(policy, options: Options) {
try {
const response = await snyk.test(process.cwd(), options) as LegacyVulnApiResult;
// TODO: need to add support for multiple test results being returned
// from test (for example gradle modules)

if (!response.vulnerabilities) {
const e = new CustomError('Code is already patched');
e.strCode = 'ALREADY_PATCHED';
e.code = 204;
throw e;
}
return protect.patch(res.vulnerabilities, !options['dry-run']);
}).then(() => {
await protect.patch(response.vulnerabilities, !options['dry-run']);
analytics.add('success', true);
return 'Successfully applied Snyk patches';
}).catch((e) => {
} catch (e) {
if (e.code === 'ALREADY_PATCHED') {
analytics.add('success', true);
return e.message + ', nothing to do';
Expand All @@ -79,7 +87,7 @@ function patch(policy, options) {
analytics.add('success', false);

throw e;
});
}
}

module.exports = protectFunc;
12 changes: 6 additions & 6 deletions src/cli/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {isCI} from '../../lib/is-ci';
import {apiTokenExists} from '../../lib/api-token';
import {SEVERITIES, WIZARD_SUPPORTED_PMS} from '../../lib/snyk-test/common';
import * as Debug from 'debug';
import {TestOptions} from '../../lib/types';
import {Options} from '../../lib/types';
import {isLocalFolder} from '../../lib/detect';
import { MethodArgs } from '../args';

Expand All @@ -24,10 +24,10 @@ interface OptionsAtDisplayStage {
async function test(...args: MethodArgs): Promise<string> {
const resultOptions = [] as any[];
let results = [] as any[];
let options = {} as any as TestOptions;
let options = {} as any as Options;

if (typeof args[args.length - 1] === 'object') {
options = args.pop() as any as TestOptions;
options = args.pop() as any as Options;
}

// populate with default path (cwd) if no path given
Expand Down Expand Up @@ -215,7 +215,7 @@ function summariseErrorResults(errorResults) {
return '';
}

function displayResult(res, options: TestOptions & OptionsAtDisplayStage) {
function displayResult(res, options: Options & OptionsAtDisplayStage) {
const meta = metaForDisplay(res, options) + '\n\n';
const dockerAdvice = dockerRemediationForDisplay(res);
const packageManager = options.packageManager;
Expand Down Expand Up @@ -333,7 +333,7 @@ function displayResult(res, options: TestOptions & OptionsAtDisplayStage) {
function formatDockerBinariesIssues(
dockerBinariesSortedGroupedVulns,
binariesVulns,
options: TestOptions & OptionsAtDisplayStage) {
options: Options & OptionsAtDisplayStage) {
const binariesIssuesOutput = [] as string[];
for (const pkgInfo of _.values(binariesVulns.affectedPkgs)) {
binariesIssuesOutput.push(createDockerBinaryHeading(pkgInfo));
Expand All @@ -355,7 +355,7 @@ function createDockerBinaryHeading(pkgInfo) {
` for ${binaryName}@${binaryVersion} ------------`, '\n') : '';
}

function formatIssues(vuln, options: TestOptions & OptionsAtDisplayStage) {
function formatIssues(vuln, options: Options & OptionsAtDisplayStage) {
const vulnID = vuln.list[0].id;
const packageManager = options.packageManager;
const uniquePackages = _.uniq(
Expand Down
1 change: 1 addition & 0 deletions src/lib/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export {MissingApiTokenError} from './missing-api-token';
export {FileFlagBadInputError} from './file-flag-bad-input';
export {MissingTargetFileError} from './missing-targetfile-error';
export {NoSupportedManifestsFoundError} from './no-supported-manifests-found';
export {CustomError} from './custom-error';
4 changes: 2 additions & 2 deletions src/lib/print-deps.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DepDict, TestOptions, MonitorOptions, DepTree } from './types';
import { DepDict, Options, MonitorOptions, DepTree } from './types';

// This option is still experimental and might be deprecated.
// It might be a better idea to convert it to a command (i.e. do not perform test/monitor).
export function maybePrintDeps(options: TestOptions | MonitorOptions, rootPackage: DepTree) {
export function maybePrintDeps(options: Options | MonitorOptions, rootPackage: DepTree) {
if (options['print-deps']) {
if (options.json) {
// Will produce 2 JSON outputs, one for the deps, one for the vuln scan.
Expand Down
16 changes: 9 additions & 7 deletions src/lib/snyk-test/run-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import request = require('../request');
import snyk = require('../');
import spinner = require('../spinner');
import common = require('./common');
import {DepTree} from '../types';
import {DepTree, TestOptions} from '../types';
import gemfileLockToDependencies = require('../../lib/plugins/rubygems/gemfile-lock-to-dependencies');
import {convertTestDepGraphResultToLegacy, AnnotatedIssue, LegacyVulnApiResult, TestDepGraphResponse} from './legacy';
import {SingleDepRootResult, MultiDepRootsResult, isMultiResult, TestOptions} from '../types';
import {SingleDepRootResult, MultiDepRootsResult, isMultiResult, Options} from '../types';
import { NoSupportedManifestsFoundError } from '../errors';
import { maybePrintDeps } from '../print-deps';
import { SupportedPackageManagers } from '../package-managers';

// tslint:disable-next-line:no-var-requires
const debug = require('debug')('snyk');
Expand Down Expand Up @@ -53,7 +54,8 @@ interface Payload {
modules?: DepTreeFromResolveDeps;
}

async function runTest(packageManager: string, root: string, options): Promise<LegacyVulnApiResult[]> {
async function runTest(packageManager: SupportedPackageManagers,
root: string, options: Options & TestOptions): Promise<LegacyVulnApiResult[]> {
const results: LegacyVulnApiResult[] = [];
const spinnerLbl = 'Querying vulnerabilities database...';
try {
Expand Down Expand Up @@ -184,7 +186,7 @@ function sendPayload(payload: Payload, hasDevDependencies: boolean):
});
}

function assemblePayloads(root: string, options): Promise<Payload[]> {
function assemblePayloads(root: string, options: Options & TestOptions): Promise<Payload[]> {
let isLocal;
if (options.docker) {
isLocal = true;
Expand All @@ -200,7 +202,7 @@ function assemblePayloads(root: string, options): Promise<Payload[]> {
}

// Force getDepsFromPlugin to return depRoots for processing in assembleLocalPayload
async function getDepsFromPlugin(root, options: TestOptions): Promise<MultiDepRootsResult> {
async function getDepsFromPlugin(root, options: Options): Promise<MultiDepRootsResult> {
options.file = options.file || detect.detectPackageFile(root);
if (!options.docker && !(options.file || options.packageManager)) {
throw NoSupportedManifestsFoundError([...root]);
Expand Down Expand Up @@ -242,7 +244,7 @@ async function getDepsFromPlugin(root, options: TestOptions): Promise<MultiDepRo
}

// Payload to send to the Registry for scanning a package from the local filesystem.
async function assembleLocalPayloads(root, options): Promise<Payload[]> {
async function assembleLocalPayloads(root, options: Options & TestOptions): Promise<Payload[]> {
const analysisType = options.docker ? 'docker' : options.packageManager;
const spinnerLbl = 'Analyzing ' + analysisType + ' dependencies for ' +
(pathUtil.relative('.', pathUtil.join(root, options.file || '')) ||
Expand Down Expand Up @@ -344,7 +346,7 @@ async function assembleLocalPayloads(root, options): Promise<Payload[]> {

if (['yarn', 'npm'].indexOf(options.packageManager) !== -1) {
const isLockFileBased = options.file
&& options.file.endsWith('package-lock.json') || options.file.endsWith('yarn.lock');
&& (options.file.endsWith('package-lock.json') || options.file.endsWith('yarn.lock'));
if (!isLockFileBased || options.traverseNodeModules) {
payload.modules = pkg as DepTreeFromResolveDeps; // See the output of resolve-deps
}
Expand Down
12 changes: 10 additions & 2 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as depGraphLib from '@snyk/dep-graph';
import { SupportedPackageManagers } from './package-managers';

// TODO(kyegupov): use a shared repository snyk-cli-interface

export interface PluginMetadata {
name: string;
packageFormatVersion?: string;
packageManager: string;
packageManager: SupportedPackageManagers;
imageLayers?: any;
targetFile?: string; // this is wrong (because Shaun said it)
runtime?: any;
Expand Down Expand Up @@ -57,12 +56,21 @@ export class MonitorError extends Error {
}

export interface TestOptions {
traverseNodeModules: boolean;
interactive: boolean;
}
export interface ProtectOptions {
loose: boolean;
}
export interface Options {
org: string;
path: string;
docker?: boolean;
file?: string;
policy?: string;
json?: boolean;
vulnEndpoint?: string;
projectName?: string;
'all-sub-projects'?: boolean; // Corresponds to multiDepRoot in plugins
'project-name'?: string;
'show-vulnerable-paths'?: string;
Expand Down

0 comments on commit 2db2107

Please sign in to comment.