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

fix: Include swiftshader directory when creating installer for Electron 10+ #375

Merged
merged 12 commits into from
Feb 10, 2021
Binary file removed spec/fixtures/app/libEGL.dll
Binary file not shown.
Binary file removed spec/fixtures/app/libGLESv2.dll
Binary file not shown.
Empty file.
Empty file.
Empty file.
Empty file.
60 changes: 47 additions & 13 deletions spec/installer-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@ import path from 'path';
import { createTempDir } from '../src/temp-utils';
import fs from 'fs-extra';
import { createWindowsInstaller } from '../src';
import spawn from '../src/spawn-promise';

const log = require('debug')('electron-windows-installer:spec');

const appDirectory = path.join(__dirname, 'fixtures/app');
const fixtureAppDirectory = path.join(__dirname, 'fixtures/app');

test.beforeEach(async (): Promise<void> => {
const updateExePath = path.join(appDirectory, 'Squirrel.exe');
function spawn7z(args: string[]): Promise<string> {
const sevenZipPath = path.join(__dirname, '..', 'vendor', '7z.exe');
return process.platform !== 'win32'
? spawn(process.arch === 'x64' ? 'wine64' : 'wine', [sevenZipPath, ...args])
: spawn(sevenZipPath, args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally I'd ask to refactor this to look a bit more like how it's done elsewhere in the module (I do not agree with multi-line ternary statements), but I have a PR to drastically refactor how spawn works in #373 so it's kind of a moot point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I tried to stay true to the current coding style but old habits die hard, I'll extract the wine binary name into a variable.

}

if (await fs.pathExists(updateExePath)) {
await fs.unlink(updateExePath);
}
});
async function createTempAppDirectory(): Promise<string> {
const appDirectory = await createTempDir('ad-');
niik marked this conversation as resolved.
Show resolved Hide resolved
await fs.copy(fixtureAppDirectory, appDirectory);
return appDirectory;
}

test('creates a nuget package and installer', async (t): Promise<void> => {
const outputDirectory = await createTempDir('ei-');

const options = {
appDirectory: appDirectory,
outputDirectory: outputDirectory
};
const appDirectory = await createTempAppDirectory();
const options = { appDirectory, outputDirectory };

await createWindowsInstaller(options);

log(`Verifying assertions on ${outputDirectory}`);
log(JSON.stringify(await fs.readdir(outputDirectory)));

t.true(await fs.pathExists(path.join(outputDirectory, 'myapp-1.0.0-full.nupkg')));
const nupkgPath = path.join(outputDirectory, 'myapp-1.0.0-full.nupkg');

t.true(await fs.pathExists(nupkgPath));
t.true(await fs.pathExists(path.join(outputDirectory, 'MyAppSetup.exe')));

if (process.platform === 'win32') {
Expand All @@ -38,4 +43,33 @@ test('creates a nuget package and installer', async (t): Promise<void> => {

log('Verifying Update.exe');
t.true(await fs.pathExists(path.join(appDirectory, 'Squirrel.exe')));

log('Verifying contents of .nupkg');

const packageContents = await spawn7z(['l', nupkgPath]);

t.true(packageContents.includes('lib\\net45\\vk_swiftshader_icd.json'));
t.true(packageContents.includes('lib\\net45\\swiftshader\\libEGL.dll'));
});

test('creates an installer when swiftshader files are missing', async (t): Promise<void> => {
const appDirectory = await createTempAppDirectory();
const outputDirectory = await createTempDir('ei-');
niik marked this conversation as resolved.
Show resolved Hide resolved
const options = { appDirectory, outputDirectory };

// Remove swiftshader folder and swiftshader json file, simulating Electron < 10.0
await fs.remove(path.join(appDirectory, 'swiftshader', 'libEGL.dll'));
await fs.remove(path.join(appDirectory, 'swiftshader', 'libGLESv2.dll'));
await fs.rmdir(path.join(appDirectory, 'swiftshader'));
await fs.remove(path.join(appDirectory, 'vk_swiftshader_icd.json'));

await createWindowsInstaller(options);

const nupkgPath = path.join(outputDirectory, 'myapp-1.0.0-full.nupkg');

log('Verifying contents of .nupkg');

const packageContents = await spawn7z(['l', nupkgPath]);
t.false(packageContents.includes('vk_swiftshader_icd.json'));
t.false(packageContents.includes('swiftshader\\'));
});
13 changes: 13 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,23 @@ export async function createWindowsInstaller(options: Options): Promise<void> {
metadata.version = convertVersion(metadata.version as string);
metadata.copyright = metadata.copyright ||
`Copyright © ${new Date().getFullYear()} ${metadata.authors || metadata.owners}`;
metadata.additionalFiles = metadata.additionalFiles || [];

if (await fs.pathExists(path.join(appDirectory, 'swiftshader'))) {
metadata.additionalFiles.push({ src: 'swiftshader\\**', target: 'lib\\net45\\swiftshader' });
}

if (await fs.pathExists(path.join(appDirectory, 'vk_swiftshader_icd.json'))) {
metadata.additionalFiles.push({ src: 'vk_swiftshader_icd.json', target: 'lib\\net45' });
}

let templateData = await fs.readFile(path.join(__dirname, '..', 'template.nuspectemplate'), 'utf8');
if (path.sep === '/') {
templateData = templateData.replace(/\\/g, '/');
for (const f of metadata.additionalFiles) {
f.src = f.src.replace(/\\/g, '/');
f.target = f.target.replace(/\\/g, '/');
}
}
const nuspecContent = template(templateData)(metadata);

Expand Down
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export interface PersonMetadata {
url?: string;
}

export interface AdditionalFile {
src: string;
target: string;
}

export interface Metadata {
name?: string;
productName?: string;
Expand All @@ -143,4 +148,5 @@ export interface Metadata {
owners?: string | PersonMetadata[];
description?: string;
iconUrl?: string;
additionalFiles?: AdditionalFile[];
}
3 changes: 3 additions & 0 deletions template.nuspectemplate
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@
<file src="Squirrel.exe" target="lib\net45\squirrel.exe" />
<file src="LICENSE" target="lib\net45\LICENSE" />
<file src="<%- exe %>" target="lib\net45\<%- exe %>" />
<% additionalFiles.forEach(function(f) { %>
<file src="<%- f.src %>" target="<%- f.target %>" />
<% }); %>
</files>
</package>