Skip to content

Commit

Permalink
feat: plugins can now add modules to a project
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Apr 22, 2018
1 parent d6506da commit 26f38c7
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 19 deletions.
57 changes: 39 additions & 18 deletions src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ export class Garden {
private readonly environment: string,
private readonly namespace: string,
public readonly config: EnvironmentConfig,
plugins: RegisterPluginParam[],
logger?: RootLogNode,
) {
this.modulesScanned = false
Expand All @@ -173,21 +172,6 @@ export class Garden {

this.pluginContext = createPluginContext(this)
this.taskGraph = new TaskGraph(this.pluginContext)

// Register plugins
for (const plugin of builtinPlugins.concat(plugins)) {
this.registerPlugin(plugin)
}

for (const plugin of fixedPlugins) {
this.loadPlugin(plugin, {})
}

// Load configured plugins
// Validate configuration
for (const [providerName, provider] of Object.entries(config.providers)) {
this.loadPlugin(providerName, provider)
}
}

static async factory(projectRoot: string, { env, config, logger, plugins = [] }: ContextOpts = {}) {
Expand Down Expand Up @@ -254,7 +238,24 @@ export class Garden {
// Resolve the project configuration based on selected environment
const projectConfig = merge({}, globalConfig, envConfig)

return new Garden(projectRoot, projectName, environment, namespace, projectConfig, plugins, logger)
const garden = new Garden(projectRoot, projectName, environment, namespace, projectConfig, logger)

// Register plugins
for (const plugin of builtinPlugins.concat(plugins)) {
garden.registerPlugin(plugin)
}

for (const plugin of fixedPlugins) {
await garden.loadPlugin(plugin, {})
}

// Load configured plugins
// Validate configuration
for (const [providerName, provider] of Object.entries(projectConfig.providers)) {
await garden.loadPlugin(providerName, provider)
}

return garden
}

getEnvironment(): Environment {
Expand Down Expand Up @@ -336,7 +337,7 @@ export class Garden {
this.registeredPlugins[name] = factory
}

private loadPlugin(pluginName: string, config: object) {
private async loadPlugin(pluginName: string, config: object) {
const factory = this.registeredPlugins[pluginName]

if (!factory) {
Expand Down Expand Up @@ -369,6 +370,19 @@ export class Garden {
this.config.providers[pluginName] = plugin.config
}

for (const modulePath of plugin.modules || []) {
const module = await this.resolveModule(modulePath)
if (!module) {
throw new PluginError(`Could not load module "${modulePath}" specified in plugin "${pluginName}"`, {
pluginName,
modulePath,
})
}
module.name = `${pluginName}.${module.name}`
module.updateConfig("name", module.name)
await this.addModule(module)
}

const actions = plugin.actions || {}

for (const actionType of pluginActionNames) {
Expand Down Expand Up @@ -472,6 +486,13 @@ export class Garden {
return output
}

/**
* Returns the module with the specified name. Throws error if it doesn't exist.
*/
async getModule(name: string, noScan?: boolean): Promise<Module<any>> {
return (await this.getModules([name], noScan))[name]
}

/*
Returns all services that are registered in this context.
Scans for modules and services in the project root if it hasn't already been done.
Expand Down
2 changes: 2 additions & 0 deletions src/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type WrappedFromGarden = Pick<Garden,
"getEnvironment" |
"resolveModule" |
"getModules" |
"getModule" |
"getServices" |
"getService" |
"getTemplateContext" |
Expand Down Expand Up @@ -140,6 +141,7 @@ export function createPluginContext(garden: Garden): PluginContext {
clearBuilds: wrap(garden.clearBuilds),
getEnvironment: wrap(garden.getEnvironment),
getModules: wrap(garden.getModules),
getModule: wrap(garden.getModule),
getServices: wrap(garden.getServices),
getService: wrap(garden.getService),
getTemplateContext: wrap(garden.getTemplateContext),
Expand Down
9 changes: 8 additions & 1 deletion src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { PluginContext } from "../plugin-context"
import { identifierRegex, joiIdentifier, joiVariables, PrimitiveMap } from "./common"
import { ConfigurationError } from "../exceptions"
import Bluebird = require("bluebird")
import { extend } from "lodash"
import {
extend,
set,
} from "lodash"
import { ServiceConfig } from "./service"
import { resolveTemplateStrings, TemplateStringContext } from "../template-string"
import { Memoize } from "typescript-memoize"
Expand Down Expand Up @@ -93,6 +96,10 @@ export class Module<T extends ModuleConfig = ModuleConfig> {
return config
}

updateConfig(key: string, value: any) {
set(this.config, key, value)
}

async getVersion(): Promise<TreeVersion> {
const treeVersion = await this.ctx.vcs.getTreeVersion([this.path])

Expand Down
3 changes: 3 additions & 0 deletions src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ export interface GardenPlugin {
config?: object
configKeys?: string[]

modules?: string[]

actions?: Partial<PluginActions>
moduleActions?: { [moduleType: string]: Partial<ModuleActions<any>> }
}
Expand All @@ -282,6 +284,7 @@ export type RegisterPluginParam = string | PluginFactory

export const pluginSchema = Joi.object().keys({
config: Joi.object(),
modules: Joi.array().items(Joi.string()),
actions: Joi.object().keys(mapValues(pluginActionDescriptions, () => Joi.func())),
moduleActions: joiIdentifierMap(
Joi.object().keys(mapValues(moduleActionDescriptions, () => Joi.func())),
Expand Down

0 comments on commit 26f38c7

Please sign in to comment.