@theia/plugin-ext 1.27.0-next.77 → 1.27.0-next.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/plugin-protocol.d.ts +9 -4
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +7 -6
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +8 -5
- package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.js +55 -16
- package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.js +1 -0
- package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
- package/lib/main/node/plugin-deployer-impl.d.ts +7 -7
- package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-impl.js +15 -13
- package/lib/main/node/plugin-deployer-impl.js.map +1 -1
- package/lib/main/node/plugin-server-handler.d.ts +3 -3
- package/lib/main/node/plugin-server-handler.d.ts.map +1 -1
- package/lib/main/node/plugin-server-handler.js +9 -5
- package/lib/main/node/plugin-server-handler.js.map +1 -1
- package/lib/main/node/plugin-uninstallation-manager.d.ts +5 -2
- package/lib/main/node/plugin-uninstallation-manager.d.ts.map +1 -1
- package/lib/main/node/plugin-uninstallation-manager.js +25 -6
- package/lib/main/node/plugin-uninstallation-manager.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +5 -9
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/package.json +24 -24
- package/src/common/plugin-protocol.ts +10 -4
- package/src/hosted/browser/hosted-plugin.ts +7 -6
- package/src/hosted/node/hosted-plugin-deployer-handler.ts +55 -18
- package/src/main/node/handlers/plugin-theia-file-handler.ts +1 -0
- package/src/main/node/plugin-deployer-impl.ts +17 -15
- package/src/main/node/plugin-server-handler.ts +10 -6
- package/src/main/node/plugin-uninstallation-manager.ts +20 -6
- package/src/plugin/plugin-manager.ts +5 -9
|
@@ -46,7 +46,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
46
46
|
protected readonly uninstallationManager: PluginUninstallationManager;
|
|
47
47
|
|
|
48
48
|
private readonly deployedLocations = new Map<PluginIdentifiers.VersionedId, Set<string>>();
|
|
49
|
-
protected readonly
|
|
49
|
+
protected readonly sourceLocations = new Map<PluginIdentifiers.VersionedId, Set<string>>();
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Managed plugin metadata backend entries.
|
|
@@ -80,7 +80,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
80
80
|
const matches: DeployedPlugin[] = [];
|
|
81
81
|
const handle = (plugins: Iterable<DeployedPlugin>): void => {
|
|
82
82
|
for (const plugin of plugins) {
|
|
83
|
-
if (PluginIdentifiers.componentsToVersionWithId(plugin.metadata.model).
|
|
83
|
+
if (PluginIdentifiers.componentsToVersionWithId(plugin.metadata.model).id === pluginId) {
|
|
84
84
|
matches.push(plugin);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -117,28 +117,33 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
async deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<
|
|
120
|
+
async deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<number> {
|
|
121
|
+
let successes = 0;
|
|
121
122
|
for (const plugin of frontendPlugins) {
|
|
122
|
-
await this.deployPlugin(plugin, 'frontend')
|
|
123
|
+
if (await this.deployPlugin(plugin, 'frontend')) { successes++; }
|
|
123
124
|
}
|
|
124
125
|
// resolve on first deploy
|
|
125
126
|
this.frontendPluginsMetadataDeferred.resolve(undefined);
|
|
127
|
+
return successes;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
async deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<
|
|
130
|
+
async deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<number> {
|
|
131
|
+
let successes = 0;
|
|
129
132
|
for (const plugin of backendPlugins) {
|
|
130
|
-
await this.deployPlugin(plugin, 'backend')
|
|
133
|
+
if (await this.deployPlugin(plugin, 'backend')) { successes++; }
|
|
131
134
|
}
|
|
132
135
|
// rebuild translation config after deployment
|
|
133
136
|
this.localizationService.buildTranslationConfig([...this.deployedBackendPlugins.values()]);
|
|
134
137
|
// resolve on first deploy
|
|
135
138
|
this.backendPluginsMetadataDeferred.resolve(undefined);
|
|
139
|
+
return successes;
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
/**
|
|
139
|
-
* @throws never! in order to isolate plugin deployment
|
|
143
|
+
* @throws never! in order to isolate plugin deployment.
|
|
144
|
+
* @returns whether the plugin is deployed after running this function. If the plugin was already installed, will still return `true`.
|
|
140
145
|
*/
|
|
141
|
-
protected async deployPlugin(entry: PluginDeployerEntry, entryPoint: keyof PluginEntryPoint): Promise<
|
|
146
|
+
protected async deployPlugin(entry: PluginDeployerEntry, entryPoint: keyof PluginEntryPoint): Promise<boolean> {
|
|
142
147
|
const pluginPath = entry.path();
|
|
143
148
|
const deployPlugin = this.stopwatch.start('deployPlugin');
|
|
144
149
|
let id;
|
|
@@ -147,7 +152,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
147
152
|
const manifest = await this.reader.readPackage(pluginPath);
|
|
148
153
|
if (!manifest) {
|
|
149
154
|
deployPlugin.error(`Failed to read ${entryPoint} plugin manifest from '${pluginPath}''`);
|
|
150
|
-
return;
|
|
155
|
+
return success = false;
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
const metadata = this.reader.readMetadata(manifest);
|
|
@@ -155,15 +160,15 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
155
160
|
|
|
156
161
|
id = PluginIdentifiers.componentsToVersionedId(metadata.model);
|
|
157
162
|
|
|
158
|
-
const deployedLocations = this.deployedLocations.get(id)
|
|
163
|
+
const deployedLocations = this.deployedLocations.get(id) ?? new Set<string>();
|
|
159
164
|
deployedLocations.add(entry.rootPath);
|
|
160
165
|
this.deployedLocations.set(id, deployedLocations);
|
|
161
|
-
this.
|
|
166
|
+
this.setSourceLocationsForPlugin(id, entry);
|
|
162
167
|
|
|
163
168
|
const deployedPlugins = entryPoint === 'backend' ? this.deployedBackendPlugins : this.deployedFrontendPlugins;
|
|
164
169
|
if (deployedPlugins.has(id)) {
|
|
165
170
|
deployPlugin.debug(`Skipped ${entryPoint} plugin ${metadata.model.name} already deployed`);
|
|
166
|
-
return;
|
|
171
|
+
return true;
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
const { type } = entry;
|
|
@@ -173,23 +178,25 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
173
178
|
deployedPlugins.set(id, deployed);
|
|
174
179
|
deployPlugin.log(`Deployed ${entryPoint} plugin "${id}" from "${metadata.model.entryPoint[entryPoint] || pluginPath}"`);
|
|
175
180
|
} catch (e) {
|
|
176
|
-
success = false;
|
|
177
181
|
deployPlugin.error(`Failed to deploy ${entryPoint} plugin from '${pluginPath}' path`, e);
|
|
182
|
+
return success = false;
|
|
178
183
|
} finally {
|
|
179
184
|
if (success && id) {
|
|
180
|
-
this.
|
|
185
|
+
this.markAsInstalled(id);
|
|
181
186
|
}
|
|
182
187
|
}
|
|
188
|
+
return success;
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
async uninstallPlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
|
|
186
192
|
try {
|
|
187
|
-
const
|
|
188
|
-
if (!
|
|
193
|
+
const sourceLocations = this.sourceLocations.get(pluginId);
|
|
194
|
+
if (!sourceLocations) {
|
|
189
195
|
return false;
|
|
190
196
|
}
|
|
191
|
-
await
|
|
192
|
-
|
|
197
|
+
await Promise.all(Array.from(sourceLocations,
|
|
198
|
+
location => fs.remove(location).catch(err => console.error(`Failed to remove source for ${pluginId} at ${location}`, err))));
|
|
199
|
+
this.sourceLocations.delete(pluginId);
|
|
193
200
|
this.uninstallationManager.markAsUninstalled(pluginId);
|
|
194
201
|
return true;
|
|
195
202
|
} catch (e) {
|
|
@@ -198,6 +205,26 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
207
|
|
|
208
|
+
protected markAsInstalled(id: PluginIdentifiers.VersionedId): void {
|
|
209
|
+
const metadata = PluginIdentifiers.idAndVersionFromVersionedId(id);
|
|
210
|
+
if (metadata) {
|
|
211
|
+
const toMarkAsUninstalled: PluginIdentifiers.VersionedId[] = [];
|
|
212
|
+
const checkForDifferentVersions = (others: Iterable<PluginIdentifiers.VersionedId>) => {
|
|
213
|
+
for (const other of others) {
|
|
214
|
+
const otherMetadata = PluginIdentifiers.idAndVersionFromVersionedId(other);
|
|
215
|
+
if (metadata.id === otherMetadata?.id && metadata.version !== otherMetadata.version) {
|
|
216
|
+
toMarkAsUninstalled.push(other);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
checkForDifferentVersions(this.deployedFrontendPlugins.keys());
|
|
221
|
+
checkForDifferentVersions(this.deployedBackendPlugins.keys());
|
|
222
|
+
this.uninstallationManager.markAsUninstalled(...toMarkAsUninstalled);
|
|
223
|
+
this.uninstallationManager.markAsInstalled(id);
|
|
224
|
+
toMarkAsUninstalled.forEach(pluginToUninstall => this.uninstallPlugin(pluginToUninstall));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
201
228
|
async undeployPlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
|
|
202
229
|
this.deployedBackendPlugins.delete(pluginId);
|
|
203
230
|
this.deployedFrontendPlugins.delete(pluginId);
|
|
@@ -220,4 +247,14 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
220
247
|
|
|
221
248
|
return true;
|
|
222
249
|
}
|
|
250
|
+
|
|
251
|
+
protected setSourceLocationsForPlugin(id: PluginIdentifiers.VersionedId, entry: PluginDeployerEntry): void {
|
|
252
|
+
const knownLocations = this.sourceLocations.get(id) ?? new Set();
|
|
253
|
+
const maybeStoredLocations = entry.getValue('sourceLocations');
|
|
254
|
+
const storedLocations = Array.isArray(maybeStoredLocations) && maybeStoredLocations.every(location => typeof location === 'string')
|
|
255
|
+
? maybeStoredLocations.concat(entry.originalPath())
|
|
256
|
+
: [entry.originalPath()];
|
|
257
|
+
storedLocations.forEach(location => knownLocations.add(location));
|
|
258
|
+
this.sourceLocations.set(id, knownLocations);
|
|
259
|
+
}
|
|
223
260
|
}
|
|
@@ -66,6 +66,7 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
|
66
66
|
fs.copyFile(currentPath, newPath, error => error ? reject(error) : resolve());
|
|
67
67
|
});
|
|
68
68
|
context.pluginEntry().updatePath(newPath);
|
|
69
|
+
context.pluginEntry().storeValue('sourceLocations', [newPath]);
|
|
69
70
|
} catch (e) {
|
|
70
71
|
console.error(`[${context.pluginEntry().id}]: Failed to copy to user directory. Future sessions may not have access to this plugin.`);
|
|
71
72
|
}
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
|
|
23
23
|
PluginDeployerEntry, PluginDeployer, PluginDeployerParticipant, PluginDeployerStartContext,
|
|
24
24
|
PluginDeployerResolverInit, PluginDeployerFileHandlerContext,
|
|
25
|
-
PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers
|
|
25
|
+
PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions
|
|
26
26
|
} from '../../common/plugin-protocol';
|
|
27
27
|
import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
|
|
28
28
|
import {
|
|
@@ -146,15 +146,16 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
async deploy(plugin: UnresolvedPluginEntry): Promise<
|
|
149
|
+
async deploy(plugin: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
|
|
150
150
|
const deploy = this.measure('deploy');
|
|
151
|
-
await this.deployMultipleEntries([plugin]);
|
|
152
|
-
deploy.log(`Deploy plugin ${plugin}`);
|
|
151
|
+
const numDeployedPlugins = await this.deployMultipleEntries([plugin], options);
|
|
152
|
+
deploy.log(`Deploy plugin ${plugin.id}`);
|
|
153
|
+
return numDeployedPlugins;
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[]): Promise<
|
|
156
|
-
const pluginsToDeploy = await this.resolvePlugins(plugins);
|
|
157
|
-
|
|
156
|
+
protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<number> {
|
|
157
|
+
const pluginsToDeploy = await this.resolvePlugins(plugins, options);
|
|
158
|
+
return this.deployPlugins(pluginsToDeploy);
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
/**
|
|
@@ -166,7 +167,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
166
167
|
* deployer.deployPlugins(await deployer.resolvePlugins(allPluginEntries));
|
|
167
168
|
* ```
|
|
168
169
|
*/
|
|
169
|
-
async resolvePlugins(plugins: UnresolvedPluginEntry[]): Promise<PluginDeployerEntry[]> {
|
|
170
|
+
async resolvePlugins(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
170
171
|
const visited = new Set<string>();
|
|
171
172
|
const hasBeenVisited = (id: string) => visited.has(id) || (visited.add(id), false);
|
|
172
173
|
const pluginsToDeploy = new Map<PluginIdentifiers.VersionedId, PluginDeployerEntry>();
|
|
@@ -184,7 +185,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
184
185
|
}
|
|
185
186
|
const type = entry.type ?? PluginType.System;
|
|
186
187
|
try {
|
|
187
|
-
const pluginDeployerEntries = await this.resolveAndHandle(entry.id, type);
|
|
188
|
+
const pluginDeployerEntries = await this.resolveAndHandle(entry.id, type, options);
|
|
188
189
|
for (const deployerEntry of pluginDeployerEntries) {
|
|
189
190
|
const pluginData = await this.pluginDeployerHandler.getPluginDependencies(deployerEntry);
|
|
190
191
|
const versionedId = pluginData && PluginIdentifiers.componentsToVersionedId(pluginData.metadata.model);
|
|
@@ -222,8 +223,8 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
222
223
|
return [...pluginsToDeploy.values()];
|
|
223
224
|
}
|
|
224
225
|
|
|
225
|
-
protected async resolveAndHandle(id: string, type: PluginType): Promise<PluginDeployerEntry[]> {
|
|
226
|
-
const entries = await this.resolvePlugin(id, type);
|
|
226
|
+
protected async resolveAndHandle(id: string, type: PluginType, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
227
|
+
const entries = await this.resolvePlugin(id, type, options);
|
|
227
228
|
await this.applyFileHandlers(entries);
|
|
228
229
|
await this.applyDirectoryFileHandlers(entries);
|
|
229
230
|
return entries;
|
|
@@ -265,7 +266,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
265
266
|
/**
|
|
266
267
|
* deploy all plugins that have been accepted
|
|
267
268
|
*/
|
|
268
|
-
async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<
|
|
269
|
+
async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<number> {
|
|
269
270
|
const acceptedPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted());
|
|
270
271
|
const acceptedFrontendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.FRONTEND));
|
|
271
272
|
const acceptedBackendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.BACKEND));
|
|
@@ -282,12 +283,13 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
282
283
|
const pluginPaths = acceptedBackendPlugins.map(pluginEntry => pluginEntry.path());
|
|
283
284
|
this.logger.debug('local path to deploy on remote instance', pluginPaths);
|
|
284
285
|
|
|
285
|
-
await Promise.all([
|
|
286
|
+
const deployments = await Promise.all([
|
|
286
287
|
// start the backend plugins
|
|
287
288
|
this.pluginDeployerHandler.deployBackendPlugins(acceptedBackendPlugins),
|
|
288
289
|
this.pluginDeployerHandler.deployFrontendPlugins(acceptedFrontendPlugins)
|
|
289
290
|
]);
|
|
290
291
|
this.onDidDeployEmitter.fire(undefined);
|
|
292
|
+
return deployments.reduce<number>((accumulated, current) => accumulated += current ?? 0, 0);
|
|
291
293
|
}
|
|
292
294
|
|
|
293
295
|
/**
|
|
@@ -333,7 +335,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
333
335
|
/**
|
|
334
336
|
* Check a plugin ID see if there are some resolvers that can handle it. If there is a matching resolver, then we resolve the plugin
|
|
335
337
|
*/
|
|
336
|
-
public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System): Promise<PluginDeployerEntry[]> {
|
|
338
|
+
public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
337
339
|
const pluginDeployerEntries: PluginDeployerEntry[] = [];
|
|
338
340
|
const foundPluginResolver = this.pluginResolvers.find(pluginResolver => pluginResolver.accept(pluginId));
|
|
339
341
|
// there is a resolver for the input
|
|
@@ -342,7 +344,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
342
344
|
// create context object
|
|
343
345
|
const context = new PluginDeployerResolverContextImpl(foundPluginResolver, pluginId);
|
|
344
346
|
|
|
345
|
-
await foundPluginResolver.resolve(context);
|
|
347
|
+
await foundPluginResolver.resolve(context, options);
|
|
346
348
|
|
|
347
349
|
context.getPlugins().forEach(entry => {
|
|
348
350
|
entry.type = type;
|
|
@@ -18,7 +18,7 @@ import { injectable, inject } from '@theia/core/shared/inversify';
|
|
|
18
18
|
import { CancellationToken } from '@theia/core/lib/common/cancellation';
|
|
19
19
|
import { PluginDeployerImpl } from './plugin-deployer-impl';
|
|
20
20
|
import { PluginsKeyValueStorage } from './plugins-key-value-storage';
|
|
21
|
-
import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry, PluginIdentifiers } from '../../common/plugin-protocol';
|
|
21
|
+
import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions } from '../../common/plugin-protocol';
|
|
22
22
|
import { KeysToAnyValues, KeysToKeysToAnyValue } from '../../common/types';
|
|
23
23
|
|
|
24
24
|
@injectable()
|
|
@@ -30,16 +30,20 @@ export class PluginServerHandler implements PluginServer {
|
|
|
30
30
|
@inject(PluginsKeyValueStorage)
|
|
31
31
|
protected readonly pluginsKeyValueStorage: PluginsKeyValueStorage;
|
|
32
32
|
|
|
33
|
-
deploy(pluginEntry: string, arg2?: PluginType | CancellationToken): Promise<void> {
|
|
33
|
+
async deploy(pluginEntry: string, arg2?: PluginType | CancellationToken, options?: PluginDeployOptions): Promise<void> {
|
|
34
34
|
const type = typeof arg2 === 'number' ? arg2 as PluginType : undefined;
|
|
35
|
-
|
|
35
|
+
const succesfulDeployments = await this.doDeploy({
|
|
36
36
|
id: pluginEntry,
|
|
37
37
|
type: type ?? PluginType.User
|
|
38
|
-
});
|
|
38
|
+
}, options);
|
|
39
|
+
if (succesfulDeployments === 0) {
|
|
40
|
+
const optionText = options ? ` and options ${JSON.stringify(options)} ` : ' ';
|
|
41
|
+
throw new Error(`Deployment of extension with ID ${pluginEntry}${optionText}failed.`);
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
protected doDeploy(pluginEntry: UnresolvedPluginEntry): Promise<
|
|
42
|
-
return this.pluginDeployer.deploy(pluginEntry);
|
|
45
|
+
protected doDeploy(pluginEntry: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
|
|
46
|
+
return this.pluginDeployer.deploy(pluginEntry, options);
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
uninstall(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
|
|
@@ -28,25 +28,39 @@ export class PluginUninstallationManager {
|
|
|
28
28
|
|
|
29
29
|
protected uninstalledPlugins: PluginIdentifiers.VersionedId[] = [];
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
protected fireDidChange(): void {
|
|
32
|
+
this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
markAsUninstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
|
|
36
|
+
let didChange = false;
|
|
37
|
+
for (const id of pluginIds) { didChange = this.markOneAsUninstalled(id) || didChange; }
|
|
38
|
+
if (didChange) { this.fireDidChange(); }
|
|
39
|
+
return didChange;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected markOneAsUninstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
|
|
32
43
|
if (!this.uninstalledPlugins.includes(pluginId)) {
|
|
33
44
|
this.uninstalledPlugins.push(pluginId);
|
|
34
|
-
this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
|
|
35
45
|
return true;
|
|
36
46
|
}
|
|
37
47
|
return false;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
markAsInstalled(
|
|
50
|
+
markAsInstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
|
|
51
|
+
let didChange = false;
|
|
52
|
+
for (const id of pluginIds) { didChange = this.markOneAsInstalled(id) || didChange; }
|
|
53
|
+
if (didChange) { this.fireDidChange(); }
|
|
54
|
+
return didChange;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected markOneAsInstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
|
|
41
58
|
let index: number;
|
|
42
59
|
let didChange = false;
|
|
43
60
|
while ((index = this.uninstalledPlugins.indexOf(pluginId)) !== -1) {
|
|
44
61
|
this.uninstalledPlugins.splice(index, 1);
|
|
45
62
|
didChange = true;
|
|
46
63
|
}
|
|
47
|
-
if (didChange) {
|
|
48
|
-
this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
|
|
49
|
-
}
|
|
50
64
|
return didChange;
|
|
51
65
|
}
|
|
52
66
|
|
|
@@ -240,10 +240,10 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
|
|
|
240
240
|
|
|
241
241
|
protected registerPlugin(plugin: Plugin): void {
|
|
242
242
|
if (plugin.model.id === 'vscode.json-language-features' && this.jsonValidation.length) {
|
|
243
|
-
// VS Code
|
|
244
|
-
// we enrich them with Theia validations registered on
|
|
245
|
-
//
|
|
246
|
-
//
|
|
243
|
+
// VS Code contributes all built-in validations via vscode.json-language-features;
|
|
244
|
+
// we enrich them with Theia validations registered on startup.
|
|
245
|
+
// Dynamic validations can be provided only via VS Code extensions.
|
|
246
|
+
// Content is fetched by the extension later via vscode.workspace.openTextDocument.
|
|
247
247
|
const contributes = plugin.rawModel.contributes = (plugin.rawModel.contributes || {});
|
|
248
248
|
contributes.jsonValidation = (contributes.jsonValidation || []).concat(this.jsonValidation);
|
|
249
249
|
}
|
|
@@ -337,11 +337,7 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
protected async activateByBaseEvent(baseEvent: string): Promise<void> {
|
|
340
|
-
await Promise.all(Array.from(this.activations.keys(), activation =>
|
|
341
|
-
if (activation.startsWith(baseEvent)) {
|
|
342
|
-
return this.activateBySingleEvent(activation);
|
|
343
|
-
}
|
|
344
|
-
}));
|
|
340
|
+
await Promise.all(Array.from(this.activations.keys(), activation => activation.startsWith(baseEvent) && this.activateBySingleEvent(activation)));
|
|
345
341
|
}
|
|
346
342
|
|
|
347
343
|
protected async activateBySingleEvent(activationEvent: string): Promise<void> {
|