Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
Allow --wizard for subcommands (#399)
Browse files Browse the repository at this point in the history
  • Loading branch information
IMax153 authored Nov 30, 2023
1 parent 3e21194 commit cc03d2b
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
8 changes: 4 additions & 4 deletions src/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,16 +307,16 @@ export const withSubcommands: {
*/
export const wizard: {
(
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
): <Name extends string, R, E, A>(
self: Command<Name, R, E, A>
) => Effect<FileSystem | Terminal, QuitException | ValidationError, ReadonlyArray<string>>
) => Effect<Terminal | FileSystem, QuitException | ValidationError, ReadonlyArray<string>>
<Name extends string, R, E, A>(
self: Command<Name, R, E, A>,
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
): Effect<FileSystem | Terminal, QuitException | ValidationError, ReadonlyArray<string>>
): Effect<Terminal | FileSystem, QuitException | ValidationError, ReadonlyArray<string>>
} = Internal.wizard

/**
Expand Down
8 changes: 4 additions & 4 deletions src/CommandDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,14 @@ export const withSubcommands: {
*/
export const wizard: {
(
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
): <A>(
self: Command<A>
) => Effect<FileSystem | Terminal, QuitException | ValidationError, ReadonlyArray<string>>
) => Effect<FileSystem | Terminal, ValidationError | QuitException, ReadonlyArray<string>>
<A>(
self: Command<A>,
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
): Effect<FileSystem | Terminal, QuitException | ValidationError, ReadonlyArray<string>>
): Effect<FileSystem | Terminal, ValidationError | QuitException, ReadonlyArray<string>>
} = Internal.wizard
36 changes: 29 additions & 7 deletions src/internal/cliApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as Console from "effect/Console"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import { dual, pipe } from "effect/Function"
import * as HashMap from "effect/HashMap"
import * as Option from "effect/Option"
import { pipeArguments } from "effect/Pipeable"
import * as ReadonlyArray from "effect/ReadonlyArray"
Expand Down Expand Up @@ -90,13 +91,13 @@ export const run = dual<
Effect.catchSome((e) =>
InternalValidationError.isValidationError(e) &&
InternalValidationError.isHelpRequested(e)
? Option.some(handleBuiltInOption(self, e.showHelp, execute, config))
? Option.some(handleBuiltInOption(self, args, e.showHelp, execute, config))
: Option.none()
)
)
}
case "BuiltIn": {
return handleBuiltInOption(self, directive.option, execute, config).pipe(
return handleBuiltInOption(self, args, directive.option, execute, config).pipe(
Effect.catchSome((e) =>
InternalValidationError.isValidationError(e)
? Option.some(Effect.zipRight(printDocs(e.error), Effect.fail(e)))
Expand All @@ -122,6 +123,7 @@ const isQuitException = (u: unknown): u is Terminal.QuitException =>

const handleBuiltInOption = <R, E, A>(
self: CliApp.CliApp<A>,
args: ReadonlyArray<string>,
builtIn: BuiltInOptions.BuiltInOptions,
execute: (a: A) => Effect.Effect<R, E, void>,
config: CliConfig.CliConfig
Expand Down Expand Up @@ -228,20 +230,23 @@ const handleBuiltInOption = <R, E, A>(
)
const help = InternalHelpDoc.sequence(header, description)
const text = InternalHelpDoc.toAnsiText(help)
const wizardPrefix = getWizardPrefix(builtIn, programName, args)
return Console.log(text).pipe(
Effect.zipRight(InternalCommand.wizard(builtIn.command, programName, config)),
Effect.zipRight(InternalCommand.wizard(builtIn.command, wizardPrefix, config)),
Effect.tap((args) => Console.log(InternalHelpDoc.toAnsiText(renderWizardArgs(args)))),
Effect.flatMap((args) =>
InternalTogglePrompt.toggle({
message: "Would you like to run the command?",
initial: true,
active: "yes",
inactive: "no"
}).pipe(Effect.flatMap((shouldRunCommand) =>
shouldRunCommand
? Console.log().pipe(Effect.zipRight(run(self, args.slice(1), execute)))
}).pipe(Effect.flatMap((shouldRunCommand) => {
return shouldRunCommand
? Console.log().pipe(
Effect.zipRight(run(self, ReadonlyArray.drop(args, 1), execute))
)
: Effect.unit
))
}))
),
Effect.catchAll((e) => {
if (isQuitException(e)) {
Expand Down Expand Up @@ -296,6 +301,23 @@ const prefixCommand = <A>(self: Command.Command<A>): ReadonlyArray<string> => {
return prefix
}

const getWizardPrefix = (
builtIn: BuiltInOptions.ShowWizard,
rootCommand: string,
commandLineArgs: ReadonlyArray<string>
): ReadonlyArray<string> => {
const subcommands = InternalCommand.getSubcommands(builtIn.command)
const [parentArgs, childArgs] = ReadonlyArray.span(
commandLineArgs,
(name) => !HashMap.has(subcommands, name)
)
const args = ReadonlyArray.matchLeft(childArgs, {
onEmpty: () => ReadonlyArray.filter(parentArgs, (arg) => arg !== "--wizard"),
onNonEmpty: (head) => ReadonlyArray.append(parentArgs, head)
})
return ReadonlyArray.prepend(args, rootCommand)
}

const renderWizardArgs = (args: ReadonlyArray<string>) => {
const params = pipe(
ReadonlyArray.filter(args, (param) => param.length > 0),
Expand Down
6 changes: 3 additions & 3 deletions src/internal/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ export const withSubcommands = dual<
/** @internal */
export const wizard = dual<
(
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
) => <Name extends string, R, E, A>(
self: Command.Command<Name, R, E, A>
Expand All @@ -399,14 +399,14 @@ export const wizard = dual<
>,
<Name extends string, R, E, A>(
self: Command.Command<Name, R, E, A>,
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig
) => Effect.Effect<
FileSystem | Terminal,
QuitException | ValidationError.ValidationError,
ReadonlyArray<string>
>
>(3, (self, rootCommand, config) => InternalDescriptor.wizard(self.descriptor, rootCommand, config))
>(3, (self, prefix, config) => InternalDescriptor.wizard(self.descriptor, prefix, config))

/** @internal */
export const run = dual<
Expand Down
10 changes: 5 additions & 5 deletions src/internal/commandDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ export const withSubcommands = dual<
/** @internal */
export const wizard = dual<
(
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig.CliConfig
) => <A>(self: Descriptor.Command<A>) => Effect.Effect<
FileSystem.FileSystem | Terminal.Terminal,
Expand All @@ -352,14 +352,14 @@ export const wizard = dual<
>,
<A>(
self: Descriptor.Command<A>,
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig.CliConfig
) => Effect.Effect<
FileSystem.FileSystem | Terminal.Terminal,
Terminal.QuitException | ValidationError.ValidationError,
ReadonlyArray<string>
>
>(3, (self, rootCommand, config) => wizardInternal(self as Instruction, rootCommand, config))
>(3, (self, prefix, config) => wizardInternal(self as Instruction, prefix, config))

// =============================================================================
// Internals
Expand Down Expand Up @@ -883,7 +883,7 @@ const optionsWizardHeader = InternalSpan.code("Options Wizard - ")

const wizardInternal = (
self: Instruction,
rootCommand: string,
prefix: ReadonlyArray<string>,
config: CliConfig.CliConfig
): Effect.Effect<
FileSystem.FileSystem | Terminal.Terminal,
Expand Down Expand Up @@ -970,7 +970,7 @@ const wizardInternal = (
}
}
}
return Ref.make<ReadonlyArray<string>>(ReadonlyArray.of(rootCommand)).pipe(
return Ref.make(prefix).pipe(
Effect.flatMap((commandLineRef) =>
loop(getWizardCommandSequence(self), commandLineRef).pipe(
Effect.zipRight(Ref.get(commandLineRef))
Expand Down

0 comments on commit cc03d2b

Please sign in to comment.