diff --git a/apps/miragon-process-ide-cli/src/app/deployment/api.ts b/apps/miragon-process-ide-cli/src/app/deployment/api.ts index 398df63f..39d77997 100644 --- a/apps/miragon-process-ide-cli/src/app/deployment/api.ts +++ b/apps/miragon-process-ide-cli/src/app/deployment/api.ts @@ -1,41 +1,49 @@ import { Command, InvalidArgumentError } from "commander"; import { Deployment } from "./deployment"; import * as colors from "colors"; +import { DigiwfLib } from "@miragon-process-ide/digiwf-lib"; -const deployment = new Deployment(); +export class DeploymentCommand { + private deployment: Deployment; -export function deployFileCommand(): Command { - return new Command() - .command("deploy-file") - .description("deploys an artifact to the target environment") - .requiredOption("-f --file ", "specify the file (full path)") - .requiredOption("-t, --target ", "specify the target environment") - .requiredOption("--type ", "specify the file type") - .option("-p, --project ", "specify the project") - .hook("preAction", (thisCommand) => { - // validate inputs before action is called - const type = thisCommand.opts()["type"]; - if (!(type === "bpmn" || type === "dmn" || type === "form" || type === "config")) { - throw new InvalidArgumentError("type must be either bpmn, dmn, form or config"); - } - }) - .action((options) => { - deployment.deployArtifact(options.file, options.type, options.project, options.target) - .then( () => console.log("Deployment was successfully")) - .catch(err => console.log(colors.red.bold("FAILED") + ` with -> ${err}`)); - }); -} + constructor(digiwfLib: DigiwfLib) { + this.deployment = new Deployment(digiwfLib); + } + + public deployFileCommand(): Command { + return new Command() + .command("deploy-file") + .description("deploys an artifact to the target environment") + .requiredOption("-f --file ", "specify the file (full path)") + .requiredOption("-t, --target ", "specify the target environment") + .requiredOption("--type ", "specify the file type") + .option("-p, --project ", "specify the project") + .hook("preAction", (thisCommand) => { + // validate inputs before action is called + const type = thisCommand.opts()["type"]; + if (!(type === "bpmn" || type === "dmn" || type === "form" || type === "config")) { + throw new InvalidArgumentError("type must be either bpmn, dmn, form or config"); + } + }) + .action((options) => { + this.deployment.deployArtifact(options.file, options.type, options.project, options.target) + .then( () => console.log("Deployment was successfully")) + .catch(err => console.log(colors.red.bold("FAILED") + ` with -> ${err}`)); + }); + } + + public deployAllFiles(): Command { + return new Command() + .command("deploy-all") + .description("deploys all artifacts to the target environment") + .requiredOption("-d --directory ", "specify the directory of the source files") + .requiredOption("-t, --target ", "specify the target environment") + .option("-p, --project ", "specify the project") + .action((options) => { + this.deployment.deployAllArtifacts(options.directory, options.project, options.target) + .then( () => console.log(`Project ${options.project} was successfully deployed to environment ${options.target}`)) + .catch(err => console.log(colors.red.bold("FAILED") + ` with -> ${err}`)); + }); + } -export function deployAllFiles(): Command { - return new Command() - .command("deploy-all") - .description("deploys all artifacts to the target environment") - .requiredOption("-d --directory ", "specify the directory of the source files") - .requiredOption("-t, --target ", "specify the target environment") - .option("-p, --project ", "specify the project") - .action((options) => { - deployment.deployAllArtifacts(options.directory, options.project, options.target) - .then( () => console.log(`Project ${options.project} was successfully deployed to environment ${options.target}`)) - .catch(err => console.log(colors.red.bold("FAILED") + ` with -> ${err}`)); - }); } diff --git a/apps/miragon-process-ide-cli/src/app/deployment/deployment.ts b/apps/miragon-process-ide-cli/src/app/deployment/deployment.ts index 97a89ad6..f03b7aae 100644 --- a/apps/miragon-process-ide-cli/src/app/deployment/deployment.ts +++ b/apps/miragon-process-ide-cli/src/app/deployment/deployment.ts @@ -1,13 +1,10 @@ -import { DigiwfConfig, DigiwfLib } from "@miragon-process-ide/digiwf-lib"; +import { DigiwfLib } from "@miragon-process-ide/digiwf-lib"; import { getFile, getFiles } from "../shared/fs"; import * as colors from "colors"; export class Deployment { - private digiwfLib: DigiwfLib; - constructor(config?: DigiwfConfig) { - this.digiwfLib = new DigiwfLib(config); - } + constructor(private digiwfLib: DigiwfLib) {} public async deployArtifact(path: string, type: string, project: string | undefined, target: string): Promise { const file = await getFile(path); diff --git a/apps/miragon-process-ide-cli/src/app/deployment/deployments.spec.ts b/apps/miragon-process-ide-cli/src/app/deployment/deployments.spec.ts index 26b75088..f42bd3d9 100644 --- a/apps/miragon-process-ide-cli/src/app/deployment/deployments.spec.ts +++ b/apps/miragon-process-ide-cli/src/app/deployment/deployments.spec.ts @@ -1,19 +1,19 @@ import { Deployment } from "./deployment"; -import { Artifact } from "@miragon-process-ide/digiwf-lib"; +import { Artifact, createDigiwfLib, DigiWFDeploymentPlugin } from "@miragon-process-ide/digiwf-lib"; const pathToProject = "resources/my-process-automation-project/"; const project = "my-process-automation-project"; const target = "local"; -const dryDeploymentPlugin = { - name: "dry", +const dryDeploymentPlugin: DigiWFDeploymentPlugin = { + plugin: "dry", targetEnvironments: [{name:"local",url:"http://localhost:8080"}], deploy: function(target: string, artifact: Artifact) { return Promise.resolve(artifact); } }; -const deployment = new Deployment({deploymentPlugins: [dryDeploymentPlugin], generatorPlugins: []}); +const deployment = new Deployment(createDigiwfLib("0.0.1", "test-project", {}, [dryDeploymentPlugin])); describe("deployArtifact", () => { it("should work", async () => { diff --git a/apps/miragon-process-ide-cli/src/app/generate/api.ts b/apps/miragon-process-ide-cli/src/app/generate/api.ts index e573a4f8..48e3ecd7 100644 --- a/apps/miragon-process-ide-cli/src/app/generate/api.ts +++ b/apps/miragon-process-ide-cli/src/app/generate/api.ts @@ -1,39 +1,48 @@ import { Command } from "commander"; import { ProjectGenerator } from "./generate"; +import { DigiwfLib } from "@miragon-process-ide/digiwf-lib"; -const generate = new ProjectGenerator(); +export class GenerateCommand { + private generate: ProjectGenerator; -export function generateProject(): Command { - return new Command() - .command("generate-project") - .description("generates a project foundation") - .requiredOption("-n, --name ", "specify the project name") - .option("-p, --path ", "specify the targeted path") - .action((options) => { - generate.generateProject(options.name, options.path) - .then(() => console.log(`Successfully generated project ${options.name}`)) - .catch(err => { - console.log(`Project ${options.name} could not be created`); - console.log(err); - }); - }); -} + constructor(digiwfLib: DigiwfLib) { + this.generate = new ProjectGenerator(digiwfLib); + } + + public generateProject(): Command { + return new Command() + .command("generate-project") + .description("generates a project foundation") + .requiredOption("-n, --name ", "specify the project name") + .option("-p, --path ", "specify the targeted path") + .action((options) => { + this.generate.generateProject(options.name, options.path) + .then(() => console.log(`Successfully generated project ${options.name}`)) + .catch(err => { + console.log(`Project ${options.name} could not be created`); + console.log(err); + }); + }); + } -export function generateFile(): Command { - return new Command() - .command("generate-file") - .description("generates a process model") - .requiredOption("-t --type ", "specify the file type that is to be generated") - .requiredOption("-n, --name ", "specify the name") - .requiredOption("-p, --path ", "specify the targeted path") - .option("--template ", "specify a custom template that is to be used") - .option("-d --data ", "specify the data that is to be used for your template") - .action((options) => { - generate.generateFile(options.name, options.type, options.path, options.template, options.data) - .then(() => console.log(`Successfully created file ${options.name}`)) - .catch(err => { - console.log(`File ${options.name} could not be created`); - console.log(err); - }); - }); + public generateFile(): Command { + return new Command() + .command("generate-file") + .description("generates a process model") + .requiredOption("-t --type ", "specify the file type that is to be generated") + .requiredOption("-n, --name ", "specify the name") + .requiredOption("-p, --path ", "specify the targeted path") + .option("--template ", "specify a custom template that is to be used") + .option("-d --data ", "specify the data that is to be used for your template") + .action((options) => { + this.generate.generateFile(options.name, options.type, options.path, options.template, options.data) + .then(() => console.log(`Successfully created file ${options.name}`)) + .catch(err => { + console.log(`File ${options.name} could not be created`); + console.log(err); + }); + }); + } } + + diff --git a/apps/miragon-process-ide-cli/src/app/generate/generate.ts b/apps/miragon-process-ide-cli/src/app/generate/generate.ts index 06cd2ac1..ded91dce 100644 --- a/apps/miragon-process-ide-cli/src/app/generate/generate.ts +++ b/apps/miragon-process-ide-cli/src/app/generate/generate.ts @@ -1,13 +1,10 @@ -import { Artifact, DigiwfConfig, DigiwfLib } from "@miragon-process-ide/digiwf-lib"; +import { Artifact, DigiwfLib } from "@miragon-process-ide/digiwf-lib"; import { saveFile } from "../shared/fs"; import * as colors from "colors"; export class ProjectGenerator { - private digiwfLib: DigiwfLib; - constructor(config?: DigiwfConfig) { - this.digiwfLib = new DigiwfLib(config); - } + constructor(private digiwfLib: DigiwfLib) {} public async generateProject(name: string, path: string): Promise { const artifacts = await this.digiwfLib.initProject(name); @@ -17,7 +14,7 @@ export class ProjectGenerator { } public async generateFile(name: string, type: string, path: string, templateBase?: string, additionalData?: object): Promise { - const artifact = await this.digiwfLib.generateArtifact(name, type); + const artifact = await this.digiwfLib.generateArtifact(name, type, ""); await this.generate(artifact, path); } diff --git a/apps/miragon-process-ide-cli/src/main.ts b/apps/miragon-process-ide-cli/src/main.ts index 04e14147..5a309719 100644 --- a/apps/miragon-process-ide-cli/src/main.ts +++ b/apps/miragon-process-ide-cli/src/main.ts @@ -1,10 +1,12 @@ import { Command } from "commander"; -import { deployAllFiles, deployFileCommand } from "./app/deployment/api"; -import { generateFile, generateProject } from "./app/generate/api"; +import { getFile } from "./app/shared/fs"; +import * as colors from "colors"; +import { createDigiwfLib, DigiWFDeploymentPlugin, DigiwfDeploymentPluginRest } from "@miragon-process-ide/digiwf-lib"; +import { DeploymentCommand } from "./app/deployment/api"; +import { GenerateCommand } from "./app/generate/api"; const program = new Command(); - program .name("Miragon Process IDE CLI") .description(` @@ -18,8 +20,27 @@ program |___/ `) .version("0.0.1"); -program.addCommand(deployFileCommand()); -program.addCommand(deployAllFiles()); -program.addCommand(generateFile()); -program.addCommand(generateProject()); -program.parse(); + +getFile("process-ide.json") + .then(processIdeJson => { + const processIdeConfig = JSON.parse(processIdeJson.content); + const plugins: DigiWFDeploymentPlugin[] = []; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + processIdeConfig.deployment.forEach(p => { + plugins.push(new DigiwfDeploymentPluginRest(p.plugin, p.targetEnvironments)); + }); + const digiwf = createDigiwfLib(processIdeConfig.projectVersion, processIdeConfig.name, processIdeConfig.workspace, plugins); + const deployment = new DeploymentCommand(digiwf); + const generate = new GenerateCommand(digiwf) + program.addCommand(deployment.deployFileCommand()); + program.addCommand(deployment.deployAllFiles()); + program.addCommand(generate.generateFile()); + program.addCommand(generate.generateProject()); + }) + .catch(err => { + console.log(colors.red.bold("ERROR ") + "You are not inside a valid project. Make sure process-ide.json exists."); + }) + .finally(() =>{ + program.parse() + }); diff --git a/libs/digiwf-lib/src/index.ts b/libs/digiwf-lib/src/index.ts index 7eb00689..928eb081 100644 --- a/libs/digiwf-lib/src/index.ts +++ b/libs/digiwf-lib/src/index.ts @@ -1,3 +1,4 @@ export * from "./lib/digiwf-lib"; export * from "./lib/types"; export * from "./lib/deployment/plugins"; +export * from "./lib/deployment/rest/digiwf-deployment-plugin-rest"; diff --git a/libs/digiwf-lib/src/lib/deployment/plugins.ts b/libs/digiwf-lib/src/lib/deployment/plugins.ts index 93c83ffd..e0203d55 100644 --- a/libs/digiwf-lib/src/lib/deployment/plugins.ts +++ b/libs/digiwf-lib/src/lib/deployment/plugins.ts @@ -1,13 +1,6 @@ import { DigiwfDeploymentPluginRest } from "./rest/digiwf-deployment-plugin-rest"; -import { Artifact, DigiWFDeploymentPlugin } from "../types"; +import { DigiWFDeploymentPlugin } from "../types"; -const dryPlugin = { - name: "dry", - targetEnvironments: [{name:"local",url:"http://localhost:8080"}], - deploy: function(target: string, artifact: Artifact) { - return Promise.resolve(artifact); - } -}; const restPlugin = new DigiwfDeploymentPluginRest("rest", [ { name: "local", @@ -24,6 +17,5 @@ const restPlugin = new DigiwfDeploymentPluginRest("rest", [ ]); export const availableDeploymentPlugins: DigiWFDeploymentPlugin[] = [ - dryPlugin, restPlugin ]; diff --git a/libs/digiwf-lib/src/lib/deployment/rest/digiwf-deployment-plugin-rest.ts b/libs/digiwf-lib/src/lib/deployment/rest/digiwf-deployment-plugin-rest.ts index 7b7af346..3db0732b 100644 --- a/libs/digiwf-lib/src/lib/deployment/rest/digiwf-deployment-plugin-rest.ts +++ b/libs/digiwf-lib/src/lib/deployment/rest/digiwf-deployment-plugin-rest.ts @@ -3,11 +3,11 @@ import { Artifact, DigiWFDeploymentPlugin, DigiWFDeploymentTarget } from "../../ export class DigiwfDeploymentPluginRest implements DigiWFDeploymentPlugin { - name: string; + plugin: string; targetEnvironments: DigiWFDeploymentTarget[]; - constructor(name: string, targetEnvironments: DigiWFDeploymentTarget[]) { - this.name = name; + constructor(plugin: string, targetEnvironments: DigiWFDeploymentTarget[]) { + this.plugin = plugin; this.targetEnvironments = targetEnvironments; } diff --git a/libs/digiwf-lib/src/lib/digiwf-lib.spec.ts b/libs/digiwf-lib/src/lib/digiwf-lib.spec.ts index 485a4708..ed892827 100644 --- a/libs/digiwf-lib/src/lib/digiwf-lib.spec.ts +++ b/libs/digiwf-lib/src/lib/digiwf-lib.spec.ts @@ -1,15 +1,35 @@ -import { DigiwfLib } from "./digiwf-lib"; -import { availableDeploymentPlugins } from "./deployment/plugins"; -import { DigiwfConfig } from "./types"; +import { createDigiwfLib, DigiwfLib } from "./digiwf-lib"; +import { Artifact } from "./types"; const target = "local"; - -const config: DigiwfConfig = { - deploymentPlugins: availableDeploymentPlugins.filter(plugin => plugin.name === "dry"), - generatorPlugins: [] +const workspace = { + forms: "forms", + elementTemplates: "element-templates", + processConfigs: "configs" }; - -const digiwfLib = new DigiwfLib(config); +const deployment = [ + { + plugin: "dry", + targetEnvironments: [ + { + name: "local", + url: "http://localhost:8080" + }, + { + name: "dev", + url: "http://localhost:8080" + }, + { + name: "test", + url: "http://localhost:8080" + } + ], + async deploy(target : string, artifact : Artifact) : Promise { + return artifact; + } + } +]; +const digiwfLib: DigiwfLib = createDigiwfLib("1.0.0", "my-project", workspace, deployment); describe("deploy", () => { it("should work", async () => { diff --git a/libs/digiwf-lib/src/lib/digiwf-lib.ts b/libs/digiwf-lib/src/lib/digiwf-lib.ts index 2eaf9892..6966fb58 100644 --- a/libs/digiwf-lib/src/lib/digiwf-lib.ts +++ b/libs/digiwf-lib/src/lib/digiwf-lib.ts @@ -1,29 +1,35 @@ import { Artifact, DigiwfConfig, DigiWFDeploymentPlugin, DigiWFGeneratorPlugin } from "./types"; -import { availableDeploymentPlugins } from "./deployment/plugins"; import { availableGeneratorPlugins } from "./generate/plugins"; +export function createDigiwfLib(projectVersion: string, projectName: string, workspace: object, deployment: DigiWFDeploymentPlugin[]): DigiwfLib { + return new DigiwfLib({ + projectVersion: projectVersion, + name: projectName, + workspace: workspace, + deployment: deployment + }); +} + // observer pattern // https://en.wikipedia.org/wiki/Observer_pattern#Java export class DigiwfLib { - deploymentPlugins: DigiWFDeploymentPlugin[] = availableDeploymentPlugins; + projectConfig: DigiwfConfig; generatorPlugins: DigiWFGeneratorPlugin[] = availableGeneratorPlugins; - constructor(config?: DigiwfConfig) { - if (config) { - this.deploymentPlugins = config.deploymentPlugins; - this.generatorPlugins = config.generatorPlugins; - } + constructor(config: DigiwfConfig) { + this.projectConfig = config } public async deploy(target: string, artifact: Artifact): Promise { await Promise.all( - this.deploymentPlugins.map(plugin => plugin.deploy(target, artifact)) + this.projectConfig.deployment.map(plugin => plugin.deploy(target, artifact)) ); return artifact; } public async initProject(projectName: string): Promise { const filesToGenerate = [ + {name: projectName, type: "process-ide.json"}, {name: projectName, type: "bpmn"}, // {name: name, type: "dmn"} {name: "start", type: "form"}, @@ -35,17 +41,17 @@ export class DigiwfLib { ]; const generatedFiles = []; for (const file of filesToGenerate) { - generatedFiles.push(await this.generateArtifact(file.name, file.type)); + generatedFiles.push(await this.generateArtifact(file.name, file.type, projectName)); } return generatedFiles; } - public async generateArtifact(artifactName: string, type: string): Promise { + public async generateArtifact(artifactName: string, type: string, project: string): Promise { const generator = this.generatorPlugins.find(generator => generator.type === type); if (!generator) { throw new Error(`File type ${type} is not supported.`); } - return generator.generate(artifactName, type); + return generator.generate(artifactName, project); } } diff --git a/libs/digiwf-lib/src/lib/generate/plugins.spec.ts b/libs/digiwf-lib/src/lib/generate/plugins.spec.ts index a3e6d9d7..2374d0a3 100644 --- a/libs/digiwf-lib/src/lib/generate/plugins.spec.ts +++ b/libs/digiwf-lib/src/lib/generate/plugins.spec.ts @@ -1,6 +1,7 @@ import { availableGeneratorPlugins } from "./plugins"; const filesToGenerate = [ + {name: "process-ide", type: "process-ide.json", extension: "json", dir: ""}, {name: "my-process", type: "bpmn", extension: "bpmn", dir: ""}, {name: "my-decision-table", type: "dmn", extension: "dmn", dir: ""}, {name: "my-form", type: "form", extension: "form", dir: "forms"}, diff --git a/libs/digiwf-lib/src/lib/generate/plugins.ts b/libs/digiwf-lib/src/lib/generate/plugins.ts index ff16d15f..1f17ad3e 100644 --- a/libs/digiwf-lib/src/lib/generate/plugins.ts +++ b/libs/digiwf-lib/src/lib/generate/plugins.ts @@ -38,6 +38,34 @@ export class DigiwfArtifactGenerator implements DigiWFGeneratorPlugin { } } +export class ProcessIdeJsonGenerator implements DigiWFGeneratorPlugin { + basePath: string | undefined; + defaultData = {}; + fileExtension = "json"; + template: string; + type = "process-ide.json"; + + constructor(template: string) { + this.template = template; + } + + async generate(name : string, project : string) : Promise { + const fileContent = await Sqrl.render(this.template, {projectName: project}); + const fileDetails = { + name: "process-ide", + extension: this.fileExtension, + content: fileContent, + pathInProject: `/${this.type}` + } + return { + type: this.type, + project: project, + file: fileDetails + } + } + +} + export class GitkeepGenerator implements DigiWFGeneratorPlugin { type = ".gitkeep"; fileExtension = ".gitkeep"; @@ -176,6 +204,34 @@ const elementTemplateGenerator = new DigiwfArtifactGenerator("element-template", } ] }`, {}, "/element-templates"); +const processIdeJsonGenerator = new ProcessIdeJsonGenerator(`{ + "projectVersion": "1.0.0", + "name": "{{it.projectName}}", + "workspace": { + "forms": "forms", + "elementTemplates": "element-templates", + "processConfigs": "configs" + }, + "deployment": [ + { + "plugin": "rest", + "targetEnvironments": [ + { + "name": "local", + "url": "http://localhost:8080" + }, + { + "name": "dev", + "url": "http://localhost:8080" + }, + { + "name": "test", + "url": "http://localhost:8080" + } + ] + } + ] +}`); const gitkeepGenerator = new GitkeepGenerator(); const readmeGenerator = new ReadmeGenerator( `# {{it.name}} @@ -202,6 +258,7 @@ export const availableGeneratorPlugins: DigiWFGeneratorPlugin[] = [ formGenerator, configGenerator, elementTemplateGenerator, + processIdeJsonGenerator, gitkeepGenerator, readmeGenerator ]; diff --git a/libs/digiwf-lib/src/lib/types.ts b/libs/digiwf-lib/src/lib/types.ts index 742e6de3..a65772b7 100644 --- a/libs/digiwf-lib/src/lib/types.ts +++ b/libs/digiwf-lib/src/lib/types.ts @@ -13,12 +13,14 @@ export interface FileDetails { } export interface DigiwfConfig { - deploymentPlugins: DigiWFDeploymentPlugin[]; - generatorPlugins: DigiWFGeneratorPlugin[]; + projectVersion: string, + name: string; + workspace: object; + deployment: DigiWFDeploymentPlugin[]; } export interface DigiWFDeploymentPlugin { - name: string; + plugin: string; targetEnvironments: DigiWFDeploymentTarget[]; deploy(target: string, artifact: Artifact): Promise; } diff --git a/process-ide.json b/process-ide.json new file mode 100644 index 00000000..3a40fd72 --- /dev/null +++ b/process-ide.json @@ -0,0 +1,28 @@ +{ + "projectVersion": "1.0.0", + "name": "process-ide-test", + "workspace": { + "forms": "forms", + "elementTemplates": "element-templates", + "processConfigs": "configs" + }, + "deployment": [ + { + "plugin": "rest", + "targetEnvironments": [ + { + "name": "local", + "url": "http://localhost:8080" + }, + { + "name": "dev", + "url": "http://localhost:8080" + }, + { + "name": "test", + "url": "http://localhost:8080" + } + ] + } + ] +} diff --git a/spring-boot-apps/digiwf-deployment-proxy/digiwf-deployment-proxy-example/src/main/resources/application.properties b/spring-boot-apps/digiwf-deployment-proxy/digiwf-deployment-proxy-example/src/main/resources/application.properties index f59fe007..7b3c5e66 100644 --- a/spring-boot-apps/digiwf-deployment-proxy/digiwf-deployment-proxy-example/src/main/resources/application.properties +++ b/spring-boot-apps/digiwf-deployment-proxy/digiwf-deployment-proxy-example/src/main/resources/application.properties @@ -4,7 +4,7 @@ io.miragon.digiwf.digiwf-deployment-proxy.targets.local=http://localhost:39146 ## Deployment Handlers # io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.= -io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.local=RestHandler +io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.local=DryHandler io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.dev=DryHandler io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.test=DryHandler io.miragon.digiwf.digiwf-deployment-proxy.deploymentHandlers.prod=DryHandler