defmodule Mix.Tasks.Openapi.Spec.Yaml do @moduledoc """ Serialize the given OpenApi spec module to a YAML file. ## Examples $ mix openapi.spec.yaml """ use Mix.Task require Mix.Generator alias Mix.Tasks.Openapi.Spec.{Json, Json.Options} alias OpenApiSpex.OpenApi @default_filename "openapi.yaml" @impl Mix.Task def run(argv) do options = parse_options(argv) generate_json(options) options.filename |> load_spec_to_yaml() |> sanitize_spec() |> store_spec(options.filename) end defp generate_json(options) do Json.run(~w( --spec=#{options.spec} --pretty=#{options.pretty} #{options.filename} )) end defp load_spec_to_yaml(filename) do filename |> File.read!() |> OpenApi.json_encoder().decode!() |> Ymlr.document!() end defp sanitize_spec(spec) do spec |> String.split("\n") # vendor_extensions |> Enum.reject(&String.contains?(&1, ~w(operationId x-struct))) |> Enum.join("\n") end defp parse_options(argv) do parse_options = [strict: [spec: :string, endpoint: :string, pretty: :boolean]] {opts, args, _} = OptionParser.parse(argv, parse_options) %Options{ filename: args |> List.first() || @default_filename, spec: Keyword.get(opts, :spec), pretty: Keyword.get(opts, :pretty, false) } end defp store_spec(spec, filename), do: File.write!(filename, spec) end