Skip to content

Commit 78ad904

Browse files
committed
print primitive default values in cli help output, closes #6098
1 parent 6e77c20 commit 78ad904

8 files changed

Lines changed: 164 additions & 12 deletions

File tree

.changeset/sad-areas-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@effect/cli": patch
3+
---
4+
5+
print primitive default values in cli help output

packages/cli/src/internal/args.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,16 +535,17 @@ const getHelpInternal = (self: Instruction): HelpDoc.HelpDoc => {
535535
return InternalHelpDoc.mapDescriptionList(
536536
getHelpInternal(self.args as Instruction),
537537
(span, block) => {
538+
const defaultDescription = (value: unknown) => {
539+
const inspectableValue = Predicate.isObject(value) ? value : String(value)
540+
const displayValue = Inspectable.toStringUnknown(inspectableValue, 0)
541+
return InternalHelpDoc.p(`This setting is optional. Defaults to: ${displayValue}`)
542+
}
538543
const optionalDescription = Option.isOption(self.fallback)
539544
? Option.match(self.fallback, {
540545
onNone: () => InternalHelpDoc.p("This setting is optional."),
541-
onSome: (fallbackValue) => {
542-
const inspectableValue = Predicate.isObject(fallbackValue) ? fallbackValue : String(fallbackValue)
543-
const displayValue = Inspectable.toStringUnknown(inspectableValue, 0)
544-
return InternalHelpDoc.p(`This setting is optional. Defaults to: ${displayValue}`)
545-
}
546+
onSome: defaultDescription
546547
})
547-
: InternalHelpDoc.p("This setting is optional.")
548+
: defaultDescription(self.fallback)
548549
return [span, InternalHelpDoc.sequence(block, optionalDescription)]
549550
}
550551
)

packages/cli/src/internal/options.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -789,16 +789,17 @@ const getHelpInternal = (self: Instruction): HelpDoc.HelpDoc => {
789789
return InternalHelpDoc.mapDescriptionList(
790790
getHelpInternal(self.options as Instruction),
791791
(span, block) => {
792+
const defaultDescription = (value: unknown) => {
793+
const inspectableValue = Predicate.isObject(value) ? value : String(value)
794+
const displayValue = Inspectable.toStringUnknown(inspectableValue, 0)
795+
return InternalHelpDoc.p(`This setting is optional. Defaults to: ${displayValue}`)
796+
}
792797
const optionalDescription = Option.isOption(self.fallback)
793798
? Option.match(self.fallback, {
794799
onNone: () => InternalHelpDoc.p("This setting is optional."),
795-
onSome: (fallbackValue) => {
796-
const inspectableValue = Predicate.isObject(fallbackValue) ? fallbackValue : String(fallbackValue)
797-
const displayValue = Inspectable.toStringUnknown(inspectableValue, 0)
798-
return InternalHelpDoc.p(`This setting is optional. Defaults to: ${displayValue}`)
799-
}
800+
onSome: defaultDescription
800801
})
801-
: InternalHelpDoc.p("This setting is optional.")
802+
: defaultDescription(self.fallback)
802803
return [span, InternalHelpDoc.sequence(block, optionalDescription)]
803804
}
804805
)

packages/cli/test/Args.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,13 @@ describe("Args", () => {
171171
const helpDoc = Args.getHelp(option)
172172
yield* Effect.promise(() => expect(helpDoc).toMatchFileSnapshot("./snapshots/help-output/args-no-default"))
173173
}).pipe(runEffect))
174+
175+
it("displays default value in help when default is a primitive value", () =>
176+
Effect.gen(function*() {
177+
const args = Args.withDefault(Args.integer({ name: "count" }), 42)
178+
const helpDoc = Args.getHelp(args)
179+
yield* Effect.promise(() =>
180+
expect(helpDoc).toMatchFileSnapshot("./snapshots/help-output/args-default-primitive-value")
181+
)
182+
}).pipe(runEffect))
174183
})

