Skip to content

feature request: Generate Static Files From Spec via Mix Task for Static Docs #678

@bradschwartz

Description

@bradschwartz

I think it would be nice to have a new mix task to rely on the output of the existing task and generate a markdown file that ExDoc can parse and include in our statically generated documentation. I've experimented with this locally and came up with something like this (might not match this project patterns):

defmodule Mix.Tasks.GenerateSwaggerDoc do
    @shortdoc "Generate an OpenAPI specification file for the REST API."
    @moduledoc """
    Generate an OpenAPI specification file for the REST API.
  
    Usage:
  
    ```
    $ mix generate_swagger_doc <output_file>
    ```
    """
  
    use Mix.Task
  
    alias Mix.Tasks.Openapi.Spec.Json
  
    @contents """
    <head>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/swagger-ui.css" />
    </head>
  
    <body>
    <div id="swagger-ui"></div>
    <script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" crossorigin></script>
    <script src="https://unpkg.com/[email protected]/swagger-ui-standalone-preset.js" crossorigin></script>
    <script>
      window.onload = () => {
        window.ui = SwaggerUIBundle({
          spec: <%= json_spec %>,
          dom_id: '#swagger-ui',
        });
      };
    </script>
    </body>
    """
  
    @args [output_file: :string, spec: :string]
    @args_aliases [o: :output_file, s: :spec]
    @default_file "guides/swagger.md"
  
    @impl Mix.Task
    @spec run([String.t()]) :: any()
    def run(args) do
      {parsed_args, _rest} = OptionParser.parse!(args, switches: @args, aliases: @args_aliases)
      output_file = Keyword.get(parsed_args, :output_file, @default_file)
  
      Mix.Task.run("app.start")
  
      # generate the openapi.json file
      Json.run(["--spec", "PhoenixAppWeb.ApiSpec"])
      json_spec = File.read!("openapi.json")
  
      :ok = File.write!(output_file, EEx.eval_string(@contents, json_spec: json_spec))
    end
  end

and can be added to the mix.exs docs as an extra:

# mix.exs
def project do
  ...
  docs: [extras: ["guides/swagger.md"]]
  ...
end

Happy to contribute this back if there's interest and openness to it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions