Elixir 如何搭配长生不老药信条中的两条线
因此,我正在进行一项自定义检查,旨在“识别缺少描述的graphql类型/字段定义” 代码如下所示Elixir 如何搭配长生不老药信条中的两条线,elixir,Elixir,因此,我正在进行一项自定义检查,旨在“识别缺少描述的graphql类型/字段定义” 代码如下所示 defmodule MockProject.MockModule do @moduledoc false node object1(:random_object) do @desc "random description" field :random_field, non_null(:random_name) do
defmodule MockProject.MockModule do
@moduledoc false
node object1(:random_object) do
@desc "random description"
field :random_field, non_null(:random_name) do
resolve &Resolver.RandomResolver.random_field/3
end
end
@desc "random node description"
node object2(:random_object) do
@desc "random description"
field :random_field, non_null(:random_name) do
resolve &Resolver.RandomResolver.random_field/3
end
end
end
我可以很容易地找到包含节点、字段或描述的行
但是我不知道如何找到一个带有node的行,它在前一行中缺少@desc
,是否有办法找到ast的前一行?否。您需要做的是跟踪最后遇到的
@desc
并在每次发现字段
调用时重置它(没有调用时发出错误)
另外,仅获取前一行是不够的,因为您可以执行以下操作:
@desc "foo"
@another_attr 1
field :my_field, non_null(:val) do
# …
end
这仍然是定义
描述的正确方法:我的_字段
在我看来,试图用信条来做这件事是一种受虐行为。考虑下面的有效代码位:
defmodule MyAppWeb.Schema.Finance.MoneyTypes do
use Absinthe.Schema.Notation
@desc "UNUSED 1"
@desc "MONEY 1"
object :money do
description("MONEY 2")
field :amount, :decimal
@desc "CURRENCY 1"
field :currency, :string do
description("CURRENCY 2")
end
end
end
<> > CREDO检查器必须处理(可能标志)未使用的<代码> @ DESC/<代码>属性,识别重复的描述(可以使用不同的语法),并且处理这个事实,您将不得不考虑在代码> [[对象:,节点::字段] < /代码>中的第一个元素]中的AST元组。每一个都可能有或可能没有关联的do
块
这不是不可能的,但很难,而且很容易被打破(如果苦艾酒引入了新的对象语法或描述速记)
简言之,我认为应该使用已经开发良好的GraphQL内省工具来完成您要做的事情
考虑以下模块:
defmodule MyAppWeb.Schema.IntrospectionUtils do
@moduledoc """
Convenience functions for inspecting the schema
"""
@doc """
iex> missing_desc_list(MyAppWeb.Schema)
[...]
"""
def missing_desc_list(schema_module) do
schema_module
|> type_names_and_descs()
|> missing_descs()
end
defp type_names_and_descs(schema_module) do
case " {__schema {types {name description fields {name description}}}} "
|> Absinthe.run(schema_module) do
{:ok, %{data: %{"__schema" => %{"types" => types}}}} -> types
_ -> raise("Unable to get types name and descs map")
end
end
defp missing_descs(types) do
types
|> Enum.reduce([], &missing_type_descs/2)
end
# ignore type names that start with double underscore
defp missing_type_descs(%{"name" => "__" <> _}, acc), do: acc
defp missing_type_descs(%{"name" => name, "description" => nil, "fields" => fields}, acc) do
missing_field_descs(fields, ["type #{name} is missing a description" | acc], name)
end
defp missing_type_descs(%{"name" => name, "description" => desc, "fields" => fields}, acc)
when is_binary(desc) do
missing_field_descs(fields, acc, name)
end
defp missing_field_descs(nil, acc, _type_name), do: acc
# ignore type names that start with double underscore
defp missing_field_descs(_fields, acc, "__" <> _), do: acc
defp missing_field_descs(fields, acc, type_name) when is_list(fields) do
fields
|> Enum.reduce(acc, &missing_field_descs(&1, &2, type_name))
end
defp missing_field_descs(%{"name" => name, "description" => nil}, acc, type_name) do
["field #{name} on type #{type_name} is missing a description" | acc]
end
defp missing_field_descs(_field, acc, _type_name), do: acc
end
注意,我添加了一些函数来“忽略”以2个下划线开头的模式类型名称。这表示内置GQ类型,不需要说明
还要注意的是,我的代码只是说明了一种方法,并没有经过测试或审查。可能会好得多
此方法可作为CI或类似方法的一部分使用,但不能像普通混合任务或信条检查器那样运行,因为应用程序需要运行才能正常工作。即使是此方法也不够,因为某些描述可能使用不同的语法编写。请看这里:
MyAppWeb.Schema.IntrospectionUtils.missing_desc_list(MyAppWeb.Schema)