packages/cli/test/Options.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,27 @@ describe("Options", () => {
701701
yield* Effect.promise(() => expect(helpDoc).toMatchFileSnapshot("./snapshots/help-output/options-no-default"))
702702
}).pipe(runEffect))
703703

704+
it("displays default value in help when default is a primitive value", () =>
705+
Effect.gen(function*() {
706+
const option = Options.withDefault(Options.integer("count"), 42)
707+
const helpDoc = Options.getHelp(option)
708+
yield* Effect.promise(() =>
709+
expect(helpDoc).toMatchFileSnapshot("./snapshots/help-output/options-default-primitive-value")
710+
)
711+
}).pipe(runEffect))
712+
713+
it("displays default value in help when default is a primitive boolean", () =>
714+
Effect.gen(function*() {
715+
const option = Options.withDefault(
716+
Options.choiceWithValue("uppercase", [["true", true], ["false", false]]),
717+
false
718+
)
719+
const helpDoc = Options.getHelp(option)
720+
yield* Effect.promise(() =>
721+
expect(helpDoc).toMatchFileSnapshot("./snapshots/help-output/options-default-primitive-boolean")
722+
)
723+
}).pipe(runEffect))
724+
704725
describe("options after positional arguments", () => {
705726
it("parses a text option that appears after positional args", () =>
706727
Effect.gen(function*() {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"_tag": "DescriptionList",
3+
"definitions": [
4+
[
5+
{
6+
"_tag": "Weak",
7+
"value": {
8+
"_tag": "Text",
9+
"value": "<count>",
10+
},
11+
},
12+
{
13+
"_tag": "Sequence",
14+
"left": {
15+
"_tag": "Paragraph",
16+
"value": {
17+
"_tag": "Text",
18+
"value": "An integer.",
19+
},
20+
},
21+
"right": {
22+
"_tag": "Paragraph",
23+
"value": {
24+
"_tag": "Text",
25+
"value": "This setting is optional. Defaults to: 42",
26+
},
27+
},
28+
},
29+
],
30+
],
31+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"_tag": "DescriptionList",
3+
"definitions": [
4+
[
5+
{
6+
"_tag": "Sequence",
7+
"left": {
8+
"_tag": "Text",
9+
"value": "--uppercase",
10+
},
11+
"right": {
12+
"_tag": "Sequence",
13+
"left": {
14+
"_tag": "Text",
15+
"value": " ",
16+
},
17+
"right": {
18+
"_tag": "Text",
19+
"value": "true | false",
20+
},
21+
},
22+
},
23+
{
24+
"_tag": "Sequence",
25+
"left": {
26+
"_tag": "Paragraph",
27+
"value": {
28+
"_tag": "Text",
29+
"value": "One of the following: true, false",
30+
},
31+
},
32+
"right": {
33+
"_tag": "Paragraph",
34+
"value": {
35+
"_tag": "Text",
36+
"value": "This setting is optional. Defaults to: false",
37+
},
38+
},
39+
},
40+
],
41+
],
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"_tag": "DescriptionList",
3+
"definitions": [
4+
[
5+
{
6+
"_tag": "Sequence",
7+
"left": {
8+
"_tag": "Text",
9+
"value": "--count",
10+
},
11+
"right": {
12+
"_tag": "Sequence",
13+
"left": {
14+
"_tag": "Text",
15+
"value": " ",
16+
},
17+
"right": {
18+
"_tag": "Text",
19+
"value": "integer",
20+
},
21+
},
22+
},
23+
{
24+
"_tag": "Sequence",
25+
"left": {
26+
"_tag": "Paragraph",
27+
"value": {
28+
"_tag": "Text",
29+
"value": "An integer.",
30+
},
31+
},
32+
"right": {
33+
"_tag": "Paragraph",
34+
"value": {
35+
"_tag": "Text",
36+
"value": "This setting is optional. Defaults to: 42",
37+
},
38+
},
39+
},
40+
],
41+
],
42+
}

0 commit comments

Comments
 (0)