diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 46bafd4f2..45ba9f875 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -4,8 +4,9 @@ ### Patch Changes -- Updated dependencies [6d52ddf] - - @openfn/deploy@0.4.4 +- Added debug logging for workflow loading +- Better docs output +- Fix execute example in help ## 1.1.1 diff --git a/packages/cli/src/docs/handler.ts b/packages/cli/src/docs/handler.ts index a60acd5cc..95350cf60 100644 --- a/packages/cli/src/docs/handler.ts +++ b/packages/cli/src/docs/handler.ts @@ -1,4 +1,5 @@ import { readFile } from 'node:fs/promises'; +import c from 'chalk'; import docgen from '../docgen/handler'; import { Opts } from '../options'; @@ -12,16 +13,13 @@ import type { import { getNameAndVersion, getLatestVersion } from '@openfn/runtime'; import expandAdaptors from '../util/expand-adaptors'; -const describeFn = (adaptorName: string, fn: FunctionDescription) => `## ${ +const describeFn = (adaptorName: string, fn: FunctionDescription) => [ + c.green(`## ${ fn.name -}(${fn.parameters.map(({ name }) => name).join(',')}) - -${fn.description} - -### Usage Examples - -${ - fn.examples.length +}(${fn.parameters.map(({ name }) => name).join(',')})`), +`${fn.description}`, +c.green('### Usage Examples'), +fn.examples.length ? fn.examples .map(({ code, caption }) => { if (caption) { @@ -30,24 +28,21 @@ ${ return code; }) .join('\n\n') - : 'None' -} - -### API Reference - -https://docs.openfn.org/adaptors/packages/${adaptorName.replace( + : 'None', +c.green('### API Reference'), +`https://docs.openfn.org/adaptors/packages/${adaptorName.replace( '@openfn/language-', '' )}-docs#${fn.name} -`; +`].join('\n\n'); const describeLib = ( adaptorName: string, data: PackageDescription -) => `## ${adaptorName} ${data.version} +) => c.green(`## ${adaptorName} ${data.version}`) + ` ${data.functions - .map((fn) => ` ${fn.name}(${fn.parameters.map((p) => p.name).join(', ')})`) + .map((fn) => ` ${c.yellow(fn.name)} (${fn.parameters.map((p) => p.name).join(', ')})`) .sort() .join('\n')} `; @@ -92,7 +87,7 @@ const docsHandler = async ( const fn = data.functions.find(({ name }) => name === operation); if (fn) { logger.debug('Operation schema:', fn); - logger.success(`Documentation for ${name}.${operation} v${version}:\n`); + logger.break() // Generate a documentation string desc = describeFn(name, fn); @@ -100,16 +95,25 @@ const docsHandler = async ( logger.error(`Failed to find ${operation} in ${name}`); } } else { - logger.debug('No operation provided, listing available operations'); + logger.debug('No operation name provided'); + logger.always('Available functions:\n'); desc = describeLib(name, data); + } // Log the description without any ceremony/meta stuff from the logger logger.print(desc); + if (!operation) { + logger.always(`For more details on a specfic functions, use: + + openfn docs ${name} +`) + } + if (didError) { logger.error('Error'); } else { - logger.success('Done!'); + logger.info('Done!'); } } else { logger.error('Not found'); diff --git a/packages/cli/src/execute/command.ts b/packages/cli/src/execute/command.ts index a18cdd40d..41950cca2 100644 --- a/packages/cli/src/execute/command.ts +++ b/packages/cli/src/execute/command.ts @@ -75,8 +75,8 @@ const executeCommand: yargs.CommandModule = { 'Execute foo/job.js with no adaptor and write the final state to foo/job.json' ) .example( - 'openfn workflow.json -i', - 'Execute workflow.json with autoinstall enabled' + 'openfn workflow.json', + 'Execute the workflow contained in workflow.json' ) .example( 'openfn job.js -a common --log info', diff --git a/packages/cli/src/util/load-plan.ts b/packages/cli/src/util/load-plan.ts index 490fadede..eff5cd8cc 100644 --- a/packages/cli/src/util/load-plan.ts +++ b/packages/cli/src/util/load-plan.ts @@ -50,6 +50,7 @@ const loadJson = async (workflowPath: string, logger: Logger): Promise => { try { text = await fs.readFile(workflowPath, 'utf8'); + logger.debug('Loaded workflow from', workflowPath) } catch (e) { return abort( logger, @@ -169,6 +170,7 @@ const fetchFile = async ( ? filePath : path.resolve(rootDir, filePath); const result = await fs.readFile(fullPath, 'utf8'); + log.debug('Loaded file', fullPath) return result; } catch (e) { abort( @@ -242,7 +244,7 @@ const loadXPlan = async ( } await mapAdaptorsToMonorepo(options.monorepoPath, plan, logger); - // Assign options form the CLI into the Xplan + // Assign options from the CLI into the Xplan // TODO support state props to remove maybeAssign(options, plan.options, ['timeout', 'start']); diff --git a/packages/cli/test/commands.test.ts b/packages/cli/test/commands.test.ts index a0d339945..c28b6b55c 100644 --- a/packages/cli/test/commands.test.ts +++ b/packages/cli/test/commands.test.ts @@ -628,7 +628,8 @@ test.serial('docs should print documentation with full names', async (t) => { opts.repoDir = '/repo'; await commandParser(opts, logger); - const docs = logger._parse(logger._history[3]).message as string; + const docs = logger._parse(logger._history[2]).message as string; + // match the signature t.regex(docs, /\#\# fn\(\)/); // Match usage examples @@ -637,13 +638,9 @@ test.serial('docs should print documentation with full names', async (t) => { docs, /https:\/\/docs.openfn.org\/adaptors\/packages\/common-docs#fn/ ); - - const { message, level } = logger._parse(logger._last); - t.is(level, 'success'); - t.is(message, 'Done!'); }); -test.serial('docs adaptor should print list operations', async (t) => { +test.serial('docs adaptor should list operations', async (t) => { const pkgPath = path.resolve('./package.json'); mock({ [pkgPath]: mock.load(pkgPath), @@ -664,14 +661,11 @@ test.serial('docs adaptor should print list operations', async (t) => { opts.repoDir = '/repo'; await commandParser(opts, logger); - const docs = logger._parse(logger._history[2]).message as string; + + const docs = logger._parse(logger._history[3]).message as string; t.notRegex(docs, /\[object Object\]/); t.notRegex(docs, /\#\#\# Usage Examples/); - t.regex(docs, /fn\(a, b\)/); - - const { message, level } = logger._parse(logger._last); - t.is(level, 'success'); - t.is(message, 'Done!'); + t.regex(docs, /fn.+\(a, b\)/); }); test.serial( @@ -694,7 +688,7 @@ test.serial( opts.repoDir = '/repo'; await commandParser(opts, logger); - const docs = logger._parse(logger._history[3]).message as string; + const docs = logger._parse(logger._history[2]).message as string; // match the signature t.regex(docs, /\#\# fn\(\)/); // Match usage examples @@ -704,9 +698,5 @@ test.serial( docs, /https:\/\/docs.openfn.org\/adaptors\/packages\/common-docs#fn/ ); - - const { message, level } = logger._parse(logger._last); - t.is(level, 'success'); - t.is(message, 'Done!'); } );