# `NetRunner.Command`
[🔗](https://github.com/nyo16/net_runner/blob/v1.2.2/lib/net_runner/command.ex#L1)

Reusable command templates with default arguments and options.

Define commands once, reuse them everywhere:

    defmodule MyApp.Commands do
      use NetRunner.Command

      defcommand :curl, "curl",
        args: ["-s", "--compressed", "-L"],
        timeout: 10_000

      defcommand :rg, "rg",
        args: ["--no-heading", "--color=never"],
        stderr: :consume
    end

    # Returns a %Command{} struct:
    cmd = MyApp.Commands.curl(["https://example.com"])

    # Pass to NetRunner API:
    NetRunner.run(cmd)
    NetRunner.run(cmd, timeout: 30_000)
    NetRunner.stream!(cmd)

    # Introspection:
    MyApp.Commands.__commands__()
    #=> [:curl, :rg]

Commands can also be built at runtime without macros:

    cmd = NetRunner.Command.new("echo", ["hello"], timeout: 5_000)
    NetRunner.run(cmd)

# `t`

```elixir
@type t() :: %NetRunner.Command{
  args: [String.t()],
  executable: String.t(),
  opts: keyword()
}
```

# `defcommand`
*macro* 

Defines a reusable command template.

Generates a function with the given `name` that returns a `%NetRunner.Command{}` struct.

## Options

  * `:args` - default arguments prepended to any extra args at call time
  * All other options (`:timeout`, `:stderr`, `:pty`, etc.) become default
    process options, overridable when passed to `NetRunner.run/2` et al.

## Examples

    defcommand :echo, "echo"

    defcommand :curl, "curl",
      args: ["-s", "--compressed"],
      timeout: 10_000

The above generates:

    def curl(extra_args \\ [])

So that:

    curl(["https://example.com"])
    #=> %NetRunner.Command{
    #=>   executable: "curl",
    #=>   args: ["-s", "--compressed", "https://example.com"],
    #=>   opts: [timeout: 10_000]
    #=> }

# `new`

```elixir
@spec new(String.t(), [String.t()], keyword()) :: t()
```

Creates a new command struct.

## Examples

    iex> NetRunner.Command.new("echo", ["hello"])
    %NetRunner.Command{executable: "echo", args: ["hello"], opts: []}

    iex> NetRunner.Command.new("curl", ["-s"], timeout: 10_000)
    %NetRunner.Command{executable: "curl", args: ["-s"], opts: [timeout: 10_000]}

# `to_cmd_args_opts`

```elixir
@spec to_cmd_args_opts(
  t(),
  keyword()
) :: {String.t(), [String.t()], keyword()}
```

Decomposes a command struct into `{executable, args, opts}`.

Runtime `override_opts` are merged on top of the command's default opts,
so callers can override specific options per invocation.

## Examples

    iex> cmd = NetRunner.Command.new("echo", ["hello"], timeout: 5_000)
    iex> NetRunner.Command.to_cmd_args_opts(cmd)
    {"echo", ["hello"], [timeout: 5_000]}

    iex> cmd = NetRunner.Command.new("echo", ["hello"], timeout: 5_000)
    iex> NetRunner.Command.to_cmd_args_opts(cmd, timeout: 30_000)
    {"echo", ["hello"], [timeout: 30_000]}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
