-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add run commands for ad-hoc runs of modules, services and tests
- Loading branch information
Showing
30 changed files
with
730 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io> | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import { safeDump } from "js-yaml" | ||
import { PluginContext } from "../../plugin-context" | ||
import { RuntimeContext } from "../../types/service" | ||
import { highlightYaml } from "../../util" | ||
import { Command } from "../base" | ||
import { RunModuleCommand } from "./module" | ||
import { RunServiceCommand } from "./service" | ||
import { RunTestCommand } from "./test" | ||
|
||
export class RunCommand extends Command { | ||
name = "run" | ||
alias = "r" | ||
help = "Run ad-hoc instances of your modules, services and tests" | ||
|
||
subCommands = [ | ||
new RunModuleCommand(), | ||
new RunServiceCommand(), | ||
new RunTestCommand(), | ||
] | ||
|
||
async action() { } | ||
} | ||
|
||
export function printRuntimeContext(ctx: PluginContext, runtimeContext: RuntimeContext) { | ||
ctx.log.verbose("-----------------------------------\n") | ||
ctx.log.verbose("Environment variables:") | ||
ctx.log.verbose(highlightYaml(safeDump(runtimeContext.envVars))) | ||
ctx.log.verbose("Dependencies:") | ||
ctx.log.verbose(highlightYaml(safeDump(runtimeContext.dependencies))) | ||
ctx.log.verbose("-----------------------------------\n") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io> | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import chalk from "chalk" | ||
import { PluginContext } from "../../plugin-context" | ||
import { BuildTask } from "../../tasks/build" | ||
import { RunResult } from "../../types/plugin" | ||
import { BooleanParameter, Command, ParameterValues, StringParameter } from "../base" | ||
import { | ||
uniq, | ||
values, | ||
flatten, | ||
} from "lodash" | ||
import { printRuntimeContext } from "./index" | ||
|
||
export const runArgs = { | ||
module: new StringParameter({ | ||
help: "The name of the module to run", | ||
required: true, | ||
}), | ||
// TODO: make this a variadic arg | ||
command: new StringParameter({ | ||
help: "The command to run in the module", | ||
}), | ||
} | ||
|
||
export const runOpts = { | ||
// TODO: we could provide specific parameters like this by adding commands for specific modules, via plugins | ||
//entrypoint: new StringParameter({ help: "Override default entrypoint in module" }), | ||
interactive: new BooleanParameter({ | ||
help: "Set to false to skip interactive mode and just output the command result", | ||
defaultValue: true, | ||
}), | ||
"force-build": new BooleanParameter({ help: "Force rebuild of module" }), | ||
} | ||
|
||
export type Args = ParameterValues<typeof runArgs> | ||
export type Opts = ParameterValues<typeof runOpts> | ||
|
||
export class RunModuleCommand extends Command<typeof runArgs, typeof runOpts> { | ||
name = "module" | ||
alias = "m" | ||
help = "Run the specified module" | ||
|
||
arguments = runArgs | ||
options = runOpts | ||
|
||
async action(ctx: PluginContext, args: Args, opts: Opts): Promise<RunResult> { | ||
const name = args.module | ||
const module = await ctx.getModule(name) | ||
|
||
const msg = args.command | ||
? `Running command ${chalk.white(args.command)} in module ${chalk.white(name)}` | ||
: `Running module ${chalk.white(name)}` | ||
|
||
ctx.log.header({ | ||
emoji: "runner", | ||
command: msg, | ||
}) | ||
|
||
await ctx.configureEnvironment() | ||
|
||
const buildTask = new BuildTask(ctx, module, opts["force-build"]) | ||
await ctx.addTask(buildTask) | ||
await ctx.processTasks() | ||
|
||
const command = args.command ? args.command.split(" ") : [] | ||
|
||
// combine all dependencies for all services in the module, to be sure we have all the context we need | ||
const services = values(await module.getServices()) | ||
const depNames = uniq(flatten(services.map(s => s.config.dependencies))) | ||
const deps = values(await ctx.getServices(depNames)) | ||
|
||
const runtimeContext = await module.prepareRuntimeContext(deps) | ||
|
||
printRuntimeContext(ctx, runtimeContext) | ||
|
||
return ctx.runModule({ module, command, runtimeContext, silent: false, interactive: opts.interactive }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io> | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import chalk from "chalk" | ||
import { PluginContext } from "../../plugin-context" | ||
import { BuildTask } from "../../tasks/build" | ||
import { RunResult } from "../../types/plugin" | ||
import { BooleanParameter, Command, ParameterValues, StringParameter } from "../base" | ||
import { printRuntimeContext } from "./index" | ||
|
||
export const runArgs = { | ||
service: new StringParameter({ | ||
help: "The command to run in the module", | ||
required: true, | ||
}), | ||
} | ||
|
||
export const runOpts = { | ||
interactive: new BooleanParameter({ | ||
help: "Set to false to skip interactive mode and just output the command result", | ||
defaultValue: true, | ||
}), | ||
"force-build": new BooleanParameter({ help: "Force rebuild of module" }), | ||
} | ||
|
||
export type Args = ParameterValues<typeof runArgs> | ||
export type Opts = ParameterValues<typeof runOpts> | ||
|
||
export class RunServiceCommand extends Command<typeof runArgs, typeof runOpts> { | ||
name = "service" | ||
alias = "s" | ||
help = "Run an ad-hoc instance of the specified service" | ||
|
||
arguments = runArgs | ||
options = runOpts | ||
|
||
async action(ctx: PluginContext, args: Args, opts: Opts): Promise<RunResult> { | ||
const name = args.service | ||
const service = await ctx.getService(name) | ||
const module = service.module | ||
|
||
ctx.log.header({ | ||
emoji: "runner", | ||
command: `Running service ${chalk.cyan(name)} in module ${chalk.cyan(module.name)}`, | ||
}) | ||
|
||
await ctx.configureEnvironment() | ||
|
||
const buildTask = new BuildTask(ctx, module, opts["force-build"]) | ||
await ctx.addTask(buildTask) | ||
await ctx.processTasks() | ||
|
||
const dependencies = await service.getDependencies() | ||
const runtimeContext = await module.prepareRuntimeContext(dependencies) | ||
|
||
printRuntimeContext(ctx, runtimeContext) | ||
|
||
return ctx.runService({ service, runtimeContext, silent: false, interactive: opts.interactive }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Copyright (C) 2018 Garden Technologies, Inc. <info@garden.io> | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import chalk from "chalk" | ||
import { ParameterError } from "../../exceptions" | ||
import { PluginContext } from "../../plugin-context" | ||
import { BuildTask } from "../../tasks/build" | ||
import { RunResult } from "../../types/plugin" | ||
import { BooleanParameter, Command, ParameterValues, StringParameter } from "../base" | ||
import { values } from "lodash" | ||
import { printRuntimeContext } from "./index" | ||
|
||
export const runArgs = { | ||
module: new StringParameter({ | ||
help: "The name of the module to run", | ||
required: true, | ||
}), | ||
test: new StringParameter({ | ||
help: "The name of the test to run in the module", | ||
required: true, | ||
}), | ||
} | ||
|
||
export const runOpts = { | ||
interactive: new BooleanParameter({ | ||
help: "Set to false to skip interactive mode and just output the command result", | ||
defaultValue: true, | ||
}), | ||
"force-build": new BooleanParameter({ help: "Force rebuild of module" }), | ||
} | ||
|
||
export type Args = ParameterValues<typeof runArgs> | ||
export type Opts = ParameterValues<typeof runOpts> | ||
|
||
export class RunTestCommand extends Command<typeof runArgs, typeof runOpts> { | ||
name = "test" | ||
alias = "t" | ||
help = "Run the specified module test" | ||
|
||
arguments = runArgs | ||
options = runOpts | ||
|
||
async action(ctx: PluginContext, args: Args, opts: Opts): Promise<RunResult> { | ||
const moduleName = args.module | ||
const testName = args.test | ||
const module = await ctx.getModule(moduleName) | ||
const config = await module.getConfig() | ||
|
||
const testSpec = config.test[testName] | ||
|
||
if (!testSpec) { | ||
throw new ParameterError(`Could not find test "${testName}" in module ${moduleName}`, { | ||
moduleName, | ||
testName, | ||
availableTests: Object.keys(config.test), | ||
}) | ||
} | ||
|
||
ctx.log.header({ | ||
emoji: "runner", | ||
command: `Running test ${chalk.cyan(testName)} in module ${chalk.cyan(moduleName)}`, | ||
}) | ||
|
||
await ctx.configureEnvironment() | ||
|
||
const buildTask = new BuildTask(ctx, module, opts["force-build"]) | ||
await ctx.addTask(buildTask) | ||
await ctx.processTasks() | ||
|
||
const interactive = opts.interactive | ||
const deps = await ctx.getServices(testSpec.dependencies) | ||
const runtimeContext = await module.prepareRuntimeContext(values(deps)) | ||
|
||
printRuntimeContext(ctx, runtimeContext) | ||
|
||
return ctx.testModule({ module, interactive, runtimeContext, silent: false, testName, testSpec }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.