Validate current node version (#19154)

* feat(12976): node version validation at runtime.

* refact(12976): move the code into a static utilities class.

* test(12976): added first test case using jest.

* test(12976): added test cases for node_version.

* feat(12976): create setup env node to bootstrap babel, ts-node and node version validator.

* refact(12976): migrated node version code from es6 to es5.

* feat(12976): node version validation at runtime.

* refact(12976): move the code into a static utilities class.

* test(12976): added first test case using jest.

* test(12976): added test cases for node_version.

* feat(12976): create setup env node to bootstrap babel, ts-node and node version validator.

* refact(12976): migrated node version code from es6 to es5.

* fix(12976): remove one level from ts node register cache directory link.

* chore(12976): added caret to semver dependecy in order to support minor versions.

* refact(12976): small change from named import to default import on node version validator.

* refact(12976): removed ts_node_register and add the code to babel_register.

* feat(12976): split eslint config in order to properly support files built to run before and after node version validator. refact(12976): convert script files to es5 code. refact(12976): delete inline eslint configs from node version check related files.

* refact(12976): remove ts node register file.

* refact(12976): completely port setup_node_env to es5.

* refact(12976): remove babel_register invokation from external dependencies in scripts.

* refact(12976): move node_version code directly into node_version_validator inside setup_node_env folder.

* refact(12976): only node version validator for kbn script.
This commit is contained in:
Tiago Costa 2018-05-25 18:43:01 +01:00 committed by GitHub
parent ee041de216
commit 194aba149f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 145 additions and 51 deletions

View file

@ -96,7 +96,7 @@ module.exports = {
},
/**
* files that ARE NOT allowed to use devDepenedncies
* Files that ARE NOT allowed to use devDependencies
*/
{
files: ['packages/kbn-ui-framework/**/*', 'x-pack/**/*'],
@ -112,7 +112,7 @@ module.exports = {
},
/**
* files that ARE allowed to use devDepenedncies
* Files that ARE allowed to use devDependencies
*/
{
files: [
@ -138,7 +138,39 @@ module.exports = {
},
/**
* Files that are not transpiled with babel
* Files that run BEFORE node version check
*/
{
files: ['scripts/**/*', 'src/setup_node_env/**/*'],
rules: {
'import/no-commonjs': 'off',
'prefer-object-spread/prefer-object-spread': 'off',
'no-var': 'off',
'prefer-const': 'off',
'prefer-destructuring': 'off',
'no-restricted-syntax': [
'error',
'ImportDeclaration',
'ExportNamedDeclaration',
'ExportDefaultDeclaration',
'ExportAllDeclaration',
'ArrowFunctionExpression',
'AwaitExpression',
'ClassDeclaration',
'RestElement',
'SpreadElement',
'YieldExpression',
'VariableDeclaration[kind="const"]',
'VariableDeclaration[kind="let"]',
'VariableDeclarator[id.type="ArrayPattern"]',
'VariableDeclarator[id.type="ObjectPattern"]',
],
},
},
/**
* Files that run AFTER node version check
* and are not also transpiled with babel
*/
{
files: [

View file

@ -1,4 +1,4 @@
require('./src/babel-register');
require('./src/setup_node_env');
module.exports = function (grunt) {
// set the config once before calling load-grunt-config

View file

@ -192,7 +192,7 @@
"rison-node": "1.0.0",
"rxjs": "5.4.3",
"script-loader": "0.7.2",
"semver": "5.1.0",
"semver": "^5.5.0",
"style-loader": "0.19.0",
"tar": "2.2.0",
"tinygradient": "0.3.0",

View file

@ -7,7 +7,7 @@ function babelRegister() {
try {
// add support for moved babel-register source: https://github.com/elastic/kibana/pull/13973
require(resolve(plugin.kibanaRoot, 'src/babel-register'));
require(resolve(plugin.kibanaRoot, 'src/setup_node_env/babel_register'));
} catch (error) {
if (error.code === 'MODULE_NOT_FOUND') {
require(resolve(plugin.kibanaRoot, 'src/optimize/babel/register'));

View file

@ -10,7 +10,7 @@ node scripts/{{script name}} --help
This directory is excluded from the build and tools within it should help users discover their capabilities. Each script in this directory must:
- require `src/babel-register` to bootstrap babel
- require `src/setup_node_env` to bootstrap NodeJS environment
- call out to source code in the [`src`](../src) or [`packages`](../packages) directories
- react to the `--help` flag
- run everywhere OR check and fail fast when a required OS or toolchain is not available

View file

@ -1 +1,2 @@
require('../src/setup_node_env/node_version_validator');
require('backport');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/build/cli');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/docs/cli');

View file

@ -1,16 +1,18 @@
const path = require('path');
const pkg = require('../package.json');
const kbnEs = require('@kbn/es');
var resolve = require('path').resolve;
var pkg = require('../package.json');
var kbnEs = require('@kbn/es');
require('../src/setup_node_env');
kbnEs
.run({
license: 'basic',
password: 'changeme',
version: pkg.version,
'source-path': path.resolve(__dirname, '../../elasticsearch'),
'base-path': path.resolve(__dirname, '../.es'),
'source-path': resolve(__dirname, '../../elasticsearch'),
'base-path': resolve(__dirname, '../.es'),
})
.catch(e => {
.catch(function (e) {
console.error(e);
process.exitCode = 1;
});

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/es_archiver/cli');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/run_eslint');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/functional_test_runner/cli');

View file

@ -1,4 +1,4 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../packages/kbn-test').runTestsCli([
require.resolve('../test/functional/config.js'),
require.resolve('../test/api_integration/config.js'),

View file

@ -1,4 +1,4 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../packages/kbn-test').startServersCli(
require.resolve('../test/functional/config.js'),
);

View file

@ -1 +1,2 @@
require('../src/setup_node_env');
require('@kbn/plugin-generator').run(process.argv.slice(2));

View file

@ -10,8 +10,8 @@
//
// See all cli options in https://facebook.github.io/jest/docs/cli.html
const { resolve } = require('path');
var resolve = require('path').resolve;
process.argv.push('--config', resolve(__dirname, '../src/dev/jest/config.js'));
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/jest/cli');

View file

@ -10,8 +10,8 @@
//
// See all cli options in https://facebook.github.io/jest/docs/cli.html
const { resolve } = require('path');
var resolve = require('path').resolve;
process.argv.push('--config', resolve(__dirname, '../src/dev/jest/config.integration.js'));
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/jest/cli');

View file

@ -1,2 +1,3 @@
require('../src/setup_node_env/node_version_validator');
require('../packages/kbn-pm/cli');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/cli/cli');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/cli_keystore');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/cli_plugin/cli');

View file

@ -1 +1,2 @@
require('../src/setup_node_env/node_version_validator');
require('makelogs');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/mocha').runMochaCli();

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/notice/cli');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/run_precommit_hook');

View file

@ -1,2 +1,2 @@
require('../src/babel-register');
require('../src/setup_node_env');
require('../src/dev/tslint').runTslintCli();

View file

@ -10,7 +10,7 @@ program
.version(pkg.version)
.description(
'Kibana is an open source (Apache Licensed), browser ' +
'based analytics and search dashboard for Elasticsearch.'
'based analytics and search dashboard for Elasticsearch.'
);
// attach commands

View file

@ -1,2 +1,2 @@
require('../babel-register');
require('../setup_node_env');
require('./cli');

View file

@ -1,2 +1,2 @@
require('../babel-register');
require('../setup_node_env');
require('./cli_keystore');

View file

@ -1,2 +1,2 @@
require('../babel-register');
require('../setup_node_env');
require('./cli');

View file

@ -8,6 +8,8 @@ export default {
'<rootDir>/src/cli_keystore',
'<rootDir>/src/cli_plugin',
'<rootDir>/src/dev',
'<rootDir>/src/utils',
'<rootDir>/src/setup_node_env',
'<rootDir>/packages',
],
collectCoverageFrom: [

View file

@ -1,4 +1,4 @@
// Note: In theory importing the polyfill should not be needed, as Babel should
// include the necessary polyfills when using `babel-preset-env`, but for some
// reason it did not work. See https://github.com/elastic/kibana/issues/14506
import '../../../babel-register/polyfill';
import '../../../setup_node_env/babel_register/polyfill';

View file

@ -1,2 +1,2 @@
require('../../babel-register');
require('../../setup_node_env');
module.exports = require('./ts_transform.ts');

View file

@ -24,8 +24,8 @@ export function runMochaCli() {
// check that we aren't leaking any globals
process.argv.push('--check-leaks');
// ensure that mocha requires the babel-register script
process.argv.push('--require', require.resolve('../../babel-register'));
// ensure that mocha requires the setup_node_env script
process.argv.push('--require', require.resolve('../../setup_node_env'));
// set default test timeout
if (opts.timeout == null && !opts['no-timeouts']) {

View file

@ -1,5 +1,5 @@
// when the reporter is loaded by mocha in child process it might be before babel-register
require('../../babel-register');
// when the reporter is loaded by mocha in child process it might be before setup_node_env
require('../../setup_node_env');
module.exports = require('./auto_junit_reporter').createAutoJunitReporter({
reportName: 'Server Mocha Tests',

View file

@ -3,7 +3,7 @@ import { spawn } from 'child_process';
import expect from 'expect.js';
const RUN_KBN_SERVER_STARTUP = require.resolve('./fixtures/run_kbn_server_startup');
const BABEL_REGISTER = require.resolve('../../../babel-register');
const SETUP_NODE_ENV = require.resolve('../../../setup_node_env');
const SECOND = 1000;
describe('config/deprecation warnings mixin', function () {
@ -14,7 +14,7 @@ describe('config/deprecation warnings mixin', function () {
before(() => new Promise((resolve, reject) => {
proc = spawn(process.execPath, [
'-r', BABEL_REGISTER,
'-r', SETUP_NODE_ENV,
RUN_KBN_SERVER_STARTUP
], {
stdio: ['ignore', 'pipe', 'pipe'],

View file

@ -1,15 +1,15 @@
// unless we are running a prebuilt/distributable version of
// kibana, automatically transpile typescript to js before babel
if (!global.__BUILT_WITH_BABEL__) {
const { resolve } = require('path');
var resolve = require('path').resolve;
require('ts-node').register({
transpileOnly: true,
cacheDirectory: resolve(__dirname, '../../optimize/.cache/ts-node')
cacheDirectory: resolve(__dirname, '../../../optimize/.cache/ts-node')
});
}
// register and polyfill need to happen in this
// order and in separate files. Checkout each file
// for a much more detailed explaination
// for a much more detailed explanation
require('./register');
require('./polyfill');

View file

@ -7,4 +7,4 @@
//
// This is why we have this single statement in it's own file and require
// it from ./index.js
import 'babel-polyfill';
require('babel-polyfill');

View file

@ -1,13 +1,13 @@
const { resolve } = require('path');
var resolve = require('path').resolve;
// this must happen before `require('babel-register')` and can't be changed
// once the module has been loaded
if (!process.env.BABEL_CACHE_PATH) {
process.env.BABEL_CACHE_PATH = resolve(__dirname, '../../optimize/.babelcache.json');
process.env.BABEL_CACHE_PATH = resolve(__dirname, '../../../optimize/.babelcache.json');
}
// paths that babel-register should ignore
const ignore = [
var ignore = [
/\/bower_components\//,
/\/kbn-pm\/dist\//,
@ -32,7 +32,7 @@ if (global.__BUILT_WITH_BABEL__) {
// We still need babel-register for plugins though, we've been
// building their server code at require-time since version 4.2
// TODO: the plugin install process could transpile plugin server code...
ignore.push(resolve(__dirname, '../../src'));
ignore.push(resolve(__dirname, '../../../src'));
}
// modifies all future calls to require() to automatically

View file

@ -0,0 +1,2 @@
require('./node_version_validator');
require('./babel_register');

View file

@ -0,0 +1,18 @@
var pkg = require('../../package.json');
// Note: This is written in ES5 so we can run this before anything else
// and gives support for older NodeJS versions
var currentVersion = (process && process.version) || null;
var rawRequiredVersion = (pkg && pkg.engines && pkg.engines.node) || null;
var requiredVersion = rawRequiredVersion ? 'v' + rawRequiredVersion : rawRequiredVersion;
var isVersionValid = !!currentVersion && !!requiredVersion && (currentVersion === requiredVersion);
// Validates current the NodeJS version compatibility when Kibana starts.
if (!isVersionValid) {
var errorMessage = 'Kibana does not support the current Node.js version ' + currentVersion
+ '. Please use Node.js ' + requiredVersion + '.';
// Actions to apply when validation fails: error report + exit.
console.error(errorMessage);
process.exit(1);
}

View file

@ -0,0 +1,34 @@
var exec = require('child_process').exec;
var pkg = require('../../package.json');
var REQUIRED_NODE_JS_VERSION = 'v' + pkg.engines.node;
var INVALID_NODE_JS_VERSION = 'v0.10.0';
describe('NodeVersionValidator', function () {
it('should run the script WITH error', function (done) {
var processVersionOverwrite = 'Object.defineProperty(process, \'version\', { value: \''
+ INVALID_NODE_JS_VERSION + '\', writable: true });';
var command = 'node -e "' + processVersionOverwrite + 'require(\'./node_version_validator.js\')"';
exec(command, { cwd: __dirname }, function (error, stdout, stderr) {
expect(error.code).toBe(1);
expect(stderr).toBeDefined();
expect(stderr).not.toHaveLength(0);
done();
});
});
it('should run the script WITHOUT error', function (done) {
var processVersionOverwrite = 'Object.defineProperty(process, \'version\', { value: \''
+ REQUIRED_NODE_JS_VERSION + '\', writable: true });';
var command = 'node -e "' + processVersionOverwrite + 'require(\'./node_version_validator.js\')"';
exec(command, { cwd: __dirname }, function (error, stdout, stderr) {
expect(error).toBeNull();
expect(stderr).toBeDefined();
expect(stderr).toHaveLength(0);
done();
});
});
});