defmodule Mix.Tasks.Openapi.Spec.Yaml do
@default_filename "openapi.yaml"
@moduledoc """
Serialize the given OpenApi spec module to a YAML file.
## Examples
$ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec apispec.yaml
$ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec --start-app=false
$ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec --vendor-extensions=false
## Command line options
* `--spec` - The ApiSpec module from which to generate the OpenAPI YAML file
* `--start-app` - Whether to start the application before generating the schema (defaults to true)
* `--vendor-extensions` - Whether to include open_api_spex OpenAPI vendor extensions
(defaults to true)
* `--quiet` - Whether to disable output printing (defaults to false)
* `--filename` - The output filename (defaults to "#{@default_filename}")
"""
use Mix.Task
require Mix.Generator
@dialyzer {:nowarn_function, encoder: 0}
@impl Mix.Task
def run(argv) do
{opts, _, _} = OptionParser.parse(argv, strict: [start_app: :boolean])
Keyword.get(opts, :start_app, true) |> maybe_start_app()
OpenApiSpex.ExportSpec.call(argv, &encode/2, @default_filename)
end
defp maybe_start_app(true), do: Mix.Task.run("app.start")
defp maybe_start_app(_), do: Mix.Task.run("app.config", preload_modules: true)
defp encode(spec, opts) do
spec
|> encoder().encode(opts)
|> case do
{:ok, yaml} ->
yaml
{:error, error} ->
Mix.raise("could not encode #{inspect(spec)}, error: #{inspect(error)}.")
end
end
defp encoder do
OpenApiSpex.OpenApi.yaml_encoder() ||
Mix.raise(
"could not load YAML encoder, please add one of supported encoders to dependencies."
)
end
end