Skip to content

Commit

Permalink
eclipse-theiaGH-934: Aligned the version of the third-party dependenc…
Browse files Browse the repository at this point in the history
…ies.

It is a must for the bundled electron application.
Otherwise, these two dependencies won't be hoisted into
the root `node_modules` folder.
Instead, they will stay in `node_modules/@theia/core/node_modules`,
and will not make into the bundled electron application.

Added a `prepare` script to check the hoisted dependencies.

Closes: eclipse-theia#934.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
  • Loading branch information
Akos Kitta authored and kittaakos committed Oct 23, 2018
1 parent 3c31f27 commit c9e7656
Show file tree
Hide file tree
Showing 11 changed files with 402 additions and 235 deletions.
2 changes: 1 addition & 1 deletion dev-packages/application-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"source-map-loader": "^0.2.1",
"source-map-support": "^0.4.18",
"umd-compat-loader": "^2.1.1",
"url-loader": "^1.0.1",
"url-loader": "^1.1.2",
"webpack": "^4.0.0",
"webpack-cli": "2.0.12",
"worker-loader": "^1.1.1"
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
"chai": "^4.1.0",
"chai-string": "^1.4.0",
"concurrently": "^3.5.0",
"cross-env": "^5.2.0",
"electron-mocha": "~3.5.0",
"ignore-styles": "^5.0.1",
"istanbul": "^0.4.5",
"istanbul-instrumenter-loader": "^3.0.0",
"istanbul-instrumenter-loader": "^3.0.1",
"jsdom": "^11.5.1",
"lerna": "^2.2.0",
"mocha": "^3.4.2",
Expand All @@ -46,8 +47,9 @@
"webdriverio": "4.9.2"
},
"scripts": {
"prepare": "yarn prepare:travis && yarn rebuild:clean && yarn build:clean",
"prepare": "yarn prepare:travis && yarn prepare:hoisting && yarn rebuild:clean && yarn build:clean",
"prepare:travis": "node scripts/prepare-travis",
"prepare:hoisting": "node scripts/check-hoisting",
"build": "run build",
"build:clean": "run prepare",
"docs": "run docs \"@theia/!(example-)*\"",
Expand Down
10 changes: 5 additions & 5 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"@types/react-dom": "^16.0.6",
"@types/react-virtualized": "^9.18.3",
"@types/route-parser": "^0.1.1",
"@types/ws": "^3.0.2",
"@types/yargs": "^8.0.2",
"ajv": "^5.2.2",
"@types/ws": "^5.1.2",
"@types/yargs": "^11.1.0",
"ajv": "^6.5.3",
"body-parser": "^1.17.2",
"electron": "1.8.2-beta.5",
"es6-promise": "^4.2.4",
Expand All @@ -40,8 +40,8 @@
"vscode-nsfw": "^1.0.17",
"vscode-uri": "^1.0.1",
"vscode-ws-jsonrpc": "^0.0.2-1",
"ws": "^3.0.0",
"yargs": "^9.0.1"
"ws": "^5.2.2",
"yargs": "^11.1.0"
},
"publishConfig": {
"access": "public"
Expand Down
12 changes: 7 additions & 5 deletions packages/keymaps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"@theia/userstorage": "^0.3.15",
"@theia/workspace": "^0.3.15",
"@types/lodash.debounce": "4.0.3",
"ajv": "^5.2.2",
"ajv": "^6.5.3",
"fuzzy": "^0.1.3",
"jsonc-parser": "^1.0.1",
"jsonc-parser": "^2.0.2",
"lodash.debounce": "^4.0.8"
},
"devDependencies": {
Expand All @@ -21,9 +21,11 @@
"publishConfig": {
"access": "public"
},
"theiaExtensions": [{
"frontend": "lib/browser/keymaps-frontend-module"
}],
"theiaExtensions": [
{
"frontend": "lib/browser/keymaps-frontend-module"
}
],
"keywords": [
"theia-extension"
],
Expand Down
25 changes: 24 additions & 1 deletion packages/keymaps/src/browser/keymaps-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class KeymapsParser {
const bindings = parser.parse(strippedContent, parsingErrors);
if (parsingErrors && errors) {
for (const error of parsingErrors) {
errors.push(`${parser.ParseErrorCode[error.error]} at ${error.offset} offset of ${error.length} length`);
errors.push(`${this.printParseErrorCode(error.error)} at ${error.offset} offset of ${error.length} length`);
}
}
if (this.validate(bindings)) {
Expand All @@ -72,4 +72,27 @@ export class KeymapsParser {
return [];
}

// https://github.com/Microsoft/node-jsonc-parser/issues/13
protected printParseErrorCode(code: number | undefined) {
switch (code) {
case parser.ParseErrorCode.InvalidSymbol: return 'InvalidSymbol';
case parser.ParseErrorCode.InvalidNumberFormat: return 'InvalidNumberFormat';
case parser.ParseErrorCode.PropertyNameExpected: return 'PropertyNameExpected';
case parser.ParseErrorCode.ValueExpected: return 'ValueExpected';
case parser.ParseErrorCode.ColonExpected: return 'ColonExpected';
case parser.ParseErrorCode.CommaExpected: return 'CommaExpected';
case parser.ParseErrorCode.CloseBraceExpected: return 'CloseBraceExpected';
case parser.ParseErrorCode.CloseBracketExpected: return 'CloseBracketExpected';
case parser.ParseErrorCode.EndOfFileExpected: return 'EndOfFileExpected';
case parser.ParseErrorCode.InvalidCommentToken: return 'InvalidCommentToken';
case parser.ParseErrorCode.UnexpectedEndOfComment: return 'UnexpectedEndOfComment';
case parser.ParseErrorCode.UnexpectedEndOfString: return 'UnexpectedEndOfString';
case parser.ParseErrorCode.UnexpectedEndOfNumber: return 'UnexpectedEndOfNumber';
case parser.ParseErrorCode.InvalidUnicode: return 'InvalidUnicode';
case parser.ParseErrorCode.InvalidEscapeCharacter: return 'InvalidEscapeCharacter';
case parser.ParseErrorCode.InvalidCharacter: return 'InvalidCharacter';
}
return '<unknown ParseErrorCode>';
}

}
2 changes: 1 addition & 1 deletion packages/preferences/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@theia/workspace": "^0.3.15",
"@types/fs-extra": "^4.0.2",
"fs-extra": "^4.0.2",
"jsonc-parser": "^1.0.1"
"jsonc-parser": "^2.0.2"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 1 addition & 1 deletion packages/process/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dependencies": {
"@theia/core": "^0.3.15",
"node-pty": "0.7.6",
"string-argv": "0.0.2"
"string-argv": "^0.1.1"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 1 addition & 1 deletion packages/task/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@theia/terminal": "^0.3.15",
"@theia/variable-resolver": "^0.3.15",
"@theia/workspace": "^0.3.15",
"jsonc-parser": "^1.0.1"
"jsonc-parser": "^2.0.2"
},
"publishConfig": {
"access": "public"
Expand Down
14 changes: 8 additions & 6 deletions packages/workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@
"@theia/filesystem": "^0.3.15",
"@theia/variable-resolver": "^0.3.15",
"@types/fs-extra": "^4.0.2",
"ajv": "^6.5.4",
"ajv": "^6.5.3",
"fs-extra": "^4.0.2",
"jsonc-parser": "^1.0.1",
"jsonc-parser": "^2.0.2",
"moment": "^2.21.0",
"valid-filename": "^2.0.1"
},
"publishConfig": {
"access": "public"
},
"theiaExtensions": [{
"frontend": "lib/browser/workspace-frontend-module",
"backend": "lib/node/workspace-backend-module"
}],
"theiaExtensions": [
{
"frontend": "lib/browser/workspace-frontend-module",
"backend": "lib/node/workspace-backend-module"
}
],
"keywords": [
"theia-extension"
],
Expand Down
145 changes: 145 additions & 0 deletions scripts/check-hoisting
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/usr/bin/env node
/********************************************************************************
* Copyright (c) 2018 TypeFox and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
// @ts-check

const fs = require('fs');
const path = require('path');

/**
* This scrip makes sure all the dependencies are hoisted into the root `node_modules` after running `yarn`.
* - https://github.com/theia-ide/theia/pull/2994#issuecomment-425447650
* - https://github.com/theia-ide/theia/pull/2994#issuecomment-425649817
*
* If you do not want to bail the execution, set the `THEIA_CHECK_HOISTING_NO_BAIL` environment variable to `true`. Use `cross-env`.
* ```json
* ...
* "scripts": {
* ...,
* "prepare:hoisting": "cross-env THEIA_CHECK_HOISTING_NO_BAIL=true node scripts/check-hoisting",
* ...
* }
* ...
* ```
*/

(() => {

function collectIssues() {

console.log('🔍 Analyzing hoisted dependencies in the Theia extensions:');
const root = path.join(__dirname, '..');
const rootNodeModules = path.join(root, 'node_modules');
const packages = path.join(root, 'packages');

const issues = new Map();
for (const extension of fs.readdirSync(packages)) {
console.log(` - Checking @theia/${extension}...`);
const extensionPath = path.join(packages, extension);
const nodeModulesPath = path.join(extensionPath, 'node_modules');
if (fs.existsSync(nodeModulesPath)) {
for (const dependency of fs.readdirSync(nodeModulesPath).filter(name => name !== '.bin')) {
const dependencyPath = path.join(nodeModulesPath, dependency);
const version = versionOf(dependencyPath);
let message = `Dependency '${dependency}' ${version ? `[${version}] ` : ''}was not hoisted to the root 'node_modules' folder.`;
const existingDependency = path.join(rootNodeModules, dependency);
if (fs.existsSync(existingDependency)) {
const otherVersion = versionOf(existingDependency);
if (otherVersion) {
message += ` The same dependency already exists with version ${otherVersion} at '${existingDependency}'.`;
}
}
error(issues, extension, message);
}
} else {
warn(issues, extension, "Does not have 'node_modules' folder.");
}
}
return issues;
}

function versionOf(npmPackagePath) {
const packageJsonPath = path.join(npmPackagePath, 'package.json');
if (fs.existsSync(packageJsonPath)) {
return require(packageJsonPath).version || '';
}
return '';
}

function warn(issues, extension, message) {
return log(issues, extension, message, 'warn');
}

function error(issues, extension, message) {
return log(issues, extension, message, 'error');
}

function log(issues, extension, message, type) {
const key = `@theia/${extension}`;
if (!issues.has(key)) {
issues.set(key, []);
}
const severity = toSeverity(type);
issues.get(key).push({ severity, message });
return issues;
}

function toSeverity(type) {
switch (type) {
case 'error': return 0;
case 'warn': return 1;
default: throw new Error(`Unexpected type: ${type}.`);
}
}

function toType(severity) {
switch (severity) {
case 0: return 'error';
case 1: return 'warning';
default: throw new Error(`Unexpected severity: ${severity}.`);
}
}

function assert(issues) {
console.log('📖 Summary:');
let code = 0;
if (issues && issues.length > 0) {
for (const extension of issues.keys()) {
const issuesPerExtension = issues.get(extension).sort((left, right) => left.severity - right.severity);
if (issuesPerExtension) {
console.log(`The following dependency issues were detected in '${extension}':`);
for (const { severity, message } of issuesPerExtension) {
const type = toType(severity);
console.log(` - ${type}: ${message}`);
if (type === 'error') {
code = 1;
}
}
}
}
} else {
console.log('🎉 No dependency issues were detected.');
}
if (code !== 0 && process.env.THEIA_CHECK_HOISTING_NO_BAIL === 'true') {
console.log("⚠️ 'THEIA_CHECK_HOISTING_NO_BAIL' was 'true'. This is a kind reminder to fix the dependency issues.");
process.exit(0);
}
process.exit(code);
}

assert(collectIssues());

})();
Loading

0 comments on commit c9e7656

Please sign in to comment.