Skip to content

Commit

Permalink
Abstracted package manager utility functions (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
andersevenrud committed Apr 11, 2020
1 parent 233e2e4 commit 8877506
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 40 deletions.
44 changes: 15 additions & 29 deletions src/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,17 @@ const fs = require('fs-extra');
const fg = require('fast-glob');
const path = require('path');
const consola = require('consola');
const bent = require('bent');
const tar = require('tar');
const Package = require('./package.js');
const {getPrefix} = require('./utils/vfs.js');
const logger = consola.withTag('Packages');

const relative = filename => filename.replace(process.cwd(), '');
const {
relative,
archiveName,
fetchSteam,
readOrDefault,
extract
} = require('./utils/packages.js');

const readOrDefault = filename => fs.existsSync(filename)
? fs.readJsonSync(filename)
: [];

const extract = (stream, target) => new Promise((resolve, reject) => {
stream.once('end', () => resolve());
stream.once('error', error => reject(error));
stream.pipe(tar.extract({C: target}));
});
const logger = consola.withTag('Packages');

/**
* @typedef InstallPackageOptions
Expand Down Expand Up @@ -156,30 +150,22 @@ class Packages {
* @param {object} user
*/
async installPackage(url, options, user) {
const {realpath} = this.core.make('osjs/vfs');

if (!options.root) {
throw new Error('Missing package installation root path');
}

const {realpath} = this.core.make('osjs/vfs');

const name = path.basename(url.split('?')[0])
.replace(/\.[^/.]+$/, '');

const userRoot = options.root;
const target = await realpath(`${userRoot}/${name}`, user);
const name = archiveName(url);
const target = await realpath(`${options.root}/${name}`, user);

if (await fs.exists(target)) {
throw new Error('Target already exists');
}

if (options.system) {
} else if (options.system) {
throw new Error('System packages not yet implemented');
}

const stream = await bent()(url, null, {
headers: options.headers || {}
});

const stream = await fetchSteam(url, options);
await fs.mkdir(target);
await extract(stream, target);

Expand All @@ -190,7 +176,7 @@ class Packages {
throw new Error('Invalid package');
}

await this.writeUserManifest(userRoot, user);
await this.writeUserManifest(options.root, user);

return {
reload: !options.system
Expand Down
28 changes: 17 additions & 11 deletions src/providers/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,23 @@ class PackageServiceProvider extends ServiceProvider {
res.status(400).json({error: 'Action failed'});
});

routeAuthenticated('GET', '/api/packages/metadata', usingPackageManager((req, res) => {
return this.packages.readPackageManifests(req.query.root || [], req.session.user);
}));

routeAuthenticated('POST', '/api/packages/install', usingPackageManager((req, res) => {
return this.packages.installPackage(req.body.url, req.body.options, req.session.user);
}));

routeAuthenticated('POST', '/api/packages/uninstall', usingPackageManager((req, res) => {
return this.packages.uninstallPackage(req.body.name, req.body.options, req.session.user);
}));
routeAuthenticated(
'GET',
'/api/packages/metadata',
usingPackageManager(req => this.packages.readPackageManifests(req.query.root || [], req.session.user))
);

routeAuthenticated(
'POST',
'/api/packages/install',
usingPackageManager(req => this.packages.installPackage(req.body.url, req.body.options, req.session.user))
);

routeAuthenticated(
'POST',
'/api/packages/uninstall',
usingPackageManager(req => this.packages.uninstallPackage(req.body.name, req.body.options, req.session.user))
);

return this.packages.init();
}
Expand Down
63 changes: 63 additions & 0 deletions src/utils/packages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* OS.js - JavaScript Cloud/Web Desktop Platform
*
* Copyright (c) 2011-2020, Anders Evenrud <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Anders Evenrud <[email protected]>
* @licence Simplified BSD License
*/

const bent = require('bent');
const tar = require('tar');
const path = require('path');
const fs = require('fs-extra');

const relative = filename => filename
.replace(process.cwd(), '');

const archiveName = url => path
.basename(url.split('?')[0])
.replace(/\.[^/.]+$/, '');

const fetchSteam = (url, options) => bent()(url, null, {
headers: options.headers || {}
});

const readOrDefault = filename => fs.existsSync(filename)
? fs.readJsonSync(filename)
: [];

const extract = (stream, target) => new Promise((resolve, reject) => {
stream.once('end', () => resolve());
stream.once('error', error => reject(error));
stream.pipe(tar.extract({C: target}));
});

module.exports = {
relative,
archiveName,
fetchSteam,
readOrDefault,
extract
};

0 comments on commit 8877506

Please sign in to comment.