Skip to content

Commit

Permalink
Merge pull request #10 from joncloud/test-plugins
Browse files Browse the repository at this point in the history
Adds tests for plugins
  • Loading branch information
joncloud authored Sep 10, 2020
2 parents f264e6c + 85fcb18 commit 45688f2
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 62 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
os: [ 'windows-latest', 'ubuntu-latest', 'macos-latest' ]
os: [ 'windows-latest', 'ubuntu-20.04', 'macos-latest' ]
node-version: [12.x]

steps:
Expand All @@ -26,10 +26,14 @@ jobs:

- name: 'Install makensis (apt)'
run: sudo apt update && sudo apt install -y nsis nsis-pluginapi
if: ${{ matrix.os == 'ubuntu-latest' }}
if: ${{ matrix.os == 'ubuntu-20.04' }}

- name: 'Install makensis (homebrew)'
run: brew update && brew install makensis
if: ${{ matrix.os == 'macos-latest' }}

- name: 'Set Plugin permissions'
run: sudo chown -R $(whoami) /usr/share/nsis/Plugins/
if: ${{ matrix.os == 'ubuntu-20.04' }}

- run: npm test
38 changes: 21 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const core = require('@actions/core');
const Installer = require('./installer').Installer;
const { Installer } = require('./installer');

