venus-acm
Version:
Merge cpp codes into single sources file.
864 lines (831 loc) • 35 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var path = require('path');
var tslib = require('tslib');
var commanderHelper = require('@guanghechen/commander-helper');
var locateHelper = require('@guanghechen/locate-helper');
var optionHelper = require('@guanghechen/option-helper');
var fs = require('fs-extra');
var ChalkLogger = require('@guanghechen/chalk-logger');
var clipboardy = require('clipboardy');
var inquirer = require('inquirer');
var fileHelper = require('@guanghechen/file-helper');
var plopHelper = require('@guanghechen/plop-helper');
var nodePlop = require('node-plop');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var ChalkLogger__default = /*#__PURE__*/_interopDefaultLegacy(ChalkLogger);
var clipboardy__default = /*#__PURE__*/_interopDefaultLegacy(clipboardy);
var inquirer__default = /*#__PURE__*/_interopDefaultLegacy(inquirer);
var nodePlop__default = /*#__PURE__*/_interopDefaultLegacy(nodePlop);
var name = "venus-acm";
var version = "2.0.1";
const COMMAND_NAME = 'venus-acm';
const resourceDir = path__default["default"].resolve(__dirname, '../resources');
const templateRootDir = path__default["default"].join(resourceDir, 'boilerplate');
const languageConfig = {
get macroMarker() {
return '#';
},
get quoteMarker() {
return ["'", '"'];
},
get inlineCommentMarker() {
return '//';
},
get blockCommentMarker() {
return ['/*', '*/'];
},
};
const logger = new ChalkLogger__default["default"]({
name: COMMAND_NAME,
colorful: true,
inline: true,
date: true,
}, process.argv);
function isExists(filepath) {
return filepath !== null && fs__default["default"].existsSync(filepath);
}
function isFile(filepath) {
return isExists(filepath) && fs__default["default"].statSync(filepath).isFile();
}
function ensureExists(filepath, message) {
if (isExists(filepath))
return;
throw new ReferenceError(message !== null && message !== void 0 ? message : `Cannot find '${filepath}'.`);
}
function ensureFileExists(filepath, message) {
ensureExists(filepath, message);
if (fs__default["default"].statSync(filepath).isFile())
return;
throw new ReferenceError(message !== null && message !== void 0 ? message : `${filepath} is not a file path.`);
}
const __defaultGlobalCommandOptions = {
encoding: 'utf-8',
};
function resolveGlobalCommandOptions(commandName, subCommandName, workspaceDir, defaultOptions, options, strategies = {}) {
const resolvedDefaultOptions = commanderHelper.resolveCommandConfigurationOptions(logger, commandName, subCommandName, workspaceDir, Object.assign(Object.assign({}, __defaultGlobalCommandOptions), defaultOptions), options, strategies);
const encoding = optionHelper.cover(resolvedDefaultOptions.encoding, options.encoding, optionHelper.isNonBlankString);
logger.debug('encoding:', encoding);
return Object.assign(Object.assign({}, resolvedDefaultOptions), { encoding });
}
const __defaultCommandOptions$1 = Object.assign(Object.assign({}, __defaultGlobalCommandOptions), { sourceFilepath: '', get includes() {
return [];
}, force: false, copy: false, uglify: false, removeComments: true, removeSpaces: false, removeFreopen: true, removeAssert: true, output: null });
const createSubCommandGenerate = function (handle, commandName = 'generate', aliases = ['g']) {
const command = new commanderHelper.Command();
command
.name(commandName)
.aliases(aliases)
.arguments('<sourceFilepath> [outputFilepath]')
.option('--remove-comments', 'remove comments')
.option('--no-remove-comments')
.option('--remove-spaces', 'remove spaces')
.option('--no-remove-spaces')
.option('--remove-freopen', 'remove freopen statements')
.option('--no-remove-freopen')
.option('--remove-assert', 'remove assert statements')
.option('--no-remove-assert')
.option('-u, --uglify', 'shortcut of --rc --rs.')
.option('--no-uglify')
.option('-c, --copy', 'write generated code into system clipboard')
.option('--no-copy')
.option('-f, --force', 'force write the generated code into output filepath')
.option('--no-force')
.option('-I, --include <include_directory...>', 'include directories')
.option('-o, --output <output filepath>', 'specify the output filepath')
.action(function ([_sourceFilepath], options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
logger.setName(commandName);
const sourceFilepath = path__default["default"].resolve(process.cwd(), _sourceFilepath);
const configFilepath = locateHelper.locateLatestPackageJson(sourceFilepath);
logger.debug('sourceFilepath:', sourceFilepath);
ensureFileExists(configFilepath, 'Cannot find the package.json');
const _workspaceDir = path__default["default"].dirname(configFilepath);
const defaultOptions = resolveGlobalCommandOptions(name, commandName, _workspaceDir, __defaultCommandOptions$1, options);
const { workspace } = defaultOptions;
const includes = optionHelper.cover(defaultOptions.includes, options.includes, optionHelper.isNotEmptyArray);
{
const cmakeListsFilepath = locateHelper.locateNearestFilepath(workspace, 'CMakeLists.txt');
if (cmakeListsFilepath != null) {
const content = yield fs__default["default"].readFile(cmakeListsFilepath, defaultOptions.encoding);
const regex = /\s*include_directories\(\s*(\S+?)\s*\)\s*/gu;
const includeDirectories = [];
for (let m; (m = regex.exec(content)) != null;) {
const includeDirectory = m[1].trim();
includeDirectories.push(includeDirectory);
}
includes.push(...includeDirectories);
}
}
logger.debug('includes:', includes);
const force = optionHelper.coverBoolean(defaultOptions.force, options.force);
logger.debug('force:', force);
const copy = optionHelper.coverBoolean(defaultOptions.copy, options.copy);
logger.debug('copy:', copy);
const uglify = optionHelper.coverBoolean(defaultOptions.uglify, options.uglify);
logger.debug('uglify:', uglify);
const removeComments = optionHelper.coverBoolean(uglify || defaultOptions.removeComments, options.removeComments);
logger.debug('removeComments:', removeComments);
const removeSpaces = optionHelper.coverBoolean(uglify || defaultOptions.removeSpaces, options.removeSpaces);
logger.debug('removeSpaces:', removeSpaces);
const removeFreopen = optionHelper.coverBoolean(defaultOptions.removeFreopen, options.removeFreopen);
logger.debug('removeFreopen:', removeFreopen);
const removeAssert = optionHelper.coverBoolean(defaultOptions.removeAssert, options.removeAssert);
logger.debug('removeAssert:', removeAssert);
const output = optionHelper.cover(copy
? defaultOptions.output != null
? path__default["default"].join(workspace, defaultOptions.output)
: null
: path__default["default"].join(workspace, 'venus.cpp'), options.output, optionHelper.isNonBlankString);
logger.debug('output:', output);
const resolvedOptions = Object.assign(Object.assign({}, defaultOptions), { sourceFilepath,
includes,
removeComments,
removeSpaces,
removeFreopen,
removeAssert,
uglify,
force,
copy,
output });
if (handle != null) {
yield handle(resolvedOptions);
}
});
});
return command;
};
function createGenerateContextFromOptions(options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const context = {
cwd: options.cwd,
workspace: options.workspace,
encoding: options.encoding,
sourceFilepath: options.sourceFilepath,
includes: options.includes,
outputFilepath: options.output,
removeComments: options.removeComments,
removeSpaces: options.removeSpaces,
removeFreopen: options.removeFreopen,
removeAssert: options.removeAssert,
force: options.force,
copy: options.copy,
};
return context;
});
}
function calcInDegree(node, du, nodeMap) {
if (node == null)
return;
nodeMap.set(node.value, node);
for (const o of node.children) {
if (du.has(o.value))
du.set(o.value, du.get(o.value) + 1);
else {
du.set(o.value, 1);
calcInDegree(o, du, nodeMap);
}
}
}
function toposort(node) {
const du = new Map();
const nodeMap = new Map();
const values = [];
const q = [];
calcInDegree(node, du, nodeMap);
du.set(node.value, 0);
for (const [key, val] of du.entries()) {
if (val === 0)
q.push(key);
}
while (q.length > 0) {
const x = q.shift();
values.push(x);
const u = nodeMap.get(x);
for (const v of u.children) {
du.set(v.value, du.get(v.value) - 1);
if (du.get(v.value) === 0)
q.push(v.value);
}
}
return values;
}
function merge(sourceItem) {
const contentPieces = [
...sourceItem.macros.map(({ start, content }) => ({
type: 'macro',
rank: start,
content,
})),
...sourceItem.sources.map(({ start, content }) => ({
type: 'source',
rank: start,
content,
})),
...sourceItem.comments.map(({ start, content }) => ({
type: 'comment',
rank: start,
content,
})),
...sourceItem.literals.map(({ start, content }) => ({
type: 'literal',
rank: start,
content,
})),
]
.sort((x, y) => x.rank - y.rank)
.map((token) => {
if (token.type === 'macro') {
return token.content.replace(/^[\n]*/, '').trimRight() + '\n';
}
return token.content;
});
const dependencies = Array.from(new Set(sourceItem.dependencies))
.sort((x, y) => {
if (x === y)
return 0;
return x < y ? -1 : 1;
})
.map(dependency => `#include <${dependency.trim()}>`)
.join('\n');
const namespaceSet = new Set();
const namespaces = sourceItem.namespaces
.map(ns => ns.trim())
.filter(ns => {
if (namespaceSet.has(ns))
return false;
namespaceSet.add(ns);
return true;
})
.map(ns => `using namespace ${ns};`)
.join('\n');
const typedefs = Array.from(sourceItem.typedefs.entries())
.map(([alias, raw]) => `typedef ${raw} ${alias};`)
.join('\n');
const content = contentPieces
.join('')
.trim()
.replace(/(\n\s*?){2,}/g, '\n\n')
.concat('\n');
const result = dependencies
.concat(namespaces != null && namespaces.length > 0 ? '\n' + namespaces : '')
.concat('\n\n\n')
.concat(typedefs != null && typedefs.length > 0 ? typedefs + '\n\n' : '')
.concat(content.trim())
.concat('\n');
return result;
}
function matchMacro(content, start) {
let i = start;
for (; i > 0; --i) {
if (!/^[\t ]$/u.test(content.charAt(i - 1)))
break;
}
let end = start;
for (; end < content.length; ++end) {
const c = content.charAt(end);
if (c === '\n')
break;
if (c !== '\\')
continue;
for (end += 1; end < content.length; ++end) {
if (/[\S]/u.test(content.charAt(end)))
break;
}
end -= 1;
}
return { start: i, content: content.slice(i, end + 1) };
}
function matchLiteral(content, start) {
let end = start + 1;
const quote = content.charAt(start);
for (; end < content.length; ++end) {
const c = content.charAt(end);
if (c === quote)
break;
if (c === '\\')
end += 1;
}
if (end >= content.length) {
logger.fatal('[Bad]: quote is not closed.', content.slice(start));
process.exit(-1);
}
return { start, content: content.slice(start, end + 1) };
}
function matchInlineComment(content, start, marker) {
let end = start + marker.length;
for (; end < content.length; ++end) {
if (content.charAt(end) === '\n')
break;
}
return { start, content: content.slice(start, end) };
}
function matchBlockComment(content, start, marker) {
let i = start;
for (; i > 0; --i) {
if (!/^[\t ]$/u.test(content.charAt(i - 1)))
break;
}
let end = i + marker[0].length;
for (; end < content.length; ++end) {
if (content.startsWith(marker[1], end))
break;
}
if (end >= content.length) {
logger.fatal('[Bad] block comment is not closed.', content.slice(start));
process.exit(-1);
}
end += marker[1].length;
let lastLinefeedPos = end;
for (; end < content.length; ++end) {
const c = content.charAt(end);
if (c === '\n')
lastLinefeedPos = end + 1;
if (/\S/u.test(c))
break;
}
end = lastLinefeedPos;
return { start: i, content: content.slice(i, end) };
}
function parse(content) {
const { macroMarker, quoteMarker, inlineCommentMarker, blockCommentMarker } = languageConfig;
const macros = [];
const sources = [];
const comments = [];
const literals = [];
const dependencies = [];
const namespaces = [];
const typedefs = new Map();
let lastIndex = 0;
for (let i = lastIndex; i < content.length; ++i) {
let sourcePiece = null;
if (sourcePiece == null && content.startsWith(macroMarker, i)) {
sourcePiece = matchMacro(content, i);
macros.push(sourcePiece);
}
if (sourcePiece == null) {
for (const quote of quoteMarker) {
if (content.startsWith(quote, i)) {
sourcePiece = matchLiteral(content, i);
literals.push(sourcePiece);
}
}
}
if (sourcePiece == null && content.startsWith(inlineCommentMarker, i)) {
sourcePiece = matchInlineComment(content, i, inlineCommentMarker);
comments.push(sourcePiece);
}
if (sourcePiece == null && content.startsWith(blockCommentMarker[0], i)) {
sourcePiece = matchBlockComment(content, i, blockCommentMarker);
comments.push(sourcePiece);
}
if (sourcePiece == null)
continue;
sources.push({
start: lastIndex,
content: content.slice(lastIndex, sourcePiece.start),
});
lastIndex = sourcePiece.start + sourcePiece.content.length;
i = lastIndex - 1;
}
sources.push({ start: lastIndex, content: content.slice(lastIndex) });
for (const macro of macros) {
macro.content = macro.content.replace(/#include\s*[<"]([@\w\-_.:/\\]+)[>"]\s*?\n/g, (_, dependency) => {
dependencies.push(dependency);
return '';
});
}
for (const source of sources) {
source.content = source.content.replace(/using\s+namespace\s+(\w+)\s*;\s*/g, (_, ns) => {
namespaces.push(ns);
return '';
});
}
for (const source of sources) {
source.content = source.content.replace(/typedef\s+([\w* <>]+)\s+(\w+)\s*;\s*/g, (_, raw, alias) => {
typedefs.set(alias, raw);
return '';
});
}
const isNotEmptyPiece = (sourcePiece) => sourcePiece.content.length > 0;
const result = {
macros,
sources: sources.filter(isNotEmptyPiece),
comments: comments.filter(isNotEmptyPiece),
literals: literals.filter(isNotEmptyPiece),
dependencies: Array.from(new Set(dependencies)).filter(d => d.length > 0),
namespaces: namespaces.filter(ns => ns.length > 0),
typedefs,
};
return result;
}
function resolveLocalDependencyPath(dependencies, absoluteSourcePath, workspace, includes) {
const absoluteSourceDirectory = path__default["default"].dirname(absoluteSourcePath);
const resolvedDependencies = [];
for (const dependency of dependencies) {
let resolvedDependency = null;
for (let i = 0; i < includes.length; ++i) {
const absoluteDependencyPath = path__default["default"].resolve(workspace, includes[i], dependency);
if (isFile(absoluteDependencyPath)) {
resolvedDependency = absoluteDependencyPath;
break;
}
}
if (resolvedDependency == null) {
const absoluteDependencyPath = path__default["default"].resolve(absoluteSourceDirectory, dependency);
if (isFile(absoluteDependencyPath)) {
resolvedDependency = absoluteDependencyPath;
}
}
resolvedDependencies.push(resolvedDependency);
}
return resolvedDependencies;
}
function resolveDependencies(resolveDependencyPath, absoluteSourcePath, encoding) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const namespaces = [];
const standardDependencies = [];
const typedefs = new Map();
const o = yield collectDependencies(resolveDependencyPath, absoluteSourcePath, encoding, standardDependencies);
o.value = '';
const localDependencies = toposort(o)
.filter(optionHelper.isNonBlankString)
.reverse();
let result = '';
localDependencies.push(absoluteSourcePath);
for (const dependency of localDependencies) {
ensureFileExists(dependency);
const content = yield fs__default["default"].readFile(dependency, { encoding });
const sourceItem = parse(content);
namespaces.push(...sourceItem.namespaces);
for (const [key, val] of sourceItem.typedefs.entries()) {
typedefs.set(key, val);
}
result += merge(Object.assign(Object.assign({}, sourceItem), { dependencies: [] })).concat('\n');
}
const sourceItem = parse(result);
namespaces.push(...sourceItem.namespaces);
for (const [key, val] of sourceItem.typedefs.entries()) {
typedefs.set(key, val);
}
const resolvedContent = merge(Object.assign(Object.assign({}, sourceItem), { dependencies: standardDependencies, namespaces,
typedefs }));
return resolvedContent;
});
}
function collectDependencies(resolveDependencyPath, absolutePath, encoding, standardDependencies) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const dependencySet = new Set();
const topoNodeMap = new Map();
function collect(absolutePath) {
return tslib.__awaiter(this, void 0, void 0, function* () {
ensureFileExists(absolutePath);
const content = yield fs__default["default"].readFile(absolutePath, { encoding });
const dependencies = parse(content).dependencies.filter(optionHelper.isNonBlankString);
const resolvedDependencies = resolveDependencyPath(dependencies, absolutePath);
if (dependencies.length !== resolvedDependencies.length) {
logger.debug(`dependencies.length(${dependencies.length}) is not equals to resolvedDependencies.length(${resolvedDependencies.length})`);
logger.fatal('process error.');
process.exit(-1);
}
const o = { value: absolutePath, children: [] };
topoNodeMap.set(o.value, o);
for (let i = 0; i < dependencies.length; ++i) {
const dependency = dependencies[i];
const resolvedDependency = resolvedDependencies[i];
if (dependencySet.has(dependency)) {
if (resolvedDependency != null)
o.children.push(topoNodeMap.get(resolvedDependency));
continue;
}
dependencySet.add(dependency);
if (resolvedDependency == null) {
standardDependencies.push(dependency);
continue;
}
const c = yield collect(resolvedDependency);
o.children.push(c);
}
return o;
});
}
const o = yield collect(absolutePath);
return o;
});
}
const copy = (content) => tslib.__awaiter(void 0, void 0, void 0, function* () { return clipboardy__default["default"].write(content); });
function handleCopy(content) {
return tslib.__awaiter(this, void 0, void 0, function* () {
try {
yield copy(content);
logger.info(`Copied to system clipboard.`);
}
catch (error) {
logger.fatal(`Coping failed:`, error);
}
});
}
const assertRegex = /\s*assert\s*\([^]+?\)\s*;([ \t]*\n)?\n*/gu;
function handleRemoveAsserts(content) {
return content.replace(assertRegex, '\n');
}
function handleRemoveComments(content) {
let sourceItem = parse(content);
sourceItem.comments = [];
sourceItem = parse(merge(sourceItem));
return merge(sourceItem);
}
const definitionRegex = /#ifdef\s*?\w*\s*?\n\s*(?:#else)?\s*?\n#endif(?:[^\n]*?)\n+/gu;
const venusDefinitionRegex = /#ifndef\s*?(VENUS\w*)\s*?\n\s*#define\s*?\1\n([^]*?)#endif(?:[^\n]*?)\n+/gu;
function handleRemoveDefinition(content) {
return content
.replace(definitionRegex, '')
.replace(venusDefinitionRegex, '$2');
}
const freopenRegex = /\s*freopen\s*\([\s\S]+?\)\s*;([ \t]*\n)?\n*/gu;
function handleRemoveFreopen(content) {
return content.replace(freopenRegex, '\n');
}
const precedingSpaces = /\s+(?![\w_#])/g;
const followingSpaces = /(?<![\w_])\s+/g;
function handleRemoveSpaces(content) {
const sourceItem = parse(content);
sourceItem.sources = sourceItem.sources
.map(({ start, content }) => ({
start,
content: content.replace(precedingSpaces, ''),
}))
.map(({ start, content }) => ({
start,
content: content.replace(followingSpaces, ''),
}))
.map(({ start, content }) => ({ start, content: content.trim() }));
const removeCommonSpacesPrefix = (content) => {
const maxCommonSpacesPrefix = content
.split(/\n+/g)
.filter(line => !/^\s*$/.test(line))
.map(line => /^(\s*)/.exec(line)[0])
.reduce((prefix, linePrefix) => {
if (prefix == null)
return linePrefix;
let i = 0;
for (const j = Math.min(prefix.length, linePrefix.length); i < j; ++i) {
if (prefix.charAt(i) !== linePrefix.charAt(i))
break;
}
return prefix.slice(0, i);
}, null);
if (maxCommonSpacesPrefix == null)
return content;
return content
.split(/\n/g)
.map(i => i.slice(maxCommonSpacesPrefix.length))
.join('\n');
};
sourceItem.comments = sourceItem.comments
.map(({ start, content }) => ({ start, content: `\n${content}\n` }))
.map(({ start, content }) => ({
start,
content: removeCommonSpacesPrefix(content),
}));
const header = merge({
sources: [],
literals: [],
comments: [],
macros: [],
dependencies: sourceItem.dependencies,
namespaces: sourceItem.namespaces,
typedefs: new Map(),
})
.trim()
.replace(/#include\s*/, '#include');
const body = merge(Object.assign(Object.assign({}, sourceItem), { dependencies: [], namespaces: [], typedefs: new Map() })).trim();
const typedefs = [...sourceItem.typedefs.entries()]
.map(([alias, raw]) => `typedef ${raw} ${alias};`)
.join('');
return header.concat('\n').concat(typedefs).concat(body);
}
function yesOrNo(description, defaultValue = false) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const answer = yield inquirer__default["default"].prompt({
type: 'checkbox',
name: 'yesOrNo',
message: description,
default: defaultValue,
});
return answer.yesOrNo;
});
}
function isUnderThePath(filepath1, filepath2) {
const p = path__default["default"].relative(filepath2, filepath1);
return optionHelper.isNonBlankString(p) && !p.startsWith('..') && !path__default["default"].isAbsolute(p);
}
function relativePath(filepath, cwd, rootDirectory) {
const absoluteFilepath = path__default["default"].resolve(cwd, filepath);
if (rootDirectory != null) {
if (!isUnderThePath(absoluteFilepath, rootDirectory)) {
return absoluteFilepath;
}
}
return path__default["default"].relative(cwd, filepath);
}
function handleSave(context, content) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const { cwd, workspace, encoding, outputFilepath } = context;
if (outputFilepath == null)
return;
const relativeOutputPath = relativePath(outputFilepath, cwd, workspace);
if (!context.force && isExists(outputFilepath)) {
const confirm = yield yesOrNo(`overwrite ${relativeOutputPath}`);
if (!confirm)
return;
}
yield fs__default["default"].writeFile(outputFilepath, content, encoding);
logger.info(`written into ${relativeOutputPath}.`);
});
}
class GenerateProcessor {
constructor(context) {
this.context = context;
}
generate() {
return tslib.__awaiter(this, void 0, void 0, function* () {
const { context } = this;
const sourceFilepath = optionHelper.isNonBlankString(path__default["default"].extname(context.sourceFilepath))
? context.sourceFilepath
: context.sourceFilepath + '.cpp';
let content = yield resolveDependencies((dependencies, absoluteSourcePath) => {
return resolveLocalDependencyPath(dependencies, absoluteSourcePath, context.workspace, context.includes);
}, sourceFilepath, context.encoding);
if (context.removeFreopen) {
content = handleRemoveFreopen(content);
content = handleRemoveDefinition(content);
}
if (context.removeAssert) {
content = handleRemoveAsserts(content);
}
if (context.removeComments)
content = handleRemoveComments(content);
if (context.removeSpaces)
content = handleRemoveSpaces(content);
else
content = content.trim().concat('\n');
if (context.copy) {
yield handleCopy(content);
}
if (context.outputFilepath != null) {
yield handleSave(context, content);
}
});
}
}
const processSubCommandGenerate = function (options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const context = yield createGenerateContextFromOptions(options);
const processor = new GenerateProcessor(context);
yield processor.generate();
});
};
const mountSubCommandGenerate = commanderHelper.createSubCommandMounter(createSubCommandGenerate, processSubCommandGenerate);
const execSubCommandGenerate = commanderHelper.createSubCommandExecutor(createSubCommandGenerate, processSubCommandGenerate);
const __defaultCommandOptions = Object.assign(Object.assign({}, __defaultGlobalCommandOptions), { plopBypass: [] });
const createSubCommandInit = function (handle, commandName = 'init', aliases = ['i']) {
const command = new commanderHelper.Command();
command
.name(commandName)
.aliases(aliases)
.arguments('<workspace>')
.option('--plop-bypass <plopBypass>', 'bypass array to plop', (val, acc) => acc.concat(val), [])
.action(function ([_workspaceDir], options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
logger.setName(commandName);
const defaultOptions = resolveGlobalCommandOptions(name, commandName, _workspaceDir, __defaultCommandOptions, options);
const plopBypass = optionHelper.cover(defaultOptions.plopBypass, options.plopBypass, optionHelper.isNotEmptyArray);
logger.debug('plopBypass:', plopBypass);
const resolvedOptions = Object.assign(Object.assign({}, defaultOptions), { plopBypass });
if (handle != null) {
yield handle(resolvedOptions);
}
});
});
return command;
};
function createInitContextFromOptions(options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const context = {
cwd: options.cwd,
workspace: options.workspace,
encoding: options.encoding,
plopBypass: options.plopBypass,
};
return context;
});
}
function renderTemplates(context, plopBypass) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const availableTemplates = ['simple'];
let templateName;
if (plopBypass.length > 0) {
templateName = plopBypass.shift();
}
else {
templateName = (yield inquirer__default["default"].prompt([
{
type: 'list',
name: 'templateName',
default: availableTemplates[0],
message: 'Which mock server template preferred?',
choices: availableTemplates,
filter: x => optionHelper.toLowerCase(x).trim(),
transformer: (x) => optionHelper.toLowerCase(x).trim(),
},
])).templateName;
}
const templateDir = path__default["default"].join(templateRootDir, templateName);
const templateConfig = path__default["default"].join(templateDir, 'plop.js');
logger.debug('templateName:', templateName);
logger.debug('templateDir:', templateDir);
logger.debug('templateConfig:', templateConfig);
const plop = nodePlop__default["default"](templateConfig, {
force: false,
destBasePath: context.workspace,
});
let bypassForPlopConfigCount = 0;
const generators = plop.getGeneratorList();
if (generators.length === 1) {
const generator = plop.getGenerator(generators[0].name);
bypassForPlopConfigCount = generator.prompts.length;
}
else {
const generateName = plopBypass[0];
const generator = plop.getGenerator(generateName);
bypassForPlopConfigCount = generator.prompts.length + 1;
}
const bypassForPlopConfig = plopBypass.splice(0, bypassForPlopConfigCount);
logger.debug('bypassForPlopConfig:', bypassForPlopConfig);
const error = yield plopHelper.runPlop(plop, bypassForPlopConfig, {
workspace: context.workspace,
});
if (error != null)
logger.error(error);
});
}
class InitProcessor {
constructor(context) {
this.context = context;
}
init() {
return tslib.__awaiter(this, void 0, void 0, function* () {
const { context } = this;
if (!fileHelper.isNonExistentOrEmpty(context.workspace)) {
const relativeProjectPath = path__default["default"].relative(context.cwd, context.workspace);
logger.error(`${relativeProjectPath} is not a non-empty directory path`);
return;
}
const plopBypass = [...context.plopBypass];
yield renderTemplates(context, plopBypass);
const execaOptions = {
stdio: 'inherit',
cwd: context.workspace,
};
yield commanderHelper.installDependencies(execaOptions, plopBypass, logger);
yield commanderHelper.createInitialCommit(execaOptions, plopBypass, logger);
});
}
}
const processSubCommandInit = function (options) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const context = yield createInitContextFromOptions(options);
const processor = new InitProcessor(context);
yield processor.init();
});
};
const mountSubCommandInit = commanderHelper.createSubCommandMounter(createSubCommandInit, processSubCommandInit);
const execSubCommandInit = commanderHelper.createSubCommandExecutor(createSubCommandInit, processSubCommandInit);
function createProgram() {
const program = commanderHelper.createTopCommand(COMMAND_NAME, version);
program.option('--encoding <encoding>', 'default encoding of files in the workspace');
return program;
}
exports.COMMAND_NAME = COMMAND_NAME;
exports.GenerateProcessor = GenerateProcessor;
exports.__defaultGlobalCommandOptions = __defaultGlobalCommandOptions;
exports.createGenerateContextFromOptions = createGenerateContextFromOptions;
exports.createInitContextFromOptions = createInitContextFromOptions;
exports.createProgram = createProgram;
exports.createSubCommandGenerate = createSubCommandGenerate;
exports.createSubCommandInit = createSubCommandInit;
exports.execSubCommandGenerate = execSubCommandGenerate;
exports.execSubCommandInit = execSubCommandInit;
exports.languageConfig = languageConfig;
exports.mountSubCommandGenerate = mountSubCommandGenerate;
exports.mountSubCommandInit = mountSubCommandInit;
exports.packageName = name;
exports.packageVersion = version;
exports.processSubCommandGenerate = processSubCommandGenerate;
exports.processSubCommandInit = processSubCommandInit;
exports.resolveGlobalCommandOptions = resolveGlobalCommandOptions;
exports.resourceDir = resourceDir;
exports.templateRootDir = templateRootDir;
;