75 lines
1.9 KiB
Elixir
75 lines
1.9 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Mix.Tasks.Pleroma.OpenapiSpec do
|
|
def run([path]) do
|
|
# Load Pleroma application to get version info
|
|
Application.load(:pleroma)
|
|
|
|
spec_json = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
|
|
# to get rid of the structs
|
|
spec_regened = spec_json |> Jason.decode!()
|
|
|
|
check_specs!(spec_regened)
|
|
|
|
File.write(path, spec_json)
|
|
end
|
|
|
|
defp check_specs!(spec) do
|
|
with :ok <- check_specs(spec) do
|
|
:ok
|
|
else
|
|
{_, errors} ->
|
|
IO.puts(IO.ANSI.format([:red, :bright, "Spec check failed, errors:"]))
|
|
Enum.map(errors, &IO.puts/1)
|
|
|
|
raise "Spec check failed"
|
|
end
|
|
end
|
|
|
|
def check_specs(spec) do
|
|
errors =
|
|
spec["paths"]
|
|
|> Enum.flat_map(fn {path, %{} = endpoints} ->
|
|
Enum.map(
|
|
endpoints,
|
|
fn {method, endpoint} ->
|
|
with :ok <- check_endpoint(spec, endpoint) do
|
|
:ok
|
|
else
|
|
error ->
|
|
"#{endpoint["operationId"]} (#{method} #{path}): #{error}"
|
|
end
|
|
end
|
|
)
|
|
|> Enum.reject(fn res -> res == :ok end)
|
|
end)
|
|
|
|
if errors == [] do
|
|
:ok
|
|
else
|
|
{:error, errors}
|
|
end
|
|
end
|
|
|
|
defp check_endpoint(spec, endpoint) do
|
|
valid_tags = available_tags(spec)
|
|
|
|
with {_, [_ | _] = tags} <- {:tags, endpoint["tags"]},
|
|
{_, []} <- {:unavailable, Enum.reject(tags, &(&1 in valid_tags))} do
|
|
:ok
|
|
else
|
|
{:tags, _} ->
|
|
"No tags specified"
|
|
|
|
{:unavailable, tags} ->
|
|
"Tags #{inspect(tags)} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
|
|
end
|
|
end
|
|
|
|
defp available_tags(spec) do
|
|
spec["x-tagGroups"]
|
|
|> Enum.flat_map(fn %{"tags" => tags} -> tags end)
|
|
end
|
|
end
|