create-yard-app
Version:
CLI tool to create indepedent ops portal apps
195 lines (161 loc) • 6.86 kB
JavaScript
;
var _validateNpmPackageName = require('validate-npm-package-name');
var _validateNpmPackageName2 = _interopRequireDefault(_validateNpmPackageName);
var _chalk = require('chalk');
var _chalk2 = _interopRequireDefault(_chalk);
var _commander = require('commander');
var _commander2 = _interopRequireDefault(_commander);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _dns = require('dns');
var _dns2 = _interopRequireDefault(_dns);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _crossSpawn = require('cross-spawn');
var _crossSpawn2 = _interopRequireDefault(_crossSpawn);
var _package = require('../package.json');
var _package2 = _interopRequireDefault(_package);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function validateAppName(appName) {
var validationResult = (0, _validateNpmPackageName2.default)(appName);
if (!validationResult.validForNewPackages) {
console.error('Could not create a App called ' + _chalk2.default.red(appName) + ' because of npm naming restrictions');
console.error(validationResult.errors);
console.warn(validationResult.warnings);
process.exit(1);
}
}
function checkIfOnline() {
return new Promise(function (resolve) {
_dns2.default.resolve('registry.yarnpkg.com', function (err) {
resolve(err === null);
});
});
}
function isSafeToCreateProjectIn(root, name) {
var validFiles = ['.DS_Store', 'Thumbs.db', '.git', '.gitignore', '.idea', 'README.md', 'LICENSE', 'web.iml'];
var isSafe = _fsExtra2.default.readdirSync(root).every(function (file) {
return validFiles.indexOf(file) >= 0;
});
if (!isSafe) {
console.log('The directory ' + _chalk2.default.green(name) + ' contains files that could conflict.');
console.log('Try using a new directory name.');
process.exit(1);
}
}
function install() {
var depedencies = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var isOnline = arguments[1];
return new Promise(function (resolve, reject) {
var command = 'yarnpkg';
var args = ['add', '--exact'].concat(depedencies);
if (!isOnline) {
console.log(_chalk2.default.yellow('You appear to be offline'));
console.log(_chalk2.default.yellow('Falling back to yarn local cache'));
console.log();
}
(0, _crossSpawn2.default)(command, args, { stdio: 'inherit' }).on('close', function (code) {
if (code !== 0) {
reject({
command: command + ' ' + args.join(' ')
});
return;
}
resolve();
});
});
}
function writeBasicPackageJSON(name, root) {
var packageJSONContents = {
name: name,
version: '0.1.0',
private: true
};
_fsExtra2.default.writeFileSync(_path2.default.join(root, 'package.json'), JSON.stringify(packageJSONContents, null, 2));
}
function initProject(root, packageName, name) {
var scriptsPath = _path2.default.resolve(root, 'node_modules', packageName, 'dist', 'scripts', 'init.js');
var init = require(scriptsPath).default;
init(root, name);
}
function fixDependencies(packageName) {
var packagePath = _path2.default.join(process.cwd(), 'package.json');
var packageJson = require(packagePath);
if (typeof packageJson.dependencies === 'undefined') {
console.error(_chalk2.default.red('Missing dependencies in package.json'));
process.exit(1);
}
var packageVersion = packageJson.dependencies[packageName];
if (typeof packageVersion === 'undefined') {
console.error(_chalk2.default.red('Unable to find ' + packageName + ' in package.json'));
process.exit(1);
}
packageJson.devDependencies = packageJson.devDependencies || {};
packageJson.devDependencies[packageName] = packageVersion;
delete packageJson.dependencies[packageName];
_fsExtra2.default.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
}
function installYardScripts(root, name) {
var packageToBeInstalled = 'g2-ops-scripts';
checkIfOnline().then(function (isOnline) {
// Online
console.log('Installing ' + _chalk2.default.cyan(packageToBeInstalled) + ' ...');
return install([packageToBeInstalled], isOnline);
}).then(function () {
fixDependencies(packageToBeInstalled);
initProject(root, packageToBeInstalled);
}).catch(function (reason) {
console.log();
console.log('Aborting installation.');
if (reason.command) {
console.log(' ' + _chalk2.default.cyan(reason.command), 'has failed.');
} else {
console.log(_chalk2.default.red('Unexpected error. Please report it as a bug:'));
console.log(reason);
}
console.log();
// On 'exit' we will delete these files from target directory.
var knownGeneratedFiles = ['package.json', 'npm-debug.log', 'yarn-error.log', 'yarn-debug.log', 'node_modules'];
var currentFiles = _fsExtra2.default.readdirSync(_path2.default.join(root));
currentFiles.forEach(function (file) {
knownGeneratedFiles.forEach(function (fileToMatch) {
// This will catch `(npm-debug|yarn-error|yarn-debug).log*` files
// and the rest of knownGeneratedFiles.
if (fileToMatch.match(/.log/g) && file.indexOf(fileToMatch) === 0 || file === fileToMatch) {
console.log('Deleting generated file...', _chalk2.default.cyan(file));
_fsExtra2.default.removeSync(_path2.default.join(root, file));
}
});
});
var remainingFiles = _fsExtra2.default.readdirSync(_path2.default.join(root));
if (!remainingFiles.length) {
// Delete target folder if empty
console.log('Deleting', _chalk2.default.cyan(appName + '/'), 'from', _chalk2.default.cyan(_path2.default.resolve(root, '..')));
process.chdir(_path2.default.resolve(root, '..'));
_fsExtra2.default.removeSync(_path2.default.join(root));
}
console.log('Done.');
process.exit(1);
});
}
function createProject(name) {
validateAppName(name);
var root = _path2.default.resolve(name);
var appName = _path2.default.basename(root);
// Here we have valid app name
_fsExtra2.default.ensureDirSync(name); // Create app directory if you don't have a directory
isSafeToCreateProjectIn(root, name);
// it is safe to create project
writeBasicPackageJSON(name, root);
process.chdir(root);
installYardScripts(root, name);
// TODO: Copy Template to the destination
// TODO: Install all depedencies declared in template
}
var appName = '';
// Reading in Command Line arguments
new _commander2.default.Command(_package2.default.name).version(_package2.default.version).arguments('<project-directory>').usage(_chalk2.default.green('<project-directory>') + ' [options]').action(function (name) {
appName = name;
}).parse(process.argv);
createProject(appName);