@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
104 lines (96 loc) • 3.39 kB
JavaScript
const os = require('node:os')
const cp = require('node:child_process')
const term = require('../util/term')
const IS_WIN = os.platform() === 'win32'
const REGEX_FLAGS = /--[a-z,a-z-]+[,\s+]\s+/gm
const REGEX_OPTIONS = /--[a-z,a-z-]+\s[^\s]/gm
const REGEX_SHORTCUT_MAPPINGS = /\s-[a-zA-Z]+, --[a-zA-Z-]+/gm
module.exports = {
/**
* Generates `cds lint` help string to print when calling `cds lint [-h, --help]`
* by getting available options/shortcuts from installed version of ESLint
* @param {string} eslintCmd - ESLint command to call
* @returns {string} `cds lint` help string
*/
genEslintHelp: function (eslintCmd) {
let eslintHelp
try {
eslintHelp = cp
.execSync(`${eslintCmd} -h`, {
cwd: process.cwd(),
shell: IS_WIN,
stdio: 'pipe',
})
.toString()
} catch {
console.log(
`${term.error('Cannot call "eslint -h", install and try again.')}\n`
)
}
const eslintOpts = eslintHelp.split('\n')
const cdslintCmd = eslintOpts[0].replace('eslint', '*cds lint*')
eslintOpts[0] = `
# SYNOPSIS
${cdslintCmd}
Runs environment checks and/or checks the specified models
based on the ESLint framework
# OPTIONS`
return `${eslintOpts.join('\n ')}\n`
},
/**
* Generates `cds lint` options array by extracting
* all [--options] and [-shortcuts] strings from help string
* Shortcut order must match order of [options, flags]
* Any options without an shortcut must act as filler (undefined)
* until the shortcuts for the flags start
* @param {string} help - help string and shortcuts array for `cds lint`
* @param {string[]} flags help string and shortcuts array for `cds lint`
* @returns {{
* help: string,
* options: string[],
* shortcuts: string[],
* flags: string[]
* }} `cds lint` allowed options
*/
genEslintShortcutsAndOpts: function (help, flags) {
const allOptions = help
.match(REGEX_OPTIONS)
.map((str) => str.split(' ')[0].trim().replace(',', ''))
const shortcutMappings = help
.match(REGEX_SHORTCUT_MAPPINGS)
.map((str) => str.trim().split(/,\s?/))
const optionsWithShortcuts = []
/** @type {string[]} */
let shortcuts = []
const shortcutsForFlags = []
shortcutMappings.forEach(([short, long]) => {
if (!flags.includes(long)) {
optionsWithShortcuts.push(long)
shortcuts.push(short)
} else {
const index = flags.indexOf(long)
flags.splice(index, 1)
flags.unshift(long)
shortcutsForFlags.unshift(short)
}
})
const optionsWithoutShortcuts = allOptions.filter((o) => !optionsWithShortcuts.includes(o))
optionsWithoutShortcuts.forEach(() => {
shortcuts.push(undefined)
})
/** @type {string[]} */
const options = optionsWithShortcuts.concat(optionsWithoutShortcuts)
shortcuts = shortcuts.concat(shortcutsForFlags)
return [help, options, shortcuts, flags]
},
/**
* Generates a list of ESLint flags by extracting
* all [--options] strings from help string which
* do not require an extra argument
* @param help string from `cds lint [-h, --help]`
* @returns ESLint flags
*/
genEslintFlags: help => help
.match(REGEX_FLAGS)
.map(str => str.trim().replace(',', ''))
}