Elixir 如何搭配长生不老药信条中的两条线

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

因此,我正在进行一项自定义检查,旨在“识别缺少描述的graphql类型/字段定义”

代码如下所示

    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)