Skip to content

Commit

Permalink
fix(cli): do not render hidden commands (#5975)
Browse files Browse the repository at this point in the history
Before this fix, hidden commands (and subcommands) were visible when
running the help command and in our docs.

This fixes that.
  • Loading branch information
eysi09 committed Apr 25, 2024
1 parent 58dee94 commit 053c786
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 25 deletions.
1 change: 1 addition & 0 deletions core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export class GardenCli {
async renderHelp(log: Log, workingDir: string) {
const commands = Object.values(this.commands)
.sort()
.filter((cmd) => !cmd.hidden)
.filter((cmd) => cmd.getPath().length === 1)

// `dedent` has a bug where it doesn't indent correctly
Expand Down
10 changes: 9 additions & 1 deletion core/src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,10 @@ export abstract class Command<
}

renderHelp() {
if (this.hidden) {
return ""
}

let out = this.description
? `\n${cliStyles.heading("DESCRIPTION")}\n\n${styles.secondary(this.description.trim())}\n\n`
: ""
Expand Down Expand Up @@ -674,7 +678,11 @@ export abstract class CommandGroup extends Command {
}

override renderHelp() {
const commands = this.getSubCommands()
const commands = this.getSubCommands().filter((cmd) => !cmd.hidden)

if (commands.length === 0) {
return ""
}

return `
${cliStyles.heading("USAGE")}
Expand Down
1 change: 1 addition & 0 deletions core/src/commands/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class SetDefaultEnvCommand extends Command<SetDefaultEnvArgs, {}> {
name = "default-env"

help = "Locally override the default environment for the project."
override hidden = true

override description = dedent`
Override the default environment for the project for this working copy.
Expand Down
39 changes: 39 additions & 0 deletions core/test/unit/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,45 @@ describe("cli", () => {
})
})

describe("renderHelp", () => {
it("should skip hidden commands", async () => {
class TestCommand extends Command {
name = "test-command"
help = "halp!"
override noProject = true

override printHeader() {}

async action({ args }) {
return { result: { args } }
}
}
class HiddenTestCommand extends Command {
name = "hidden-test-command"
help = "halp!"
override noProject = true
override hidden = true

override printHeader() {}

async action({ args }) {
return { result: { args } }
}
}

const cmd = new TestCommand()
const hiddenCmd = new HiddenTestCommand()
cli.addCommand(cmd)
cli.addCommand(hiddenCmd)

const { code, consoleOutput } = await cli.run({ args: ["--help"], exitOnError: false })

expect(code).to.equal(0)
expect(consoleOutput).to.include("test-command")
expect(consoleOutput).to.not.include("hidden-test-command")
})
})

describe("makeDummyGarden", () => {
it("should initialise and resolve config graph in a directory with no project", async () => {
const path = join(GARDEN_CORE_ROOT, "tmp", "foobarbas")
Expand Down
155 changes: 155 additions & 0 deletions core/test/unit/src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ describe("Command", () => {
[array:string]
`)
})
it("returns an empty string for hidden commands", async () => {
class TestCommand extends Command {
name = "test-command"
override aliases = ["some-alias"]
override hidden = true
help = "Hi, how are you?"

override arguments = {
foo: new StringsParameter({
help: "Some help text.",
required: true,
}),
bar: new StringsParameter({
help: "Another help text.",
}),
}

override options = {
floop: new StringsParameter({
help: "Option help text.",
}),
}

override printHeader() {}

async action() {
return {}
}
}

const cmd = new TestCommand()

expect(cmd.renderHelp()).to.equal("")
})
})

describe("getPaths", () => {
Expand Down Expand Up @@ -386,3 +420,124 @@ describe("CommandGroup", () => {
})
})
})

describe("CommandGroup", () => {
describe("renderHelp", () => {
it("renders the command help text", async () => {
class TestSubCommand extends Command {
name = "test-command"
override aliases = ["some-alias"]
help = "Hi, how are you?"

override arguments = {
foo: new StringsParameter({
help: "Some help text.",
required: true,
}),
bar: new StringsParameter({
help: "Another help text.",
}),
}

override options = {
floop: new StringsParameter({
help: "Option help text.",
}),
}

override printHeader() {}

async action() {
return {}
}
}

class TestCommandGroup extends CommandGroup {
name = "test-command-group"
subCommands = [TestSubCommand]
help = "Hi, how are you?"
}

const cmdGroup = new TestCommandGroup()
const helpTxt = stripAnsi(cmdGroup.renderHelp()).trim()

expect(helpTxt).to.equal(dedent`
USAGE
garden test-command-group <command> [options]
COMMANDS
test-command-group test-command Hi, how are you?
`)
})
it("skips hidden commands", async () => {
class TestSubCommand extends Command {
name = "test-command"
override aliases = ["some-alias"]
help = ""

async action() {
return {}
}
}
class HiddenTestSubCommand extends Command {
name = "test-command-hidden"
override aliases = ["some-alias"]
override hidden = true
help = "Hi, how are you?"

async action() {
return {}
}
}

class TestCommandGroup extends CommandGroup {
name = "test-command-group"
subCommands = [HiddenTestSubCommand, TestSubCommand]
help = "Hi, how are you?"
}

const cmdGroup = new TestCommandGroup()
const helpTxt = stripAnsi(cmdGroup.renderHelp()).trim()

expect(helpTxt).to.equal(dedent`
USAGE
garden test-command-group <command> [options]
COMMANDS
test-command-group test-command
`)
})
it("returns an empty string if all sub commands are hidden", async () => {
class HiddenTestSubCommandA extends Command {
name = "test-command-hidden-a"
override aliases = ["some-alias"]
override hidden = true
help = "Hi, how are you?"

async action() {
return {}
}
}
class HiddenTestSubCommandB extends Command {
name = "test-command-hidden-b"
override aliases = ["some-alias"]
override hidden = true
help = "Hi, how are you?"

async action() {
return {}
}
}

class TestCommandGroup extends CommandGroup {
name = "test-command-group"
subCommands = [HiddenTestSubCommandA, HiddenTestSubCommandB]
help = "Hi, how are you?"
}

const cmdGroup = new TestCommandGroup()

expect(cmdGroup.renderHelp()).to.equal("")
})
})
})
24 changes: 0 additions & 24 deletions docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -4986,30 +4986,6 @@ Examples:
Note! If you use a non-stable version (i.e. pre-release, or draft, or edge), then the latest possible major version will be installed.


### garden set default-env

**Locally override the default environment for the project.**

Override the default environment for the project for this working copy.

Examples:

garden set default-env remote # Set the default env to remote (with the configured default namespace)
garden set default-env dev.my-env # Set the default env to dev.my-env
garden set default-env # Clear any previously set override

#### Usage

garden set default-env [env]

#### Arguments

| Argument | Required | Description |
| -------- | -------- | ----------- |
| `env` | No | The default environment to set for the current project



### garden sync start

**Start any configured syncs to the given Deploy action(s).**
Expand Down

0 comments on commit 053c786

Please sign in to comment.