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
});
}