atomic-reactor-cli
Version:
A CLI for creating Atomic Reactor Awesomeness
177 lines (152 loc) • 5.68 kB
JavaScript
const npm = require('npm');
const tar = require('tar');
const path = require('path');
const chalk = require('chalk');
const fs = require('fs-extra');
const _ = require('underscore');
const op = require('object-path');
const request = require('request');
const mod = path.dirname(require.main.filename);
const targetApp = require(`${mod}/lib/targetApp`);
module.exports = spinner => {
let app, cwd, dir, filepath, name, plugin, sessionToken, tmp, url, version;
const message = text => {
if (spinner) {
spinner.text = text;
}
};
const slugify = str =>
String(str)
.toLowerCase()
.replace(/[^0-9a-z@\-\/]/gi, '-');
const normalize = (...args) => path.normalize(path.join(...args));
return {
init: ({ params, props }) => {
cwd = String(props.cwd)
.split('\\')
.join('/');
app = targetApp(cwd);
sessionToken = op.get(props, 'config.registry.sessionToken');
name = op.get(params, 'name');
if (!name) {
spinner.fail('input plugin name');
process.exit();
}
name = _.compact(String(name).split('@'))[0];
name = String(params.name).substr(0, 1) === '@' ? `@${name}` : name;
const appID = op.get(props, 'config.registry.app', 'ReactiumRegistry');
const serverURL = op.get(props, 'config.registry.server', 'https://v1.reactium.io/api');
Actinium.serverURL = serverURL;
Actinium.initialize(appID);
},
check: () => {
if (!app) {
spinner.fail(
`Current working directory ${chalk.cyan(
cwd,
)} is not an Actinium or Reactium project`,
);
process.exit();
}
},
fetch: () => {
message(`Fetching ${chalk.cyan('plugin')}...`);
return Actinium.Cloud.run(
'registry-get',
{ name, serialized: true },
{ sessionToken },
)
.then(result => {
plugin = result;
})
.catch(err => {
spinner.fail(err.message);
console.log('');
process.exit();
});
},
version: ({ params }) => {
const versions = Object.values(op.get(plugin, 'version', {}));
const nrr = _.compact(String(params.name).split('@'));
version = nrr.length > 1 ? nrr[1] : 'latest';
plugin =
version !== 'latest'
? _.findWhere(versions, { version })
: _.last(versions);
},
download: () => {
message(`Downloading ${chalk.cyan(`${name}@${version}`)}...`);
// Set module dir
dir = normalize(cwd, app + '_modules', slugify(name));
// Create tmp directory
tmp = normalize(dir + '_tmp');
fs.ensureDirSync(tmp);
// File path
filepath = normalize(tmp, plugin.file.name());
// Pipe download to tmp path
return new Promise((resolve, reject) => {
request(plugin.file.url())
.pipe(fs.createWriteStream(filepath))
.on('error', error => reject(error))
.on('close', () => resolve({ action, status: 200 }));
});
},
extract: () => {
message(`Extracting ${chalk.cyan(`${name}@${version}`)}...`);
tar.extract({
cwd: tmp,
file: filepath,
sync: true,
});
},
move: () => {
message(`Copying ${chalk.cyan('files')}...`);
fs.ensureDirSync(dir);
fs.removeSync(filepath);
fs.removeSync(dir);
fs.ensureDirSync(dir);
fs.copySync(tmp, dir);
fs.removeSync(tmp);
fs.ensureDirSync(normalize(dir, 'npm'));
fs.moveSync(
normalize(dir, 'package.json'),
normalize(dir, '_npm', 'package.json'),
{ overwrite: true },
);
},
registerPkg: () => {
message(`Registering plugin...`);
const pkgjson = normalize(cwd, 'package.json');
const pkg = require(pkgjson);
op.set(pkg, [`${app}Dependencies`, name], version);
fs.writeFileSync(pkgjson, JSON.stringify(pkg, null, 2));
},
npm: async () => {
spinner.stopAndPersist({
text: `Installing ${chalk.cyan('dependencies')}...`,
symbol: chalk.cyan('+'),
});
console.log('');
const pkg = [`./${app}_modules`, slugify(name), '_npm'].join('/');
await new Promise((resolve, reject) =>
npm.load(err => {
if (err) reject(err);
npm.commands.install([pkg], err => {
if (err) reject(err);
else resolve();
});
}),
)
.then(() => console.log(''))
.catch(err => {
console.log(err);
process.exit();
});
},
complete: () => {
console.log('');
spinner.start();
spinner.succeed(`Installed ${chalk.cyan(`${name}@${version}`)}`);
},
};
};