Skip to content

Commit 1e178d6

Browse files
CopilotJoeRobich
andcommitted
Add isOptional field to packages and handle optional package failures
Co-authored-by: JoeRobich <611219+JoeRobich@users.noreply.github.com>
1 parent 28b16ed commit 1e178d6

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

src/packageManager/IPackage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export interface IPackage {
1313
platformId?: string;
1414
integrity?: string;
1515
isFramework?: boolean;
16+
isOptional?: boolean;
1617
}

src/packageManager/absolutePathPackage.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ export class AbsolutePathPackage implements IPackage {
2020
public fallbackUrl?: string,
2121
public platformId?: string,
2222
public integrity?: string,
23-
public isFramework?: boolean
23+
public isFramework?: boolean,
24+
public isOptional?: boolean
2425
) {}
2526

2627
public static getAbsolutePathPackage(pkg: Package, extensionPath: string) {
@@ -36,7 +37,8 @@ export class AbsolutePathPackage implements IPackage {
3637
pkg.fallbackUrl,
3738
pkg.platformId,
3839
pkg.integrity,
39-
pkg.isFramework
40+
pkg.isFramework,
41+
pkg.isOptional
4042
);
4143
}
4244
}

src/packageManager/downloadAndInstallPackages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ export async function downloadAndInstallPackages(
6161
eventStream.post(new InstallationFailure(installationStage, error));
6262
}
6363

64+
// If the package is optional, log and continue with the next package
65+
if (pkg.isOptional) {
66+
continue;
67+
}
68+
6469
return false;
6570
} finally {
6671
try {

test/omnisharp/omnisharpUnitTests/packages/downloadAndInstallPackages.test.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,79 @@ describe(`${downloadAndInstallPackages.name}`, () => {
218218
});
219219
});
220220

221+
describe('Optional packages', () => {
222+
test('Returns true and continues when an optional package fails to download', async () => {
223+
const optionalPackage = <AbsolutePathPackage[]>[
224+
{
225+
url: `${server.baseUrl}/notDownloadablePackage`,
226+
description: 'Optional Package',
227+
installPath: new AbsolutePath(tmpDirPath),
228+
isOptional: true,
229+
},
230+
];
231+
232+
const result = await downloadAndInstallPackages(
233+
optionalPackage,
234+
networkSettingsProvider,
235+
eventStream,
236+
downloadValidator
237+
);
238+
expect(result).toBe(true);
239+
});
240+
241+
test('Continues to install remaining packages after optional package fails', async () => {
242+
const tmpInstallDir2 = await CreateTmpDir(true);
243+
const mixedPackages = <AbsolutePathPackage[]>[
244+
{
245+
url: `${server.baseUrl}/notDownloadablePackage`,
246+
description: 'Optional Package',
247+
installPath: new AbsolutePath(tmpDirPath),
248+
isOptional: true,
249+
},
250+
{
251+
url: `${server.baseUrl}/downloadablePackage`,
252+
description: packageDescription,
253+
installPath: new AbsolutePath(tmpInstallDir2.name),
254+
},
255+
];
256+
257+
const result = await downloadAndInstallPackages(
258+
mixedPackages,
259+
networkSettingsProvider,
260+
eventStream,
261+
downloadValidator
262+
);
263+
expect(result).toBe(true);
264+
expect(await util.fileExists(path.join(tmpInstallDir2.name, 'install.Lock'))).toBe(true);
265+
tmpInstallDir2.dispose();
266+
});
267+
268+
test('InstallationFailure event is logged for optional package', async () => {
269+
const optionalPackage = <AbsolutePathPackage[]>[
270+
{
271+
url: `${server.baseUrl}/notDownloadablePackage`,
272+
description: 'Optional Package',
273+
installPath: new AbsolutePath(tmpDirPath),
274+
isOptional: true,
275+
},
276+
];
277+
278+
eventBus.getEvents(); // Clear any previous events
279+
await downloadAndInstallPackages(
280+
optionalPackage,
281+
networkSettingsProvider,
282+
eventStream,
283+
downloadValidator
284+
);
285+
const obtainedEvents = eventBus.getEvents();
286+
const installationFailureEvent = obtainedEvents.find(
287+
(event) => event instanceof InstallationFailure
288+
) as InstallationFailure;
289+
expect(installationFailureEvent).toBeDefined();
290+
expect(installationFailureEvent.stage).toEqual('downloadPackage');
291+
});
292+
});
293+
221294
afterEach(async () => {
222295
if (tmpInstallDir) {
223296
tmpInstallDir.dispose();

0 commit comments

Comments
 (0)