From ba263570437393c1c8f9c51f28ab59b4c88e953a Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 30 Sep 2020 11:12:46 -0700 Subject: [PATCH] move validation to bootstrap (#13) Co-authored-by: spalger --- packages/kbn-pm/dist/index.js | 51 +++++++++ .../kbn-pm/src/utils/validate_yarn_lock.ts | 61 ++++++++++ scripts/check_single_version_dependencies.js | 21 ---- .../run_check_single_version_dependencies.ts | 105 ------------------ .../checks/single_version_dependencies.sh | 7 -- vars/tasks.groovy | 1 - 6 files changed, 112 insertions(+), 134 deletions(-) delete mode 100644 scripts/check_single_version_dependencies.js delete mode 100644 src/dev/run_check_single_version_dependencies.ts delete mode 100644 test/scripts/checks/single_version_dependencies.sh diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 8d88d4fc8bc95..e807975607a51 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -37906,6 +37906,57 @@ async function validateYarnLock(kbn, yarnLock) { `); process.exit(1); + } // look through all the package.json files to find packages which have mismatched version ranges + + + const depRanges = new Map(); + + for (const project of kbn.getAllProjects().values()) { + for (const [dep, range] of Object.entries(project.allDependencies)) { + const existingDep = depRanges.get(dep); + + if (!existingDep) { + depRanges.set(dep, [{ + range, + projects: [project] + }]); + continue; + } + + const existingRange = existingDep.find(existing => existing.range === range); + + if (!existingRange) { + existingDep.push({ + range, + projects: [project] + }); + continue; + } + + existingRange.projects.push(project); + } + } + + const duplicateRanges = Array.from(depRanges.entries()).filter(([, ranges]) => ranges.length > 1).reduce((acc, [dep, ranges]) => [...acc, dep, ...ranges.map(({ + range, + projects + }) => ` ${range} => ${projects.map(p => p.name).join(', ')}`)], []).join('\n '); + + if (duplicateRanges) { + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` + + [single_version_dependencies] Multiple version ranges for the same dependency + were found declared across different package.json files. Please consolidate + those to match across all package.json files. Different versions for the + same dependency is not supported. + + If you have questions about this please reach out to the operations team. + + The conflicting dependencies are: + + ${duplicateRanges} + `); + process.exit(1); } _log__WEBPACK_IMPORTED_MODULE_3__["log"].success('yarn.lock analysis completed without any issues'); diff --git a/packages/kbn-pm/src/utils/validate_yarn_lock.ts b/packages/kbn-pm/src/utils/validate_yarn_lock.ts index e110dc4d921cf..ed03682ee7539 100644 --- a/packages/kbn-pm/src/utils/validate_yarn_lock.ts +++ b/packages/kbn-pm/src/utils/validate_yarn_lock.ts @@ -25,6 +25,7 @@ import { writeFile } from './fs'; import { Kibana } from './kibana'; import { YarnLock } from './yarn_lock'; import { log } from './log'; +import { Project } from './project'; export async function validateYarnLock(kbn: Kibana, yarnLock: YarnLock) { // look through all of the packages in the yarn.lock file to see if @@ -95,5 +96,65 @@ export async function validateYarnLock(kbn: Kibana, yarnLock: YarnLock) { process.exit(1); } + // look through all the package.json files to find packages which have mismatched version ranges + const depRanges = new Map>(); + for (const project of kbn.getAllProjects().values()) { + for (const [dep, range] of Object.entries(project.allDependencies)) { + const existingDep = depRanges.get(dep); + if (!existingDep) { + depRanges.set(dep, [ + { + range, + projects: [project], + }, + ]); + continue; + } + + const existingRange = existingDep.find((existing) => existing.range === range); + if (!existingRange) { + existingDep.push({ + range, + projects: [project], + }); + continue; + } + + existingRange.projects.push(project); + } + } + + const duplicateRanges = Array.from(depRanges.entries()) + .filter(([, ranges]) => ranges.length > 1) + .reduce( + (acc: string[], [dep, ranges]) => [ + ...acc, + dep, + ...ranges.map( + ({ range, projects }) => ` ${range} => ${projects.map((p) => p.name).join(', ')}` + ), + ], + [] + ) + .join('\n '); + + if (duplicateRanges) { + log.error(dedent` + + [single_version_dependencies] Multiple version ranges for the same dependency + were found declared across different package.json files. Please consolidate + those to match across all package.json files. Different versions for the + same dependency is not supported. + + If you have questions about this please reach out to the operations team. + + The conflicting dependencies are: + + ${duplicateRanges} + `); + + process.exit(1); + } + log.success('yarn.lock analysis completed without any issues'); } diff --git a/scripts/check_single_version_dependencies.js b/scripts/check_single_version_dependencies.js deleted file mode 100644 index 340d9308da343..0000000000000 --- a/scripts/check_single_version_dependencies.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -require('../src/setup_node_env'); -require('../src/dev/run_check_single_version_dependencies'); diff --git a/src/dev/run_check_single_version_dependencies.ts b/src/dev/run_check_single_version_dependencies.ts deleted file mode 100644 index c9de59db3cd77..0000000000000 --- a/src/dev/run_check_single_version_dependencies.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import dedent from 'dedent'; -import globby from 'globby'; -import { readFileSync } from 'fs'; -import { createFailError, run } from '@kbn/dev-utils'; - -function addPackage( - parsedDependencies: { [key: string]: Array<{ path: string; version: string }> }, - name: string, - version: string, - packagePath: string -) { - if (version.match(/link:/)) return; - - if (!parsedDependencies[name]) { - parsedDependencies[name] = []; - } - - parsedDependencies[name].push({ - path: packagePath, - version, - }); -} - -function checkPackages( - parsedDependencies: { [key: string]: Array<{ path: string; version: string }> }, - packages: { [key: string]: string }, - packagePath: string -) { - if (!packages) return; - - for (const [name, version] of Object.entries(packages)) { - addPackage(parsedDependencies, name, version, packagePath); - } -} - -run(async ({ log }) => { - const packagePaths = await globby(['**/package.json'], { gitignore: true }); - const parsedDependencies: { [key: string]: Array<{ path: string; version: string }> } = {}; - - packagePaths.forEach((packagePath) => { - try { - const pkg = JSON.parse(readFileSync(packagePath).toString()); - - checkPackages(parsedDependencies, pkg.dependencies, packagePath); - checkPackages(parsedDependencies, pkg.devDependencies, packagePath); - } catch (e) { - throw createFailError(`failed to parse ${packagePath}`, e.message); - } - }); - - const dependenciesWithMultipleVersions = Object.keys(parsedDependencies).reduce( - (errStr, name) => { - const dependency = parsedDependencies[name]; - const unique = [...new Set(dependency.map((d) => d.version))]; - - if (unique.length > 1) { - errStr = errStr + `${name} (${unique.join(',')})\n`; - dependency.forEach((d) => (errStr = errStr + ` - ${d.path}@${d.version}\n`)); - } - return errStr; - }, - '' - ); - - if (dependenciesWithMultipleVersions) { - throw createFailError( - dedent(` - - [single_version_dependencies] Multiple versions for the same dependency - were found declared across different package.json files. Please consolidate - those into the same version as declaring different versions for the - same dependency is not supported. - - If you have questions about this please reach out to the operations team. - - The conflicting dependencies are: - - ${dependenciesWithMultipleVersions} - `) - ); - } - - log.success( - '[single_version_dependencies] dependency versions are consistent across the entire project.' - ); -}); diff --git a/test/scripts/checks/single_version_dependencies.sh b/test/scripts/checks/single_version_dependencies.sh deleted file mode 100644 index f4234cd246b56..0000000000000 --- a/test/scripts/checks/single_version_dependencies.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -checks-reporter-with-killswitch "Check single version dependencies" \ - node scripts/check_single_version_dependencies \ - --quiet diff --git a/vars/tasks.groovy b/vars/tasks.groovy index d12b70ba2345e..edd2c0aa47401 100644 --- a/vars/tasks.groovy +++ b/vars/tasks.groovy @@ -12,7 +12,6 @@ def check() { kibanaPipeline.scriptTask('Check File Casing', 'test/scripts/checks/file_casing.sh'), kibanaPipeline.scriptTask('Check Lockfile Symlinks', 'test/scripts/checks/lock_file_symlinks.sh'), kibanaPipeline.scriptTask('Check Licenses', 'test/scripts/checks/licenses.sh'), - kibanaPipeline.scriptTask('Check Single Version Dependencies', 'test/scripts/checks/single_version_dependencies.sh'), kibanaPipeline.scriptTask('Verify Dependency Versions', 'test/scripts/checks/verify_dependency_versions.sh'), kibanaPipeline.scriptTask('Verify NOTICE', 'test/scripts/checks/verify_notice.sh'), kibanaPipeline.scriptTask('Test Projects', 'test/scripts/checks/test_projects.sh'),