Skip to content

Commit

Permalink
fix: help fallback prevents the version being displayed
Browse files Browse the repository at this point in the history
  • Loading branch information
adbayb committed Sep 10, 2024
1 parent 97613ac commit 44648d3
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/pretty-dingos-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"termost": patch
---

Help fallback prevents the version being displayed.
14 changes: 14 additions & 0 deletions examples/empty/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"private": true,
"name": "@examples/empty",
"version": "0.0.0",
"scripts": {
"start": "node -r esbuild-register ./src/index.ts"
},
"dependencies": {
"termost": "workspace:^"
},
"devDependencies": {
"esbuild-register": "3.6.0"
}
}
13 changes: 13 additions & 0 deletions examples/empty/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { termost } from "termost";

const program = termost("Example to showcase empty `command` fallback");

program.command({
name: "build",
description: "Transpile and bundle in production mode",
});

program.command({
name: "watch",
description: "Rebuild your assets on any code change",
});
5 changes: 5 additions & 0 deletions examples/empty/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.json",
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 37 additions & 8 deletions termost/src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,53 @@ OPTIONS:
 -f, --flag  A super useful CLI flag"
`;

exports[`termost > should display \`help\` given empty root command 1`] = `
exports[`termost > should display \`help\` given empty command 1`] = `
"
USAGE:
[37m[37m[32m[32m@examples/command[32m[37m <command> [...options][37m[39m
[37m[37m[32m[32m@examples/empty[32m[37m <command> [...options][37m[39m

DESCRIPTION:
[37m[37mExample to showcase the \`command\` API[37m[39m
[37m[37mExample to showcase empty \`command\` fallback[37m[39m

COMMANDS:
[37m[37m [32m[32mbuild [32m[37m Transpile and bundle in production mode[37m[39m
[37m[37m [32m[32mwatch [32m[37m Rebuild your assets on any code change[37m[39m
[37m[37m [32m[32mbuild [32m[37m Transpile and bundle in production mode[37m[39m
[37m[37m [32m[32mwatch [32m[37m Rebuild your assets on any code change[37m[39m

OPTIONS:
 -h, --help  Display the help center
 -v, --version  Print the version
 --global  Shared flag between commands"
 -h, --help  Display the help center
 -v, --version  Print the version"
`;
exports[`termost > should display \`help\` given empty command 2`] = `
"
USAGE:
@examples/empty build [...options]

DESCRIPTION:
Transpile and bundle in production mode

OPTIONS:
 -h, --help  Display the help center
 -v, --version  Print the version"
`;
exports[`termost > should display \`help\` given empty command 3`] = `
"
USAGE:
@examples/empty watch [...options]

DESCRIPTION:
Rebuild your assets on any code change

OPTIONS:
 -h, --help  Display the help center
 -v, --version  Print the version"
`;
exports[`termost > should display \`version\` 1`] = `"0.0.0"`;
exports[`termost > should display \`version\` 2`] = `"0.0.0"`;
exports[`termost > should handle \`command\` api 1`] = `
"
USAGE:
Expand Down
26 changes: 17 additions & 9 deletions termost/src/api/command/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,14 @@ export const createCommand = <Values extends ObjectLikeConstraint>(
// metadata (especially to let the global help option to display all available commands):
const optionKeys = Object.keys(argv.options);

if (
optionKeys.includes(OPTION_HELP_NAMES[0]) ||
optionKeys.includes(OPTION_HELP_NAMES[1]) ||
(isRootCommand && !metadata.hasOutput[rootCommandName])
) {
const help = () => {
showHelp({
controller,
currentCommandName: name,
isRootCommand,
rootCommandName,
});

return;
}
};

if (
optionKeys.includes(OPTION_VERSION_NAMES[0]) ||
Expand All @@ -64,7 +58,21 @@ export const createCommand = <Values extends ObjectLikeConstraint>(
return;
}

void controller.enable();
if (
optionKeys.includes(OPTION_HELP_NAMES[0]) ||
optionKeys.includes(OPTION_HELP_NAMES[1])
) {
help();

return;
}

if (metadata.isEmptyCommand[name]) {
// Show help by default if no processing is done for the current command
help();
} else {
void controller.enable();
}
}
}, 0);

Expand Down
31 changes: 28 additions & 3 deletions termost/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import { describe, expect, test } from "vitest";
import { exec } from "./helpers/process";

describe("termost", () => {
test("should display `version`", async () => {
const longFlagOutput = await safeExec(
"pnpm --filter @examples/default start --version",
);

const shortFlagOutput = await safeExec(
"pnpm --filter @examples/default start -v",
);

expect(longFlagOutput).toMatchSnapshot();
expect(shortFlagOutput).toMatchSnapshot();
});

test("should display `help`", async () => {
const longFlagOutput = await safeExec(
"pnpm --filter @examples/default start --help",
Expand All @@ -16,10 +29,22 @@ describe("termost", () => {
expect(shortFlagOutput).toMatchSnapshot();
});

test("should display `help` given empty root command", async () => {
const output = await safeExec("pnpm --filter @examples/command start");
test("should display `help` given empty command", async () => {
const rootCommand = await safeExec(
"pnpm --filter @examples/empty start",
);

expect(output).toMatchSnapshot();
const buildCommand = await safeExec(
"pnpm --filter @examples/empty start build",
);

const watchCommand = await safeExec(
"pnpm --filter @examples/empty start watch",
);

expect(rootCommand).toMatchSnapshot();
expect(buildCommand).toMatchSnapshot();
expect(watchCommand).toMatchSnapshot();
});

test("should handle `command` api", async () => {
Expand Down
7 changes: 4 additions & 3 deletions termost/src/termost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function termost<Values extends ObjectLikeConstraint = EmptyObject>(
name,
description,
argv: { command, operands, options },
hasOutput: {},
isEmptyCommand: {},
version,
});
}
Expand Down Expand Up @@ -115,12 +115,13 @@ export const createProgram = <Values extends ObjectLikeConstraint>(
const program: Termost<Values> = {
command<CommandValues>(params: CommandParameters) {
currentCommandName = createCommand(params, metadata);
metadata.hasOutput[currentCommandName] = false;
metadata.isEmptyCommand[currentCommandName] = true;

return this as Termost<CommandValues & Values>;
},
input(params) {
createInstruction(createInput, params);
metadata.isEmptyCommand[currentCommandName] = false;

return this;
},
Expand All @@ -137,7 +138,7 @@ export const createProgram = <Values extends ObjectLikeConstraint>(
},
task(params) {
createInstruction(createTask, params);
metadata.hasOutput[currentCommandName] = true;
metadata.isEmptyCommand[currentCommandName] = false;

return this;
},
Expand Down
2 changes: 1 addition & 1 deletion termost/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type PackageMetadata = {

export type ProgramMetadata = PackageMetadata & {
argv: ArgumentValues;
hasOutput: Record<CommandName, boolean>;
isEmptyCommand: Record<CommandName, boolean>;
};

export type Context<Values extends ObjectLikeConstraint> = Values;
Expand Down

0 comments on commit 44648d3

Please sign in to comment.