UNPKG

imo-img

Version:

image optimize.

285 lines 9.23 kB
// require dependencies var exec = require('child_process').exec, colors = require('colors/safe'), inquirer = require('inquirer'), request = require('request'), fs = require('fs-extra'), del = require('del'); // script default options var remoteConfigURL = 'https://gitlab.com/yasir-yk/imo/blob/master/config.json' + ('?' + Date.now()), basePath = process.cwd() + '/', fileName = 'project.json', clonePath = '', projectConfig; // console menu helper function showMenu(menuConfig, callback) { var menu = { type: 'list', name: 'value', message: '', choices: [] }; menuConfig.forEach(function(item) { menu.choices.push({ name: item.caption, value: item.value }); if(item.question) { menu.message = item.question; } }); inquirer.prompt([menu], function( answers ) { var selectedValue = answers.value, childMenuConfig = null; if(!callback._menuAnswers) { callback._menuAnswers = []; } callback._menuAnswers.push(selectedValue); // need to show submenu? menuConfig.forEach(function(item) { if(item.value === selectedValue && item.menu) { childMenuConfig = item.menu; } }); // show submenu or user selected everything? if(childMenuConfig) { showMenu(childMenuConfig, callback); } else if(typeof callback === 'function') { callback(callback._menuAnswers); delete callback._menuAnswers; } }); } // remote config handler function useMenuConfig(remoteConfig) { var buildConfig = function(selectedOptions, configSample) { var isSelectedOption = function(optionName) { return selectedOptions.indexOf(optionName) > -1; }; ['source', 'ignore', 'run', 'rename'].forEach(function(keyName) { var currentData = configSample[keyName], resultData = []; currentData.forEach(function(item) { var dependenciesOk = true, noConflicts = true; if(item.dependenciesAll) { item.dependenciesAll.forEach(function(depName) { if(!isSelectedOption(depName)) { dependenciesOk = false; } }); } if(item.dependenciesAny && dependenciesOk) { dependenciesOk = false; item.dependenciesAny.forEach(function(depName) { if(isSelectedOption(depName)) { dependenciesOk = true; } }); } if(item.excludeIf) { item.excludeIf.forEach(function(depName) { if(isSelectedOption(depName)) { noConflicts = false; } }); } if(dependenciesOk && noConflicts) { resultData.push(item.matchValue); } }); configSample[keyName] = resultData; }); return configSample; }; showMenu(remoteConfig.createMenu, function(userSelection) { projectConfig = buildConfig(userSelection, remoteConfig.data); clonePath += projectConfig.path || ''; if(projectConfig.source) { cloneGitRepo(); } }); } function startExisting(remoteConfig) { showMenu(remoteConfig.updateMenu, function(userSelection) { var selectedMode = userSelection[0], selectedCommands = null; // detect selected commands remoteConfig.updateMenu.forEach(function(item) { if(item.value === selectedMode) { selectedCommands = item.run; } }); // process commands var resultCommands = []; selectedCommands.forEach(function(item, index) { if(typeof item === 'object') { if(item.fsNotExist && !fs.existsSync(basePath + item.fsNotExist)) { console.log('>>>', item.matchValue); resultCommands.push(item.matchValue); } } else { resultCommands.push(item); } }); // execute specified shell commands if(resultCommands.length) { runShellCommands(resultCommands, basePath + remoteConfig.data.path); } }); } function startInstall() { // search for default file exists var localConfig; if(!fs.existsSync(basePath + fileName)) { console.log('Searching for configuration files in current directory...'); fs.readdirSync(basePath).forEach(function(tmpFileName){ if(fs.statSync(basePath + tmpFileName).isFile() && /^project.*\.json$/i.test(tmpFileName)) { fileName = tmpFileName; } }); } function executeConfig(cfg) { // show copyright if(cfg.copyright) { console.log(colors.yellow(cfg.copyright)); } if(fs.existsSync(basePath + cfg.data.path)) { startExisting(cfg); } else { useMenuConfig(cfg); } } if(fs.existsSync(basePath + fileName)) { // checkout or use existing folder try { console.log('Using configuration file: "' + fileName + '"'); localConfig = require(basePath + fileName); executeConfig(localConfig); } catch(e) { console.log(colors.red('Error in configuration file!')); process.exit(); } } else { console.log('No configuration file found! Loading remote config...'); loadRemoteConfig(function(remoteConfig) { executeConfig(remoteConfig); }); } } function loadRemoteConfig(callback) { request(remoteConfigURL, function (error, response, body) { var remoteConfig = null; if(error) { console.log(colors.red('Cannot load config ' + error)); } else { try { remoteConfig = JSON.parse(body); if(typeof callback === 'function') { callback(remoteConfig); } } catch(e) { console.log(colors.red('Remote config parsing failed!')); } } }); } // 1. Clone git repo: function cloneGitRepo() { var currentCloneIndex = 0, tempFolder = '_w3m-temp'; var cloneRepo = function() { var repoURL = projectConfig.source[currentCloneIndex], child; if(repoURL) { console.log('Cloning git repo: "' + repoURL + '"'); child = exec('git clone ' + repoURL + ' "' + tempFolder + '"'); child.stdout.pipe(process.stdout); child.stderr.pipe(process.stderr); child.on('exit', function() { del.sync(tempFolder + '/.git'); fs.copySync(tempFolder, projectConfig.path); fs.removeSync(tempFolder); currentCloneIndex++; cloneRepo(); }); } else { fs.removeSync(tempFolder); removeUnneededFiles(); } }; if(clonePath && fs.existsSync(clonePath)) { console.log('Folder "' + clonePath + '" already exists. Skip git clone.'); removeUnneededFiles(); } else { console.log('creating target directory: "' + projectConfig.path + '"'); fs.mkdirsSync(projectConfig.path); cloneRepo(); } } // 2. Remove unneeded files function removeUnneededFiles() { var filesToRemove; if(projectConfig.ignore) { console.log('Removing unneeded files...'); filesToRemove = projectConfig.ignore.map(function(value){ return basePath + clonePath + '/' + value; }); del.sync(filesToRemove); } renameFiles(); } // 3. Rename files function renameFiles() { var oldFileName, newFileName; if(projectConfig.rename) { console.log('Renaming files...'); projectConfig.rename.forEach(function(item) { for(var fileName in item) { oldFileName = basePath + clonePath + '/' + fileName; newFileName = basePath + clonePath + '/' + item[fileName]; try { fs.renameSync(oldFileName, newFileName); } catch(e) { } } }); runShellCommands(projectConfig.run, clonePath); } else { runShellCommands(projectConfig.run, clonePath); } } // 4. Run shell command function runShellCommands(commands, cwd, callback) { var activeProcessIndex = 0; var startProcess = function() { var command = commands[activeProcessIndex], child; if(command) { console.log('Starting shell command: "' + command + '"'); child = exec(command); child.stdout.pipe(process.stdout); child.stderr.pipe(process.stderr); child.on('exit', function() { activeProcessIndex++; startProcess(); }); } else if(typeof callback === 'function') { callback(); } }; if(commands && commands.length) { process.chdir(cwd); startProcess(); } } // CLI exports module.exports = { interpret: function(argv) { var cliArgs = argv.slice(2), customFileName = cliArgs[0]; if(customFileName) { fileName = customFileName; } startInstall(); } };