Current section
Files
Jump to
Current section
Files
lib/cli.ex
defmodule Argos.CLI do
@moduledoc """
Command-line interface para Argos.
Permite ejecutar múltiples comandos del sistema en paralelo desde la línea de comandos.
Los comandos se ejecutan de forma concurrente y su salida se muestra preservando
los códigos ANSI.
## Uso
# Ejecutar un único comando
argos --command="echo 'Hello World'"
# Ejecutar múltiples comandos en paralelo
argos --command="echo 'First'" --command="echo 'Second'"
# Comandos con códigos ANSI (como aurora)
argos --command="echo \"$(aurora --text='joroña' --hex='bada55')\""
## Opciones
- `--command="..."` o `-c "..."`: Comando a ejecutar (puede especificarse múltiples veces)
- `--load-config`: Cargar explícitamente el archivo de configuración del shell
- `--no-config`: No cargar el archivo de configuración del shell
- `--no-login`: (Deprecated) Equivalente a `--no-config`
- `--help` o `-h`: Muestra la ayuda
- `--version` o `-v`: Muestra la versión
## Notas
- Los comandos se ejecutan en paralelo usando Tasks
- La salida de cada comando se muestra preservando los códigos ANSI
- El código de salida será 0 si todos los comandos tienen éxito, o 1 si alguno falla
- Por defecto se carga el archivo de configuración del shell (`.zshrc`, `.bashrc`, etc.)
para permitir usar aliases y funciones personalizadas
- El archivo de configuración se detecta automáticamente según el shell usado
- Usa `--no-config` si no quieres cargar la configuración del shell
## Ejemplos con aliases
# Usar un alias definido en .zshrc
argos --command="mi_alias argumentos"
# Ejecutar múltiples comandos con aliases
argos --command="alias1" --command="alias2"
# Si no quieres cargar .zshrc
argos --no-login --command="comando_sin_config"
"""
alias Argos.CLI.{Executor, Formatter, Parser}
@doc """
Parsea los argumentos de línea de comandos.
"""
@spec parse_args([String.t()]) :: {[String.t()], [String.t()], keyword()}
defdelegate parse_args(argv), to: Parser
@doc """
Recoge todos los comandos de las opciones (puede haber múltiples --command).
"""
@spec collect_commands(keyword()) :: [String.t()]
defdelegate collect_commands(opts), to: Parser
@doc """
Ejecuta un comando individual.
"""
@spec execute_command(String.t(), keyword()) :: Argos.CommandResult.t()
defdelegate execute_command(command, opts \\ []), to: Executor
@doc """
Punto de entrada principal del CLI.
"""
@spec main([String.t()]) :: no_return()
def main(argv) do
_ = Code.ensure_loaded(Aurora.Color)
load_aurora_colors()
argv
|> Parser.parse_args()
|> execute()
end
@dialyzer {:no_return, execute: 1}
defp execute({commands, _remaining, opts, command_for_help}) do
cond do
Keyword.get(opts, :help, false) and not is_nil(command_for_help) ->
Formatter.show_command_help(command_for_help)
System.halt(0)
Keyword.get(opts, :help, false) ->
Formatter.show_help()
System.halt(0)
Keyword.get(opts, :examples, false) ->
Formatter.show_examples()
System.halt(0)
Keyword.get(opts, :version, false) ->
Formatter.show_version()
System.halt(0)
Enum.empty?(commands) ->
Formatter.show_help()
System.halt(0)
true ->
Executor.run_commands_parallel(commands, opts)
end
end
defp load_aurora_colors do
case Application.get_env(:aurora, :colors) do
nil ->
default_colors = get_default_aurora_colors()
Application.put_env(:aurora, :colors, default_colors)
:ok
[] ->
default_colors = get_default_aurora_colors()
Application.put_env(:aurora, :colors, default_colors)
:ok
_ ->
:ok
end
end
defp get_default_aurora_colors do
[
colors: %{
no_color: %{
name: :no_color,
hex: "#F8F8F2",
rgb: {248, 248, 242},
argb: {255, 248, 248, 242},
hsv: {60.0, 0.024, 0.972},
hsl: {60.0, 0.286, 0.961},
cmyk: {0.0, 0.0, 0.024, 0.028},
inverted: false
},
primary: %{
name: :primary,
hex: "#A1E7FA",
rgb: {161, 231, 250},
argb: {255, 161, 231, 250},
hsv: {192.0, 0.356, 0.980},
hsl: {192.0, 0.892, 0.806},
cmyk: {0.356, 0.076, 0.0, 0.020},
inverted: false
},
secondary: %{
name: :secondary,
hex: "#3AABA3",
rgb: {58, 171, 163},
argb: {255, 58, 171, 163},
hsv: {176.0, 0.661, 0.671},
hsl: {176.0, 0.493, 0.449},
cmyk: {0.661, 0.0, 0.047, 0.329},
inverted: false
},
ternary: %{
name: :ternary,
hex: "#FF8000",
rgb: {255, 128, 0},
argb: {255, 255, 128, 0},
hsv: {30.0, 1.0, 1.0},
hsl: {30.0, 1.0, 0.5},
cmyk: {0.0, 0.498, 1.0, 0.0},
inverted: false
},
success: %{
name: :success,
hex: "#97C53C",
rgb: {151, 197, 60},
argb: {255, 151, 197, 60},
hsv: {80.0, 0.695, 0.773},
hsl: {80.0, 0.534, 0.504},
cmyk: {0.234, 0.0, 0.695, 0.227},
inverted: false
},
warning: %{
name: :warning,
hex: "#FDD808",
rgb: {253, 216, 8},
argb: {255, 253, 216, 8},
hsv: {51.0, 0.968, 0.992},
hsl: {51.0, 0.984, 0.509},
cmyk: {0.0, 0.146, 0.968, 0.008},
inverted: false
},
error: %{
name: :error,
hex: "#FF5B5B",
rgb: {255, 91, 91},
argb: {255, 255, 91, 91},
hsv: {0.0, 0.643, 1.0},
hsl: {0.0, 1.0, 0.678},
cmyk: {0.0, 0.643, 0.643, 0.0},
inverted: false
},
info: %{
name: :info,
hex: "#00FFFF",
rgb: {0, 255, 255},
argb: {255, 0, 255, 255},
hsv: {180.0, 1.0, 1.0},
hsl: {180.0, 1.0, 0.5},
cmyk: {1.0, 0.0, 0.0, 0.0},
inverted: false
},
happy: %{
name: :happy,
hex: "#EE80C3",
rgb: {238, 128, 195},
argb: {255, 238, 128, 195},
hsv: {326.0, 0.462, 0.933},
hsl: {326.0, 0.767, 0.718},
cmyk: {0.0, 0.462, 0.181, 0.067},
inverted: false
},
menu: %{
name: :menu,
hex: "#ABCDF1",
rgb: {171, 205, 241},
argb: {255, 171, 205, 241},
hsv: {210.0, 0.290, 0.945},
hsl: {210.0, 0.714, 0.808},
cmyk: {0.290, 0.149, 0.0, 0.055},
inverted: false
}
},
gradients: %{}
]
end
end