From dab0aade1d0de8a1394975e249db636070b4b9b8 Mon Sep 17 00:00:00 2001 From: Simon Graband Date: Fri, 14 Jul 2023 11:43:16 +0200 Subject: [PATCH] cli: Add `check:theia-extensions` command (#12596) This allows to check for duplicate versions of theia extensions only. Added the option `only-theia-extensions` to `theia check:dependencies`. Theia extensions are identified via their `theiaExtensions` field in the `package.json`. The check is running recursively as long as it finds Theia extensions. The advantage of this approach is that a shorter, but more important, list is returned. Contributed on behalf of STMicroelectronics --- CHANGELOG.md | 1 + dev-packages/cli/src/check-dependencies.ts | 28 +++++++++++++--- dev-packages/cli/src/theia.ts | 37 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 219b55851a171..665dc4ceedc62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ## v1.40.0 - - Show command shortcuts in toolbar item tooltips. #12660 (https://github.com/eclipse-theia/theia/pull/12660) - Contributed on behalf of STMicroelectronics +- [cli] added `check:theia-extensions` which checks the uniqueness of Theia extension versions [#12596](https://github.com/eclipse-theia/theia/pull/12596) - Contributed on behalf of STMicroelectronics [Breaking Changes:](#breaking_changes_1.40.0) diff --git a/dev-packages/cli/src/check-dependencies.ts b/dev-packages/cli/src/check-dependencies.ts index 426ba004de97e..bccdd7c1d4752 100644 --- a/dev-packages/cli/src/check-dependencies.ts +++ b/dev-packages/cli/src/check-dependencies.ts @@ -32,6 +32,7 @@ interface CheckDependenciesOptions { skipHoisted: boolean, skipUniqueness: boolean, skipSingleTheiaVersion: boolean, + onlyTheiaExtensions: boolean, suppress: boolean } @@ -46,7 +47,9 @@ interface Package { /** Whether the package is hoisted or not, i.e., whether it is contained in the root `node_modules`. */ hoisted: boolean, /** Workspace location in which the package was found. */ - dependent: string | undefined + dependent: string | undefined, + /** Whether the package is a Theia extension or not */ + isTheiaExtension?: boolean, } /** Issue found with a specific package. */ @@ -122,9 +125,14 @@ function findDependencies(workspace: string, options: CheckDependenciesOptions): `[^@]*/*/**/${PACKAGE_JSON}`, // package.json that isn't at the package root (and not in an @org) `@*/*/*/**/${PACKAGE_JSON}`, // package.json that isn't at the package root (and in an @org) ...options.exclude] // user-specified exclude patterns - }).forEach(packageJson => - matchingPackageJsons.push(toDependency(packageJson, nodeModulesDir, dependent)) - ) + }).forEach(packageJsonPath => { + const dependency = toDependency(packageJsonPath, nodeModulesDir, dependent); + if (!options.onlyTheiaExtensions || dependency.isTheiaExtension) { + matchingPackageJsons.push(dependency); + } + const childNodeModules: string = path.join(nodeModulesDir, packageJsonPath, '..'); + matchingPackageJsons.push(...findDependencies(childNodeModules, options)); + }) ); return matchingPackageJsons; } @@ -138,7 +146,8 @@ function toDependency(packageJsonPath: string, nodeModulesDir: string, dependent version: version ?? 'unknown', path: path.relative(process.cwd(), fullPackageJsonPath), hoisted: nodeModulesDir === NODE_MODULES, - dependent: dependent + dependent: dependent, + isTheiaExtension: isTheiaExtension(fullPackageJsonPath) }; } @@ -158,6 +167,15 @@ function getPackageName(fullPackageJsonPath: string): string | undefined { } } +function isTheiaExtension(fullPackageJsonPath: string): boolean { + try { + const theiaExtension = require(fullPackageJsonPath).theiaExtensions; + return theiaExtension ? true : false; + } catch (error) { + return false; + } +} + function analyzeDependencies(packages: Package[], options: CheckDependenciesOptions): DependencyIssue[] { const issues: DependencyIssue[] = []; if (!options.skipHoisted) { diff --git a/dev-packages/cli/src/theia.ts b/dev-packages/cli/src/theia.ts index 416707f073d54..41acf9d6e09e4 100644 --- a/dev-packages/cli/src/theia.ts +++ b/dev-packages/cli/src/theia.ts @@ -201,6 +201,7 @@ async function theiaCli(): Promise { skipHoisted: false, skipUniqueness: true, skipSingleTheiaVersion: true, + onlyTheiaExtensions: false, suppress }); } @@ -226,6 +227,33 @@ async function theiaCli(): Promise { skipHoisted: true, skipUniqueness: false, skipSingleTheiaVersion: false, + onlyTheiaExtensions: false, + suppress + }); + } + }) + .command<{ + suppress: boolean + }>({ + command: 'check:theia-extensions', + describe: 'Check uniqueness of Theia extension versions or whether they are hoisted', + builder: { + 'suppress': { + alias: 's', + describe: 'Suppress exiting with failure code', + boolean: true, + default: false + } + }, + handler: ({ suppress }) => { + checkDependencies({ + workspaces: undefined, + include: ['**'], + exclude: [], + skipHoisted: true, + skipUniqueness: false, + skipSingleTheiaVersion: true, + onlyTheiaExtensions: true, suppress }); } @@ -237,6 +265,7 @@ async function theiaCli(): Promise { skipHoisted: boolean, skipUniqueness: boolean, skipSingleTheiaVersion: boolean, + onlyTheiaExtensions: boolean, suppress: boolean }>({ command: 'check:dependencies', @@ -280,6 +309,12 @@ async function theiaCli(): Promise { boolean: true, default: false }, + 'only-theia-extensions': { + alias: 'o', + describe: 'Only check dependencies which are Theia extensions', + boolean: true, + default: false + }, 'suppress': { alias: 's', describe: 'Suppress exiting with failure code', @@ -294,6 +329,7 @@ async function theiaCli(): Promise { skipHoisted, skipUniqueness, skipSingleTheiaVersion, + onlyTheiaExtensions, suppress }) => { checkDependencies({ @@ -303,6 +339,7 @@ async function theiaCli(): Promise { skipHoisted, skipUniqueness, skipSingleTheiaVersion, + onlyTheiaExtensions, suppress }); }