UNPKG

@candrewsintegralblue/snyk

Version:

snyk library and cli utility

308 lines (292 loc) 13.9 kB
"use strict"; exports.id = 27; exports.ids = [27,875]; exports.modules = { /***/ 24027: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); const cloneDeep = __webpack_require__(83465); const path = __webpack_require__(71017); const get = __webpack_require__(29208); const chalk_1 = __webpack_require__(32589); const detect_1 = __webpack_require__(45318); const get_deps_from_plugin_1 = __webpack_require__(4842); const spinner_1 = __webpack_require__(86766); const process_command_args_1 = __webpack_require__(52369); const types_1 = __webpack_require__(55246); const theme_1 = __webpack_require__(86988); const analytics = __webpack_require__(82744); const Debug = __webpack_require__(15158); const depGraphLib = __webpack_require__(71479); const theme = __webpack_require__(86988); const failed_to_run_client_sbom_error_1 = __webpack_require__(13490); const errors_1 = __webpack_require__(55191); const extract_package_manager_1 = __webpack_require__(22805); const is_multi_project_scan_1 = __webpack_require__(62435); const package_managers_1 = __webpack_require__(53847); const cdx = __webpack_require__(27769); const packageurl_js_1 = __webpack_require__(38382); const print_deps_1 = __webpack_require__(79792); const version_1 = __webpack_require__(74970); const check_paths_1 = __webpack_require__(94501); const prune_1 = __webpack_require__(87725); const console_1 = __webpack_require__(96206); const debug = Debug('snyk-client-sbom'); function validateProjectType(options, projectType) { if (!((0, is_multi_project_scan_1.isMultiProjectScan)(options) || package_managers_1.SUPPORTED_PACKAGE_MANAGER_NAME[projectType])) { throw new errors_1.UnsupportedPackageManagerError(projectType); } } /** * Generate a {@link https://github.com/package-url/purl-spec purl (Package URL)} for a given {@link depGraphLib.PkgInfo}. * @param packageManager {@link SupportedPackageManagers} which discovered `dep` * @param dep {@link depGraphLib.PkgInfo} package for which purl is to be generated * @returns {@link PackageURL} for the given `dep` * @see {@link https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst PURL Types Specification} */ function depToPackageURL(packageManager, dep) { let namespace = undefined; let name = dep.name; let type; switch (packageManager) { case 'rubygems': type = 'gem'; break; case 'npm': case 'pnpm': case 'yarn': type = 'npm'; break; case 'maven': case 'gradle': case 'sbt': { const splitName = dep.name.split(':', 2); if (splitName.length == 1) { namespace = undefined; name = splitName[0]; } else { [namespace, name] = splitName; } type = 'maven'; break; } case 'pip': case 'poetry': type = 'pypi'; break; case 'golangdep': case 'gomodules': case 'govendor': type = 'golang'; break; case 'nuget': case 'paket': type = 'nuget'; break; case 'composer': type = 'composer'; break; case 'cocoapods': type = 'carthage'; break; case 'hex': type = 'hex'; break; case 'Unmanaged (C/C++)': type = 'generic'; break; case 'swift': type = 'swift'; break; default: { const exhaustiveCheck = packageManager; throw new Error(`Unhandled packageManager case: ${exhaustiveCheck}`); } } return new packageurl_js_1.PackageURL(type, namespace, name, dep.version, undefined, undefined); } /** * Create and add a {@link cdx.Models.Component} for the given {@link depGraphLib.PkgInfo} to the given {@link cdx.Models.Bom} if it hasn't already been created. * @param dep the dep to add to `bom` * @param packageURLToComponent map used to determine if a {@link cdx.Models.Component} has been previously created. Used to determine if a new {@link cdx.Models.Component} should be created or if an existing one should be used. * @param packageManager {@link SupportedPackageManagers} which constructed `depGraph` * @param targetFile path to the file from which the `depGraph` was derived. * @param bom {@link cdx.Models.Bom} to which to add the component. * @param depGraph {@link depGraphLib.DepGraph} that contains `dep` * @returns the {@link cdx.Models.Component} representation of `dep` */ function component(dep, packageURLToComponent, packageManager, targetFile, bom, depGraph) { var _a; const packageURL = depToPackageURL(packageManager, dep); const packageURLString = packageURL.toString(); if (!(packageURLString in packageURLToComponent)) { const depComponent = new cdx.Models.Component(cdx.Enums.ComponentType.Library, packageURL.name, { version: dep.version, purl: packageURL, group: (_a = packageURL.namespace) === null || _a === void 0 ? void 0 : _a.toString(), bomRef: `${targetFile}:${packageURL}`, }); // The "snyk" property namespace has been reserved: https://github.com/CycloneDX/cyclonedx-property-taxonomy depComponent.properties.add(new cdx.Models.Property('snyk:package_manager:name', packageManager)); depComponent.properties.add(new cdx.Models.Property('snyk:source_file:path', targetFile)); packageURLToComponent[packageURLString] = depComponent; bom.components.add(depComponent); // dependency graph if (depGraph.rootPkg !== dep) { for (const pathToRoot of depGraph.pkgPathsToRoot(dep)) { (0, console_1.assert)(pathToRoot.length > 1); // pathToRoot is always greater than 1 for non-root packages (and the root package isn't included) (0, console_1.assert)(dep === pathToRoot[0]); // sanity check; the path to root always starts with the given package const revDep = pathToRoot[1]; const revDepComponent = component(revDep, packageURLToComponent, packageManager, targetFile, bom, depGraph); revDepComponent.dependencies.add(depComponent.bomRef); } } } return packageURLToComponent[packageURLString]; } exports["default"] = async (...args) => { const { options: originalOptions, paths } = (0, process_command_args_1.processCommandArgs)(...args); debug(originalOptions); (0, check_paths_1.checkOSSPaths)(paths, originalOptions); const humanReadableArr = []; const bom = new cdx.Models.Bom(); bom.metadata.tools.add(new cdx.Models.Tool({ vendor: 'Snyk', name: 'snyk-cli', version: await (0, version_1.default)(), })); const featureFlags = new Set([package_managers_1.PNPM_FEATURE_FLAG]); // Promise waterfall to test all other paths sequentially for (const root of paths) { // Create a copy of the options so a specific test can // modify them i.e. add `options.file` etc. We'll need // these options later. const options = cloneDeep(originalOptions); options.path = root; if (!options.allProjects) { options.packageManager = (0, detect_1.detectPackageManager)(root, options, featureFlags); } const projectType = options.packageManager; validateProjectType(options, projectType); // For --all-projects packageManager is yet undefined here. Use 'all' let analysisTypeText = 'all dependencies for '; if (options.packageManager) { analysisTypeText = options.packageManager + ' dependencies for '; } const spinnerLbl = 'Analyzing ' + analysisTypeText + (path.relative('.', path.join(root, options.file || '')) || path.relative('..', '.') + ' project dir'); try { await spinner_1.spinner.clear(spinnerLbl)(); if (!options.quiet) { await (0, spinner_1.spinner)(spinnerLbl); } const deps = await (0, get_deps_from_plugin_1.getDepsFromPlugin)(root, options, featureFlags); const failedResults = deps.failedResults; if (failedResults === null || failedResults === void 0 ? void 0 : failedResults.length) { await spinner_1.spinner.clear(spinnerLbl)(); if (!options.json && !options.quiet) { console.warn(chalk_1.default.bold.red(`${theme_1.icon.ISSUE} ${failedResults.length}/${failedResults.length + deps.scannedProjects .length} potential projects failed to get dependencies.`)); failedResults.forEach((f) => { if (f.targetFile) { console.warn(theme.color.status.error(`${f.targetFile}:`)); } console.warn(theme.color.status.error(` ${f.errMessage}`)); }); } debug('getDepsFromPlugin returned failed results, cannot run deps', failedResults); if (options['fail-fast']) { throw new failed_to_run_client_sbom_error_1.FailedToRunClientSbomError((0, errors_1.errorMessageWithRetry)('Your deps request could not be completed.')); } } analytics.add('pluginName', deps.plugin.name); const javaVersion = get(deps.plugin, 'meta.versionBuildInfo.metaBuildVersion.javaVersion', null); const mvnVersion = get(deps.plugin, 'meta.versionBuildInfo.metaBuildVersion.mvnVersion', null); const sbtVersion = get(deps.plugin, 'meta.versionBuildInfo.metaBuildVersion.sbtVersion', null); if (javaVersion) { analytics.add('javaVersion', javaVersion); } if (mvnVersion) { analytics.add('mvnVersion', mvnVersion); } if (sbtVersion) { analytics.add('sbtVersion', sbtVersion); } for (const scannedProject of deps.scannedProjects) { const project = scannedProject; const packageManager = (0, extract_package_manager_1.extractPackageManager)(project, deps, options); const pkg = scannedProject.depGraph ? scannedProject.depGraph : scannedProject.depTree; let depGraph; if (scannedProject.depGraph) { depGraph = scannedProject.depGraph; } else { // Graphs are more compact and robust representations. // Legacy parts of the code are still using trees, but will eventually be fully migrated. debug('converting dep-tree to dep-graph', { name: pkg.name, targetFile: scannedProject.targetFile || options.file, }); depGraph = await depGraphLib.legacy.depTreeToGraph(pkg, packageManager); debug('done converting dep-tree to dep-graph', { uniquePkgsCount: depGraph.getDepPkgs().length, }); } (0, print_deps_1.maybePrintDepGraph)(options, depGraph); depGraph = await (0, prune_1.pruneGraph)(depGraph, packageManager, options.pruneIsRequired); const targetFile = path.relative('.', path.resolve(root, scannedProject.targetFile || options.file || '.')); humanReadableArr.push(`${targetFile}: Found ${depGraph.getPkgs().length} ${depGraph.pkgManager.name} dependencies`); const packageURLToComponent = new Map(); for (const dep of depGraph.getPkgs()) { component(dep, packageURLToComponent, packageManager, targetFile, bom, depGraph); } } } finally { await spinner_1.spinner.clear(spinnerLbl)(); } } const cyclonedxJsonResult = new cdx.Serialize.JsonSerializer(new cdx.Serialize.JSON.Normalize.Factory(cdx.Spec.Spec1dot4)).serialize(bom); return types_1.ClientSbomCommandResult.createClientSbomCommandResult(originalOptions['cyclonedx-json'] ? cyclonedxJsonResult : humanReadableArr.join('\n'), cyclonedxJsonResult); }; /***/ }), /***/ 74970: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); const version_1 = __webpack_require__(38217); async function version() { let version = (0, version_1.getVersion)(); if ((0, version_1.isStandaloneBuild)()) { version += ' (standalone)'; } return version; } exports["default"] = version; /***/ }), /***/ 13490: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); exports.FailedToRunClientSbomError = void 0; const custom_error_1 = __webpack_require__(17188); class FailedToRunClientSbomError extends custom_error_1.CustomError { constructor(userMessage, errorCode) { const code = errorCode || 500; super(userMessage || FailedToRunClientSbomError.ERROR_MESSAGE); this.code = errorCode || code; this.userMessage = userMessage || FailedToRunClientSbomError.ERROR_MESSAGE; } } exports.FailedToRunClientSbomError = FailedToRunClientSbomError; FailedToRunClientSbomError.ERROR_MESSAGE = 'Failed to run client-sbom'; /***/ }) }; ; //# sourceMappingURL=27.index.js.map