Skip to content

Commit

Permalink
refactor: rename logEntry to log and require for tests, cmds and actions
Browse files Browse the repository at this point in the history
This leverages the recent changes to the logger that allow for empty
log entries.
  • Loading branch information
edvald committed Oct 8, 2018
1 parent bb59304 commit e745046
Show file tree
Hide file tree
Showing 73 changed files with 667 additions and 342 deletions.
42 changes: 22 additions & 20 deletions garden-service/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ export interface ContextStatus {
}

export interface DeployServicesParams {
serviceNames?: string[],
log: LogEntry
serviceNames?: string[]
force?: boolean
forceBuild?: boolean
}
Expand Down Expand Up @@ -119,11 +120,11 @@ export class ActionHelper implements TypeGuard {
* run `garden init`
*/
async prepareEnvironment(
{ force = false, pluginName, logEntry, allowUserInput = false }:
{ force?: boolean, pluginName?: string, logEntry?: LogEntry, allowUserInput?: boolean },
{ force = false, pluginName, log, allowUserInput = false }:
{ force?: boolean, pluginName?: string, log: LogEntry, allowUserInput?: boolean },
) {
const handlers = this.garden.getActionHandlers("prepareEnvironment", pluginName)
const statuses = await this.getEnvironmentStatus({ pluginName })
const statuses = await this.getEnvironmentStatus({ pluginName, log })

const needUserInput = Object.entries(statuses)
.map(([name, status]) => ({ ...status, name }))
Expand Down Expand Up @@ -151,13 +152,13 @@ export class ActionHelper implements TypeGuard {
continue
}

const envLogEntry = (logEntry || this.garden.log).info({
const envLogEntry = (log || this.garden.log).info({
status: "active",
section: name,
msg: "Preparing environment...",
})

await handler({ ...this.commonParams(handler), force, status, logEntry: envLogEntry })
await handler({ ...this.commonParams(handler), force, status, log: envLogEntry })

envLogEntry.setSuccess("Configured")

Expand All @@ -168,11 +169,11 @@ export class ActionHelper implements TypeGuard {
}

async cleanupEnvironment(
{ pluginName }: ActionHelperParams<CleanupEnvironmentParams>,
{ pluginName, log }: ActionHelperParams<CleanupEnvironmentParams>,
): Promise<EnvironmentStatusMap> {
const handlers = this.garden.getActionHandlers("cleanupEnvironment", pluginName)
await Bluebird.each(values(handlers), h => h({ ...this.commonParams(h) }))
return this.getEnvironmentStatus({ pluginName })
return this.getEnvironmentStatus({ pluginName, log })
}

async getSecret(params: RequirePluginName<ActionHelperParams<GetSecretParams>>): Promise<GetSecretResult> {
Expand Down Expand Up @@ -254,13 +255,13 @@ export class ActionHelper implements TypeGuard {
}

async deleteService(params: ServiceActionHelperParams<DeleteServiceParams>): Promise<ServiceStatus> {
const logEntry = this.garden.log.info({
const log = this.garden.log.info({
section: params.service.name,
msg: "Deleting...",
status: "active",
})
return this.callServiceHandler({
params: { ...params, logEntry },
params: { ...params, log },
actionType: "deleteService",
defaultHandler: dummyDeleteServiceHandler,
})
Expand Down Expand Up @@ -292,14 +293,14 @@ export class ActionHelper implements TypeGuard {
//region Helper Methods
//===========================================================================

async getStatus(): Promise<ContextStatus> {
const envStatus: EnvironmentStatusMap = await this.getEnvironmentStatus({})
async getStatus({ log }: { log: LogEntry }): Promise<ContextStatus> {
const envStatus: EnvironmentStatusMap = await this.getEnvironmentStatus({ log })
const services = keyBy(await this.garden.getServices(), "name")

const serviceStatus = await Bluebird.props(mapValues(services, async (service: Service) => {
const dependencies = await this.garden.getServices(service.config.dependencies)
const runtimeContext = await prepareRuntimeContext(this.garden, service.module, dependencies)
return this.getServiceStatus({ service, runtimeContext })
return this.getServiceStatus({ service, runtimeContext, log })
}))

return {
Expand All @@ -309,7 +310,7 @@ export class ActionHelper implements TypeGuard {
}

async deployServices(
{ serviceNames, force = false, forceBuild = false }: DeployServicesParams,
{ serviceNames, force = false, forceBuild = false, log }: DeployServicesParams,
): Promise<ProcessResults> {
const services = await this.garden.getServices(serviceNames)

Expand All @@ -319,6 +320,7 @@ export class ActionHelper implements TypeGuard {
watch: false,
handler: async (module) => getDeployTasks({
garden: this.garden,
log,
module,
serviceNames,
force,
Expand All @@ -331,11 +333,11 @@ export class ActionHelper implements TypeGuard {
//endregion

// TODO: find a nicer way to do this (like a type-safe wrapper function)
private commonParams(handler, logEntry?: LogEntry): PluginActionParamsBase {
private commonParams(handler, log?: LogEntry): PluginActionParamsBase {
return {
ctx: createPluginContext(this.garden, handler["pluginName"]),
// TODO: find a better way for handlers to log during execution
logEntry,
log: log || this.garden.log.info(),
}
}

Expand Down Expand Up @@ -410,8 +412,8 @@ export class ActionHelper implements TypeGuard {
}
}

const dummyLogStreamer = async ({ service, logEntry }: GetServiceLogsParams) => {
logEntry && logEntry.warn({
const dummyLogStreamer = async ({ service, log }: GetServiceLogsParams) => {
log.warn({
section: service.name,
msg: chalk.yellow(`No handler for log retrieval available for module type ${service.module.type}`),
})
Expand All @@ -429,8 +431,8 @@ const dummyPublishHandler = async ({ module }) => {
}
}

const dummyDeleteServiceHandler = async ({ module, logEntry }: DeleteServiceParams) => {
const dummyDeleteServiceHandler = async ({ module, log }: DeleteServiceParams) => {
const msg = `No delete service handler available for module type ${module.type}`
logEntry && logEntry.setError(msg)
log.setError(msg)
return {}
}
2 changes: 2 additions & 0 deletions garden-service/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,11 @@ export class GardenCli {
contextOpts.config = MOCK_CONFIG
}
garden = await Garden.factory(root, contextOpts)
const log = garden.log.info()
// TODO: enforce that commands always output DeepPrimitiveMap
result = await command.action({
garden,
log,
args: parsedArgs,
opts: parsedOpts,
})
Expand Down
2 changes: 2 additions & 0 deletions garden-service/src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TaskResults } from "../task-graph"
import { LoggerType } from "../logger/logger"
import { ProcessResults } from "../process"
import { Garden } from "../garden"
import { LogEntry } from "../logger/log-entry"

export class ValidationError extends Error { }

Expand Down Expand Up @@ -188,6 +189,7 @@ export interface CommandParams<T extends Parameters = {}, U extends Parameters =
args: ParameterValues<T>
opts: ParameterValues<U>
garden: Garden
log: LogEntry
}

export abstract class Command<T extends Parameters = {}, U extends Parameters = {}> {
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class BuildCommand extends Command<BuildArguments, BuildOptions> {
options = buildOptions

async action(
{ args, opts, garden }: CommandParams<BuildArguments, BuildOptions>,
{ args, opts, garden, log }: CommandParams<BuildArguments, BuildOptions>,
): Promise<CommandResult<TaskResults>> {

await garden.clearBuilds()
Expand All @@ -70,11 +70,11 @@ export class BuildCommand extends Command<BuildArguments, BuildOptions> {
garden,
modules,
watch: opts.watch,
handler: async (module) => [new BuildTask({ garden, module, force: opts.force })],
handler: async (module) => [new BuildTask({ garden, log, module, force: opts.force })],
changeHandler: async (module: Module) => {
return (await withDependants(garden, [module], autoReloadDependants))
.filter(m => moduleNames.includes(m.name))
.map(m => new BuildTask({ garden, module: m, force: true }))
.map(m => new BuildTask({ garden, log, module: m, force: true }))
},
})

Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/commands/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ export class CallCommand extends Command<Args> {

arguments = callArgs

async action({ garden, args }: CommandParams<Args>): Promise<CommandResult> {
async action({ garden, log, args }: CommandParams<Args>): Promise<CommandResult> {
let [serviceName, path] = splitFirst(args.serviceAndPath, "/")

// TODO: better error when service doesn't exist
const service = await garden.getService(serviceName)
const status = await garden.actions.getServiceStatus({ service })
const status = await garden.actions.getServiceStatus({ service, log })

if (status.state !== "ready") {
throw new RuntimeError(`Service ${service.name} is not running`, {
Expand Down
14 changes: 8 additions & 6 deletions garden-service/src/commands/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ export class DeleteSecretCommand extends Command<typeof deleteSecretArgs> {

arguments = deleteSecretArgs

async action({ garden, args }: CommandParams<DeleteSecretArgs>): Promise<CommandResult<DeleteSecretResult>> {
async action(
{ garden, log, args }: CommandParams<DeleteSecretArgs>,
): Promise<CommandResult<DeleteSecretResult>> {
const key = args.key!
const result = await garden.actions.deleteSecret({ pluginName: args.provider!, key })
const result = await garden.actions.deleteSecret({ log, pluginName: args.provider!, key })

if (result.found) {
garden.log.info(`Deleted config key ${args.key}`)
Expand All @@ -91,11 +93,11 @@ export class DeleteEnvironmentCommand extends Command {
resources.
`

async action({ garden }: CommandParams): Promise<CommandResult<EnvironmentStatusMap>> {
async action({ garden, log }: CommandParams): Promise<CommandResult<EnvironmentStatusMap>> {
const { name } = garden.environment
garden.log.header({ emoji: "skull_and_crossbones", command: `Deleting ${name} environment` })

const result = await garden.actions.cleanupEnvironment({})
const result = await garden.actions.cleanupEnvironment({ log })

garden.log.finish()

Expand Down Expand Up @@ -126,7 +128,7 @@ export class DeleteServiceCommand extends Command {
garden delete service my-service # deletes my-service
`

async action({ garden, args }: CommandParams<DeleteServiceArgs>): Promise<CommandResult> {
async action({ garden, log, args }: CommandParams<DeleteServiceArgs>): Promise<CommandResult> {
const services = await garden.getServices(args.service)

if (services.length === 0) {
Expand All @@ -139,7 +141,7 @@ export class DeleteServiceCommand extends Command {
const result: { [key: string]: ServiceStatus } = {}

await Bluebird.map(services, async service => {
result[service.name] = await garden.actions.deleteService({ service })
result[service.name] = await garden.actions.deleteService({ log, service })
})

garden.log.finish()
Expand Down
6 changes: 4 additions & 2 deletions garden-service/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class DeployCommand extends Command<Args, Opts> {
arguments = deployArgs
options = deployOpts

async action({ garden, args, opts }: CommandParams<Args, Opts>): Promise<CommandResult<TaskResults>> {
async action({ garden, log, args, opts }: CommandParams<Args, Opts>): Promise<CommandResult<TaskResults>> {
const services = await garden.getServices(args.service)
const serviceNames = getNames(services)

Expand All @@ -70,14 +70,15 @@ export class DeployCommand extends Command<Args, Opts> {
garden.log.header({ emoji: "rocket", command: "Deploy" })

// TODO: make this a task
await garden.actions.prepareEnvironment({})
await garden.actions.prepareEnvironment({ log })

const results = await processServices({
garden,
services,
watch: opts.watch,
handler: async (module) => getDeployTasks({
garden,
log,
module,
serviceNames,
force: opts.force,
Expand All @@ -86,6 +87,7 @@ export class DeployCommand extends Command<Args, Opts> {
}),
changeHandler: async (module) => getDeployTasks({
garden,
log,
module,
serviceNames,
force: true,
Expand Down
10 changes: 5 additions & 5 deletions garden-service/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ export class DevCommand extends Command {
garden dev
`

async action({ garden }: CommandParams): Promise<CommandResult> {
async action({ garden, log }: CommandParams): Promise<CommandResult> {
// print ANSI banner image
const data = await readFile(ansiBannerPath)
console.log(data.toString())

garden.log.info(chalk.gray.italic(`\nGood ${getGreetingTime()}! Let's get your environment wired up...\n`))

await garden.actions.prepareEnvironment({})
await garden.actions.prepareEnvironment({ log })

const autoReloadDependants = await computeAutoReloadDependants(garden)
const modules = await garden.getModules()
Expand All @@ -72,15 +72,15 @@ export class DevCommand extends Command {
: [module]

const testTasks: Task[] = flatten(await Bluebird.map(
testModules, m => getTestTasks({ garden, module: m })))
testModules, m => getTestTasks({ garden, log, module: m })))

const deployTasks = await getDeployTasks({
garden, module, force: watch, forceBuild: watch, includeDependants: watch,
garden, log, module, force: watch, forceBuild: watch, includeDependants: watch,
})
const tasks = testTasks.concat(deployTasks)

if (tasks.length === 0) {
return [new BuildTask({ garden, module, force: watch })]
return [new BuildTask({ garden, log, module, force: watch })]
} else {
return tasks
}
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/commands/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class ExecCommand extends Command<Args> {
options = runOpts
loggerType = LoggerType.basic

async action({ garden, args }: CommandParams<Args>): Promise<CommandResult<ExecInServiceResult>> {
async action({ garden, log, args }: CommandParams<Args>): Promise<CommandResult<ExecInServiceResult>> {
const serviceName = args.service
const command = args.command || []

Expand All @@ -68,7 +68,7 @@ export class ExecCommand extends Command<Args> {
})

const service = await garden.getService(serviceName)
const result = await garden.actions.execInService({ service, command })
const result = await garden.actions.execInService({ log, service, command })

return { result }
}
Expand Down
8 changes: 6 additions & 2 deletions garden-service/src/commands/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ export class GetSecretCommand extends Command<typeof getSecretArgs> {

async action({ garden, args }: CommandParams<GetArgs>): Promise<CommandResult> {
const key = args.key
const { value } = await garden.actions.getSecret({ pluginName: args.provider, key })
const { value } = await garden.actions.getSecret({
pluginName: args.provider,
key,
log: garden.log.info(),
})

if (value === null || value === undefined) {
throw new NotFoundError(`Could not find config key ${key}`, { key })
Expand All @@ -79,7 +83,7 @@ export class GetStatusCommand extends Command {
help = "Outputs the status of your environment."

async action({ garden }: CommandParams): Promise<CommandResult<ContextStatus>> {
const status = await garden.actions.getStatus()
const status = await garden.actions.getStatus({ log: garden.log.info() })
const yamlStatus = yaml.safeDump(status, { noRefs: true, skipInvalid: true })

// TODO: do a nicer print of this by default and add --yaml/--json options (maybe globally) for exporting
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ export class InitCommand extends Command {

options = initOpts

async action({ garden, opts }: CommandParams<{}, Opts>): Promise<CommandResult<{}>> {
async action({ garden, log, opts }: CommandParams<{}, Opts>): Promise<CommandResult<{}>> {
const { name } = garden.environment
garden.log.header({ emoji: "gear", command: `Initializing ${name} environment` })

await garden.actions.prepareEnvironment({ force: opts.force, allowUserInput: true })
await garden.actions.prepareEnvironment({ log, force: opts.force, allowUserInput: true })

garden.log.info("")
garden.log.header({ emoji: "heavy_check_mark", command: `Done!` })
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/commands/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class LogsCommand extends Command<Args, Opts> {
options = logsOpts
loggerType = LoggerType.basic

async action({ garden, args, opts }: CommandParams<Args, Opts>): Promise<CommandResult<ServiceLogEntry[]>> {
async action({ garden, log, args, opts }: CommandParams<Args, Opts>): Promise<CommandResult<ServiceLogEntry[]>> {
const tail = opts.tail
const services = await garden.getServices(args.service)

Expand Down Expand Up @@ -87,7 +87,7 @@ export class LogsCommand extends Command<Args, Opts> {
// NOTE: This will work differently when we have Elasticsearch set up for logging, but is
// quite servicable for now.
await Bluebird.map(services, async (service: Service<any>) => {
await garden.actions.getServiceLogs({ service, stream, tail })
await garden.actions.getServiceLogs({ service, stream, tail, log })
})

return { result }
Expand Down
Loading

0 comments on commit e745046

Please sign in to comment.