const getBoolean = (value) => {
if (!value) {
Expand All @@ -11,20 +11,24 @@ const getBoolean = (value) => {
return value === 'true';
};

try {
const debugMode = getBoolean(process.env.debug);
const installer = new Installer(debugMode);
installer.setCustomArguments(core.getInput('arguments'));

core.getInput('additional-plugin-paths')
.split(/\n?\r/)
.map(pluginPath => pluginPath.trim())
.filter(pluginPath => !!pluginPath)
.forEach(pluginPath => installer.addPluginPath(pluginPath.trim()));

installer.createInstaller(
core.getInput('script-file')
);
} catch (error) {
core.setFailed(error.message);
const run = async () => {
try {
const debugMode = getBoolean(process.env.debug);
const installer = new Installer(debugMode);
installer.setCustomArguments(core.getInput('arguments'));

core.getInput('additional-plugin-paths')
.split(/\n?\r/)
.map(pluginPath => pluginPath.trim())
.filter(pluginPath => !!pluginPath)
.forEach(pluginPath => installer.addPluginPath(pluginPath.trim()));

await installer.createInstallerAsync(
core.getInput('script-file')
);
} catch (error) {
core.setFailed(error.message);
}
}

run();
40 changes: 25 additions & 15 deletions installer.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
const { promisify } = require('util');

const fs = require('fs');
const statAsync = promisify(fs.stat);
const existsAsync = promisify(fs.exists);
const mkdirAsync = promisify(fs.mkdir);
const readdirAsync = promisify(fs.readdir);
const copyFileAsync = promisify(fs.copyFile);

const path = require('path');
const makensis = require('./makensis');

const isDirectory = (item) => {
const stats = fs.statSync(item);
const isDirectoryAsync = async (item) => {
const stats = await statAsync(item);

return stats.isDirectory();
};

const copyDirectory = (src, dest) => {
const copyDirectoryAsync = async (src, dest) => {
console.log('copyDirectory', src, dest);

if (!fs.existsSync(dest)) {
fs.mkdirSync(dest);
if (!await existsAsync(dest)) {
await mkdirAsync(dest);
}

const items = fs.readdirSync(src);
items.forEach(item => {
const items = await readdirAsync(src);
const promises = items.map(async item => {
const name = path.basename(item);
const srcPath = path.join(src, name);
if (isDirectory(srcPath)) {
copyDirectory(
if (await isDirectoryAsync(srcPath)) {
await copyDirectoryAsync(
srcPath,
path.join(dest, name)
);
Expand All @@ -31,12 +39,13 @@ const copyDirectory = (src, dest) => {
srcPath,
path.join(dest, name)
);
fs.copyFileSync(
await copyFileAsync(
srcPath,
path.join(dest, name)
);
}
});
await Promise.all(promises);
};

class Installer {
Expand Down Expand Up @@ -84,29 +93,30 @@ class Installer {
return args;
}

createInstaller(scriptPath) {
async createInstallerAsync(scriptPath) {
console.log(`Creating installer for: ${scriptPath}`);

// Include any of the plugins that may have been requested.
if (this.pluginPaths.length) {
const nsisdir = makensis.getSymbols().NSISDIR;
const nsisdir = (await makensis.getSymbolsAsync()).NSISDIR;
if (!nsisdir) {
throw new Error('Unable to determine NSISDIR. Check makensis -HDRINFO output');
}
const nsisPluginPath = path.join(nsisdir, 'Plugins');
this.debugLog(`Using system Plugins path ${nsisPluginPath}`);

this.pluginPaths.forEach(pluginPath => {
const copies = this.pluginPaths.map(pluginPath => {
console.log('Including plugin path', pluginPath);
copyDirectory(pluginPath, nsisPluginPath);
return copyDirectoryAsync(pluginPath, nsisPluginPath);
});
await Promise.all(copies);
}

const args = this.getProcessArguments(scriptPath)
.join(' ');

this.debugLog(`Running ${args}`);
const _ = makensis.execSync(args);
const _ = await makensis.execAsync(args);
}
};

Expand Down
19 changes: 12 additions & 7 deletions makensis.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
const { promisify } = require('util');
const fs = require('fs');
const { execSync } = require('child_process');

const { exec } = require('child_process');
const execAsync = promisify(exec);

const path = require('path');
const { platform, env } = require('process');


const firstValidPath = (paths) => {
const possiblePaths = paths.filter(fs.existsSync);

Expand Down Expand Up @@ -31,20 +36,20 @@ const getLinuxPath = () => {

class Makensis {
constructor(path) {
if (!fs.existsSync(path)) {
if (!path || !fs.existsSync(path)) {
throw new Error('Unable to find makensis executable');
}
this.path = path;
}

execSync(args) {
const buffer = execSync(`"${this.path}" ${args}`);
async execAsync(args) {
const result = await execAsync(`"${this.path}" ${args}`);

return buffer;
return result.stdout;
}

getSymbols() {
const buffer = this.execSync('-HDRINFO');
async getSymbolsAsync() {
const buffer = await this.execAsync('-HDRINFO');

// Look for the defined symbols in the output.
const exp = /Defined symbols: (.*)/g;
Expand Down
Binary file added test/EnVar/amd64-unicode/EnVar.dll
Binary file not shown.
18 changes: 18 additions & 0 deletions test/EnVar/license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
EnVar plugin for NSIS

Coded by Jason Ross aka JasonFriday13 on the forums.

Copyright (C) 2014-2016, 2018, 2020 MouseHelmet Software


EULA - End User License Agreement

This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.
Binary file added test/EnVar/x86-ansi/EnVar.dll
Binary file not shown.
Binary file added test/EnVar/x86-unicode/EnVar.dll
Binary file not shown.
2 changes: 1 addition & 1 deletion install.nsi → test/basic.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
;---------------------------------
;General

OutFile "installsig.exe"
OutFile "basic.exe"
ShowInstDetails "nevershow"
ShowUninstDetails "nevershow"

Expand Down
65 changes: 45 additions & 20 deletions test/installer.spec.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,57 @@
const fs = require('fs');
const { promisify } = require('util');

const { exists, unlink } = require('fs');
const existsAsync = promisify(exists);
const unlinkAsync = promisify(unlink);

const path = require('path');
const { expect } = require('chai');
const { Installer } = require('../installer');

const installerExists = () => fs.existsSync('./installsig.exe');
const unlinkIfExistsAsync = async (path) => {
if (await existsAsync(path)) {
unlinkAsync(path);
}
};

describe('Installer', () => {
const existingScriptPath = './install.nsi';
before(() => {
if (installerExists()) {
fs.unlinkSync('./installsig.exe');
}
const existingScriptPath = './test/basic.nsi';
before(async () => {
const promises = ['./basic.exe', './with-plugins.exe']
.map(unlinkIfExistsAsync);

await Promise.all(promises);
});

describe('createInstaller', () => {
it('should create installer for install.nsi', () => {
const debugMode = true;
const target = new Installer(debugMode);

target.createInstaller(existingScriptPath);

const actual = installerExists();

expect(actual).to.equal(
true,
'Installer `./installsig.exe` should exist'
);
});
const test = (script, fn) => {
it(`should create installer for ${script}.nsi`, async () => {
const debugMode = true;
const target = new Installer(debugMode);

if (fn) {
fn(target);
}

try {
await target.createInstallerAsync(`./test/${script}.nsi`);
}
catch (err) {
console.error(err);
throw err;
}

const actual = await existsAsync(`./test/${script}.exe`);

expect(actual).to.equal(
true,
`Installer \`./test/${script}.exe\` should exist`
);
});
};

test('basic');
test('with-plugins', target => target.addPluginPath('./test/EnVar'));
});

describe('getProcessArguments', () => {
Expand Down
Loading

0 comments on commit 45688f2

Please sign in to comment.