Skip to content

Commit

Permalink
Add check and message for x64 VSIX on M1 Mac (#7303)
Browse files Browse the repository at this point in the history
  • Loading branch information
Colengms authored Apr 6, 2021
1 parent 0b4f51b commit bdd881b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 56 deletions.
39 changes: 11 additions & 28 deletions Extension/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,21 +417,18 @@ export function getHttpsProxyAgent(): HttpsProxyAgent | undefined {
return new HttpsProxyAgent(proxyOptions);
}

/** Creates a file if it doesn't exist */
function touchFile(file: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
fs.writeFile(file, "", (err) => {
if (err) {
reject(err);
}

resolve();
});
});
}
export interface InstallLockContents {
platform: string;
architecture: string;
};

export function touchInstallLockFile(): Promise<void> {
return touchFile(getInstallLockPath());
export function touchInstallLockFile(info: PlatformInformation): Promise<void> {
const installLockObject: InstallLockContents = {
platform: info.platform,
architecture: info.architecture
};
const content: string = JSON.stringify(installLockObject);
return writeFileText(getInstallLockPath(), content);
}

export function touchExtensionFolder(): Promise<void> {
Expand Down Expand Up @@ -503,20 +500,6 @@ export function checkInstallLockFile(): Promise<boolean> {
return checkFileExists(getInstallLockPath());
}

/** Get the platform that the installed binaries belong to.*/
export function getInstalledBinaryPlatform(): string | undefined {
// the LLVM/bin folder is utilized to identify the platform
let installedPlatform: string | undefined;
if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.exe"))) {
installedPlatform = "win32";
} else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.darwin"))) {
installedPlatform = "darwin";
} else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format"))) {
installedPlatform = "linux";
}
return installedPlatform;
}

/** Check if the core binaries exists in extension's installation folder */
export async function checkInstallBinariesExist(): Promise<boolean> {
if (!checkInstallLockFile()) {
Expand Down
89 changes: 61 additions & 28 deletions Extension/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,38 +75,71 @@ export async function activate(context: vscode.ExtensionContext): Promise<CppToo

await processRuntimeDependencies();

const installedPlatform: string | undefined = util.getInstalledBinaryPlatform();
const promptForMacArchictureMismatch: PersistentState<boolean> = new PersistentState<boolean>("CPP.promptForMacArchictureMismatch", true);

// Read archictures of binaries from install.lock
const fileContents: string = await util.readFileText(util.getInstallLockPath());
let installedPlatformAndArchitecture: util.InstallLockContents;
// Just in case we're debugging with an existing install.lock that is empty, assume current platform if empty.
if (fileContents.length === 0) {
installedPlatformAndArchitecture = {
platform: process.platform,
architecture: arch
};
} else {
installedPlatformAndArchitecture = <util.InstallLockContents>JSON.parse(fileContents);
}

// Check the main binaries files to declare if the extension has been installed successfully.
if (installedPlatform && process.platform !== installedPlatform) {
if (process.platform !== installedPlatformAndArchitecture.platform
|| (arch !== installedPlatformAndArchitecture.architecture && (arch !== "x64" || installedPlatformAndArchitecture.architecture !== 'x86' || process.platform !== "win32"))) {
// Check if the correct offline/insiders vsix is installed on the correct platform.
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
const vsixName: string = vsixNameForPlatform(platformInfo);
errMsg = localize("native.binaries.not.supported", "This {0} version of the extension is incompatible with your OS. Please download and install the \"{1}\" version of the extension.", GetOSName(installedPlatform), vsixName);
const downloadLink: string = localize("download.button", "Go to Download Page");
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
if (selection === downloadLink) {
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
}
});
} else if (!(await util.checkInstallBinariesExist())) {
errMsg = localize("extension.installation.failed", "The C/C++ extension failed to install successfully. You will need to repair or reinstall the extension for C/C++ language features to function properly.");
const reload: string = localize("remove.extension", "Attempt to Repair");
vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => {
if (value === reload) {
await util.removeInstallLockFile();
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
});
} else if (!(await util.checkInstallJsonsExist())) {
// Check the Json files to declare if the extension has been installed successfully.
errMsg = localize("jason.files.missing", "The C/C++ extension failed to install successfully. You will need to reinstall the extension for C/C++ language features to function properly.");
const downloadLink: string = localize("download.button", "Go to Download Page");
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
if (selection === downloadLink) {
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
if (installedPlatformAndArchitecture.platform === 'darwin' && installedPlatformAndArchitecture.architecture === "x64" && arch === "arm64") {
if (promptForMacArchictureMismatch.Value) {
// Display a message specifically referring the user to the ARM64 Mac build on ARM64 Mac.
errMsg = localize("native.binaries.mismatch.osx", "This Intel version of the extension has been installed. Since you are on an Apple Silicon Mac, we recommend installing the Apple Silicon version of the extension.");
promptForMacArchictureMismatch.Value = false;
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
if (selection === downloadLink) {
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
}
});
}
});
} else {
// Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX.
promptForMacArchictureMismatch.Value = true;
errMsg = localize("native.binaries.not.supported", "This {0} version of the extension is incompatible with your OS. Please download and install the \"{1}\" version of the extension.", GetOSName(installedPlatformAndArchitecture.platform), vsixName);
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
if (selection === downloadLink) {
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
}
});
}
} else {
// Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX.
promptForMacArchictureMismatch.Value = true;
if (!(await util.checkInstallBinariesExist())) {
errMsg = localize("extension.installation.failed", "The C/C++ extension failed to install successfully. You will need to repair or reinstall the extension for C/C++ language features to function properly.");
const reload: string = localize("remove.extension", "Attempt to Repair");
vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => {
if (value === reload) {
await util.removeInstallLockFile();
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
});
} else if (!(await util.checkInstallJsonsExist())) {
// Check the Json files to declare if the extension has been installed successfully.
errMsg = localize("jason.files.missing", "The C/C++ extension failed to install successfully. You will need to reinstall the extension for C/C++ language features to function properly.");
const downloadLink: string = localize("download.button", "Go to Download Page");
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
if (selection === downloadLink) {
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
}
});
}
}

return cppTools;
Expand Down Expand Up @@ -219,7 +252,7 @@ async function onlineInstallation(info: PlatformInformation): Promise<void> {
await rewriteManifest();

setInstallationStage('touchInstallLockFile');
await touchInstallLockFile();
await touchInstallLockFile(info);

setInstallationStage('postInstall');
await postInstall(info);
Expand Down Expand Up @@ -311,8 +344,8 @@ function removeUnnecessaryFile(): Promise<void> {
return Promise.resolve();
}

function touchInstallLockFile(): Promise<void> {
return util.touchInstallLockFile();
function touchInstallLockFile(info: PlatformInformation): Promise<void> {
return util.touchInstallLockFile(info);
}

function handleError(error: any): void {
Expand Down

0 comments on commit bdd881b

Please sign in to comment.