diff --git a/src/cli/commands/protect/index.js b/src/cli/commands/protect/index.js index 27396b7556..7bbd50806b 100644 --- a/src/cli/commands/protect/index.js +++ b/src/cli/commands/protect/index.js @@ -3,17 +3,7 @@ var snyk = require('../../../lib/'); var protect = require('../../../lib/protect'); var analytics = require('../../../lib/analytics'); var detect = require('../../../lib/detect'); -var unsupportedPackageManagers = { - rubygems: 'RubyGems', - maven: 'Maven', - pip: 'Python', - sbt: 'SBT', - gradle: 'Gradle', - golangdep: 'Golang/Dep', - govendor: 'Govendor', - nuget: 'NuGet', - composer: 'Composer', -}; +var pm = require('../../../lib/package-managers'); function protectFunc(options = {}) { @@ -31,10 +21,11 @@ function protectFunc(options = {}) { try { var packageManager = detect.detectPackageManager(process.cwd(), options); - var unsupported = unsupportedPackageManagers[packageManager]; - if (unsupported) { + var supportsProtect = pm.PROTECT_SUPPORTED_PACKAGE_MANAGERS + .includes(packageManager); + if (!supportsProtect) { throw new Error( - 'Snyk protect for ' + unsupported + + 'Snyk protect for ' + pm.SUPPORTED_PACKAGE_MANAGER_NAME[packageManager] + ' projects is not currently supported'); } } catch (error) { diff --git a/src/cli/commands/protect/wizard.js b/src/cli/commands/protect/wizard.js index 505ea49f1b..73843b3a0d 100644 --- a/src/cli/commands/protect/wizard.js +++ b/src/cli/commands/protect/wizard.js @@ -33,8 +33,7 @@ const detect = require('../../../lib/detect'); const plugins = require('../../../lib/plugins'); const moduleInfo = require('../../../lib/module-info'); const {MissingTargetFileError} = require('../../../lib/errors/missing-targetfile-error'); - -const wizardSupportedPackageManagers = ['npm', 'yarn']; +const pm = require('../../../lib/package-managers'); function wizard(options = {}) { options.org = options.org || config.org || null; @@ -47,10 +46,11 @@ function wizard(options = {}) { async function processPackageManager(options) { const packageManager = detect.detectPackageManager(cwd, options); - const supportsWizard = wizardSupportedPackageManagers.includes(packageManager); + const supportsWizard = pm.WIZARD_SUPPORTED_PACKAGE_MANAGERS + .includes(packageManager); if (!supportsWizard) { return Promise.reject( - `Snyk wizard for ${packageManager} projects is not currently supported`); + `Snyk wizard for ${pm.SUPPORTED_PACKAGE_MANAGER_NAME[packageManager]} projects is not currently supported`); } return fs.exists(path.join('.', 'node_modules')) diff --git a/src/lib/detect.ts b/src/lib/detect.ts index e5ddd8599d..60e36f7dd0 100644 --- a/src/lib/detect.ts +++ b/src/lib/detect.ts @@ -3,10 +3,11 @@ import * as pathLib from 'path'; import * as debugLib from 'debug'; import * as _ from 'lodash'; import { NoSupportedManifestsFoundError } from './errors'; +import { SupportedPackageManagers } from './package-managers'; -const debug = debugLib('snyk'); +const debug = debugLib('snyk-detect'); -const DETECTABLE_FILES = [ +const DETECTABLE_FILES: string[] = [ 'yarn.lock', 'package-lock.json', 'package.json', @@ -28,7 +29,9 @@ const DETECTABLE_FILES = [ ]; // when file is specified with --file, we look it up here -const DETECTABLE_PACKAGE_MANAGERS = { +const DETECTABLE_PACKAGE_MANAGERS: { + [name: string]: SupportedPackageManagers; +} = { 'Gemfile': 'rubygems', 'Gemfile.lock': 'rubygems', '.gemspec': 'rubygems', diff --git a/src/lib/package-managers.ts b/src/lib/package-managers.ts new file mode 100644 index 0000000000..3836376815 --- /dev/null +++ b/src/lib/package-managers.ts @@ -0,0 +1,25 @@ +export type SupportedPackageManagers = 'rubygems' | 'npm' | 'yarn' | +'maven' | 'pip' | 'sbt' | 'gradle' | 'golangdep' | 'govendor' | +'nuget' | 'paket' | 'composer'; + +export const SUPPORTED_PACKAGE_MANAGER_NAME: { + readonly [packageManager in SupportedPackageManagers]: string; +} = { + rubygems: 'RubyGems', + npm: 'npm', + yarn: 'Yarn', + maven: 'Maven', + pip: 'pip', + sbt: 'SBT', + gradle: 'Gradle', + golangdep: 'dep (Go)', + govendor: 'govendor', + nuget: 'NuGet', + paket: 'Paket', + composer: 'Composer', +}; + +export const WIZARD_SUPPORTED_PACKAGE_MANAGERS: SupportedPackageManagers[] + = ['yarn', 'npm']; +export const PROTECT_SUPPORTED_PACKAGE_MANAGERS: SupportedPackageManagers[] + = ['yarn', 'npm']; diff --git a/src/lib/plugins/index.ts b/src/lib/plugins/index.ts index dfb3a0a298..ddbc7876b9 100644 --- a/src/lib/plugins/index.ts +++ b/src/lib/plugins/index.ts @@ -9,8 +9,10 @@ import * as nugetPlugin from 'snyk-nuget-plugin'; import * as phpPlugin from 'snyk-php-plugin'; import * as nodejsPlugin from './nodejs-plugin'; import * as types from './types'; +import {SupportedPackageManagers} from '../package-managers'; -export function loadPlugin(packageManager: string, options: types.Options = {}): types.Plugin { +export function loadPlugin(packageManager: SupportedPackageManagers, + options: types.Options = {}): types.Plugin { if (options.docker) { return dockerPlugin; } diff --git a/src/lib/snyk-test/index.js b/src/lib/snyk-test/index.js index 361fef08e4..ddb204392a 100644 --- a/src/lib/snyk-test/index.js +++ b/src/lib/snyk-test/index.js @@ -3,6 +3,7 @@ module.exports = test; var detect = require('../detect'); var runTest = require('./run-test'); var chalk = require('chalk'); +var pm = require('../package-managers'); function test(root, options, callback) { if (typeof options === 'function') { @@ -47,20 +48,7 @@ function executeTest(root, options) { function run(root, options) { var packageManager = options.packageManager; - if (!options.docker && [ - 'npm', - 'yarn', - 'rubygems', - 'maven', - 'gradle', - 'sbt', - 'pip', - 'golangdep', - 'govendor', - 'nuget', - 'paket', - 'composer', - ].indexOf(packageManager) === -1) { + if (!(options.docker || pm.SUPPORTED_PACKAGE_MANAGER_NAME[packageManager])) { throw new Error('Unsupported package manager: ' + packageManager); } return runTest(packageManager, root, options); diff --git a/src/lib/types.ts b/src/lib/types.ts index 7613690bb3..772473101c 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,4 +1,5 @@ import * as depGraphLib from '@snyk/dep-graph'; +import { SupportedPackageManagers } from './package-managers'; // TODO(kyegupov): use a shared repository snyk-cli-interface @@ -66,7 +67,7 @@ export interface TestOptions { 'project-name'?: string; 'show-vulnerable-paths'?: string; showVulnPaths?: boolean; - packageManager: string; + packageManager: SupportedPackageManagers; advertiseSubprojectsCount?: number; subProjectNames?: string[]; severityThreshold?: string; diff --git a/test/acceptance/cli.acceptance.test.ts b/test/acceptance/cli.acceptance.test.ts index 15158707e8..82e337a7f2 100644 --- a/test/acceptance/cli.acceptance.test.ts +++ b/test/acceptance/cli.acceptance.test.ts @@ -2663,18 +2663,18 @@ test('`wizard` for unsupported package managers', async (t) => { const cases = [ { file: 'ruby-app/Gemfile.lock', type: 'RubyGems' }, { file: 'maven-app/pom.xml', type: 'Maven' }, - { file: 'pip-app/requirements.txt', type: 'Python' }, + { file: 'pip-app/requirements.txt', type: 'pip' }, { file: 'sbt-app/build.sbt', type: 'SBT' }, { file: 'gradle-app/build.gradle', type: 'Gradle' }, { file: 'gradle-kotlin-dsl-app/build.gradle.kts', type: 'Gradle' }, - { file: 'golang-app/Gopkg.lock', type: 'Golang/Dep' }, - { file: 'golang-app/vendor/vendor.json', type: 'Govendor' }, + { file: 'golang-app/Gopkg.lock', type: 'dep (Go)' }, + { file: 'golang-app/vendor/vendor.json', type: 'govendor' }, { file: 'composer-app/composer.lock', type: 'Composer' }, ]; const results = await Promise.all(cases.map(testUnsupported)); results.map((result, i) => { const type = cases[i].type; - t.match(result, 'Snyk wizard for ' + type + + t.equal(result, 'Snyk wizard for ' + type + ' projects is not currently supported', type); }); }); @@ -2692,18 +2692,18 @@ test('`protect` for unsupported package managers', async (t) => { const cases = [ { file: 'ruby-app/Gemfile.lock', type: 'RubyGems' }, { file: 'maven-app/pom.xml', type: 'Maven' }, - { file: 'pip-app/requirements.txt', type: 'Python' }, + { file: 'pip-app/requirements.txt', type: 'pip' }, { file: 'sbt-app/build.sbt', type: 'SBT' }, { file: 'gradle-app/build.gradle', type: 'Gradle' }, { file: 'gradle-kotlin-dsl-app/build.gradle.kts', type: 'Gradle' }, - { file: 'golang-app/Gopkg.lock', type: 'Golang/Dep' }, - { file: 'golang-app/vendor/vendor.json', type: 'Govendor' }, + { file: 'golang-app/Gopkg.lock', type: 'dep (Go)' }, + { file: 'golang-app/vendor/vendor.json', type: 'govendor' }, { file: 'composer-app/composer.lock', type: 'Composer' }, ]; const results = await Promise.all(cases.map(testUnsupported)); results.map((result, i) => { const type = cases[i].type; - t.match(result.message, 'Snyk protect for ' + type + + t.equal(result.message, 'Snyk protect for ' + type + ' projects is not currently supported', type); }); });