move application.yaml to collections/windows.yaml #40

This commit is contained in:
undergroundwires
2021-01-09 02:02:16 +01:00
parent 72e925fb6f
commit 6b83dcbf8f
24 changed files with 265 additions and 286 deletions

View File

@@ -2,14 +2,15 @@ import { IApplication } from '@/domain/IApplication';
import { IProjectInformation } from '@/domain/IProjectInformation';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { parseCategoryCollection } from './CategoryCollectionParser';
import applicationFile, { YamlApplication } from 'js-yaml-loader!@/application/application.yaml';
import WindowsData from 'js-yaml-loader!@/application/collections/windows.yaml';
import { CollectionData } from 'js-yaml-loader!@/*';
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
import { Application } from '@/domain/Application';
export function parseApplication(
parser = CategoryCollectionParser,
processEnv: NodeJS.ProcessEnv = process.env,
collectionData = CollectionData): IApplication {
collectionData = LoadedCollectionData): IApplication {
const information = parseProjectInformation(processEnv);
const collection = parser(collectionData, information);
const app = new Application(information, [ collection ]);
@@ -17,11 +18,10 @@ export function parseApplication(
}
export type CategoryCollectionParserType
= (file: YamlApplication, info: IProjectInformation) => ICategoryCollection;
= (file: CollectionData, info: IProjectInformation) => ICategoryCollection;
const CategoryCollectionParser: CategoryCollectionParserType
= (file, info) => parseCategoryCollection(file, info);
const CollectionData: YamlApplication
= applicationFile;
const LoadedCollectionData: CollectionData
= WindowsData;

View File

@@ -1,5 +1,5 @@
import { Category } from '@/domain/Category';
import { YamlApplication } from 'js-yaml-loader!@/application.yaml';
import { CollectionData } from 'js-yaml-loader!@/*';
import { parseCategory } from './CategoryParser';
import { ScriptCompiler } from './Compiler/ScriptCompiler';
import { OperatingSystem } from '@/domain/OperatingSystem';
@@ -10,7 +10,7 @@ import { CategoryCollection } from '@/domain/CategoryCollection';
import { IProjectInformation } from '@/domain/IProjectInformation';
export function parseCategoryCollection(
content: YamlApplication,
content: CollectionData,
info: IProjectInformation,
osParser = createEnumParser(OperatingSystem)): ICategoryCollection {
validate(content);
@@ -29,7 +29,7 @@ export function parseCategoryCollection(
return collection;
}
function validate(content: YamlApplication): void {
function validate(content: CollectionData): void {
if (!content) {
throw new Error('content is null or undefined');
}

View File

@@ -1,4 +1,4 @@
import { YamlCategory, YamlScript } from 'js-yaml-loader!@/application.yaml';
import { CategoryData, ScriptData, CategoryOrScriptData } from 'js-yaml-loader!@/*';
import { Script } from '@/domain/Script';
import { Category } from '@/domain/Category';
import { parseDocUrls } from './DocumentationParser';
@@ -12,7 +12,7 @@ interface ICategoryChildren {
subScripts: Script[];
}
export function parseCategory(category: YamlCategory, compiler: IScriptCompiler): Category {
export function parseCategory(category: CategoryData, compiler: IScriptCompiler): Category {
if (!compiler) {
throw new Error('undefined compiler');
}
@@ -21,8 +21,8 @@ export function parseCategory(category: YamlCategory, compiler: IScriptCompiler)
subCategories: new Array<Category>(),
subScripts: new Array<Script>(),
};
for (const categoryOrScript of category.children) {
parseCategoryChild(categoryOrScript, children, category, compiler);
for (const data of category.children) {
parseCategoryChild(data, children, category, compiler);
}
return new Category(
/*id*/ categoryIdCounter++,
@@ -33,7 +33,7 @@ export function parseCategory(category: YamlCategory, compiler: IScriptCompiler)
);
}
function ensureValid(category: YamlCategory) {
function ensureValid(category: CategoryData) {
if (!category) {
throw Error('category is null or undefined');
}
@@ -46,28 +46,28 @@ function ensureValid(category: YamlCategory) {
}
function parseCategoryChild(
categoryOrScript: any,
data: CategoryOrScriptData,
children: ICategoryChildren,
parent: YamlCategory,
parent: CategoryData,
compiler: IScriptCompiler) {
if (isCategory(categoryOrScript)) {
const subCategory = parseCategory(categoryOrScript as YamlCategory, compiler);
if (isCategory(data)) {
const subCategory = parseCategory(data as CategoryData, compiler);
children.subCategories.push(subCategory);
} else if (isScript(categoryOrScript)) {
const yamlScript = categoryOrScript as YamlScript;
const script = parseScript(yamlScript, compiler);
} else if (isScript(data)) {
const scriptData = data as ScriptData;
const script = parseScript(scriptData, compiler);
children.subScripts.push(script);
} else {
throw new Error(`Child element is neither a category or a script.
Parent: ${parent.category}, element: ${JSON.stringify(categoryOrScript)}`);
Parent: ${parent.category}, element: ${JSON.stringify(data)}`);
}
}
function isScript(categoryOrScript: any): boolean {
return (categoryOrScript.code && categoryOrScript.code.length > 0)
|| categoryOrScript.call;
function isScript(data: any): boolean {
return (data.code && data.code.length > 0)
|| data.call;
}
function isCategory(categoryOrScript: any): boolean {
return categoryOrScript.category && categoryOrScript.category.length > 0;
function isCategory(data: any): boolean {
return data.category && data.category.length > 0;
}

View File

@@ -1,7 +1,7 @@
import { IScriptCode } from '@/domain/IScriptCode';
import { YamlScript } from 'js-yaml-loader!@/application.yaml';
import { ScriptData } from 'js-yaml-loader!@/*';
export interface IScriptCompiler {
canCompile(script: YamlScript): boolean;
compile(script: YamlScript): IScriptCode;
canCompile(script: ScriptData): boolean;
compile(script: ScriptData): IScriptCode;
}

View File

@@ -1,7 +1,7 @@
import { generateIlCode, IILCode } from './ILCode';
import { IScriptCode } from '@/domain/IScriptCode';
import { ScriptCode } from '@/domain/ScriptCode';
import { YamlScript, YamlFunction, FunctionCall, ScriptFunctionCall, FunctionCallParameters } from 'js-yaml-loader!@/application.yaml';
import { ScriptData, FunctionData, FunctionCallData, ScriptFunctionCallData, FunctionCallParametersData } from 'js-yaml-loader!@/*';
import { IScriptCompiler } from './IScriptCompiler';
interface ICompiledCode {
@@ -10,16 +10,16 @@ interface ICompiledCode {
}
export class ScriptCompiler implements IScriptCompiler {
constructor(private readonly functions: readonly YamlFunction[]) {
constructor(private readonly functions: readonly FunctionData[]) {
ensureValidFunctions(functions);
}
public canCompile(script: YamlScript): boolean {
public canCompile(script: ScriptData): boolean {
if (!script.call) {
return false;
}
return true;
}
public compile(script: YamlScript): IScriptCode {
public compile(script: ScriptData): IScriptCode {
this.ensureCompilable(script.call);
const compiledCodes = new Array<ICompiledCode>();
const calls = getCallSequence(script.call);
@@ -36,7 +36,7 @@ export class ScriptCompiler implements IScriptCompiler {
return new ScriptCode(script.name, scriptCode.code, scriptCode.revertCode);
}
private getFunctionByName(name: string): YamlFunction {
private getFunctionByName(name: string): FunctionData {
const func = this.functions.find((f) => f.name === name);
if (!func) {
throw new Error(`called function is not defined "${name}"`);
@@ -44,7 +44,7 @@ export class ScriptCompiler implements IScriptCompiler {
return func;
}
private ensureCompilable(call: ScriptFunctionCall) {
private ensureCompilable(call: ScriptFunctionCallData) {
if (!this.functions || this.functions.length === 0) {
throw new Error('cannot compile without shared functions');
}
@@ -62,7 +62,7 @@ function printList(list: readonly string[]): string {
return `"${list.join('","')}"`;
}
function ensureNoDuplicatesInFunctionNames(functions: readonly YamlFunction[]) {
function ensureNoDuplicatesInFunctionNames(functions: readonly FunctionData[]) {
const duplicateFunctionNames = getDuplicates(functions
.map((func) => func.name.toLowerCase()));
if (duplicateFunctionNames.length) {
@@ -70,7 +70,7 @@ function ensureNoDuplicatesInFunctionNames(functions: readonly YamlFunction[]) {
}
}
function ensureNoDuplicatesInParameterNames(functions: readonly YamlFunction[]) {
function ensureNoDuplicatesInParameterNames(functions: readonly FunctionData[]) {
const functionsWithParameters = functions
.filter((func) => func.parameters && func.parameters.length > 0);
for (const func of functionsWithParameters) {
@@ -81,7 +81,7 @@ function ensureNoDuplicatesInParameterNames(functions: readonly YamlFunction[])
}
}
function ensureNoDuplicateCode(functions: readonly YamlFunction[]) {
function ensureNoDuplicateCode(functions: readonly FunctionData[]) {
const duplicateCodes = getDuplicates(functions.map((func) => func.code));
if (duplicateCodes.length > 0) {
throw new Error(`duplicate "code" in functions: ${printList(duplicateCodes)}`);
@@ -94,7 +94,7 @@ function ensureNoDuplicateCode(functions: readonly YamlFunction[]) {
}
}
function ensureValidFunctions(functions: readonly YamlFunction[]) {
function ensureValidFunctions(functions: readonly FunctionData[]) {
if (!functions) {
return;
}
@@ -118,20 +118,20 @@ function merge(codes: readonly ICompiledCode[]): ICompiledCode {
};
}
function compileCode(func: YamlFunction, parameters: FunctionCallParameters): ICompiledCode {
function compileCode(func: FunctionData, parameters: FunctionCallParametersData): ICompiledCode {
return {
code: compileExpressions(func.code, parameters),
revertCode: compileExpressions(func.revertCode, parameters),
};
}
function compileExpressions(code: string, parameters: FunctionCallParameters): string {
function compileExpressions(code: string, parameters: FunctionCallParametersData): string {
let intermediateCode = generateIlCode(code);
intermediateCode = substituteParameters(intermediateCode, parameters);
return intermediateCode.compile();
}
function substituteParameters(intermediateCode: IILCode, parameters: FunctionCallParameters): IILCode {
function substituteParameters(intermediateCode: IILCode, parameters: FunctionCallParametersData): IILCode {
const parameterNames = intermediateCode.getUniqueParameterNames();
if (parameterNames.length && !parameters) {
throw new Error(`no parameters defined, expected: ${printList(parameterNames)}`);
@@ -146,7 +146,7 @@ function substituteParameters(intermediateCode: IILCode, parameters: FunctionCal
return intermediateCode;
}
function ensureValidCall(call: FunctionCall, scriptName: string) {
function ensureValidCall(call: FunctionCallData, scriptName: string) {
if (!call) {
throw new Error(`undefined function call in script "${scriptName}"`);
}
@@ -155,9 +155,9 @@ function ensureValidCall(call: FunctionCall, scriptName: string) {
}
}
function getCallSequence(call: ScriptFunctionCall): FunctionCall[] {
function getCallSequence(call: ScriptFunctionCallData): FunctionCallData[] {
if (call instanceof Array) {
return call as FunctionCall[];
return call as FunctionCallData[];
}
return [ call as FunctionCall ];
return [ call as FunctionCallData ];
}

View File

@@ -1,6 +1,6 @@
import { YamlDocumentable, DocumentationUrls } from 'js-yaml-loader!./application.yaml';
import { DocumentableData, DocumentationUrlsData } from 'js-yaml-loader!@/*';
export function parseDocUrls(documentable: YamlDocumentable): ReadonlyArray<string> {
export function parseDocUrls(documentable: DocumentableData): ReadonlyArray<string> {
if (!documentable) {
throw new Error('documentable is null or undefined');
}
@@ -13,7 +13,7 @@ export function parseDocUrls(documentable: YamlDocumentable): ReadonlyArray<stri
return result.getAll();
}
function addDocs(docs: DocumentationUrls, urls: DocumentationUrlContainer): DocumentationUrlContainer {
function addDocs(docs: DocumentationUrlsData, urls: DocumentationUrlContainer): DocumentationUrlContainer {
if (docs instanceof Array) {
urls.addUrls(docs);
} else if (typeof docs === 'string') {

View File

@@ -1,5 +1,5 @@
import { Script } from '@/domain/Script';
import { YamlScript } from 'js-yaml-loader!@/application.yaml';
import { ScriptData } from 'js-yaml-loader!@/*';
import { parseDocUrls } from './DocumentationParser';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { IScriptCompiler } from './Compiler/IScriptCompiler';
@@ -8,17 +8,17 @@ import { ScriptCode } from '@/domain/ScriptCode';
import { createEnumParser, IEnumParser } from '../Common/Enum';
export function parseScript(
yamlScript: YamlScript, compiler: IScriptCompiler,
data: ScriptData, compiler: IScriptCompiler,
levelParser = createEnumParser(RecommendationLevel)): Script {
validateScript(yamlScript);
validateScript(data);
if (!compiler) {
throw new Error('undefined compiler');
}
const script = new Script(
/* name */ yamlScript.name,
/* code */ parseCode(yamlScript, compiler),
/* docs */ parseDocUrls(yamlScript),
/* level */ parseLevel(yamlScript.recommend, levelParser));
/* name */ data.name,
/* code */ parseCode(data, compiler),
/* docs */ parseDocUrls(data),
/* level */ parseLevel(data.recommend, levelParser));
return script;
}
@@ -29,28 +29,28 @@ function parseLevel(level: string, parser: IEnumParser<RecommendationLevel>): Re
return parser.parseEnum(level, 'level');
}
function parseCode(yamlScript: YamlScript, compiler: IScriptCompiler): IScriptCode {
if (compiler.canCompile(yamlScript)) {
return compiler.compile(yamlScript);
function parseCode(script: ScriptData, compiler: IScriptCompiler): IScriptCode {
if (compiler.canCompile(script)) {
return compiler.compile(script);
}
return new ScriptCode(yamlScript.name, yamlScript.code, yamlScript.revertCode);
return new ScriptCode(script.name, script.code, script.revertCode);
}
function ensureNotBothCallAndCode(yamlScript: YamlScript) {
if (yamlScript.code && yamlScript.call) {
function ensureNotBothCallAndCode(script: ScriptData) {
if (script.code && script.call) {
throw new Error('cannot define both "call" and "code"');
}
if (yamlScript.revertCode && yamlScript.call) {
if (script.revertCode && script.call) {
throw new Error('cannot define "revertCode" if "call" is defined');
}
}
function validateScript(yamlScript: YamlScript) {
if (!yamlScript) {
function validateScript(script: ScriptData) {
if (!script) {
throw new Error('undefined script');
}
if (!yamlScript.code && !yamlScript.call) {
if (!script.code && !script.call) {
throw new Error('must define either "call" or "code"');
}
ensureNotBothCallAndCode(yamlScript);
ensureNotBothCallAndCode(script);
}

View File

@@ -1,5 +1,5 @@
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { YamlScriptingDefinition } from 'js-yaml-loader!@/application.yaml';
import { ScriptingDefinitionData } from 'js-yaml-loader!@/*';
import { ScriptingDefinition } from '@/domain/ScriptingDefinition';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { IProjectInformation } from '@/domain/IProjectInformation';
@@ -7,7 +7,7 @@ import { createEnumParser } from '../Common/Enum';
import { generateIlCode } from './Compiler/ILCode';
export function parseScriptingDefinition(
definition: YamlScriptingDefinition,
definition: ScriptingDefinitionData,
info: IProjectInformation,
date = new Date(),
languageParser = createEnumParser(ScriptingLanguage)): IScriptingDefinition {