mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[7.x] Add lockfile symlinks (#66211)
This commit is contained in:
parent
daea374908
commit
ded2238fac
24 changed files with 274 additions and 3 deletions
1
packages/elastic-datemath/yarn.lock
Symbolic link
1
packages/elastic-datemath/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-babel-code-parser/yarn.lock
Symbolic link
1
packages/kbn-babel-code-parser/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-babel-preset/yarn.lock
Symbolic link
1
packages/kbn-babel-preset/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-dev-utils/yarn.lock
Symbolic link
1
packages/kbn-dev-utils/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-es/yarn.lock
Symbolic link
1
packages/kbn-es/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-eslint-import-resolver-kibana/yarn.lock
Symbolic link
1
packages/kbn-eslint-import-resolver-kibana/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-eslint-plugin-eslint/yarn.lock
Symbolic link
1
packages/kbn-eslint-plugin-eslint/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-i18n/yarn.lock
Symbolic link
1
packages/kbn-i18n/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-interpreter/yarn.lock
Symbolic link
1
packages/kbn-interpreter/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-plugin-generator/yarn.lock
Symbolic link
1
packages/kbn-plugin-generator/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-plugin-helpers/yarn.lock
Symbolic link
1
packages/kbn-plugin-helpers/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-pm/yarn.lock
Symbolic link
1
packages/kbn-pm/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-spec-to-console/yarn.lock
Symbolic link
1
packages/kbn-spec-to-console/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-storybook/yarn.lock
Symbolic link
1
packages/kbn-storybook/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-test/yarn.lock
Symbolic link
1
packages/kbn-test/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-ui-framework/yarn.lock
Symbolic link
1
packages/kbn-ui-framework/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
1
packages/kbn-utility-types/yarn.lock
Symbolic link
1
packages/kbn-utility-types/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../yarn.lock
|
21
scripts/check_lockfile_symlinks.js
Normal file
21
scripts/check_lockfile_symlinks.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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_lockfile_symlinks');
|
222
src/dev/run_check_lockfile_symlinks.js
Normal file
222
src/dev/run_check_lockfile_symlinks.js
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* 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 { existsSync, lstatSync, readFileSync, readlinkSync } from 'fs';
|
||||
import globby from 'globby';
|
||||
import { dirname } from 'path';
|
||||
|
||||
import { run, createFailError } from '@kbn/dev-utils';
|
||||
|
||||
import { REPO_ROOT } from './constants';
|
||||
import { File } from './file';
|
||||
import { matchesAnyGlob } from './globs';
|
||||
|
||||
const LOCKFILE_GLOBS = ['**/yarn.lock'];
|
||||
const MANIFEST_GLOBS = ['**/package.json'];
|
||||
const IGNORE_FILE_GLOBS = [
|
||||
// tests aren't used in production, ignore them
|
||||
'**/test/**/*',
|
||||
// fixtures aren't used in production, ignore them
|
||||
'**/*fixtures*/**/*',
|
||||
// cypress isn't used in production, ignore it
|
||||
'x-pack/plugins/apm/e2e/*',
|
||||
// apm scripts aren't used in production, ignore them
|
||||
'x-pack/plugins/apm/scripts/*',
|
||||
];
|
||||
|
||||
run(async ({ log }) => {
|
||||
const paths = await globby(LOCKFILE_GLOBS.concat(MANIFEST_GLOBS), {
|
||||
cwd: REPO_ROOT,
|
||||
nodir: true,
|
||||
gitignore: true,
|
||||
ignore: [
|
||||
// the gitignore: true option makes sure that we don't
|
||||
// include files from node_modules in the result, but it still
|
||||
// loads all of the files from node_modules before filtering
|
||||
// so it's still super slow. This prevents loading the files
|
||||
// and still relies on gitignore to to final ignores
|
||||
'**/node_modules',
|
||||
],
|
||||
});
|
||||
|
||||
const files = paths.map(path => new File(path));
|
||||
|
||||
await checkLockfileSymlinks(log, files);
|
||||
});
|
||||
|
||||
async function checkLockfileSymlinks(log, files) {
|
||||
const filtered = files.filter(file => !matchesAnyGlob(file.getRelativePath(), IGNORE_FILE_GLOBS));
|
||||
await checkOnlyLockfileAtProjectRoot(filtered);
|
||||
await checkSuperfluousSymlinks(log, filtered);
|
||||
await checkMissingSymlinks(log, filtered);
|
||||
await checkIncorrectSymlinks(log, filtered);
|
||||
}
|
||||
|
||||
async function checkOnlyLockfileAtProjectRoot(files) {
|
||||
const errorPaths = [];
|
||||
|
||||
files
|
||||
.filter(file => matchesAnyGlob(file.getRelativePath(), LOCKFILE_GLOBS))
|
||||
.forEach(file => {
|
||||
const path = file.getRelativePath();
|
||||
const parent = dirname(path);
|
||||
const stats = lstatSync(path);
|
||||
if (!stats.isSymbolicLink() && parent !== '.') {
|
||||
errorPaths.push(path);
|
||||
}
|
||||
});
|
||||
|
||||
if (errorPaths.length) {
|
||||
throw createFailError(
|
||||
`These directories MUST NOT have a 'yarn.lock' file:\n${listPaths(errorPaths)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkSuperfluousSymlinks(log, files) {
|
||||
const errorPaths = [];
|
||||
|
||||
files
|
||||
.filter(file => matchesAnyGlob(file.getRelativePath(), LOCKFILE_GLOBS))
|
||||
.forEach(file => {
|
||||
const path = file.getRelativePath();
|
||||
const parent = dirname(path);
|
||||
const stats = lstatSync(path);
|
||||
if (!stats.isSymbolicLink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifestPath = `${parent}/package.json`;
|
||||
if (!existsSync(manifestPath)) {
|
||||
log.warning(
|
||||
`No manifest found at '${manifestPath}', but found an adjacent 'yarn.lock' symlink.`
|
||||
);
|
||||
errorPaths.push(path);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const manifest = readFileSync(manifestPath);
|
||||
try {
|
||||
const json = JSON.parse(manifest);
|
||||
if (!json.dependencies || !Object.keys(json.dependencies).length) {
|
||||
log.warning(
|
||||
`Manifest at '${manifestPath}' has an adjacent 'yarn.lock' symlink, but manifest has no dependencies.`
|
||||
);
|
||||
errorPaths.push(path);
|
||||
}
|
||||
} catch (err) {
|
||||
log.warning(
|
||||
`Manifest at '${manifestPath}' has an adjacent 'yarn.lock' symlink, but could not parse manifest JSON (${err.message}).`
|
||||
);
|
||||
errorPaths.push(path);
|
||||
}
|
||||
} catch (err) {
|
||||
log.warning(
|
||||
`Manifest at '${manifestPath}', has an adjacent 'yarn.lock' symlink, but could not read manifest (${err.message}).`
|
||||
);
|
||||
errorPaths.push(path);
|
||||
}
|
||||
});
|
||||
|
||||
if (errorPaths.length) {
|
||||
throw createFailError(
|
||||
`These directories MUST NOT have a 'yarn.lock' symlink:\n${listPaths(errorPaths)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkMissingSymlinks(log, files) {
|
||||
const errorPaths = [];
|
||||
|
||||
files
|
||||
.filter(file => matchesAnyGlob(file.getRelativePath(), MANIFEST_GLOBS))
|
||||
.forEach(file => {
|
||||
const path = file.getRelativePath();
|
||||
const parent = dirname(path);
|
||||
const lockfilePath = `${parent}/yarn.lock`;
|
||||
if (existsSync(lockfilePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const manifest = readFileSync(path);
|
||||
try {
|
||||
const json = JSON.parse(manifest);
|
||||
if (json.dependencies && Object.keys(json.dependencies).length) {
|
||||
const correctSymlink = getCorrectSymlink(lockfilePath);
|
||||
log.warning(
|
||||
`Manifest at '${path}' has dependencies, but did not find an adjacent 'yarn.lock' symlink to '${correctSymlink}'.`
|
||||
);
|
||||
errorPaths.push(`${parent}/yarn.lock`);
|
||||
}
|
||||
} catch (err) {
|
||||
log.warning(`Could not parse manifest JSON at '${path}' (${err.message}).`);
|
||||
}
|
||||
} catch (err) {
|
||||
log.warning(`Could not read manifest at '${path}' (${err.message}).`);
|
||||
}
|
||||
});
|
||||
|
||||
if (errorPaths.length) {
|
||||
throw createFailError(
|
||||
`These directories MUST have a 'yarn.lock' symlink:\n${listPaths(errorPaths)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkIncorrectSymlinks(log, files) {
|
||||
const errorPaths = [];
|
||||
|
||||
files
|
||||
.filter(file => matchesAnyGlob(file.getRelativePath(), LOCKFILE_GLOBS))
|
||||
.forEach(file => {
|
||||
const path = file.getRelativePath();
|
||||
const stats = lstatSync(path);
|
||||
if (!stats.isSymbolicLink()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const symlink = readlinkSync(path);
|
||||
const correctSymlink = getCorrectSymlink(path);
|
||||
if (symlink !== correctSymlink) {
|
||||
log.warning(
|
||||
`Symlink at '${path}' points to '${symlink}', but it should point to '${correctSymlink}'.`
|
||||
);
|
||||
errorPaths.push(path);
|
||||
}
|
||||
});
|
||||
|
||||
if (errorPaths.length) {
|
||||
throw createFailError(
|
||||
`These symlinks do NOT point to the 'yarn.lock' file in the project root:\n${listPaths(
|
||||
errorPaths
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getCorrectSymlink(path) {
|
||||
const count = path.split('/').length - 1;
|
||||
return `${'../'.repeat(count)}yarn.lock`;
|
||||
}
|
||||
|
||||
function listPaths(paths) {
|
||||
return paths.map(path => ` - ${path}`).join('\n');
|
||||
}
|
|
@ -106,6 +106,17 @@ module.exports = function(grunt) {
|
|||
],
|
||||
}),
|
||||
|
||||
// used by the test tasks
|
||||
// runs the check_lockfile_symlinks script to ensure manifests with non-dev dependencies have adjacent lockfile symlinks
|
||||
checkLockfileSymlinks: scriptWithGithubChecks({
|
||||
title: 'Check lockfile symlinks',
|
||||
cmd: NODE,
|
||||
args: [
|
||||
'scripts/check_lockfile_symlinks',
|
||||
'--quiet', // only log errors, not warnings
|
||||
],
|
||||
}),
|
||||
|
||||
// used by the test tasks
|
||||
// runs the check_published_api_changes script to ensure API changes are explictily accepted
|
||||
checkDocApiChanges: scriptWithGithubChecks({
|
||||
|
|
|
@ -28,6 +28,7 @@ module.exports = function(grunt) {
|
|||
'run:typeCheck',
|
||||
'run:i18nCheck',
|
||||
'run:checkFileCasing',
|
||||
'run:checkLockfileSymlinks',
|
||||
'run:licenses',
|
||||
'run:verifyDependencyVersions',
|
||||
'run:verifyNotice',
|
||||
|
|
3
x-pack/.gitignore
vendored
3
x-pack/.gitignore
vendored
|
@ -13,6 +13,3 @@
|
|||
!/legacy/plugins/infra/**/target
|
||||
.cache
|
||||
!/legacy/plugins/siem/**/target
|
||||
|
||||
# We don't want any yarn.lock files in here
|
||||
/yarn.lock
|
||||
|
|
1
x-pack/plugins/endpoint/yarn.lock
Symbolic link
1
x-pack/plugins/endpoint/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../yarn.lock
|
1
x-pack/yarn.lock
Symbolic link
1
x-pack/yarn.lock
Symbolic link
|
@ -0,0 +1 @@
|
|||
../yarn.lock
|
Loading…
Add table
Add a link
Reference in a new issue