Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package manager nullability fixes #5255

Merged
merged 24 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
09d6f49
Add undefined to parameters in UpdatePackageDependencies
winstliu Jun 1, 2022
d8f9db4
Mark getRuntimeDependencyPackageUtils as nullable
winstliu Jun 1, 2022
3abd117
Default to empty string for rzls config
winstliu Jun 1, 2022
07df02e
Bump @types/yauzl for correct types
winstliu Jun 1, 2022
085c4b2
Coerce error types in ZipInstaller
winstliu Jun 1, 2022
36bba18
Use stricter types in proxy.ts
winstliu Jun 1, 2022
a3ebcf6
Add missing architecture to OmniSharp OSX Mono x64
winstliu Jun 1, 2022
b35ec38
Simplify PackageFilterer logic
winstliu Jun 1, 2022
241cef3
Remove nulls from PackageError
winstliu Jun 1, 2022
4531daf
Mark integrity as nullable in isValidDownload
winstliu Jun 1, 2022
7e2d319
Simplify getAbsolutePathPackagesToInstall
winstliu Jun 1, 2022
df711a2
Guard against missing headers in FileDownloader
winstliu Jun 1, 2022
ba7ec1b
Simplify logic in downloadAndInstallPackages
winstliu Jun 1, 2022
05755e2
Make binaries optional for AbsolutePathPackage
winstliu Jun 1, 2022
68eec1c
Pass boolean for NetworkSettings strictSSL
winstliu Jun 1, 2022
c81362c
Update Node types
winstliu Jun 1, 2022
60bdd5d
Update test typings
winstliu Jun 1, 2022
ea7a672
Fix tests
winstliu Jun 1, 2022
7909d35
Remove unnecssary conditional
winstliu Jun 1, 2022
c2333b9
Remove isBoolean
winstliu Jun 1, 2022
4f271b6
Remove unnecessary cast
winstliu Jun 1, 2022
94ca366
Make tasks nullable-aware
winstliu Jun 1, 2022
68fcae9
Some more cleanup in OmnisharpPackageCreator
winstliu Jun 5, 2022
5b8983c
Fix tests
winstliu Jun 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@
"@types/gulp": "4.0.5",
"@types/minimist": "1.2.1",
"@types/mocha": "5.2.5",
"@types/node": "10.12.24",
"@types/node": "16.11.38",
"@types/semver": "5.5.0",
"@types/tmp": "0.0.33",
"@types/unzipper": "^0.9.1",
"@types/vscode": "1.66.0",
"@types/yauzl": "2.9.1",
"@types/yauzl": "2.10.0",
"@vscode/test-electron": "2.1.3",
"archiver": "5.3.0",
"chai": "4.3.4",
Expand Down Expand Up @@ -230,6 +230,9 @@
"platforms": [
"darwin"
],
"architectures": [
"x86_64"
],
"binaries": [
"./mono.osx",
"./run"
Expand Down
4 changes: 0 additions & 4 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ export function getUnixTempDirectory(){
return envTmp;
}

export function isBoolean(obj: any): obj is boolean {
return obj === true || obj === false;
}

export function sum<T>(arr: T[], selector: (item: T) => number): number {
return arr.reduce((prev, curr) => prev + selector(curr), 0);
}
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr-debug/activate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async function checkIsValidArchitecture(platformInformation: PlatformInformation
}

// Validate we are on compatiable macOS version if we are x86_64
if ((platformInformation.architecture !== "x86_64") ||
if ((platformInformation.architecture !== "x86_64") ||
(platformInformation.architecture === "x86_64" && !CoreClrDebugUtil.isMacOSSupported())) {
eventStream.post(new DebuggerPrerequisiteFailure("[ERROR] The debugger cannot be installed. The debugger requires macOS 10.12 (Sierra) or newer."));
return false;
Expand Down Expand Up @@ -149,8 +149,8 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip

// install.Lock does not exist, need to wait for packages to finish downloading.
let installLock = false;
let debuggerPackage = getRuntimeDependencyPackageWithId("Debugger", this.packageJSON, this.platformInfo, this.extensionPath);
if (debuggerPackage && debuggerPackage.installPath) {
const debuggerPackage = getRuntimeDependencyPackageWithId("Debugger", this.packageJSON, this.platformInfo, this.extensionPath);
if (debuggerPackage?.installPath) {
installLock = await common.installFileExists(debuggerPackage.installPath, common.InstallFileType.Lock);
}

Expand Down
5 changes: 1 addition & 4 deletions src/observers/TelemetryObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ export class TelemetryObserver {
if (event.error instanceof PackageError) {
// we can log the message in a PackageError to telemetry as we do not put PII in PackageError messages
telemetryProps['error.message'] = event.error.message;

if (event.error.pkg) {
telemetryProps['error.packageUrl'] = event.error.pkg.url;
}
telemetryProps['error.packageUrl'] = event.error.pkg.url;
}

this.reporter.sendTelemetryEvent('AcquisitionFailed', telemetryProps);
Expand Down
2 changes: 1 addition & 1 deletion src/omnisharp/OmnisharpDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class OmnisharpDownloader {
let runtimeDependencies = getRuntimeDependenciesPackages(this.packageJSON);
let omniSharpPackages = GetPackagesFromVersion(version, useFramework, runtimeDependencies, serverUrl, installPath);
let packagesToInstall = await getAbsolutePathPackagesToInstall(omniSharpPackages, this.platformInfo, this.extensionPath);
if (packagesToInstall && packagesToInstall.length > 0) {
if (packagesToInstall.length > 0) {
this.eventStream.post(new PackageInstallation(`OmniSharp Version = ${version}`));
this.eventStream.post(new LogPlatformInfo(this.platformInfo));
if (await downloadAndInstallPackages(packagesToInstall, this.networkSettingsProvider, this.eventStream, isValidDownload, useFramework)) {
Expand Down
35 changes: 8 additions & 27 deletions src/omnisharp/OmnisharpPackageCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@ import { Package } from "../packageManager/Package";
export const modernNetVersion = "6.0";

export function GetPackagesFromVersion(version: string, useFramework: boolean, runTimeDependencies: Package[], serverUrl: string, installPath: string): Package[] {
if (!version) {
throw new Error('Invalid version');
}

let versionPackages = new Array<Package>();
for (let inputPackage of runTimeDependencies) {
if (inputPackage.platformId && inputPackage.isFramework === useFramework) {
versionPackages.push(SetBinaryAndGetPackage(inputPackage, useFramework, serverUrl, version, installPath));
}
}

return versionPackages;
return runTimeDependencies
.filter(inputPackage =>
inputPackage.platformId !== undefined && inputPackage.isFramework === useFramework)
.map(inputPackage =>
SetBinaryAndGetPackage(inputPackage, useFramework, serverUrl, version, installPath));
}

export function SetBinaryAndGetPackage(inputPackage: Package, useFramework: boolean, serverUrl: string, version: string, installPath: string): Package {
Expand All @@ -28,7 +21,7 @@ export function SetBinaryAndGetPackage(inputPackage: Package, useFramework: bool
// .NET 6 packages use system `dotnet OmniSharp.dll`
installBinary = 'OmniSharp.dll';
}
else if (inputPackage.platformId === 'win-x86' || inputPackage.platformId === 'win-x64' || inputPackage.platformId === 'win-arm64') {
else if (inputPackage.platforms.includes('win32')) {
installBinary = 'OmniSharp.exe';
}
else {
Expand All @@ -39,25 +32,13 @@ export function SetBinaryAndGetPackage(inputPackage: Package, useFramework: bool
}

function GetPackage(inputPackage: Package, useFramework: boolean, serverUrl: string, version: string, installPath: string, installBinary: string): Package {
if (!version) {
throw new Error('Invalid version');
}

const packageSuffix = useFramework ? '' : `-net${modernNetVersion}`;

let versionPackage: Package = {
id: inputPackage.id,
return {
...inputPackage,
description: `${inputPackage.description}, Version = ${version}`,
url: `${serverUrl}/releases/${version}/omnisharp-${inputPackage.platformId}${packageSuffix}.zip`,
installPath: `${installPath}/${version}${packageSuffix}`,
installTestPath: `./${installPath}/${version}${packageSuffix}/${installBinary}`,
platforms: inputPackage.platforms,
architectures: inputPackage.architectures,
binaries: inputPackage.binaries,
platformId: inputPackage.platformId,
isFramework: useFramework
};

return versionPackage;
}

8 changes: 4 additions & 4 deletions src/packageManager/AbsolutePath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { isAbsolute, resolve } from "path";
import * as path from "path";

export class AbsolutePath {
constructor(public value: string) {
if (!isAbsolute(value)) {
if (!path.isAbsolute(value)) {
throw new Error("The path must be absolute");
}
}

public static getAbsolutePath(...pathSegments: string[]): AbsolutePath {
return new AbsolutePath(resolve(...pathSegments));
return new AbsolutePath(path.resolve(...pathSegments));
}
}
}
26 changes: 11 additions & 15 deletions src/packageManager/AbsolutePathPackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class AbsolutePathPackage implements IPackage {
public url: string,
public platforms: string[],
public architectures: string[],
public binaries: AbsolutePath[],
public installPath?: AbsolutePath,
public installPath: AbsolutePath,
public binaries?: AbsolutePath[],
public installTestPath?: AbsolutePath,
public fallbackUrl?: string,
public platformId?: string,
Expand All @@ -29,8 +29,8 @@ export class AbsolutePathPackage implements IPackage {
pkg.url,
pkg.platforms,
pkg.architectures,
getAbsoluteBinaries(pkg, extensionPath),
getAbsoluteInstallPath(pkg, extensionPath),
getAbsoluteBinaries(pkg, extensionPath),
getAbsoluteInstallTestPath(pkg, extensionPath),
pkg.fallbackUrl,
pkg.platformId,
Expand All @@ -40,27 +40,23 @@ export class AbsolutePathPackage implements IPackage {
}
}

function getAbsoluteInstallTestPath(pkg: Package, extensionPath: string): AbsolutePath {
if (pkg.installTestPath) {
function getAbsoluteInstallTestPath(pkg: Package, extensionPath: string): AbsolutePath | undefined {
if (pkg.installTestPath !== undefined) {
return AbsolutePath.getAbsolutePath(extensionPath, pkg.installTestPath);
}

return null;
return undefined;
}

function getAbsoluteBinaries(pkg: Package, extensionPath: string): AbsolutePath[] {
let basePath = getAbsoluteInstallPath(pkg, extensionPath).value;
if (pkg.binaries) {
return pkg.binaries.map(value => AbsolutePath.getAbsolutePath(basePath, value));
}

return null;
function getAbsoluteBinaries(pkg: Package, extensionPath: string): AbsolutePath[] | undefined {
const basePath = getAbsoluteInstallPath(pkg, extensionPath).value;
return pkg.binaries?.map(value => AbsolutePath.getAbsolutePath(basePath, value));
}

function getAbsoluteInstallPath(pkg: Package, extensionPath: string): AbsolutePath {
if (pkg.installPath) {
if (pkg.installPath !== undefined) {
return AbsolutePath.getAbsolutePath(extensionPath, pkg.installPath);
}

return new AbsolutePath(extensionPath);
}
}
21 changes: 14 additions & 7 deletions src/packageManager/FileDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/

import * as https from 'https';
import * as util from '../common';
import { EventStream } from "../EventStream";
import { DownloadSuccess, DownloadStart, DownloadFallBack, DownloadFailure, DownloadProgress, DownloadSizeObtained } from "../omnisharp/loggingEvents";
import { NestedError } from "../NestedError";
Expand All @@ -24,7 +23,7 @@ export async function DownloadFile(description: string, eventStream: EventStream
// If the package has a fallback Url, and downloading from the primary Url failed, try again from
// the fallback. This is used for debugger packages as some users have had issues downloading from
// the CDN link
if (fallbackUrl) {
if (fallbackUrl !== undefined) {
eventStream.post(new DownloadFallBack(fallbackUrl));
try {
let buffer = await downloadFile(description, fallbackUrl, eventStream, networkSettingsProvider);
Expand All @@ -51,7 +50,7 @@ async function downloadFile(description: string, urlString: string, eventStream:
path: url.path,
agent: getProxyAgent(url, proxy, strictSSL),
port: url.port,
rejectUnauthorized: util.isBoolean(strictSSL) ? strictSSL : true
rejectUnauthorized: strictSSL,
};

let buffers: any[] = [];
Expand All @@ -60,13 +59,21 @@ async function downloadFile(description: string, urlString: string, eventStream:
let request = https.request(options, response => {
if (response.statusCode === 301 || response.statusCode === 302) {
// Redirect - download from new location
if (response.headers.location === undefined) {
eventStream.post(new DownloadFailure(`Failed to download from ${urlString}. Redirected without location header`));
return reject(new NestedError('Missing location'));
}
return resolve(downloadFile(description, response.headers.location, eventStream, networkSettingsProvider));
}

else if (response.statusCode != 200) {
else if (response.statusCode !== 200) {
// Download failed - print error message
eventStream.post(new DownloadFailure(`Failed to download from ${urlString}. Error code '${response.statusCode}')`));
return reject(new NestedError(response.statusCode.toString()));
return reject(new NestedError(response.statusCode!.toString())); // Known to exist because this is from a ClientRequest
}

if (response.headers['content-length'] === undefined) {
eventStream.post(new DownloadFailure(`Failed to download from ${urlString}. No content-length header`));
return reject(new NestedError('Missing content-length'));
}

// Downloading - hook up events
Expand Down Expand Up @@ -104,4 +111,4 @@ async function downloadFile(description: string, urlString: string, eventStream:
// Execute the request
request.end();
});
}
}
2 changes: 1 addition & 1 deletion src/packageManager/IPackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

export interface IPackage {
id?: string;
id: string;
description: string;
url: string;
fallbackUrl?: string;
Expand Down
6 changes: 3 additions & 3 deletions src/packageManager/PackageError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { IPackage } from "./IPackage";
export class PackageError extends NestedError {
// Do not put PII (personally identifiable information) in the 'message' field as it will be logged to telemetry
constructor(public message: string,
public pkg: IPackage = null,
public innerError: any = null) {
public pkg: IPackage,
public innerError: Error | undefined) {
super(message, innerError);
}
}
}
Loading