diff --git a/lib/mix/tasks/openapi.spec.json.ex b/lib/mix/tasks/openapi.spec.json.ex index fe5d046b..f50cd849 100644 --- a/lib/mix/tasks/openapi.spec.json.ex +++ b/lib/mix/tasks/openapi.spec.json.ex @@ -7,6 +7,7 @@ defmodule Mix.Tasks.Openapi.Spec.Json do $ mix openapi.spec.json --spec PhoenixAppWeb.ApiSpec apispec.json $ mix openapi.spec.json --spec PhoenixAppWeb.ApiSpec --pretty=true + $ mix openapi.spec.json --spec PhoenixAppWeb.ApiSpec --check=true $ mix openapi.spec.json --spec PhoenixAppWeb.ApiSpec --start-app=false $ mix openapi.spec.json --spec PhoenixAppWeb.ApiSpec --vendor-extensions=false @@ -16,6 +17,8 @@ defmodule Mix.Tasks.Openapi.Spec.Json do * `--pretty` - Whether to prettify the generated JSON (defaults to false) + * `--check` - Whether to only compare the generated JSON with the spec file (defaults to false) + * `--start-app` - Whether need to start application before generate schema (defaults to true) * `--vendor-extensions` - Whether to include open_api_spex OpenAPI vendor extensions diff --git a/lib/mix/tasks/openapi.spec.yaml.ex b/lib/mix/tasks/openapi.spec.yaml.ex index caef6ecd..5c4c2289 100644 --- a/lib/mix/tasks/openapi.spec.yaml.ex +++ b/lib/mix/tasks/openapi.spec.yaml.ex @@ -6,6 +6,7 @@ defmodule Mix.Tasks.Openapi.Spec.Yaml do ## Examples $ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec apispec.yaml + $ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec --check=true $ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec --start-app=false $ mix openapi.spec.yaml --spec PhoenixAppWeb.ApiSpec --vendor-extensions=false @@ -13,6 +14,8 @@ defmodule Mix.Tasks.Openapi.Spec.Yaml do * `--spec` - The ApiSpec module from which to generate the OpenAPI YAML file + * `--check` - Whether to only compare the generated YAML with the spec file (defaults to false) + * `--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 diff --git a/lib/open_api_spex/export_spec.ex b/lib/open_api_spex/export_spec.ex index a6c457b8..4e8c1ff7 100644 --- a/lib/open_api_spex/export_spec.ex +++ b/lib/open_api_spex/export_spec.ex @@ -7,16 +7,27 @@ defmodule OpenApiSpex.ExportSpec do defmodule Options do @moduledoc false - defstruct filename: nil, spec: nil, pretty: false, vendor_extensions: true, quiet: false + defstruct filename: nil, + spec: nil, + pretty: false, + check: false, + vendor_extensions: true, + quiet: false end def call(argv, encode_spec, default_filename) do opts = parse_options(argv, default_filename) - opts - |> generate_spec() - |> encode_spec.(opts) - |> write_spec(opts) + encoded_spec = + opts + |> generate_spec() + |> encode_spec.(opts) + + if opts.check do + check_spec(encoded_spec, opts) + else + write_spec(encoded_spec, opts) + end end defp generate_spec(%{spec: spec, vendor_extensions: vendor_extensions}) do @@ -45,6 +56,7 @@ defmodule OpenApiSpex.ExportSpec do spec: :string, endpoint: :string, pretty: :boolean, + check: :boolean, vendor_extensions: :boolean, quiet: :boolean ] @@ -56,11 +68,18 @@ defmodule OpenApiSpex.ExportSpec do filename: args |> List.first() || default_filename, spec: find_spec(opts), pretty: Keyword.get(opts, :pretty, false), + check: Keyword.get(opts, :check, false), vendor_extensions: Keyword.get(opts, :vendor_extensions, true), quiet: Keyword.get(opts, :quiet, false) } end + defp check_spec(content, opts) do + unless content == File.read!(opts.filename) do + Mix.raise("The OpenAPI spec file does not match the generated spec:\n\n#{content}") + end + end + defp write_spec(content, opts) do case Path.dirname(opts.filename) do "." -> true