ash-project / ash-project/igniter
Proposal: `Igniter.CLI` for expanded interactivity support
- Dominant language
- Elixir
- Stars
- 404
- Forks
- 75
- Avg merge
- 9h 58m
- Merged PRs (30d)
- 3
Description
[Original discussion on Discord](https://discord.com/channels/711271361523351632/1253324141491261472/1301177970278404157)
Prerequisite: #126
This proposal is for expanding Igniter's CLI support to offer better integration between command line arguments and interactive user prompts.
As an example, consider a version of `mix phx.new` written using Igniter. It supports [many options](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html#module-options) to configure a new project, including things like `--no-ecto`, `--database postgres`, etc. When implemented, this proposal would allow for an interactive series of prompts that would guide users through those options, using command line arguments to skip prompts when appropriate.
```
$ mix igniter.phx.new my_app
[Database] Set up an Ecto Repo?
[y/N] (default y)> y
[Database] Which database will you use?
1. Postgres
2. MySQL
3. MSSQL
4. SQLite
(default 1): 1
...
```
With the `--no-ecto` flag, specified, those prompts would be skipped:
```
$ mix igniter.phx.new --no-ecto my_app
[Database] Set up an Ecto Repo? NO (--no-ecto)
...
```
And to skip all prompts, the Igniter-global `--yes` could be used:
```
$ mix igniter.phx.new --yes
[Database] Set up an Ecto Repo? YES (--yes)
[Database] Which database will you use? Postgres (--yes)
...
```
---
To support this, a new `Igniter.CLI` module will be created. The specific API is a work in progress, but it may look something like this:
```elixir
@impl Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
schema: [
ecto: :boolean,
database: :string
],
...
}
end
@impl Igniter.Mix.Task
def igniter(igniter) do
igniter
|> Igniter.CLI.yes_no_prompt(:ecto, "[Database] Set up an Ecto Repo?")
|> Igniter.CLI.select_prompt(:database, "[Database] Which database will you use?",
# only issue this prompt if the function returns truthy
if: &(&1.args.options.ecto),
options: [
{"postgres", "Postgres"},
{"mysql", "MySQL"},
{"mssql", "MSSQL"},
{"sqlite", "SQLite"}
]
)
|> generate_ecto()
end
defp generate_ecto(igniter) do
if igniter.args.options.ecto do
database = igniter.args.options.database
...
else
igniter
end
end
```
Contributor guide
Research direction
Start by reading prerequisite #126 and the linked Discord discussion; the issue names no implementation files or tests. Define the Igniter.CLI API around yes/no and selection prompts, argument-based prompt skipping, and the global --yes behavior, then verify it against the mix phx.new examples shown here.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100