From 1c230d171931b0df2592b4f575ff2d1a020de882 Mon Sep 17 00:00:00 2001 From: Roy Razon Date: Tue, 28 Nov 2023 15:14:11 +0200 Subject: [PATCH] fix flags, events --- packages/cli-common/src/commands/base-command.ts | 11 +++++++++-- packages/cli-common/src/index.ts | 2 +- packages/cli-common/src/lib/flags.ts | 3 --- packages/cli/src/commands/down.ts | 2 +- packages/cli/src/commands/logs.ts | 4 +--- packages/cli/src/commands/ls.ts | 2 +- packages/cli/src/commands/proxy/disconnect.ts | 2 +- packages/cli/src/commands/purge.ts | 2 +- packages/cli/src/commands/shell.ts | 5 +---- packages/cli/src/commands/up.ts | 5 ++--- packages/cli/src/commands/urls.ts | 2 +- packages/cli/src/commands/version.ts | 2 +- packages/cli/src/hooks/init/telemetry.ts | 2 +- packages/core/src/commands/build.ts | 2 +- packages/core/src/commands/up.ts | 4 ++-- packages/core/src/telemetry/emitter.ts | 9 +++++++-- .../plugin-github/src/commands/github/pr/comment.ts | 2 +- .../plugin-github/src/commands/github/pr/uncomment.ts | 2 +- 18 files changed, 33 insertions(+), 30 deletions(-) diff --git a/packages/cli-common/src/commands/base-command.ts b/packages/cli-common/src/commands/base-command.ts index 1e4a3951..c3ee3d52 100644 --- a/packages/cli-common/src/commands/base-command.ts +++ b/packages/cli-common/src/commands/base-command.ts @@ -3,6 +3,7 @@ import { LogLevel, Logger, logLevels, ComposeModel, ProcessError, telemetryEmitter, } from '@preevy/core' import { asyncReduce } from 'iter-tools-es' +import { ParsingToken } from '@oclif/core/lib/interfaces/parser' import { commandLogger } from '../lib/log' import { composeFlags, pluginFlags } from '../lib/common-flags' @@ -10,6 +11,8 @@ import { composeFlags, pluginFlags } from '../lib/common-flags' export type Flags = Interfaces.InferredFlags export type Args = Interfaces.InferredArgs +const argsFromRaw = (raw: ParsingToken[]) => raw.filter(arg => arg.type === 'arg').map(arg => arg.input).filter(Boolean) + abstract class BaseCommand extends Command { static baseFlags = { 'log-level': Flags.custom({ @@ -35,6 +38,7 @@ abstract class BaseCommand extends Comm protected flags!: Flags protected args!: Args + #rawArgs!: ParsingToken[] #userModel?: ComposeModel protected async userModel() { @@ -76,17 +80,18 @@ abstract class BaseCommand extends Comm public async init(): Promise { await super.init() - const { args, flags } = await this.parse({ + const { args, flags, raw } = await this.parse({ flags: this.ctor.flags, baseFlags: super.ctor.baseFlags, args: this.ctor.args, - strict: this.ctor.strict, + strict: false, }) this.args = args as Args this.flags = flags as Flags if (this.flags.debug) { oclifSettings.debug = true } + this.#rawArgs = raw this.logger = commandLogger(this, this.flags.json ? 'stderr' : 'stdout') this.stdErrLogger = commandLogger(this, 'stderr') } @@ -94,6 +99,8 @@ abstract class BaseCommand extends Comm protected logger!: Logger protected stdErrLogger!: Logger + protected get rawArgs() { return argsFromRaw(this.#rawArgs) } + public get logLevel(): LogLevel { return this.flags['log-level'] ?? this.flags.debug ? 'debug' : 'info' } diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts index b8848213..5eceef1d 100644 --- a/packages/cli-common/src/index.ts +++ b/packages/cli-common/src/index.ts @@ -5,6 +5,6 @@ export { PluginContext, PluginInitContext } from './lib/plugins/context' export { composeFlags, pluginFlags, envIdFlags, tunnelServerFlags, urlFlags, buildFlags, tableFlags, parseBuildFlags, } from './lib/common-flags' -export { formatFlagsToArgs, parseFlags, ParsedFlags, argsFromRaw } from './lib/flags' +export { formatFlagsToArgs, parseFlags, ParsedFlags } from './lib/flags' export { initHook } from './hooks/init/load-plugins' export { default as BaseCommand } from './commands/base-command' diff --git a/packages/cli-common/src/lib/flags.ts b/packages/cli-common/src/lib/flags.ts index 3e22f43a..10c1f6a9 100644 --- a/packages/cli-common/src/lib/flags.ts +++ b/packages/cli-common/src/lib/flags.ts @@ -1,5 +1,4 @@ import { Flag } from '@oclif/core/lib/interfaces' -import { ParsingToken } from '@oclif/core/lib/interfaces/parser' import { Parser } from '@oclif/core/lib/parser/parse' type FlagSpec =Pick, 'type' | 'default'> @@ -35,5 +34,3 @@ export const parseFlags = async (def: T, argv: string[]) => (await }).parse()).flags export type ParsedFlags = Omit>>, 'json'> - -export const argsFromRaw = (raw: ParsingToken[]) => raw.filter(arg => arg.type === 'arg').map(arg => arg.input).filter(Boolean) diff --git a/packages/cli/src/commands/down.ts b/packages/cli/src/commands/down.ts index 81857e77..2555afb3 100644 --- a/packages/cli/src/commands/down.ts +++ b/packages/cli/src/commands/down.ts @@ -26,7 +26,7 @@ export default class Down extends DriverCommand { async run(): Promise { const log = this.logger - const { flags } = await this.parse(Down) + const { flags } = this const driver = await this.driver() const envId = await findEnvId({ diff --git a/packages/cli/src/commands/logs.ts b/packages/cli/src/commands/logs.ts index 04e6d83a..95f3879b 100644 --- a/packages/cli/src/commands/logs.ts +++ b/packages/cli/src/commands/logs.ts @@ -5,7 +5,6 @@ import { localComposeClient, findEnvId, MachineConnection, ComposeModel, remoteUserModel, dockerEnvContext, } from '@preevy/core' import { COMPOSE_TUNNEL_AGENT_SERVICE_NAME } from '@preevy/common' -import { argsFromRaw } from '@preevy/cli-common' import DriverCommand from '../driver-command' import { envIdFlags } from '../common-flags' @@ -80,8 +79,7 @@ export default class Logs extends DriverCommand { async run(): Promise { const log = this.logger - const { flags, raw } = await this.parse(Logs) - const restArgs = argsFromRaw(raw) + const { flags, rawArgs: restArgs } = this let connection: MachineConnection let userModel: ComposeModel diff --git a/packages/cli/src/commands/ls.ts b/packages/cli/src/commands/ls.ts index ba24f139..d443eabd 100644 --- a/packages/cli/src/commands/ls.ts +++ b/packages/cli/src/commands/ls.ts @@ -18,7 +18,7 @@ export default class Ls extends DriverCommand { static enableJsonFlag = true async run(): Promise { - const { flags } = await this.parse(Ls) + const { flags } = this const driver = await this.driver() const machines = await asyncToArray( asyncMap( diff --git a/packages/cli/src/commands/proxy/disconnect.ts b/packages/cli/src/commands/proxy/disconnect.ts index d20a9e62..8b4bda1c 100644 --- a/packages/cli/src/commands/proxy/disconnect.ts +++ b/packages/cli/src/commands/proxy/disconnect.ts @@ -23,7 +23,7 @@ export default class Disconnect extends ProfileCommand { // eslint-disable-next-line class-methods-use-this async run(): Promise { - const { args } = await this.parse(Disconnect) + const { args } = this const inspector = commands.proxy.inspectRunningComposeApp(args['compose-project']) const agentContainer = await inspector.getPreevyAgentContainer() if (agentContainer) { diff --git a/packages/cli/src/commands/purge.ts b/packages/cli/src/commands/purge.ts index 45fb128c..5fb6f084 100644 --- a/packages/cli/src/commands/purge.ts +++ b/packages/cli/src/commands/purge.ts @@ -65,7 +65,7 @@ export default class Purge extends DriverCommand { static strict = false async run(): Promise { - const { flags } = await this.parse(Purge) + const { flags } = this const driver = await this.driver() const resourcePlurals: Record = { [machineResourceType]: 'machines', ...driver.resourcePlurals } diff --git a/packages/cli/src/commands/shell.ts b/packages/cli/src/commands/shell.ts index a22ec0d2..12729f0e 100644 --- a/packages/cli/src/commands/shell.ts +++ b/packages/cli/src/commands/shell.ts @@ -1,6 +1,5 @@ import { Args } from '@oclif/core' import { commands } from '@preevy/core' -import { argsFromRaw } from '@preevy/cli-common' import DriverCommand from '../driver-command' // eslint-disable-next-line no-use-before-define @@ -21,11 +20,9 @@ export default class Shell extends DriverCommand { static enableJsonFlag = false async run(): Promise { - const { args, raw } = await this.parse(Shell) + const { args, rawArgs: restArgs } = this const driver = await this.driver() - const restArgs = argsFromRaw(raw).slice(1) - const result = await commands.shell({ envId: args.envId, args: restArgs, diff --git a/packages/cli/src/commands/up.ts b/packages/cli/src/commands/up.ts index 6976cb65..6415acfc 100644 --- a/packages/cli/src/commands/up.ts +++ b/packages/cli/src/commands/up.ts @@ -11,7 +11,7 @@ import { telemetryEmitter, withSpinner, } from '@preevy/core' -import { argsFromRaw, buildFlags, parseBuildFlags, tableFlags, text, tunnelServerFlags } from '@preevy/cli-common' +import { buildFlags, parseBuildFlags, tableFlags, text, tunnelServerFlags } from '@preevy/cli-common' import { inspect } from 'util' import { editUrl, tunnelNameResolver } from '@preevy/common' import MachineCreationDriverCommand from '../machine-creation-driver-command' @@ -111,8 +111,7 @@ export default class Up extends MachineCreationDriverCommand { } async run(): Promise { - const { flags, raw } = await this.parse(Up) - const restArgs = argsFromRaw(raw) + const { flags, rawArgs: restArgs } = this const driver = await this.driver() const machineCreationDriver = await this.machineCreationDriver() diff --git a/packages/cli/src/commands/urls.ts b/packages/cli/src/commands/urls.ts index 30a1b627..61e67ef3 100644 --- a/packages/cli/src/commands/urls.ts +++ b/packages/cli/src/commands/urls.ts @@ -102,7 +102,7 @@ export default class Urls extends ProfileCommand { async run(): Promise { const log = this.logger - const { flags, args } = await this.parse(Urls) + const { flags, args } = this const envId = await findEnvId({ userSpecifiedEnvId: flags.id, diff --git a/packages/cli/src/commands/version.ts b/packages/cli/src/commands/version.ts index 0137859c..5ae78995 100644 --- a/packages/cli/src/commands/version.ts +++ b/packages/cli/src/commands/version.ts @@ -7,7 +7,7 @@ export default class Version extends BaseCommand { static enableJsonFlag = true async run(): Promise { - const { flags } = await this.parse(Version) + const { flags } = this const log = this.logger if (flags.json) { diff --git a/packages/cli/src/hooks/init/telemetry.ts b/packages/cli/src/hooks/init/telemetry.ts index f36aab33..f5fc8dbe 100644 --- a/packages/cli/src/hooks/init/telemetry.ts +++ b/packages/cli/src/hooks/init/telemetry.ts @@ -8,7 +8,7 @@ const hook: Hook.Init = async ({ config }) => { return } - const emitter = await createTelemetryEmitter(config) + const emitter = await createTelemetryEmitter({ ...config, filename: config.scopedEnvVar('TELEMETRY_FILE') }) registerEmitter(emitter) wireProcessExit(process, emitter) } diff --git a/packages/core/src/commands/build.ts b/packages/core/src/commands/build.ts index 719761ef..cf829633 100644 --- a/packages/core/src/commands/build.ts +++ b/packages/core/src/commands/build.ts @@ -50,7 +50,7 @@ const buildCommand = async ({ elapsed_sec: elapsedTimeSec, has_registry: Boolean(buildSpec.registry), }) - log.info(`Elapsed time for build step: ${elapsedTimeSec.toLocaleString(undefined, { maximumFractionDigits: 2 })} sec`) + log.info(`Build step done in ${elapsedTimeSec.toLocaleString(undefined, { maximumFractionDigits: 2 })}s`) return { buildModel, deployModel } } diff --git a/packages/core/src/commands/up.ts b/packages/core/src/commands/up.ts index ebac12c7..003f3f89 100644 --- a/packages/core/src/commands/up.ts +++ b/packages/core/src/commands/up.ts @@ -147,12 +147,12 @@ const up = async ({ await using dockerContext = await dockerEnvContext({ connection, log }) const { elapsedTimeSec } = await measureTime(() => compose.spawnPromise(composeArgs, { stdio: 'inherit', env: dockerContext.env })) - telemetryEmitter().capture('provisioning success', { + telemetryEmitter().capture('provision success', { elapsed_sec: elapsedTimeSec, with_build: Boolean(buildSpec), has_registry: Boolean(buildSpec?.registry), }) - log.info(`Elapsed time for provisioning step: ${elapsedTimeSec.toLocaleString(undefined, { maximumFractionDigits: 2 })} sec`) + log.info(`Provision step done in ${elapsedTimeSec.toLocaleString(undefined, { maximumFractionDigits: 2 })}s`) return { composeModel, projectLocalDataDir } } diff --git a/packages/core/src/telemetry/emitter.ts b/packages/core/src/telemetry/emitter.ts index 5a136260..d1c5b99d 100644 --- a/packages/core/src/telemetry/emitter.ts +++ b/packages/core/src/telemetry/emitter.ts @@ -1,4 +1,5 @@ import os from 'os' +import fs from 'fs' import crypto from 'crypto' import stringify from 'fast-safe-stringify' import fetch from 'node-fetch' @@ -20,23 +21,27 @@ type IdentifyFunction = { (id: string, person?: TelemetryProperties): void } -export const telemetryEmitter = async ({ dataDir, version, debug }: { +export const telemetryEmitter = async ({ dataDir, version, debug, filename }: { dataDir: string version: string debug: number + filename?: string }) => { const machineId = await memoizedMachineId(dataDir) let distinctId = machineId const groupIdentities = {} as Record const pendingEvents: TelemetryEvent[] = [] const runId = newRunId() + const file = filename ? fs.createWriteStream(filename, 'utf-8') : undefined // await fs.promises.open(filename, 'a') : undefined let debounceDisabled = false const flushLimit = pLimit(1) const flush = async () => await flushLimit(async () => { if (!pendingEvents.length) { return } - const body = stringify({ batch: pendingEvents.map(serializableEvent) }) + const batch = pendingEvents.map(serializableEvent) + const body = stringify({ batch }) + file?.write(batch.map(event => `${stringify(event)}${os.EOL}`).join('')) pendingEvents.length = 0 const response = await fetch(TELEMETRY_URL, { headers: { 'Content-Type': 'application/json' }, diff --git a/packages/plugin-github/src/commands/github/pr/comment.ts b/packages/plugin-github/src/commands/github/pr/comment.ts index 3662815d..21f3f283 100644 --- a/packages/plugin-github/src/commands/github/pr/comment.ts +++ b/packages/plugin-github/src/commands/github/pr/comment.ts @@ -23,7 +23,7 @@ class CommentGithubPr extends BaseGithubPrCommand { '--json', ]) as FlatTunnel[] - const { flags } = await this.parse(CommentGithubPr) + const { flags } = this const config = await this.loadGithubPullRequestCommentConfig(flags) await upsertPreevyComment({ diff --git a/packages/plugin-github/src/commands/github/pr/uncomment.ts b/packages/plugin-github/src/commands/github/pr/uncomment.ts index 454fbcfb..877bcfc9 100644 --- a/packages/plugin-github/src/commands/github/pr/uncomment.ts +++ b/packages/plugin-github/src/commands/github/pr/uncomment.ts @@ -19,7 +19,7 @@ class UnCommentGithubPr extends BaseGithubPrCommand { } async run() { - const { flags } = await this.parse(UnCommentGithubPr) + const { flags } = this const config = await this.loadGithubPullRequestCommentConfig(flags) await upsertPreevyComment({