diff --git a/lib/mix/tasks/openapi.static_docs.ex b/lib/mix/tasks/openapi.static_docs.ex new file mode 100644 index 00000000..acec79fa --- /dev/null +++ b/lib/mix/tasks/openapi.static_docs.ex @@ -0,0 +1,100 @@ +defmodule Mix.Tasks.Openapi.StaticDocs do + @shortdoc "Generate a static file that renders the OpenAPI spec using the Swagger UI" + @moduledoc """ + Generate a static file that renders the OpenAPI spec using the Swagger UI. Uses + assets from https://unpkg.com/swagger-ui-dist. + + ## Examples + + $ mix openapi.static_docs --spec PhoenixAppWeb.ApiSpec --output-file swagger.md + $ mix openapi.static_docs --spec PhoenixAppWeb.ApiSpec --output-file swagger.md --swagger-version 5.27.1 + + ## Usage with ExDoc + + To use with ExDoc, you can add the following to your `mix.exs` file: + + ```elixir + def docs do + [ + extras: ["guides/swagger.md"] + ] + end + + def aliases do + [ + "docs": [ + "cmd mkdir -p guides/", + "openapi.static_docs --spec PhoenixAppWeb.ApiSpec --output-file guides/swagger.md --swagger-version 4.4.0", + "docs" + ] + ] + end + ``` + + ## Command line options + + Accepts all the same options as `Mix.Tasks.Openapi.Spec.Json` plus: + + * `--output-file` - The file to write the static file to (defaults to `swagger.md`) + + * `--swagger-version` - The version of the Swagger UI to use (defaults to `5.27.1`) + """ + use Mix.Task + + require Mix.Generator + + alias Mix.Tasks.Openapi.Spec.Json + + @recursive true + @default_static_filename "swagger.md" + @default_swagger_version "5.27.1" + + @static_template """ + # <%= spec_name %> + + + + + + +
+ + + + + """ + + @flags [ + output_file: :string, + swagger_version: :string, + spec: :string + ] + + @impl true + def run(argv) do + {opts, _, _} = OptionParser.parse(argv, switches: @flags) + + json_spec_filename = Json.run(argv) + + output_file = Keyword.get(opts, :output_file, @default_static_filename) + swagger_version = Keyword.get(opts, :swagger_version, @default_swagger_version) + + json_spec = File.read!(json_spec_filename) + + rendered_template = + EEx.eval_string(@static_template, + spec_name: opts[:spec], + json_spec: json_spec, + swagger_version: swagger_version + ) + + Mix.Generator.create_file(output_file, rendered_template, force: true, quiet: true) + end +end diff --git a/lib/open_api_spex/export_spec.ex b/lib/open_api_spex/export_spec.ex index 4e8c1ff7..77aae9e7 100644 --- a/lib/open_api_spex/export_spec.ex +++ b/lib/open_api_spex/export_spec.ex @@ -15,6 +15,7 @@ defmodule OpenApiSpex.ExportSpec do quiet: false end + @spec call(list(binary()), (any(), any() -> any()), String.t()) :: false | nil | String.t() def call(argv, encode_spec, default_filename) do opts = parse_options(argv, default_filename) @@ -86,7 +87,9 @@ defmodule OpenApiSpex.ExportSpec do dir -> Mix.Generator.create_directory(dir, quiet: opts.quiet) end - Mix.Generator.create_file(opts.filename, content, force: true, quiet: opts.quiet) + with true <- Mix.Generator.create_file(opts.filename, content, force: true, quiet: opts.quiet) do + opts.filename + end end defp find_spec(opts) do