diff --git a/core/util.mjs b/core/util.mjs index 0d12095..2cfaacc 100644 --- a/core/util.mjs +++ b/core/util.mjs @@ -1,4 +1,5 @@ import path from 'path' +import fs from 'fs/promises' import { spawn } from 'child_process' import { fileURLToPath, pathToFileURL } from 'url' @@ -50,6 +51,22 @@ export default class Util { if (this.getAppNames(config).length === 0) throw new Error('no application was found in config') if (config.debugPort != null && (typeof(config.debugPort) !== 'number' || !config.debugPort)) throw new Error('debugPort in config not a valid number') } + + extractFile(file, stream = function() {}) { + return this.runCommand(this.get7zipExecutable(), ['x', file], path.dirname(file), stream) + .then(() => { + if (!file.indexOf('.tar.')) return + + let tarFile = file.slice(0, file.lastIndexOf('.')) + return fs.stat(tarFile) + .catch(function() { return null }) + .then((stat) => { + if (!stat) return + return this.extractFile(tarFile) + .then(function() { return fs.rm(tarFile, { force: true }) }) + }) + }) + } runCommand(command, options = [], folder = null, stream = function() {}) { return new Promise(function(res, rej) { diff --git a/test/application.test.mjs b/test/application.test.mjs index ed5cd39..7b5eb77 100644 --- a/test/application.test.mjs +++ b/test/application.test.mjs @@ -211,13 +211,39 @@ t.timeout(250).describe('#update()', function() { assert.match(db.data.core.testapp.updater, new RegExp(new Date().toISOString().split('T')[0])) }) - t.test('should call provider download latest correctly if new version', async function() { + t.test('should call provider download latest correctly if new 7zip version', async function() { + const assertError = new Error('Without a fight') + const assertLink = 'All of you' + const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' } + const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z') + + await assert.isRejected(fs.stat('./test/testapp/123456789')) + + provider.getLatestVersion.resolves(assertVersion) + provider.downloadVersion.rejects(assertError) + db.data.core.testapp.updater = '' + + let err = await assert.isRejected(app.update()) + assert.strictEqual(err, assertError) + assert.strictEqual(app.updating, false) + + assert.match(db.data.core.testapp.updater, /found/i) + assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version)) + assert.match(db.data.core.testapp.updater, /downloading/i) + assert.match(db.data.core.testapp.updater, new RegExp(assertLink)) + assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\'))) + assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion) + assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget) + + await fs.stat('./test/testapp/123456789') + }) + + t.test('should call provider download latest correctly if new 7zip version', async function() { const assertError = new Error('Without a fight') const assertLink = 'All of you' const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' } const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z') - await assert.isFulfilled(fs.stat('./test/testapp')) await assert.isRejected(fs.stat('./test/testapp/123456789')) provider.getLatestVersion.resolves(assertVersion) @@ -252,18 +278,4 @@ t.timeout(250).describe('#update()', function() { assert.match(db.data.core.testapp.updater, /already/i) assert.match(db.data.core.testapp.updater, /nothing/i) }) - - t.test('should do nothing if version is found in versions', async function() { - const assertError = new Error('should not be seen') - const assertVersion = { version: '999.888.777.666', filename: 'test.7z' } - provider.getLatestVersion.resolves(assertVersion) - provider.downloadVersion.rejects(assertError) - db.data.core.testapp.updater = '' - db.data.core.testapp.latestInstalled = assertVersion.version - - await app.update() - assert.notOk(provider.downloadVersion.called) - assert.match(db.data.core.testapp.updater, /already/i) - assert.match(db.data.core.testapp.updater, /nothing/i) - }) }) diff --git a/test/testapp/example.7z b/test/testapp/example.7z new file mode 100644 index 0000000..5d14c37 Binary files /dev/null and b/test/testapp/example.7z differ diff --git a/test/testapp/example.tar.gz b/test/testapp/example.tar.gz new file mode 100644 index 0000000..92ff315 Binary files /dev/null and b/test/testapp/example.tar.gz differ diff --git a/test/util.test.mjs b/test/util.test.mjs index d1e6c54..2253a01 100644 --- a/test/util.test.mjs +++ b/test/util.test.mjs @@ -184,3 +184,55 @@ t.describe('#verifyConfig()', function() { }) }) }) + +t.describe('#extractFile()', function() { + var util = new Util(import.meta.url) + + t.afterEach(function() { + return Promise.all([ + fs.rm('./test/testapp/example.tar', { force: true }), + fs.rm('./test/testapp/file1.txt', { force: true }), + fs.rm('./test/testapp/file2.txt', { force: true }), + ]) + }) + + t.test('should support extracting 7z file', async function() { + await Promise.all([ + assert.isRejected(fs.stat(util.getPathFromRoot('./testapp/file1.txt'))), + assert.isRejected(fs.stat(util.getPathFromRoot('./testapp/file2.txt'))), + ]) + + await util.extractFile(util.getPathFromRoot('./testapp/example.7z')) + + let stats = await Promise.all([ + fs.stat(util.getPathFromRoot('./testapp/file1.txt')), + fs.stat(util.getPathFromRoot('./testapp/file2.txt')), + ]) + assert.strictEqual(stats[0].size, 5) + assert.strictEqual(stats[1].size, 5) + }) + + t.test('should support extracting .tar.gz file', async function() { + await Promise.all([ + assert.isRejected(fs.stat(util.getPathFromRoot('./testapp/file1.txt'))), + assert.isRejected(fs.stat(util.getPathFromRoot('./testapp/file2.txt'))), + ]) + + await util.extractFile(util.getPathFromRoot('./testapp/example.tar.gz')) + + let stats = await Promise.all([ + fs.stat(util.getPathFromRoot('./testapp/file1.txt')), + fs.stat(util.getPathFromRoot('./testapp/file2.txt')), + ]) + assert.strictEqual(stats[0].size, 5) + assert.strictEqual(stats[1].size, 5) + + await assert.isRejected(fs.stat(util.getPathFromRoot('./testapp/example.tar'))) + }) + + t.test('should stream the process of extracting', async function() { + let output = '' + await util.extractFile(util.getPathFromRoot('./testapp/example.tar.gz'), function(msg) { output += msg + '\n' }) + console.log(output) + }) +})