diff --git a/engine/engine.ts b/engine/engine.ts index 3aafebd7..7019e443 100644 --- a/engine/engine.ts +++ b/engine/engine.ts @@ -1,6 +1,7 @@ import { Environment } from "./environment"; import { Playbook } from "./playbook"; import { Runner } from "./runner"; +import { RunCommand } from "./run_command"; import { RunResult } from "./run_result"; @@ -24,25 +25,26 @@ export class Engine { (await this.getRunner(this.environment.runners[runnerIndex])).init(this.playbook); } - mainloop: for (let stepIndex in this.playbook.steps) { - for (let lineIndex in this.playbook.steps[stepIndex].lines) { + mainloop: for (let stepIndex = 0; stepIndex < this.playbook.steps.length; stepIndex++) { + for (let lineIndex = 0; lineIndex < this.playbook.steps[stepIndex].lines.length; lineIndex++) { + let runCommand = this.initRunCommand(stepIndex, lineIndex); let foundRunnerToExecuteCommand = false; for (let runnerIndex in this.environment.runners) { let runner = await this.getRunner(this.environment.runners[runnerIndex]); if (runner.supports(this.playbook.steps[stepIndex].lines[lineIndex].name)) { var result = new RunResult(); - if(runner.commandIsSkippable(this.playbook.steps[stepIndex].lines[lineIndex].name)) { - console.log("Command " + this.playbook.steps[stepIndex].lines[lineIndex].name + " will be skipped."); + if(runner.commandIsSkippable(runCommand.command.name)) { + console.log("Command " + runCommand.command.name + " will be skipped."); continue; } try { - result = runner.run(this.playbook.steps[stepIndex], this.playbook.steps[stepIndex].lines[lineIndex]); + result = runner.run(runCommand); } catch (e) { result.exceptions.push(e); } - await runner.assert(this.playbook.steps[stepIndex], this.playbook.steps[stepIndex].lines[lineIndex], result); + await runner.assert(runCommand, result); foundRunnerToExecuteCommand = true; break; @@ -105,4 +107,20 @@ export class Engine { runner.playbookTitle = this.playbook.title; this.runners.set(name, runner); } + + private initRunCommand(stepIndex: number, lineIndex: number): RunCommand { + let runCommand = new RunCommand(); + if(lineIndex == 0) { + runCommand.text = this.playbook.steps[stepIndex].text; + } + if(lineIndex == (this.playbook.steps[stepIndex].lines.length - 1)){ + runCommand.textAfter = this.playbook.steps[stepIndex].textAfter; + } + runCommand.command = this.playbook.steps[stepIndex].lines[lineIndex]; + runCommand.stepIndex = stepIndex; + runCommand.lineIndex = lineIndex; + runCommand.stepTitle = this.playbook.steps[stepIndex].title; + + return runCommand; + } } \ No newline at end of file diff --git a/engine/parser.def b/engine/parser.def index b08174ca..befcbf1d 100644 --- a/engine/parser.def +++ b/engine/parser.def @@ -28,10 +28,14 @@ step stepinner = steptextlines? - "[step]" ___ - "--" ___ - steplines - "--" __ + "[step]" ___ + stepstitle? + "--" ___ + steplines + "--" __ + +stepstitle + = "==" _ string __ steptextlines = steptextline* { return { "steptextlines": text()}; } @@ -46,11 +50,11 @@ steptextafterline = !"====" string __ steplines - = stepline+ - -stepline - = !"--" string __ { return { "stepline": text()}; } + = stepline+ { return { "steplines": text()}; } +stepline + = !"--" string __ + string "string" = [^\r\n]+ { return text(); } diff --git a/engine/parser.ts b/engine/parser.ts index 2208d658..b021d1f5 100644 --- a/engine/parser.ts +++ b/engine/parser.ts @@ -12,7 +12,6 @@ export class Parser { constructor() { let def = fs.readFileSync(__dirname + "/parser.def", 'utf8'); this.parser = pegjs.generate(def); - } parse(inputFile: string): Playbook { @@ -23,9 +22,10 @@ export class Parser { result.description = parseResult[1][2].descriptionlines; for(let index in parseResult[2]){ let step = new Step(); - step.text = this.getText(parseResult,index);; - step.lines = this.getLines(parseResult,index); + step.text = this.getText(parseResult, index); + step.lines = this.getLines(parseResult, index); step.textAfter = this.getTextAfter(parseResult, index); + step.title = this.getTitle(parseResult, index); result.steps.push(step); } @@ -43,9 +43,17 @@ export class Parser { getLines(parseResult, index):Command[]{ try { - return (parseResult[2][index][5][0].stepline || parseResult[2][index][2][5][0].stepline).split("\r\n").filter(e => e != '').map(e => this.createCommand(e)); + return (parseResult[2][index][6].steplines || parseResult[2][index][2][6].steplines).split("\r\n").filter(e => e != '').map(e => this.createCommand(e)); } catch (error) { - return parseResult[2][index][2][5][0].stepline.split("\r\n").filter(e => e != '').map(e => this.createCommand(e)); + return parseResult[2][index][2][6].steplines.split("\r\n").filter(e => e != '').map(e => this.createCommand(e)); + } + } + + getTitle(parseResult, index) { + try { + return (parseResult[2][index][3][2]|| parseResult[2][index][2][3][2]); + } catch(error) { + return null; } } diff --git a/engine/run_command.ts b/engine/run_command.ts new file mode 100644 index 00000000..15910cb3 --- /dev/null +++ b/engine/run_command.ts @@ -0,0 +1,10 @@ +import { Command } from "./command"; + +export class RunCommand { + public text: string; + public command: Command; + public lineIndex: number; + public stepIndex: number; + public textAfter: string; + public stepTitle: string; +} \ No newline at end of file diff --git a/engine/runner.ts b/engine/runner.ts index c6e029cb..7fa590bc 100644 --- a/engine/runner.ts +++ b/engine/runner.ts @@ -4,6 +4,7 @@ import { Playbook } from "./playbook"; import { Step } from "./step"; import * as fs from 'fs'; import * as rimraf from 'rimraf'; +import { RunCommand } from "./run_command"; export abstract class Runner { public path: string; @@ -86,14 +87,14 @@ export abstract class Runner { this.setVariable(this.useDevonCommand, false); } - run(step: Step, command: Command): RunResult { - console.log("Run " + command.name, command.parameters); - return this[this.getMethodName("run", command.name)](step, command); + run(runCommand: RunCommand): RunResult { + console.log("Run " + runCommand.command.name, runCommand.command.parameters); + return this[this.getMethodName("run", runCommand.command.name)](runCommand); } - async assert(step: Step, command: Command, runResult: RunResult): Promise { - if (this[this.getMethodName("assert", command.name)]) { - await this[this.getMethodName("assert", command.name)](step, command, runResult); + async assert(runCommand: RunCommand, runResult: RunResult): Promise { + if (this[this.getMethodName("assert", runCommand.command.name)]) { + await this[this.getMethodName("assert", runCommand.command.name)](runCommand, runResult); } } diff --git a/engine/step.ts b/engine/step.ts index 96312fa4..2fa04549 100644 --- a/engine/step.ts +++ b/engine/step.ts @@ -3,5 +3,6 @@ import { Command } from "./command"; export class Step { public text: string; public lines: Command[] = []; + public title: string; public textAfter: string; } \ No newline at end of file diff --git a/runners/console/index.ts b/runners/console/index.ts index b8ae9120..30b9656b 100644 --- a/runners/console/index.ts +++ b/runners/console/index.ts @@ -1,7 +1,6 @@ import { Runner } from "../../engine/runner" import { RunResult } from "../../engine/run_result"; -import { Step } from "../../engine/step"; -import { Command } from "../../engine/command"; +import { RunCommand } from "../../engine/run_command"; import { Assertions } from "../../assertions"; import { Playbook } from "../../engine/playbook"; import { ConsolePlatform, AsyncProcess } from "./consoleInterfaces"; @@ -55,11 +54,11 @@ export class Console extends Runner { } } - runInstallDevonfwIde(step: Step, command: Command): RunResult { + runInstallDevonfwIde(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - if(command.parameters[0].indexOf("npm") > -1 || command.parameters[0].indexOf("ng")) { + if(runCommand.command.parameters[0].indexOf("npm") > -1 || runCommand.command.parameters[0].indexOf("ng")) { let nodeInstallDir = path.join(this.getWorkingDirectory(), "devonfw", "software", "node"); this.env["npm_config_prefix"] = nodeInstallDir; this.env["npm_config_cache"] = ""; @@ -68,7 +67,7 @@ export class Console extends Runner { let settingsDir = this.createFolder(path.join(this.getWorkingDirectory(), "devonfw-settings"), true); this.executeCommandSync("git clone https://github.com/devonfw/ide-settings.git settings", settingsDir, result); - let tools = "DEVON_IDE_TOOLS=(" + command.parameters[0].join(" ") + ")"; + let tools = "DEVON_IDE_TOOLS=(" + runCommand.command.parameters[0].join(" ") + ")"; fs.writeFileSync(path.join(settingsDir, "settings", "devon.properties"), tools); fs.appendFileSync(path.join(settingsDir, "settings", "devon", "conf", "npm", ".npmrc"), "\nunsafe-perm=true"); fs.renameSync(path.join(settingsDir, "settings"), path.join(settingsDir, "settings.git")); @@ -78,8 +77,8 @@ export class Console extends Runner { this.createFolder(installDir, true); let downloadUrl = "https://bit.ly/2BCkFa9"; - if(command.parameters.length > 1 && command.parameters[1] != "") { - downloadUrl = "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.devonfw.tools.ide&a=devonfw-ide-scripts&p=tar.gz&v=" + command.parameters[1]; + if(runCommand.command.parameters.length > 1 && runCommand.command.parameters[1] != "") { + downloadUrl = "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.devonfw.tools.ide&a=devonfw-ide-scripts&p=tar.gz&v=" + runCommand.command.parameters[1]; } if(this.platform == ConsolePlatform.WINDOWS) { this.executeCommandSync("powershell.exe \"Invoke-WebRequest -OutFile devonfw.tar.gz '" + downloadUrl + "'\"", installDir, result); @@ -97,11 +96,11 @@ export class Console extends Runner { } - runRestoreDevonfwIde(step: Step, command: Command): RunResult { - return this.runInstallDevonfwIde(step, command); + runRestoreDevonfwIde(runCommand: RunCommand): RunResult { + return this.runInstallDevonfwIde(runCommand); } - runInstallCobiGen(step: Step, command: Command): RunResult { + runInstallCobiGen(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; @@ -113,7 +112,7 @@ export class Console extends Runner { return result; } - runCreateDevon4jProject(step: Step, command: Command): RunResult { + runCreateDevon4jProject(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; @@ -122,23 +121,23 @@ export class Console extends Runner { } let workspaceDir = path.join(this.getWorkingDirectory(), "devonfw", "workspaces", "main"); - let projectName = command.parameters[0]; + let projectName = runCommand.command.parameters[0]; this.executeDevonCommandSync("java create com.example.application." + projectName, workspaceDir, result); return result; } - runCreateFile(step: Step, command: Command): RunResult { + runCreateFile(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let filepath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let filepath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); if(!fs.existsSync(filepath.substr(0, filepath.lastIndexOf(path.sep)))) { fs.mkdirSync(filepath.substr(0, filepath.lastIndexOf(path.sep)), { recursive: true }); } let content = ""; - if(command.parameters.length == 2) { - content = fs.readFileSync(path.join(this.playbookPath, command.parameters[1]), { encoding: "utf-8" }); + if(runCommand.command.parameters.length == 2) { + content = fs.readFileSync(path.join(this.playbookPath, runCommand.command.parameters[1]), { encoding: "utf-8" }); } fs.writeFileSync(filepath, content); @@ -146,12 +145,12 @@ export class Console extends Runner { } - runBuildJava(step: Step, command: Command): RunResult { + runBuildJava(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let projectDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); - let buildCommand = (command.parameters.length == 2 && command.parameters[1] == true) + let projectDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); + let buildCommand = (runCommand.command.parameters.length == 2 && runCommand.command.parameters[1] == true) ? "mvn clean install" : "mvn clean install -Dmaven.test.skip=true"; @@ -162,7 +161,7 @@ export class Console extends Runner { return result; } - runCobiGenJava(step: Step, command: Command): RunResult { + runCobiGenJava(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; @@ -171,32 +170,32 @@ export class Console extends Runner { } let workspaceDir = path.join(this.getWorkingDirectory(), "devonfw", "workspaces", "main"); - this.executeDevonCommandSync("cobigen generate " + command.parameters[0], workspaceDir, result, command.parameters[1].toString()); + this.executeDevonCommandSync("cobigen generate " + runCommand.command.parameters[0], workspaceDir, result, runCommand.command.parameters[1].toString()); return result; } - runChangeFile(step: Step, command: Command): RunResult { + runChangeFile(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let filepath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let filepath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let content = fs.readFileSync(filepath, { encoding: "utf-8" }); - if(command.parameters[1].placeholder) { - let placeholder = command.parameters[1].placeholder; - if(command.parameters[1].content || command.parameters[1].contentConsole) { - let contentReplace = command.parameters[1].contentConsole ? command.parameters[1].contentConsole : command.parameters[1].content; + if(runCommand.command.parameters[1].placeholder) { + let placeholder = runCommand.command.parameters[1].placeholder; + if(runCommand.command.parameters[1].content || runCommand.command.parameters[1].contentConsole) { + let contentReplace = runCommand.command.parameters[1].contentConsole ? runCommand.command.parameters[1].contentConsole : runCommand.command.parameters[1].content; content = content.replace(placeholder, contentReplace); - } else if (command.parameters[1].file || command.parameters[1].fileConsole) { - let file = command.parameters[1].fileConsole ? command.parameters[1].fileConsole : command.parameters[1].file; + } else if (runCommand.command.parameters[1].file || runCommand.command.parameters[1].fileConsole) { + let file = runCommand.command.parameters[1].fileConsole ? runCommand.command.parameters[1].fileConsole : runCommand.command.parameters[1].file; let contentFile = fs.readFileSync(path.join(this.playbookPath, file), { encoding: "utf-8" }); content = content.replace(placeholder, contentFile); } } else { - if(command.parameters[1].content || command.parameters[1].contentConsole) { - content = command.parameters[1].contentConsole ? command.parameters[1].contentConsole : command.parameters[1].content; + if(runCommand.command.parameters[1].content || runCommand.command.parameters[1].contentConsole) { + content = runCommand.command.parameters[1].contentConsole ? runCommand.command.parameters[1].contentConsole : runCommand.command.parameters[1].content; } else { - let file = command.parameters[1].fileConsole ? command.parameters[1].fileConsole : command.parameters[1].file; + let file = runCommand.command.parameters[1].fileConsole ? runCommand.command.parameters[1].fileConsole : runCommand.command.parameters[1].file; content = fs.readFileSync(path.join(this.playbookPath, file), { encoding: "utf-8" }); } } @@ -206,11 +205,11 @@ export class Console extends Runner { } - runDockerCompose(step: Step, command: Command): RunResult { + runDockerCompose(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let filepath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let filepath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let process = this.executeCommandAsync("docker-compose up", filepath, result); process.on('close', (code) => { @@ -218,53 +217,53 @@ export class Console extends Runner { result.returnCode = code; } }); - if(process.pid && command.parameters.length == 2) { - this.asyncProcesses.push({ pid: process.pid, name: "dockerCompose", port: command.parameters[1].port }); + if(process.pid && runCommand.command.parameters.length == 2) { + this.asyncProcesses.push({ pid: process.pid, name: "dockerCompose", port: runCommand.command.parameters[1].port }); } return result; } - runRunServerJava(step: Step, command: Command): RunResult { + runRunServerJava(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let serverDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let serverDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let process = (this.getVariable(this.useDevonCommand)) ? this.executeDevonCommandAsync("mvn spring-boot:run", serverDir, result) : this.executeCommandAsync("mvn spring-boot:run", serverDir, result); if(process.pid) { - this.asyncProcesses.push({ pid: process.pid, name: "java", port: command.parameters[1].port }); + this.asyncProcesses.push({ pid: process.pid, name: "java", port: runCommand.command.parameters[1].port }); } return result; } - runCloneRepository(step: Step, command: Command): RunResult { + runCloneRepository(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let directorypath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); - if(command.parameters[0] != "") { + let directorypath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); + if(runCommand.command.parameters[0] != "") { this.createFolder(directorypath, true); } - this.executeCommandSync("git clone " + command.parameters[1], directorypath, result); + this.executeCommandSync("git clone " + runCommand.command.parameters[1], directorypath, result); return result; } - runNpmInstall(step: Step, command: Command): RunResult { + runNpmInstall(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let projectPath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let projectPath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let npmCommand = "npm install"; - if(command.parameters.length > 1){ - if (command.parameters[1].global) npmCommand += " -g"; - if (command.parameters[1].args) npmCommand += " " + command.parameters[1].args.join(" "); - if (command.parameters[1].name) npmCommand += " " + command.parameters[1].name; + if(runCommand.command.parameters.length > 1){ + if (runCommand.command.parameters[1].global) npmCommand += " -g"; + if (runCommand.command.parameters[1].args) npmCommand += " " + runCommand.command.parameters[1].args.join(" "); + if (runCommand.command.parameters[1].name) npmCommand += " " + runCommand.command.parameters[1].name; } this.getVariable(this.useDevonCommand) ? this.executeDevonCommandSync(npmCommand, projectPath, result) @@ -273,45 +272,45 @@ export class Console extends Runner { return result; } - runDownloadFile(step: Step, command: Command): RunResult { + runDownloadFile(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; let downloadlDir = this.getVariable(this.workspaceDirectory); - if (command.parameters.length == 3) { - downloadlDir = path.join(downloadlDir, command.parameters[2]); + if (runCommand.command.parameters.length == 3) { + downloadlDir = path.join(downloadlDir, runCommand.command.parameters[2]); this.createFolder(downloadlDir, false); } let command1 = (this.platform == ConsolePlatform.WINDOWS) - ? "powershell.exe \"Invoke-WebRequest -OutFile " + command.parameters[1] + " '" + command.parameters[0] + "'\"" - : "wget -c " + command.parameters[0] + " -O " + command.parameters[1]; + ? "powershell.exe \"Invoke-WebRequest -OutFile " + runCommand.command.parameters[1] + " '" + runCommand.command.parameters[0] + "'\"" + : "wget -c " + runCommand.command.parameters[0] + " -O " + runCommand.command.parameters[1]; this.executeCommandSync(command1, downloadlDir, result); return result; } - runRunClientNg(step: Step, command: Command): RunResult { + runRunClientNg(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let projectDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let projectDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let process = this.getVariable(this.useDevonCommand) ? this.executeDevonCommandAsync("ng serve", projectDir, result) : this.executeCommandAsync("ng serve", projectDir, result); if(process.pid) { - this.asyncProcesses.push({ pid: process.pid, name: "node", port: command.parameters[1].port }); + this.asyncProcesses.push({ pid: process.pid, name: "node", port: runCommand.command.parameters[1].port }); } return result; } - runBuildNg(step: Step, command: Command): RunResult { + runBuildNg(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let projectDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let projectDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let command1 = "ng build"; - if(command.parameters.length == 2) { - command1 = command1 + " --output-path " + command.parameters[1]; + if(runCommand.command.parameters.length == 2) { + command1 = command1 + " --output-path " + runCommand.command.parameters[1]; } this.getVariable(this.useDevonCommand) ? this.executeDevonCommandSync(command1, projectDir, result) @@ -320,11 +319,11 @@ export class Console extends Runner { return result; } - runCreateFolder(step: Step, command: Command): RunResult { + runCreateFolder(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; - let folderPath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let folderPath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); if(folderPath && !fs.existsSync(folderPath)) { this.createFolder(folderPath, true); } @@ -332,12 +331,12 @@ export class Console extends Runner { return result; } - runNextKatacodaStep(step: Step, command: Command): RunResult { + runNextKatacodaStep(runCommand: RunCommand): RunResult { //Only needed for katacoda runner return null; } - runAdaptTemplatesCobiGen(step: Step, command: Command): RunResult { + runAdaptTemplatesCobiGen(runCommand: RunCommand): RunResult { let result = new RunResult(); result.returnCode = 0; @@ -348,9 +347,9 @@ export class Console extends Runner { return result; } - async assertInstallDevonfwIde(step: Step, command: Command, result: RunResult) { + async assertInstallDevonfwIde(runCommand: RunCommand, result: RunResult) { try { - let installedTools = command.parameters[0]; + let installedTools = runCommand.command.parameters[0]; let assert = new Assertions() .noErrorCode(result) @@ -368,11 +367,11 @@ export class Console extends Runner { } } - async assertRestoreDevonfwIde(step: Step, command: Command, result: RunResult) { - this.assertInstallDevonfwIde(step, command, result); + async assertRestoreDevonfwIde(runCommand: RunCommand, result: RunResult) { + this.assertInstallDevonfwIde(runCommand, result); } - async assertInstallCobiGen(step: Step, command: Command, result: RunResult) { + async assertInstallCobiGen(runCommand: RunCommand, result: RunResult) { try { new Assertions() .noErrorCode(result) @@ -386,72 +385,72 @@ export class Console extends Runner { } } - async assertBuildJava(step: Step, command: Command, result: RunResult) { + async assertBuildJava(runCommand: RunCommand, result: RunResult) { try { new Assertions() .noErrorCode(result) .noException(result) - .directoryExits(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], "api", "target")) - .directoryExits(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], "core", "target")) - .directoryExits(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], "server", "target")); + .directoryExits(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], "api", "target")) + .directoryExits(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], "core", "target")) + .directoryExits(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], "server", "target")); } catch(error) { this.cleanUp(); throw error; } } - async assertCobiGenJava(step: Step, command: Command, result: RunResult) { + async assertCobiGenJava(runCommand: RunCommand, result: RunResult) { try { new Assertions() .noErrorCode(result) .noException(result) - .fileExits(path.join(this.getWorkingDirectory(), "devonfw", "workspaces", "main", command.parameters[0])); + .fileExits(path.join(this.getWorkingDirectory(), "devonfw", "workspaces", "main", runCommand.command.parameters[0])); } catch(error) { this.cleanUp(); throw error; } } - async assertCreateDevon4jProject(step: Step, command: Command, result: RunResult) { + async assertCreateDevon4jProject(runCommand: RunCommand, result: RunResult) { try { let workspaceDir = path.join(this.getWorkingDirectory(), "devonfw", "workspaces", "main"); new Assertions() .noErrorCode(result) .noException(result) - .directoryExits(path.join(workspaceDir, command.parameters[0])) - .directoryExits(path.join(workspaceDir, command.parameters[0], "api", "src", "main", "java")) - .directoryExits(path.join(workspaceDir, command.parameters[0], "core", "src", "main", "java")) - .directoryExits(path.join(workspaceDir, command.parameters[0], "server", "src", "main", "java")) - .fileExits(path.join(workspaceDir, command.parameters[0], "core", "src", "main", "java", "com", "example", "application", command.parameters[0], "SpringBootApp.java")); + .directoryExits(path.join(workspaceDir, runCommand.command.parameters[0])) + .directoryExits(path.join(workspaceDir, runCommand.command.parameters[0], "api", "src", "main", "java")) + .directoryExits(path.join(workspaceDir, runCommand.command.parameters[0], "core", "src", "main", "java")) + .directoryExits(path.join(workspaceDir, runCommand.command.parameters[0], "server", "src", "main", "java")) + .fileExits(path.join(workspaceDir, runCommand.command.parameters[0], "core", "src", "main", "java", "com", "example", "application", runCommand.command.parameters[0], "SpringBootApp.java")); } catch(error) { this.cleanUp(); throw error; } } - async assertCreateFile(step: Step, command: Command, result: RunResult) { + async assertCreateFile(runCommand: RunCommand, result: RunResult) { try { new Assertions() .noErrorCode(result) .noException(result) - .fileExits(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0])); + .fileExits(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0])); } catch(error) { this.cleanUp(); throw error; } } - async assertChangeFile(step: Step, command: Command, result: RunResult) { + async assertChangeFile(runCommand: RunCommand, result: RunResult) { try{ let content = ""; - if(command.parameters[1].content) { - content = command.parameters[1].content; - } else if (command.parameters[1].file) { - content = fs.readFileSync(path.join(this.playbookPath, command.parameters[1].file), { encoding: "utf-8" }); + if(runCommand.command.parameters[1].content) { + content = runCommand.command.parameters[1].content; + } else if (runCommand.command.parameters[1].file) { + content = fs.readFileSync(path.join(this.playbookPath, runCommand.command.parameters[1].file), { encoding: "utf-8" }); } - let filepath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let filepath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); new Assertions() .noErrorCode(result) .noException(result) @@ -463,27 +462,27 @@ export class Console extends Runner { } } - async assertDockerCompose(step: Step, command: Command, result: RunResult) { + async assertDockerCompose(runCommand: RunCommand, result: RunResult) { try { let assert = new Assertions() .noErrorCode(result) .noException(result); - if(command.parameters.length > 1) { - if(!command.parameters[1].startupTime) { + if(runCommand.command.parameters.length > 1) { + if(!runCommand.command.parameters[1].startupTime) { console.warn("No startup time for command dockerCompose has been set") } - let startupTimeInSeconds = command.parameters[1].startupTime ? command.parameters[1].startupTime : 0; - await this.sleep(command.parameters[1].startupTime); + let startupTimeInSeconds = runCommand.command.parameters[1].startupTime ? runCommand.command.parameters[1].startupTime : 0; + await this.sleep(runCommand.command.parameters[1].startupTime); - if(!command.parameters[1].port) { + if(!runCommand.command.parameters[1].port) { this.killAsyncProcesses(); throw new Error("Missing arguments for command dockerCompose. You have to specify a port and a path for the server. For further information read the function documentation."); } else { - let isReachable = await assert.serverIsReachable(command.parameters[1].port, command.parameters[1].path); + let isReachable = await assert.serverIsReachable(runCommand.command.parameters[1].port, runCommand.command.parameters[1].path); if(!isReachable) { this.killAsyncProcesses(); - throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + command.parameters[1].port + "/" + command.parameters[1].path); + throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + runCommand.command.parameters[1].port + "/" + runCommand.command.parameters[1].path); } } } @@ -493,27 +492,27 @@ export class Console extends Runner { } } - async assertRunServerJava(step: Step, command: Command, result: RunResult) { + async assertRunServerJava(runCommand: RunCommand, result: RunResult) { try { let assert = new Assertions() .noErrorCode(result) .noException(result); - if(command.parameters.length > 1) { - if(!command.parameters[1].startupTime) { + if(runCommand.command.parameters.length > 1) { + if(!runCommand.command.parameters[1].startupTime) { console.warn("No startup time for command runServerJava has been set") } - let startupTimeInSeconds = command.parameters[1].startupTime ? command.parameters[1].startupTime : 0; - await this.sleep(command.parameters[1].startupTime); + let startupTimeInSeconds = runCommand.command.parameters[1].startupTime ? runCommand.command.parameters[1].startupTime : 0; + await this.sleep(runCommand.command.parameters[1].startupTime); - if(!command.parameters[1].port || !command.parameters[1].path) { + if(!runCommand.command.parameters[1].port || !runCommand.command.parameters[1].path) { this.killAsyncProcesses(); throw new Error("Missing arguments for command runServerJava. You have to specify a port and a path for the server. For further information read the function documentation."); } else { - let isReachable = await assert.serverIsReachable(command.parameters[1].port, command.parameters[1].path); + let isReachable = await assert.serverIsReachable(runCommand.command.parameters[1].port, runCommand.command.parameters[1].path); if(!isReachable) { this.killAsyncProcesses(); - throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + command.parameters[1].port + "/" + command.parameters[1].path) + throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + runCommand.command.parameters[1].port + "/" + runCommand.command.parameters[1].path) } } } @@ -523,17 +522,17 @@ export class Console extends Runner { } } - async assertCloneRepository(step: Step, command: Command, result: RunResult) { + async assertCloneRepository(runCommand: RunCommand, result: RunResult) { try { - let repository = command.parameters[1]; + let repository = runCommand.command.parameters[1]; let repoName = repository.slice(repository.lastIndexOf("/"), -4); - let directorypath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], repoName); + let directorypath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], repoName); new Assertions() .noErrorCode(result) .noException(result) - .directoryExits(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], repoName)) - .directoryNotEmpty(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0], repoName)) + .directoryExits(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], repoName)) + .directoryNotEmpty(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0], repoName)) .repositoryIsClean(directorypath); } catch(error) { this.cleanUp(); @@ -541,64 +540,63 @@ export class Console extends Runner { } } - async assertNpmInstall(step: Step, command: Command, result: RunResult) { + async assertNpmInstall(runCommand: RunCommand, result: RunResult) { try { - let projectDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let projectDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); new Assertions() .noErrorCode(result) .noException(result) .directoryExits(projectDir) - if(command.parameters.length < 2 || !command.parameters[1].global){ + if(runCommand.command.parameters.length < 2 || !runCommand.command.parameters[1].global){ new Assertions() .directoryExits(path.join(projectDir, "node_modules")) .directoryNotEmpty(path.join(projectDir, "node_modules")); } - } catch(error) { this.cleanUp(); throw error; } } - async assertDownloadFile(step: Step, command: Command, result: RunResult){ + async assertDownloadFile(runCommand: RunCommand, result: RunResult){ try { let directory = this.getVariable(this.workspaceDirectory); - if(command.parameters.length == 3) { - directory = path.join(directory, command.parameters[2]); + if(runCommand.command.parameters.length == 3) { + directory = path.join(directory, runCommand.command.parameters[2]); } new Assertions() .noErrorCode(result) .noException(result) .directoryExits(directory) .directoryNotEmpty(directory) - .fileExits(path.join(directory, command.parameters[1])); + .fileExits(path.join(directory, runCommand.command.parameters[1])); } catch(error) { this.cleanUp(); throw error; } } - async assertRunClientNg(step: Step, command: Command, result: RunResult) { + async assertRunClientNg(runCommand: RunCommand, result: RunResult) { try { let assert = new Assertions() .noErrorCode(result) .noException(result); - if(command.parameters.length > 1) { - if(!command.parameters[1].startupTime) { + if(runCommand.command.parameters.length > 1) { + if(!runCommand.command.parameters[1].startupTime) { console.warn("No startup time for command runClientNg has been set") } - let startupTimeInSeconds = command.parameters[1].startupTime ? command.parameters[1].startupTime : 0; - await this.sleep(command.parameters[1].startupTime); + let startupTimeInSeconds = runCommand.command.parameters[1].startupTime ? runCommand.command.parameters[1].startupTime : 0; + await this.sleep(runCommand.command.parameters[1].startupTime); - if(!command.parameters[1].port) { + if(!runCommand.command.parameters[1].port) { this.killAsyncProcesses(); throw new Error("Missing arguments for command runClientNg. You have to specify a port for the server. For further information read the function documentation."); } else { - let isReachable = await assert.serverIsReachable(command.parameters[1].port, command.parameters[1].path); + let isReachable = await assert.serverIsReachable(runCommand.command.parameters[1].port, runCommand.command.parameters[1].path); if(!isReachable) { this.killAsyncProcesses(); - throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + command.parameters[1].port + "/" + command.parameters[1].path) + throw new Error("The server has not become reachable in " + startupTimeInSeconds + " seconds: " + "http://localhost:" + runCommand.command.parameters[1].port + "/" + runCommand.command.parameters[1].path) } } } @@ -608,12 +606,12 @@ export class Console extends Runner { } } - async assertBuildNg(step: Step, command: Command, result: RunResult) { + async assertBuildNg(runCommand: RunCommand, result: RunResult) { try { - let projectPath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let projectPath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); var outputpath; - if(command.parameters.length == 2) { - outputpath = command.parameters[1].trim(); + if(runCommand.command.parameters.length == 2) { + outputpath = runCommand.command.parameters[1].trim(); } else { let content = fs.readFileSync(path.join(projectPath, "angular.json"), { encoding: "utf-8" }); outputpath = this.lookup(JSON.parse(content), "outputPath")[1]; @@ -633,9 +631,9 @@ export class Console extends Runner { } } - async assertCreateFolder(step: Step, command: Command, result: RunResult){ + async assertCreateFolder(runCommand: RunCommand, result: RunResult){ try { - let folderPath = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + let folderPath = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); new Assertions() .noErrorCode(result) .noException(result) @@ -646,7 +644,7 @@ export class Console extends Runner { } } - async assertAdaptTemplatesCobiGen(step: Step, command: Command, result: RunResult) { + async assertAdaptTemplatesCobiGen(runCommand: RunCommand, result: RunResult) { try { let templatesDir = path.join(os.homedir(), ".cobigen", "templates"); new Assertions() diff --git a/runners/katacoda/index.ts b/runners/katacoda/index.ts index 3765f0c7..6ecc5c5a 100644 --- a/runners/katacoda/index.ts +++ b/runners/katacoda/index.ts @@ -1,8 +1,7 @@ import { Runner } from "../../engine/runner" import { RunResult } from "../../engine/run_result"; import { Playbook } from "../../engine/playbook"; -import { Step } from "../../engine/step"; -import { Command } from "../../engine/command"; +import { RunCommand } from "../../engine/run_command"; import { KatacodaTools } from "./katacodaTools"; import { KatacodaStep, KatacodaSetupScript, KatacodaTerminals } from "./katacodaInterfaces"; import { KatacodaAssetManager } from "./katacodaAssetManager"; @@ -68,13 +67,13 @@ export class Katacoda extends Runner { this.assetManager.copyAssets(); // write index file, required for katacoda to load the tutorial - let indexJsonObject = KatacodaTools.generateIndexJson(playbook.title, ((this.stepsCount - 1) * 5), this.steps, this.assetManager.getKatacodaAssets()); + let indexJsonObject = KatacodaTools.generateIndexJson(playbook.title, ((this.stepsCount) * 5), this.steps, this.assetManager.getKatacodaAssets()); fs.writeFileSync(this.outputPathTutorial + 'index.json', JSON.stringify(indexJsonObject, null, 2)); } - runInstallDevonfwIde(step: Step, command: Command): RunResult { + runInstallDevonfwIde(runCommand: RunCommand): RunResult { let cdCommand = this.changeCurrentDir(path.join("/root")); - let tools = command.parameters[0].join(" ").replace(/vscode/,"").replace(/eclipse/, "").trim(); + let tools = runCommand.command.parameters[0].join(" ").replace(/vscode/,"").replace(/eclipse/, "").trim(); // create script to download devonfw ide settings this.renderTemplate(path.join("scripts", "cloneDevonfwIdeSettings.sh"), path.join(this.setupDir, "cloneDevonfwIdeSettings.sh"), { tools: tools, cloneDir: "/root/devonfw-settings/"}); @@ -85,11 +84,9 @@ export class Katacoda extends Runner { "script": "cloneDevonfwIdeSettings.sh" }); - this.steps.push({ - "title": "Install devonfw IDE", - "text": "step" + this.stepsCount + ".md", - }); - this.renderTemplate("installDevonfwIde.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand}); + this.pushStep(runCommand, "Install devonfw IDE", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("installDevonfwIde.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand}); //update current and working directory this.currentDir = path.join(this.currentDir, "devonfw"); @@ -102,8 +99,8 @@ export class Katacoda extends Runner { return null; } - runRestoreDevonfwIde(step: Step, command: Command): RunResult { - let tools = command.parameters[0].join(" ").replace(/vscode/,"").replace(/eclipse/, "").trim(); + runRestoreDevonfwIde(runCommand: RunCommand): RunResult { + let tools = runCommand.command.parameters[0].join(" ").replace(/vscode/,"").replace(/eclipse/, "").trim(); // create script to download devonfw ide settings. this.renderTemplate(path.join("scripts", "cloneDevonfwIdeSettings.sh"), path.join(this.setupDir, "cloneDevonfwIdeSettings.sh"), { tools: tools, cloneDir: "/root/devonfw-settings/"}); @@ -129,17 +126,15 @@ export class Katacoda extends Runner { return null; } - runInstallCobiGen(step: Step, command: Command): RunResult { - this.steps.push({ - "title": "Install CobiGen", - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("installCobiGen.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter}); + runInstallCobiGen(runCommand: RunCommand): RunResult { + this.pushStep(runCommand, "Install CobiGen", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("installCobiGen.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter}); return null; } - runCobiGenJava(step: Step, command: Command): RunResult { - let params = command.parameters; + runCobiGenJava(runCommand: RunCommand): RunResult { + let params = runCommand.command.parameters; let cobiGenTemplates = params[1].join(","); this.renderTemplate(path.join("scripts", "installCobiGenPlugin.sh"), path.join(this.setupDir, "installCobiGenPlugin.sh"), { }); @@ -147,182 +142,152 @@ export class Katacoda extends Runner { "name": "Install CobiGen plugin", "script": "installCobiGenPlugin.sh" }); - - this.steps.push({ - "title": "CobiGen Java", - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("cobiGenJava.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, javaFile: params[0], cobiGenTemplates: cobiGenTemplates }); + this.pushStep(runCommand, "CobiGen Java", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("cobiGenJava.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, javaFile: params[0], cobiGenTemplates: cobiGenTemplates }); return null; } - runCreateDevon4jProject(step: Step, command:Command): RunResult { + runCreateDevon4jProject(runCommand: RunCommand): RunResult { // generate template to change directory, if the current directory is not equal to the required start directory let cdCommand = this.changeCurrentDir(path.join("/root", "devonfw", "workspaces", "main")); - this.steps.push({ - "title": "Create a new project", - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Create a new project", "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("createDevon4jProject.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, name : command.parameters[0]}); + this.renderTemplate("createDevon4jProject.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, name : runCommand.command.parameters[0]}); return null; } - runCreateFile(step: Step, command: Command): RunResult{ + runCreateFile(runCommand: RunCommand): RunResult{ let workspaceDir = path.join(this.getVariable(this.workspaceDirectory).concat(path.sep).replace(path.sep + "root" + path.sep, "")); - let filePath = path.join(this.getVariable(this.workspaceDirectory), path.dirname(command.parameters[0])).replace(/\\/g, "/"); - let fileDir = path.join(workspaceDir, command.parameters[0]).replace(/\\/g, "/"); - let fileName = path.basename(path.join(command.parameters[0])); + let filePath = path.join(this.getVariable(this.workspaceDirectory), path.dirname(runCommand.command.parameters[0])).replace(/\\/g, "/"); + let fileDir = path.join(workspaceDir, runCommand.command.parameters[0]).replace(/\\/g, "/"); + let fileName = path.basename(path.join(runCommand.command.parameters[0])); let content = ""; - if(command.parameters.length == 2) { - content = fs.readFileSync(path.join(this.playbookPath, command.parameters[1]), { encoding: "utf-8" }); + if(runCommand.command.parameters.length == 2) { + content = fs.readFileSync(path.join(this.playbookPath, runCommand.command.parameters[1]), { encoding: "utf-8" }); } - - this.steps.push({ - "title": "Create a new file", - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Create a new file", "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("createFile.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, filePath: filePath, fileDir: fileDir , fileName:fileName , content: content}); + this.renderTemplate("createFile.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, filePath: filePath, fileDir: fileDir , fileName:fileName , content: content}); return null; } - runChangeFile(step: Step, command: Command): RunResult{ + runChangeFile(runCommand: RunCommand): RunResult{ let workspaceDir = path.join(this.getVariable(this.workspaceDirectory).concat(path.sep).replace(path.sep + "root" + path.sep, "")); - let fileName = path.basename(path.join(command.parameters[0])); - let fileDir = path.join(workspaceDir, command.parameters[0]).replace(/\\/g, "/"); - let placeholder = command.parameters[1].placeholder ? command.parameters[1].placeholder : ""; - let dataTarget = command.parameters[1].placeholder ? "insert" : "replace"; + let fileName = path.basename(path.join(runCommand.command.parameters[0])); + let fileDir = path.join(workspaceDir, runCommand.command.parameters[0]).replace(/\\/g, "/"); + let placeholder = runCommand.command.parameters[1].placeholder ? runCommand.command.parameters[1].placeholder : ""; + let dataTarget = runCommand.command.parameters[1].placeholder ? "insert" : "replace"; let content = ""; - if(command.parameters[1].content || command.parameters[1].contentKatacoda){ - content = (command.parameters[1].contentKatacoda) ? command.parameters[1].contentKatacoda : command.parameters[1].content; - }else if(command.parameters[1].file || command.parameters[1].fileKatacoda){ - let file = (command.parameters[1].fileKatacoda) ? command.parameters[1].fileKatacoda : command.parameters[1].file; + if(runCommand.command.parameters[1].content || runCommand.command.parameters[1].contentKatacoda){ + content = (runCommand.command.parameters[1].contentKatacoda) ? runCommand.command.parameters[1].contentKatacoda : runCommand.command.parameters[1].content; + }else if(runCommand.command.parameters[1].file || runCommand.command.parameters[1].fileKatacoda){ + let file = (runCommand.command.parameters[1].fileKatacoda) ? runCommand.command.parameters[1].fileKatacoda : runCommand.command.parameters[1].file; content = fs.readFileSync(path.join(this.playbookPath, file), { encoding: "utf-8" }); } - this.steps.push({ - "title": "Change " + fileName, - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Change " + fileName, "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("changeFile.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, fileDir: fileDir, content: content, placeholder: placeholder, dataTarget: dataTarget }); + this.renderTemplate("changeFile.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, fileDir: fileDir, content: content, placeholder: placeholder, dataTarget: dataTarget }); return null; } - runBuildJava(step: Step, command: Command): RunResult{ + runBuildJava(runCommand: RunCommand): RunResult{ - let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0])); - let skipTest = (command.parameters.length == 2 && command.parameters[1] == true) ? false : true; + let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0])); + let skipTest = (runCommand.command.parameters.length == 2 && runCommand.command.parameters[1] == true) ? false : true; - this.steps.push({ - "title": "Build the java project", - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Build the java project", "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("buildJava.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, skipTest: skipTest, useDevonCommand: this.getVariable(this.useDevonCommand)}); + this.renderTemplate("buildJava.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, skipTest: skipTest, useDevonCommand: this.getVariable(this.useDevonCommand)}); return null; } - runBuildNg(step: Step, command: Command): RunResult { - let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0])); + runBuildNg(runCommand: RunCommand): RunResult { + let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0])); - this.steps.push({ - "title": "Build the Angular Project", - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Build the Angular Project", "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("buildNg.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, outputDir: command.parameters[1], useDevonCommand: this.getVariable(this.useDevonCommand) }); + this.renderTemplate("buildNg.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, outputDir: runCommand.command.parameters[1], useDevonCommand: this.getVariable(this.useDevonCommand) }); return null; } - runCloneRepository(step: Step, command: Command): RunResult { + runCloneRepository(runCommand: RunCommand): RunResult { let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory))); let directoryPath = ""; - if(command.parameters[0].trim()) { - directoryPath = path.join(command.parameters[0]).replace(/\\/g, "/"); + if(runCommand.command.parameters[0].trim()) { + directoryPath = path.join(runCommand.command.parameters[0]).replace(/\\/g, "/"); this.currentDir = path.join(this.currentDir, directoryPath); } + this.pushStep(runCommand, "Clones Repository " + runCommand.command.parameters[1], "step" + this.getStepsCount(runCommand) + ".md"); - this.steps.push({ - "title": "Clones Repository " + command.parameters[1], - "text": "step" + this.stepsCount + ".md" - }); - - this.renderTemplate("cloneRepository.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, directoryPath: directoryPath, repository: command.parameters[1] }); + this.renderTemplate("cloneRepository.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, directoryPath: directoryPath, repository: runCommand.command.parameters[1] }); return null; } - runRunServerJava(step: Step, command: Command): RunResult{ - let serverDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + runRunServerJava(runCommand: RunCommand): RunResult{ + let serverDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let terminal = this.getTerminal('runServerJava'); let cdCommand = this.changeCurrentDir(serverDir, terminal.terminalId, terminal.isRunning); - this.steps.push({ - "title": "Start the java server", - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("runServerJava.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, useDevonCommand: this.getVariable(this.useDevonCommand)}); + this.pushStep(runCommand, "Start the java server", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("runServerJava.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, useDevonCommand: this.getVariable(this.useDevonCommand)}); return null; } - runNpmInstall(step: Step, command: Command): RunResult { - let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0])); - let packageTitle = (command.parameters.length > 1 && command.parameters[1].name) ? command.parameters[1].name : "the dependencies"; + runNpmInstall(runCommand: RunCommand): RunResult { + let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0])); + let packageTitle = (runCommand.command.parameters.length > 1 && runCommand.command.parameters[1].name) ? runCommand.command.parameters[1].name : "the dependencies"; let npmCommand = { - "name": (command.parameters.length > 1 && command.parameters[1].name) ? command.parameters[1].name : undefined, - "global": (command.parameters.length > 1 && command.parameters[1].global) ? command.parameters[1].global : false, - "args": (command.parameters.length > 1 && command.parameters[1].args) ? command.parameters[1].args.join(" ") : undefined + "name": (runCommand.command.parameters.length > 1 && runCommand.command.parameters[1].name) ? runCommand.command.parameters[1].name : undefined, + "global": (runCommand.command.parameters.length > 1 && runCommand.command.parameters[1].global) ? runCommand.command.parameters[1].global : false, + "args": (runCommand.command.parameters.length > 1 && runCommand.command.parameters[1].args) ? runCommand.command.parameters[1].args.join(" ") : undefined }; this.steps.push({ "title": "Install " + packageTitle, "text": "step" + this.stepsCount + ".md" }); - this.renderTemplate("npmInstall.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, useDevonCommand: this.getVariable(this.useDevonCommand), npmCommand: npmCommand}); + this.renderTemplate("npmInstall.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, useDevonCommand: this.getVariable(this.useDevonCommand), npmCommand: npmCommand}); return null; } - runRunClientNg(step: Step, command: Command): RunResult { - let serverDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]); + runRunClientNg(runCommand: RunCommand): RunResult { + let serverDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]); let terminal = this.getTerminal('runClientNg'); let cdCommand = this.changeCurrentDir(serverDir, terminal.terminalId, terminal.isRunning); - this.steps.push({ - "title": "Start the Angular Project", - "text": "step" + this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Start the Angular Project", "step" + this.getStepsCount(runCommand) + ".md"); fs.appendFileSync(path.join(this.getRunnerDirectory(),"templates","scripts", "intro_background.sh"), "\necho \'export NODE_OPTIONS=\"--max-old-space-size=16384\"\' >> /root/.profile\n"); - this.renderTemplate("runClientNg.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, port: command.parameters[1].port, useDevonCommand: this.getVariable(this.useDevonCommand)}); + this.renderTemplate("runClientNg.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, port: runCommand.command.parameters[1].port, useDevonCommand: this.getVariable(this.useDevonCommand)}); return null; } - runCreateFolder(step: Step, command: Command): RunResult { - let folderPath = new DirUtils().getCdParam(this.currentDir, path.join(this.getVariable(this.workspaceDirectory), command.parameters[0])); + runCreateFolder(runCommand: RunCommand): RunResult { + let folderPath = new DirUtils().getCdParam(this.currentDir, path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0])); - this.steps.push({ - "title": "Create a new folder", - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("createFolder.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, folderPath: folderPath }); + this.pushStep(runCommand, "Create a new folder", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("createFolder.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, folderPath: folderPath }); return null; } - runNextKatacodaStep(step: Step, command: Command): RunResult { - let tempFile = path.join(this.getTempDirectory(), command.name + ".md"); + runNextKatacodaStep(runCommand: RunCommand): RunResult { + let tempFile = path.join(this.getTempDirectory(), runCommand.command.name + ".md"); fs.writeFileSync(tempFile, ""); - for(let i = 0; i < command.parameters[1].length; i++) { - let param = command.parameters[1][i]; + for(let i = 0; i < runCommand.command.parameters[1].length; i++) { + let param = runCommand.command.parameters[1][i]; if(param.content) { fs.appendFileSync(tempFile, param.content); } else if(param.file) { @@ -336,38 +301,32 @@ export class Katacoda extends Runner { } let content = fs.readFileSync(tempFile, "utf-8"); - this.steps.push({ - "title": command.parameters[0], - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("nextKatacodaStep.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, content: content }); + this.pushStep(runCommand, runCommand.command.parameters[0], "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("nextKatacodaStep.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, content: content }); - if(command.parameters[2]) { - this.currentDir = path.join(this.getVariable(this.workspaceDirectory), command.parameters[2]); + if(runCommand.command.parameters[2]) { + this.currentDir = path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[2]); } return null; } - runAdaptTemplatesCobiGen(step: Step, command: Command): RunResult { - this.steps.push({ - "title": "Adapt cobiGen templates", - "text": "step" + this.stepsCount + ".md" - }); - this.renderTemplate("adaptTemplatesCobiGen.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter}); + runAdaptTemplatesCobiGen(runCommand: RunCommand): RunResult { + this.pushStep(runCommand, "Adapt cobiGen templates", "step" + this.getStepsCount(runCommand) + ".md"); + + this.renderTemplate("adaptTemplatesCobiGen.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter}); + return null; } - runDockerCompose(step: Step, command: Command) : RunResult { + runDockerCompose(runCommand: RunCommand) : RunResult { let terminal = this.getTerminal('runDockerCompose'); - let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), command.parameters[0]), terminal.terminalId, terminal.isRunning); + let cdCommand = this.changeCurrentDir(path.join(this.getVariable(this.workspaceDirectory), runCommand.command.parameters[0]), terminal.terminalId, terminal.isRunning); - this.steps.push({ - "title": "Execute Docker Compose", - "text": "step" +this.stepsCount + ".md" - }); + this.pushStep(runCommand, "Execute Docker Compose", "step" + this.getStepsCount(runCommand) + ".md"); - this.renderTemplate("dockerCompose.md", this.outputPathTutorial + "step" + (this.stepsCount++) + ".md", { text: step.text, textAfter: step.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, port: command.parameters[1].port}); + this.renderTemplate("dockerCompose.md", this.outputPathTutorial + "step" + this.stepsCount + ".md", { text: runCommand.text, textAfter: runCommand.textAfter, cdCommand: cdCommand, terminalId: terminal.terminalId, interrupt: terminal.isRunning, port: runCommand.command.parameters[1].port}); return null; } @@ -375,7 +334,7 @@ export class Katacoda extends Runner { private renderTemplate(name: string, targetPath: string, variables) { let template = fs.readFileSync(path.join(this.getRunnerDirectory(),"templates", name), 'utf8'); let result = ejs.render(template, variables); - fs.writeFileSync(targetPath, result); + fs.writeFileSync(targetPath, result, {flag: "a"}); } private writeSetupFile(setupFile: string) { @@ -416,4 +375,19 @@ export class Katacoda extends Runner { return {terminalId: this.terminalCounter, isRunning: false}; } + private getStepsCount(runCommand: RunCommand): number { + let returnCount = runCommand.stepIndex == this.stepsCount - 1 ? this.stepsCount : ++this.stepsCount; + return returnCount; + } + + private pushStep(runCommand: RunCommand, title: string, text: string) { + if (this.steps.length == this.stepsCount - 1) { + let stepTitle = runCommand.stepTitle ? runCommand.stepTitle : title; + this.steps.push({ + "title": stepTitle, + "text": text + }); + } + } + } \ No newline at end of file