Skip to content

Commit

Permalink
refactor: improve type-safety on plugin module handler definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Aug 12, 2020
1 parent 921bb6f commit 9bb9d42
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 21 deletions.
10 changes: 6 additions & 4 deletions core/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SetSecretParams, SetSecretResult } from "./types/plugin/provider/setSec
import { validateSchema } from "./config/validation"
import { defaultProvider } from "./config/provider"
import { ParameterError, PluginError, InternalError, RuntimeError } from "./exceptions"
import { Garden } from "./garden"
import { Garden, ModuleActionMap } from "./garden"
import { LogEntry } from "./logger/log-entry"
import { Module } from "./types/module"
import {
Expand Down Expand Up @@ -60,6 +60,8 @@ import {
getPluginActionDescriptions,
getModuleActionDescriptions,
PluginActionDescriptions,
ModuleActionHandler,
ActionHandler,
} from "./types/plugin/plugin"
import { CleanupEnvironmentParams } from "./types/plugin/provider/cleanupEnvironment"
import { DeleteSecretParams, DeleteSecretResult } from "./types/plugin/provider/deleteSecret"
Expand Down Expand Up @@ -128,7 +130,7 @@ export interface DeployServicesParams {
@Profile()
export class ActionRouter implements TypeGuard {
private readonly actionHandlers: WrappedPluginActionMap
private readonly moduleActionHandlers: WrappedModuleActionMap
private readonly moduleActionHandlers: ModuleActionMap
private readonly loadedPlugins: PluginMap
private readonly pluginActionDescriptions: PluginActionDescriptions
private readonly moduleActionDescriptions: PluginActionDescriptions
Expand Down Expand Up @@ -952,7 +954,7 @@ export class ActionRouter implements TypeGuard {

// Wrap the handler with identifying attributes
const wrapped = Object.assign(
<WrappedModuleActionHandlers[T]>(async (...args: any[]) => {
<ModuleActionHandlers[T]>(async (...args: any[]) => {
const result = await handler.apply(plugin, args)
if (result === undefined) {
throw new PluginError(`Got empty response from ${moduleType}.${actionType} handler on ${pluginName}`, {
Expand Down Expand Up @@ -987,7 +989,7 @@ export class ActionRouter implements TypeGuard {
* Recursively wraps the base handler (if any) on an action handler, such that the base handler receives the _next_
* base handler as the `base` parameter when called from within the handler.
*/
private wrapBase<T extends WrappedActionHandler<any, any> | WrappedModuleActionHandler<any, any>>(
private wrapBase<T extends ActionHandler<any, any> | ModuleActionHandler<any, any>>(
handler?: T
): T | undefined {
if (!handler) {
Expand Down
12 changes: 10 additions & 2 deletions core/src/plugins/conftest/conftest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export const gardenPlugin = createGardenPlugin({
}

moduleConfig.include = moduleConfig.spec.files
moduleConfig.testConfigs = [{ name: "test", dependencies: [], spec: {}, timeout: 10 }]
moduleConfig.testConfigs = [{ name: "test", dependencies: [], spec: {}, disabled: false, timeout: 10 }]
return { moduleConfig }
},
testModule: async ({ ctx, log, module, testConfig }: TestModuleParams<ConftestModule>) => {
Expand Down Expand Up @@ -211,7 +211,15 @@ export const gardenPlugin = createGardenPlugin({
configure: async ({ moduleConfig }) => {
moduleConfig.build.dependencies.push({ name: moduleConfig.spec.sourceModule, copy: [] })
moduleConfig.include = []
moduleConfig.testConfigs = [{ name: "test", dependencies: moduleConfig.spec.runtimeDependencies, spec: {} }]
moduleConfig.testConfigs = [
{
name: "test",
dependencies: moduleConfig.spec.runtimeDependencies,
spec: {},
disabled: false,
timeout: null,
},
]
return { moduleConfig }
},
testModule: async ({ ctx, log, module, testConfig }: TestModuleParams<ConftestModule>) => {
Expand Down
4 changes: 2 additions & 2 deletions core/src/plugins/hadolint/hadolint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ export const gardenPlugin = createGardenPlugin({
handlers: {
configure: async ({ moduleConfig }) => {
moduleConfig.include = [moduleConfig.spec.dockerfilePath]
moduleConfig.testConfigs = [{ name: "lint", dependencies: [], spec: {}, timeout: 10 }]
moduleConfig.testConfigs = [{ name: "lint", dependencies: [], spec: {}, timeout: 10, disabled: false }]
return { moduleConfig }
},
testModule: async ({ ctx, log, module, testConfig }: TestModuleParams<HadolintModule>) => {
testModule: async ({ ctx, log, module, testConfig }) => {
const dockerfilePath = join(module.path, module.spec.dockerfilePath)
const startedAt = new Date()
let dockerfile: string
Expand Down
42 changes: 29 additions & 13 deletions core/src/types/plugin/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,25 @@ export interface ActionHandlerParamsBase {
base?: ActionHandler<any, any>
}

export interface ActionHandler<P extends ActionHandlerParamsBase, O> {
(params: P): Promise<O>
export type ActionHandler<P extends ActionHandlerParamsBase, O> = ((params: P) => Promise<O>) & {
actionType?: string
pluginName?: string
base?: WrappedActionHandler<P, O>
base?: ActionHandler<P, O>
}

export interface ModuleActionHandler<P extends ActionHandlerParamsBase, O> extends ActionHandler<P, O> {
(params: P): Promise<O>
export type ModuleActionHandler<P extends ActionHandlerParamsBase, O> = ((params: P) => Promise<O>) & {
actionType?: string
pluginName?: string
moduleType?: string
base?: WrappedModuleActionHandler<P, O>
base?: ModuleActionHandler<P, O>
}

export interface WrappedActionHandler<P extends ActionHandlerParamsBase, O> extends ActionHandler<P, O> {
export type WrappedActionHandler<P extends ActionHandlerParamsBase, O> = ActionHandler<P, O> & {
actionType: string
pluginName: string
}

export interface WrappedModuleActionHandler<P extends ActionHandlerParamsBase, O> extends WrappedActionHandler<P, O> {
export type WrappedModuleActionHandler<P extends ActionHandlerParamsBase, O> = WrappedActionHandler<P, O> & {
moduleType: string
base?: WrappedModuleActionHandler<P, O>
}
Expand Down Expand Up @@ -95,9 +95,9 @@ export type ModuleAndRuntimeActionHandlers<T extends Module = Module> = ModuleAc
export type AllActionHandlers<T extends Module = Module> = PluginActionHandlers & ModuleAndRuntimeActionHandlers<T>

export type PluginActionName = keyof PluginActionHandlers
export type ServiceActionName = keyof ServiceActionHandlers
export type TaskActionName = keyof TaskActionHandlers
export type ModuleActionName = keyof ModuleActionHandlers
export type ServiceActionName = keyof ServiceActionParams
export type TaskActionName = keyof TaskActionParams
export type ModuleActionName = keyof ModuleActionParams

export interface PluginActionDescription {
description: string
Expand Down Expand Up @@ -270,6 +270,12 @@ export type ModuleActionParams<T extends Module = Module> = {
}
}

export type ModuleAndRuntimeActionParams<T extends GardenModule = GardenModule> = ModuleActionParams<T> &
ServiceActionParams<T> &
TaskActionParams<T>

export type ModuleAndRuntimeActionOutputs = ModuleActionOutputs & ServiceActionOutputs & TaskActionOutputs

export interface ModuleActionOutputs extends ServiceActionOutputs {
configure: ConfigureModuleResult
suggestModules: SuggestModulesResult
Expand Down Expand Up @@ -325,8 +331,18 @@ export function getModuleActionNames() {
return <ModuleActionName[]>Object.keys(getModuleActionDescriptions())
}

export interface ModuleTypeExtension {
handlers: Partial<ModuleAndRuntimeActionHandlers>
export interface ModuleTypeExtension<M extends GardenModule = GardenModule> {
// Note: This needs to be this verbose because of issues with the TS compiler
handlers: {
[T in keyof ModuleAndRuntimeActionParams<M>]?: ((
params: ModuleAndRuntimeActionParams<M>[T]
) => Promise<ModuleAndRuntimeActionOutputs[T]>) & {
actionType?: string
pluginName?: string
moduleType?: string
base?: ModuleAndRuntimeActionHandlers[T]
}
}
name: string
}

Expand Down
12 changes: 12 additions & 0 deletions core/test/unit/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,10 @@ describe("Garden", () => {
moduleConfig.serviceConfigs = [
{
name: moduleConfig.name,
dependencies: [],
disabled: false,
hotReloadable: false,
spec: {},
},
]
return { moduleConfig }
Expand Down Expand Up @@ -3128,6 +3132,10 @@ describe("Garden", () => {
moduleConfig.serviceConfigs = [
{
name: moduleConfig.name,
dependencies: [],
disabled: false,
hotReloadable: false,
spec: {},
},
]
return { moduleConfig }
Expand Down Expand Up @@ -3206,6 +3214,10 @@ describe("Garden", () => {
moduleConfig.serviceConfigs = [
{
name: moduleConfig.name,
dependencies: [],
disabled: false,
hotReloadable: false,
spec: {},
},
]
return { moduleConfig }
Expand Down

0 comments on commit 9bb9d42

Please sign in to comment.