From fda023b588cf223b7a46836c3c867a9632884241 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Tue, 27 Oct 2020 12:27:20 +0300 Subject: [PATCH 1/3] feat(command-line): added command line parser utility --- src/utils/commandLine/command.js | 127 +++++++++ src/utils/commandLine/utils.js | 51 ++++ test/commandLine-utils.spec.js | 439 +++++++++++++++++++++++++++++++ 3 files changed, 617 insertions(+) create mode 100644 src/utils/commandLine/command.js create mode 100644 src/utils/commandLine/utils.js create mode 100644 test/commandLine-utils.spec.js diff --git a/src/utils/commandLine/command.js b/src/utils/commandLine/command.js new file mode 100644 index 000000000..8e02f0187 --- /dev/null +++ b/src/utils/commandLine/command.js @@ -0,0 +1,127 @@ +const arrToObj = (arr) => arr.reduce((o, key) => ({ ...o, [key]: key }), {}) + +const initialCommands = arrToObj([ + ...new Set([ + 'create', + 'web', + 'build-DB', + 'compile', + 'build', + 'compilebuild', + 'deploy', + 'compilebuilddeploy', + 'servicepack', + 'context', + 'add', + 'run', + 'request', + 'folder', + 'job' + ]) +]) + +const initialFlags = arrToObj([ + ...new Set([ + 'target', + 'source', + 'template', + 'source', + 'datafile', + 'configfile', + 'wait', + 'output', + 'force' + ]) +]) + +export class Command { + initialCommands = initialCommands + initialFlags = initialFlags + + initialAliases = [ + { name: initialCommands['build-DB'], aliases: ['db'] }, + { name: initialCommands.compile, aliases: ['c'] }, + { name: initialCommands.build, aliases: ['b'] }, + { name: initialCommands.compilebuild, aliases: ['cb'] }, + { name: initialCommands.deploy, aliases: ['d'] }, + { name: initialCommands.compilebuilddeploy, aliases: ['cbd'] }, + { name: initialCommands.web, aliases: ['w'] }, + { name: initialCommands.add, aliases: ['a'] }, + { name: initialCommands.run, aliases: ['r'] }, + { name: initialCommands.request, aliases: ['rq'] } + ] + + commandFlags = [ + { + command: initialCommands.folder, + flags: [initialFlags.target, initialFlags.force] + }, + { + command: initialCommands.context, + flags: [initialFlags.target, initialFlags.source] + }, + { command: initialCommands.create, flags: [initialFlags.template] }, + { command: initialCommands.web, flags: [initialFlags.target] }, + { command: initialCommands['build-DB'], flags: [initialFlags.target] }, + { command: initialCommands.compile, flags: [initialFlags.target] }, + { command: initialCommands.build, flags: [initialFlags.target] }, + { command: initialCommands.compilebuild, flags: [initialFlags.target] }, + { command: initialCommands.deploy, flags: [initialFlags.target] }, + { + command: initialCommands.compilebuilddeploy, + flags: [initialFlags.target] + }, + { + command: initialCommands.servicepack, + flags: [initialFlags.target, initialFlags.source] + }, + { command: initialCommands.run, flags: [initialFlags.target] }, + { + command: initialCommands.request, + flags: [ + initialFlags.target, + initialFlags.datafile, + initialFlags.configfile + ] + }, + { + command: initialCommands.job, + flags: [initialFlags.target, initialFlags.wait, initialFlags.output] + } + ] + + constructor(name) { + if (!name || typeof name !== 'string') throw 'Not valid command name!' + + this.name = Object.keys(this.initialCommands).includes(name) + ? name + : this.initialAliases.find((alias) => alias.aliases.includes(name)).name + + this.aliases = this.initialAliases.find((alias) => alias.name === this.name) + this.aliases = this.aliases ? this.aliases.aliases : null + + this.flags = this.commandFlags.filter( + (commandFlag) => commandFlag.command === this.name + ) + this.flags = this.flags[0].flags.map((flag) => new Flag(flag)) + } +} + +class Flag { + flagsWithValue = [ + initialFlags.target, + initialFlags.source, + initialFlags.template, + initialFlags.datafile, + initialFlags.configfile + ] + + constructor(name, isRequired = false) { + if (!name || typeof name !== 'string') throw 'Not valid flag name!' + + this.name = name + this.longSyntax = '--' + name + this.shortSyntax = '-' + name[0] + this.withValue = this.flagsWithValue.includes(name) + } +} diff --git a/src/utils/commandLine/utils.js b/src/utils/commandLine/utils.js new file mode 100644 index 000000000..a361f9acc --- /dev/null +++ b/src/utils/commandLine/utils.js @@ -0,0 +1,51 @@ +import { Command } from './command' + +export function parseCommandLine(commandLine) { + if (!Array.isArray(commandLine)) throw 'commandLine should be an array' + + if (!commandLine.length) { + console.log(chalk.redBright(`Please provide sasjs command.`)) + + return + } + + const command = new Command(commandLine.shift()) + const initialFlags = Object.keys(command.initialFlags) + const commandValues = [] + const flagValues = [] + + for (let i = 0; i < commandLine.length; i++) { + if (/^-/.test(commandLine[i]) && command.flags) { + let flag = commandLine[i].split('-').join('') + const regExp = new RegExp(`^${flag}`) + + flag = initialFlags + .filter((f) => regExp.test(f)) + .filter((f) => + command.flags.map((commandFlag) => commandFlag.name).includes(f) + )[0] + flag = command.flags.find((f) => f.name === flag) + + if (flag.withValue) { + i++ + + const value = commandLine[i] + + if (value) flagValues.push({ [flag.name]: value }) + } else { + flagValues.push(flag.name) + } + } else { + commandValues.push(commandLine[i]) + } + } + + if (flagValues.length && commandValues.length) { + return { + commandValues, + flagValues + } + } else if (!flagValues.length && !commandValues.length) return {} + else if (!flagValues.length) return { commandValues } + else return { flagValues } +} diff --git a/test/commandLine-utils.spec.js b/test/commandLine-utils.spec.js new file mode 100644 index 000000000..41deade21 --- /dev/null +++ b/test/commandLine-utils.spec.js @@ -0,0 +1,439 @@ +import { parseCommandLine } from '../src/utils/commandLine/utils' + +describe('parseCommandLine', () => { + describe('folder command', () => { + test('without flags', () => { + const command = 'folder create /Public/folder'.split(' ') + + const expectedOutput = { + commandValues: ['create', '/Public/folder'] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('full syntax', () => { + const command = 'folder create /Public/folder --target targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['create', '/Public/folder'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('short syntax', () => { + const command = 'folder create /Public/folder -t targetName'.split(' ') + + const expectedOutput = { + commandValues: ['create', '/Public/folder'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('short syntax with force flag', () => { + const command = 'folder create /Public/folder -t targetName -f'.split(' ') + + const expectedOutput = { + commandValues: ['create', '/Public/folder'], + flagValues: [{ target: 'targetName' }, 'force'] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('move command full syntax', () => { + const command = 'folder move /Public/sourceFolder /Public/targetFolder --target targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('move command short syntax', () => { + const command = 'folder move -t targetName /Public/sourceFolder /Public/targetFolder'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('move command without flags', () => { + const command = 'folder move /Public/sourceFolder /Public/targetFolder'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('context command', () => { + test('create command full syntax', () => { + const command = 'context create --source ../contextConfig.json --target targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['create'], + flagValues: [ + { source: '../contextConfig.json' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('create command short syntax', () => { + const command = 'context create -s ../contextConfig.json -t targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['create'], + flagValues: [ + { source: '../contextConfig.json' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('delete command short syntax', () => { + const command = 'context delete contextName -t targetName'.split(' ') + + const expectedOutput = { + commandValues: ['delete', 'contextName'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('list command short syntax', () => { + const command = 'context list -t targetName'.split(' ') + + const expectedOutput = { + commandValues: ['list'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('export command short syntax', () => { + const command = 'context export contextName -t targetName'.split(' ') + + const expectedOutput = { + commandValues: ['export', 'contextName'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('create command', () => { + test('create command', () => { + const command = 'create'.split(' ') + + const expectedOutput = {} + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('create command with folder name', () => { + const command = 'create folderName'.split(' ') + + const expectedOutput = { commandValues: ['folderName'] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('create command with folder name and template full syntax', () => { + const command = 'create my-sas-project --template react'.split(' ') + + const expectedOutput = { + commandValues: ['my-sas-project'], + flagValues: [{ template: 'react' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('create command with folder name and template short syntax', () => { + const command = 'create -t angular my-sas-project'.split(' ') + + const expectedOutput = { + commandValues: ['my-sas-project'], + flagValues: [{ template: 'angular' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('web command', () => { + test('full syntax', () => { + const command = 'web --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'w -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('build-DB command', () => { + test('full syntax', () => { + const command = 'build-DB --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'db -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('compile command', () => { + test('full syntax', () => { + const command = 'compile --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'c -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('build command', () => { + test('full syntax', () => { + const command = 'build --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'b -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('compilebuild command', () => { + test('full syntax', () => { + const command = 'compilebuild --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'cb -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('deploy command', () => { + test('full syntax', () => { + const command = 'deploy --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'd -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('compilebuilddeploy command', () => { + test('full syntax', () => { + const command = 'compilebuilddeploy --target targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'cbd -t targetName'.split(' ') + + const expectedOutput = { flagValues: [{ target: 'targetName' }] } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('servicepack command', () => { + test('full syntax', () => { + const command = 'servicepack deploy --source ./path/services.json --target targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['deploy'], + flagValues: [ + { source: './path/services.json' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('short syntax', () => { + const command = 'servicepack deploy -s ./path/services.json -t targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['deploy'], + flagValues: [ + { source: './path/services.json' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('run command', () => { + test('full syntax', () => { + const command = 'run ./sasFilePath.sas --target targetName'.split(' ') + + const expectedOutput = { + commandValues: ['./sasFilePath.sas'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'r ./sasFilePath.sas -t targetName'.split(' ') + + const expectedOutput = { + commandValues: ['./sasFilePath.sas'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('request command', () => { + test('full syntax', () => { + const command = 'request ./sasFilePath.sas --datafile --configfile --target targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['./sasFilePath.sas'], + flagValues: [ + { datafile: '' }, + { configfile: '' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('alias', () => { + const command = 'rq ./sasFilePath.sas -d -c -t targetName'.split( + ' ' + ) + + const expectedOutput = { + commandValues: ['./sasFilePath.sas'], + flagValues: [ + { datafile: '' }, + { configfile: '' }, + { target: 'targetName' } + ] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) + + describe('job command', () => { + test('full syntax', () => { + const command = 'job execute /Public/job --target targetName'.split(' ') + + const expectedOutput = { + commandValues: ['execute', '/Public/job'], + flagValues: [{ target: 'targetName' }] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + + test('short syntax', () => { + const command = 'job execute -t targetName -w -o /Public/job'.split(' ') + + const expectedOutput = { + commandValues: ['execute', '/Public/job'], + flagValues: [{ target: 'targetName' }, 'wait', 'output'] + } + + expect(parseCommandLine(command)).toEqual(expectedOutput) + }) + }) +}) From 7583abe77d6577286ad67635a22de53cf8d07349 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Tue, 27 Oct 2020 17:03:42 +0300 Subject: [PATCH 2/3] chore(command-line): encapsulated command line parsing logic into 'Command' class --- src/utils/command.js | 161 ++++++++++ src/utils/commandLine/command.js | 127 -------- src/utils/commandLine/utils.js | 51 ---- test/commandLine-utils.spec.js | 439 --------------------------- test/utils/command.spec.js | 501 +++++++++++++++++++++++++++++++ 5 files changed, 662 insertions(+), 617 deletions(-) create mode 100644 src/utils/command.js delete mode 100644 src/utils/commandLine/command.js delete mode 100644 src/utils/commandLine/utils.js delete mode 100644 test/commandLine-utils.spec.js create mode 100644 test/utils/command.spec.js diff --git a/src/utils/command.js b/src/utils/command.js new file mode 100644 index 000000000..2eb43d4eb --- /dev/null +++ b/src/utils/command.js @@ -0,0 +1,161 @@ +const arrToObj = (arr) => arr.reduce((o, key) => ({ ...o, [key]: key }), {}) + +const initialCommands = arrToObj([ + ...new Set([ + 'create', + 'web', + 'build-DB', + 'compile', + 'build', + 'compilebuild', + 'deploy', + 'compilebuilddeploy', + 'servicepack', + 'context', + 'add', + 'run', + 'request', + 'folder', + 'job' + ]) +]) + +const initialFlags = arrToObj([ + ...new Set([ + 'target', + 'source', + 'template', + 'source', + 'datafile', + 'configfile', + 'wait', + 'output', + 'force' + ]) +]) + +const initialAliases = [ + { name: initialCommands['build-DB'], aliases: ['db'] }, + { name: initialCommands.compile, aliases: ['c'] }, + { name: initialCommands.build, aliases: ['b'] }, + { name: initialCommands.compilebuild, aliases: ['cb'] }, + { name: initialCommands.deploy, aliases: ['d'] }, + { name: initialCommands.compilebuilddeploy, aliases: ['cbd'] }, + { name: initialCommands.web, aliases: ['w'] }, + { name: initialCommands.add, aliases: ['a'] }, + { name: initialCommands.run, aliases: ['r'] }, + { name: initialCommands.request, aliases: ['rq'] } +] + +const commandFlags = [ + { + command: initialCommands.folder, + flags: [initialFlags.target, initialFlags.force] + }, + { + command: initialCommands.context, + flags: [initialFlags.target, initialFlags.source] + }, + { command: initialCommands.create, flags: [initialFlags.template] }, + { command: initialCommands.web, flags: [initialFlags.target] }, + { command: initialCommands['build-DB'], flags: [initialFlags.target] }, + { command: initialCommands.compile, flags: [initialFlags.target] }, + { command: initialCommands.build, flags: [initialFlags.target] }, + { command: initialCommands.compilebuild, flags: [initialFlags.target] }, + { command: initialCommands.deploy, flags: [initialFlags.target] }, + { + command: initialCommands.compilebuilddeploy, + flags: [initialFlags.target] + }, + { + command: initialCommands.servicepack, + flags: [initialFlags.target, initialFlags.source] + }, + { command: initialCommands.run, flags: [initialFlags.target] }, + { + command: initialCommands.request, + flags: [initialFlags.target, initialFlags.datafile, initialFlags.configfile] + }, + { + command: initialCommands.job, + flags: [initialFlags.target, initialFlags.wait, initialFlags.output] + } +] + +const flagsWithValue = [ + initialFlags.target, + initialFlags.source, + initialFlags.template, + initialFlags.datafile, + initialFlags.configfile +] + +export class Command { + values = [] + flags = [] + + constructor(commandLine) { + if (typeof commandLine === 'string') commandLine = commandLine.split(' ') + + if (!Array.isArray(commandLine)) throw 'commandLine should be an array' + const command = commandLine.shift() + + this.name = Object.keys(initialCommands).includes(command) + ? command + : initialAliases.find((alias) => alias.aliases.includes(command)).name + + this.aliases = initialAliases.find((alias) => alias.name === this.name) + this.aliases = this.aliases ? this.aliases.aliases : null + + this.supportedFlags = commandFlags.filter( + (commandFlag) => commandFlag.command === this.name + )[0].flags + + console.log(`[this]`, this) + + for (let i = 0; i < commandLine.length; i++) { + console.log(`[commandLine[i]]`, commandLine[i]) + if (/^-/.test(commandLine[i]) && this.supportedFlags) { + let flag = commandLine[i].split('-').join('') + const regExp = new RegExp(`^${flag}`) + + flag = Object.keys(initialFlags) + .filter((f) => regExp.test(f)) + .filter((f) => this.supportedFlags.includes(f))[0] + + flag = new Flag(flag) + + this.flags.push(flag) + + if (flag.withValue) { + i++ + + const value = commandLine[i] + + if (value) { + this.flags.find((f) => f.name === flag.name).setValue(value) + } + } + } else { + this.values.push(commandLine[i]) + } + } + } +} + +class Flag { + value = null + + constructor(name) { + if (!name || typeof name !== 'string') throw 'Not valid flag name!' + + this.name = name + this.longSyntax = '--' + name + this.shortSyntax = '-' + name[0] + this.withValue = flagsWithValue.includes(name) + } + + setValue(value) { + this.value = value + } +} diff --git a/src/utils/commandLine/command.js b/src/utils/commandLine/command.js deleted file mode 100644 index 8e02f0187..000000000 --- a/src/utils/commandLine/command.js +++ /dev/null @@ -1,127 +0,0 @@ -const arrToObj = (arr) => arr.reduce((o, key) => ({ ...o, [key]: key }), {}) - -const initialCommands = arrToObj([ - ...new Set([ - 'create', - 'web', - 'build-DB', - 'compile', - 'build', - 'compilebuild', - 'deploy', - 'compilebuilddeploy', - 'servicepack', - 'context', - 'add', - 'run', - 'request', - 'folder', - 'job' - ]) -]) - -const initialFlags = arrToObj([ - ...new Set([ - 'target', - 'source', - 'template', - 'source', - 'datafile', - 'configfile', - 'wait', - 'output', - 'force' - ]) -]) - -export class Command { - initialCommands = initialCommands - initialFlags = initialFlags - - initialAliases = [ - { name: initialCommands['build-DB'], aliases: ['db'] }, - { name: initialCommands.compile, aliases: ['c'] }, - { name: initialCommands.build, aliases: ['b'] }, - { name: initialCommands.compilebuild, aliases: ['cb'] }, - { name: initialCommands.deploy, aliases: ['d'] }, - { name: initialCommands.compilebuilddeploy, aliases: ['cbd'] }, - { name: initialCommands.web, aliases: ['w'] }, - { name: initialCommands.add, aliases: ['a'] }, - { name: initialCommands.run, aliases: ['r'] }, - { name: initialCommands.request, aliases: ['rq'] } - ] - - commandFlags = [ - { - command: initialCommands.folder, - flags: [initialFlags.target, initialFlags.force] - }, - { - command: initialCommands.context, - flags: [initialFlags.target, initialFlags.source] - }, - { command: initialCommands.create, flags: [initialFlags.template] }, - { command: initialCommands.web, flags: [initialFlags.target] }, - { command: initialCommands['build-DB'], flags: [initialFlags.target] }, - { command: initialCommands.compile, flags: [initialFlags.target] }, - { command: initialCommands.build, flags: [initialFlags.target] }, - { command: initialCommands.compilebuild, flags: [initialFlags.target] }, - { command: initialCommands.deploy, flags: [initialFlags.target] }, - { - command: initialCommands.compilebuilddeploy, - flags: [initialFlags.target] - }, - { - command: initialCommands.servicepack, - flags: [initialFlags.target, initialFlags.source] - }, - { command: initialCommands.run, flags: [initialFlags.target] }, - { - command: initialCommands.request, - flags: [ - initialFlags.target, - initialFlags.datafile, - initialFlags.configfile - ] - }, - { - command: initialCommands.job, - flags: [initialFlags.target, initialFlags.wait, initialFlags.output] - } - ] - - constructor(name) { - if (!name || typeof name !== 'string') throw 'Not valid command name!' - - this.name = Object.keys(this.initialCommands).includes(name) - ? name - : this.initialAliases.find((alias) => alias.aliases.includes(name)).name - - this.aliases = this.initialAliases.find((alias) => alias.name === this.name) - this.aliases = this.aliases ? this.aliases.aliases : null - - this.flags = this.commandFlags.filter( - (commandFlag) => commandFlag.command === this.name - ) - this.flags = this.flags[0].flags.map((flag) => new Flag(flag)) - } -} - -class Flag { - flagsWithValue = [ - initialFlags.target, - initialFlags.source, - initialFlags.template, - initialFlags.datafile, - initialFlags.configfile - ] - - constructor(name, isRequired = false) { - if (!name || typeof name !== 'string') throw 'Not valid flag name!' - - this.name = name - this.longSyntax = '--' + name - this.shortSyntax = '-' + name[0] - this.withValue = this.flagsWithValue.includes(name) - } -} diff --git a/src/utils/commandLine/utils.js b/src/utils/commandLine/utils.js deleted file mode 100644 index a361f9acc..000000000 --- a/src/utils/commandLine/utils.js +++ /dev/null @@ -1,51 +0,0 @@ -import { Command } from './command' - -export function parseCommandLine(commandLine) { - if (!Array.isArray(commandLine)) throw 'commandLine should be an array' - - if (!commandLine.length) { - console.log(chalk.redBright(`Please provide sasjs command.`)) - - return - } - - const command = new Command(commandLine.shift()) - const initialFlags = Object.keys(command.initialFlags) - const commandValues = [] - const flagValues = [] - - for (let i = 0; i < commandLine.length; i++) { - if (/^-/.test(commandLine[i]) && command.flags) { - let flag = commandLine[i].split('-').join('') - const regExp = new RegExp(`^${flag}`) - - flag = initialFlags - .filter((f) => regExp.test(f)) - .filter((f) => - command.flags.map((commandFlag) => commandFlag.name).includes(f) - )[0] - flag = command.flags.find((f) => f.name === flag) - - if (flag.withValue) { - i++ - - const value = commandLine[i] - - if (value) flagValues.push({ [flag.name]: value }) - } else { - flagValues.push(flag.name) - } - } else { - commandValues.push(commandLine[i]) - } - } - - if (flagValues.length && commandValues.length) { - return { - commandValues, - flagValues - } - } else if (!flagValues.length && !commandValues.length) return {} - else if (!flagValues.length) return { commandValues } - else return { flagValues } -} diff --git a/test/commandLine-utils.spec.js b/test/commandLine-utils.spec.js deleted file mode 100644 index 41deade21..000000000 --- a/test/commandLine-utils.spec.js +++ /dev/null @@ -1,439 +0,0 @@ -import { parseCommandLine } from '../src/utils/commandLine/utils' - -describe('parseCommandLine', () => { - describe('folder command', () => { - test('without flags', () => { - const command = 'folder create /Public/folder'.split(' ') - - const expectedOutput = { - commandValues: ['create', '/Public/folder'] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('full syntax', () => { - const command = 'folder create /Public/folder --target targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['create', '/Public/folder'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('short syntax', () => { - const command = 'folder create /Public/folder -t targetName'.split(' ') - - const expectedOutput = { - commandValues: ['create', '/Public/folder'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('short syntax with force flag', () => { - const command = 'folder create /Public/folder -t targetName -f'.split(' ') - - const expectedOutput = { - commandValues: ['create', '/Public/folder'], - flagValues: [{ target: 'targetName' }, 'force'] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('move command full syntax', () => { - const command = 'folder move /Public/sourceFolder /Public/targetFolder --target targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('move command short syntax', () => { - const command = 'folder move -t targetName /Public/sourceFolder /Public/targetFolder'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('move command without flags', () => { - const command = 'folder move /Public/sourceFolder /Public/targetFolder'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['move', '/Public/sourceFolder', '/Public/targetFolder'] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('context command', () => { - test('create command full syntax', () => { - const command = 'context create --source ../contextConfig.json --target targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['create'], - flagValues: [ - { source: '../contextConfig.json' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('create command short syntax', () => { - const command = 'context create -s ../contextConfig.json -t targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['create'], - flagValues: [ - { source: '../contextConfig.json' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('delete command short syntax', () => { - const command = 'context delete contextName -t targetName'.split(' ') - - const expectedOutput = { - commandValues: ['delete', 'contextName'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('list command short syntax', () => { - const command = 'context list -t targetName'.split(' ') - - const expectedOutput = { - commandValues: ['list'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('export command short syntax', () => { - const command = 'context export contextName -t targetName'.split(' ') - - const expectedOutput = { - commandValues: ['export', 'contextName'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('create command', () => { - test('create command', () => { - const command = 'create'.split(' ') - - const expectedOutput = {} - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('create command with folder name', () => { - const command = 'create folderName'.split(' ') - - const expectedOutput = { commandValues: ['folderName'] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('create command with folder name and template full syntax', () => { - const command = 'create my-sas-project --template react'.split(' ') - - const expectedOutput = { - commandValues: ['my-sas-project'], - flagValues: [{ template: 'react' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('create command with folder name and template short syntax', () => { - const command = 'create -t angular my-sas-project'.split(' ') - - const expectedOutput = { - commandValues: ['my-sas-project'], - flagValues: [{ template: 'angular' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('web command', () => { - test('full syntax', () => { - const command = 'web --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'w -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('build-DB command', () => { - test('full syntax', () => { - const command = 'build-DB --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'db -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('compile command', () => { - test('full syntax', () => { - const command = 'compile --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'c -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('build command', () => { - test('full syntax', () => { - const command = 'build --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'b -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('compilebuild command', () => { - test('full syntax', () => { - const command = 'compilebuild --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'cb -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('deploy command', () => { - test('full syntax', () => { - const command = 'deploy --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'd -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('compilebuilddeploy command', () => { - test('full syntax', () => { - const command = 'compilebuilddeploy --target targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'cbd -t targetName'.split(' ') - - const expectedOutput = { flagValues: [{ target: 'targetName' }] } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('servicepack command', () => { - test('full syntax', () => { - const command = 'servicepack deploy --source ./path/services.json --target targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['deploy'], - flagValues: [ - { source: './path/services.json' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('short syntax', () => { - const command = 'servicepack deploy -s ./path/services.json -t targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['deploy'], - flagValues: [ - { source: './path/services.json' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('run command', () => { - test('full syntax', () => { - const command = 'run ./sasFilePath.sas --target targetName'.split(' ') - - const expectedOutput = { - commandValues: ['./sasFilePath.sas'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'r ./sasFilePath.sas -t targetName'.split(' ') - - const expectedOutput = { - commandValues: ['./sasFilePath.sas'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('request command', () => { - test('full syntax', () => { - const command = 'request ./sasFilePath.sas --datafile --configfile --target targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['./sasFilePath.sas'], - flagValues: [ - { datafile: '' }, - { configfile: '' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('alias', () => { - const command = 'rq ./sasFilePath.sas -d -c -t targetName'.split( - ' ' - ) - - const expectedOutput = { - commandValues: ['./sasFilePath.sas'], - flagValues: [ - { datafile: '' }, - { configfile: '' }, - { target: 'targetName' } - ] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) - - describe('job command', () => { - test('full syntax', () => { - const command = 'job execute /Public/job --target targetName'.split(' ') - - const expectedOutput = { - commandValues: ['execute', '/Public/job'], - flagValues: [{ target: 'targetName' }] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - - test('short syntax', () => { - const command = 'job execute -t targetName -w -o /Public/job'.split(' ') - - const expectedOutput = { - commandValues: ['execute', '/Public/job'], - flagValues: [{ target: 'targetName' }, 'wait', 'output'] - } - - expect(parseCommandLine(command)).toEqual(expectedOutput) - }) - }) -}) diff --git a/test/utils/command.spec.js b/test/utils/command.spec.js new file mode 100644 index 000000000..4e806f569 --- /dev/null +++ b/test/utils/command.spec.js @@ -0,0 +1,501 @@ +import { Command } from '../../src/utils/command' + +describe('parseCommandLine', () => { + const defaultFlagNames = ['target'] + const defaultFlagValues = ['targetName'] + + describe('folder command', () => { + const expectedName = 'folder' + let expectedValues = ['create', '/Public/folder'] + const expectedFlagNames = ['target', 'force'] + const expectedFlagValues = ['targetName', null] + + test('without flags', () => { + const commandLine = 'folder create /Public/folder' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + }) + + test('full syntax', () => { + const commandLine = 'folder create /Public/folder --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('short syntax', () => { + const commandLine = 'folder create /Public/folder -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('short syntax with force flag', () => { + const commandLine = 'folder create /Public/folder -t targetName -f' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('move command full syntax', () => { + const commandLine = + 'folder move /Public/sourceFolder /Public/targetFolder --target targetName' + + expectedValues = ['move', '/Public/sourceFolder', '/Public/targetFolder'] + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('move command short syntax', () => { + const commandLine = + 'folder move -t targetName /Public/sourceFolder /Public/targetFolder' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('move command without flags', () => { + const commandLine = + 'folder move /Public/sourceFolder /Public/targetFolder' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual([]) + }) + }) + + describe('context command', () => { + const expectedName = 'context' + let expectedValues = ['create'] + let expectedFlagNames = ['source', 'target'] + let expectedFlagValues = ['../contextConfig.json', 'targetName'] + + test('create command full syntax', () => { + const commandLine = + 'context create --source ../contextConfig.json --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('create command short syntax', () => { + const commandLine = + 'context create -s ../contextConfig.json -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('delete command short syntax', () => { + const commandLine = 'context delete contextName -t targetName' + + const command = new Command(commandLine) + + expectedValues = ['delete', 'contextName'] + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('list command short syntax', () => { + const commandLine = 'context list -t targetName' + + const command = new Command(commandLine) + + expectedValues = ['list'] + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('export command short syntax', () => { + const commandLine = 'context export contextName -t targetName' + + const command = new Command(commandLine) + + expectedValues = ['export', 'contextName'] + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('create command', () => { + const expectedName = 'create' + const expectedValues = ['folderName'] + const expectedFlagNames = ['template'] + let expectedFlagValues = ['react'] + + test('create command', () => { + const commandLine = 'create' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + }) + + test('create command with folder name', () => { + const commandLine = 'create folderName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + }) + + test('create command with folder name and template full syntax', () => { + const commandLine = 'create folderName --template react' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('create command with folder name and template short syntax', () => { + const commandLine = 'create -t angular folderName' + + const command = new Command(commandLine) + + expectedFlagValues = ['angular'] + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + }) + + describe('web command', () => { + const expectedName = 'web' + + test('full syntax', () => { + const commandLine = 'web --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'w -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('build-DB command', () => { + const expectedName = 'build-DB' + + test('full syntax', () => { + const commandLine = 'build-DB --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'db -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('compile command', () => { + const expectedName = 'compile' + + test('full syntax', () => { + const commandLine = 'compile --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'c -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('build command', () => { + const expectedName = 'build' + + test('full syntax', () => { + const commandLine = 'build --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'b -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('compilebuild command', () => { + const expectedName = 'compilebuild' + + test('full syntax', () => { + const commandLine = 'compilebuild --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'cb -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('deploy command', () => { + const expectedName = 'deploy' + + test('full syntax', () => { + const commandLine = 'deploy --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'd -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('compilebuilddeploy command', () => { + const expectedName = 'compilebuilddeploy' + + test('full syntax', () => { + const commandLine = 'compilebuilddeploy --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'cbd -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('servicepack command', () => { + const expectedName = 'servicepack' + const expectedValues = ['deploy'] + const expectedFlagNames = ['source', 'target'] + const expectedFlagValues = ['./path/services.json', 'targetName'] + + test('full syntax', () => { + const commandLine = + 'servicepack deploy --source ./path/services.json --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('short syntax', () => { + const commandLine = + 'servicepack deploy -s ./path/services.json -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + }) + + describe('run command', () => { + const expectedName = 'run' + const expectedValues = ['./sasFilePath.sas'] + + test('full syntax', () => { + const commandLine = 'run ./sasFilePath.sas --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('alias', () => { + const commandLine = 'r ./sasFilePath.sas -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + }) + + describe('request command', () => { + const expectedName = 'request' + const expectedValues = ['./sasFilePath.sas'] + const expectedFlagNames = ['datafile', 'configfile', 'target'] + const expectedFlagValues = [ + '', + '', + 'targetName' + ] + + test('full syntax', () => { + const commandLine = + 'request ./sasFilePath.sas --datafile --configfile --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + + test('alias', () => { + const commandLine = + 'rq ./sasFilePath.sas -d -c -t targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + }) + + describe('job command', () => { + const expectedName = 'job' + const expectedValues = ['execute', '/Public/job'] + + test('full syntax', () => { + const commandLine = 'job execute /Public/job --target targetName' + + const command = new Command(commandLine) + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(defaultFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(defaultFlagValues) + }) + + test('short syntax', () => { + const commandLine = 'job execute -t targetName -w -o /Public/job' + + const command = new Command(commandLine) + + const expectedFlagNames = ['target', 'wait', 'output'] + const expectedFlagValues = ['targetName', null, null] + + expect(command.name).toEqual(expectedName) + expect(command.values).toEqual(expectedValues) + expect(command.flags.map((flag) => flag.name)).toEqual(expectedFlagNames) + expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) + }) + }) +}) From 064dc1f53eceb4d30a9f7c90e454dacbf61d5cd7 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Thu, 29 Oct 2020 12:21:47 +0300 Subject: [PATCH 3/3] chore(command-util): updated not supported command logic --- src/utils/command.js | 39 ++++++++++++++++++++++++++++++-------- test/utils/command.spec.js | 10 ++++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/utils/command.js b/src/utils/command.js index 2eb43d4eb..50ac10f93 100644 --- a/src/utils/command.js +++ b/src/utils/command.js @@ -1,3 +1,11 @@ +import { displayResult } from './displayResult' + +const showInvalidCommandMessage = () => { + displayResult( + {}, + `Invalid command. Run 'sasjs help' to get the list of valid commands.` + ) +} const arrToObj = (arr) => arr.reduce((o, key) => ({ ...o, [key]: key }), {}) const initialCommands = arrToObj([ @@ -95,14 +103,32 @@ export class Command { flags = [] constructor(commandLine) { - if (typeof commandLine === 'string') commandLine = commandLine.split(' ') + if (typeof commandLine === 'string') + commandLine = commandLine.replace(/\s\s+/g, ' ').split(' ') + + if (!Array.isArray(commandLine)) { + showInvalidCommandMessage() + + return + } - if (!Array.isArray(commandLine)) throw 'commandLine should be an array' const command = commandLine.shift() - this.name = Object.keys(initialCommands).includes(command) - ? command - : initialAliases.find((alias) => alias.aliases.includes(command)).name + if (Object.keys(initialCommands).includes(command)) { + this.name = command + } else { + const alias = initialAliases.find((alias) => + alias.aliases.includes(command) + ) + + if (alias) this.name = alias.name + } + + if (!this.name) { + showInvalidCommandMessage() + + return + } this.aliases = initialAliases.find((alias) => alias.name === this.name) this.aliases = this.aliases ? this.aliases.aliases : null @@ -111,10 +137,7 @@ export class Command { (commandFlag) => commandFlag.command === this.name )[0].flags - console.log(`[this]`, this) - for (let i = 0; i < commandLine.length; i++) { - console.log(`[commandLine[i]]`, commandLine[i]) if (/^-/.test(commandLine[i]) && this.supportedFlags) { let flag = commandLine[i].split('-').join('') const regExp = new RegExp(`^${flag}`) diff --git a/test/utils/command.spec.js b/test/utils/command.spec.js index 4e806f569..ea3a0375f 100644 --- a/test/utils/command.spec.js +++ b/test/utils/command.spec.js @@ -498,4 +498,14 @@ describe('parseCommandLine', () => { expect(command.flags.map((f) => f.value)).toEqual(expectedFlagValues) }) }) + + test('not supported command', () => { + const commandLine = 'notSupported command' + + const command = new Command(commandLine) + + expect(command.name).toEqual(undefined) + expect(command.values).toEqual([]) + expect(command.flags.map((flag) => flag.name)).toEqual([]) + }) })