From 683a34d12107efdc33356e69c4531d2e6f173185 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 15 Jan 2023 01:48:24 -0500 Subject: [PATCH] improvement: handle optional arguments --- lib/ash_hq/docs/resources/dsl/dsl.ex | 6 + lib/ash_hq/docs/resources/dsl/types/arg.ex | 17 + lib/ash_hq_web/pages/docs.ex | 8 +- .../20230115062845_migrate_resources40.exs | 23 ++ .../repo/dsls/20230115062845.json | 295 ++++++++++++++++++ priv/scripts/build_dsl_docs.exs | 41 ++- 6 files changed, 387 insertions(+), 3 deletions(-) create mode 100644 lib/ash_hq/docs/resources/dsl/types/arg.ex create mode 100644 priv/repo/migrations/20230115062845_migrate_resources40.exs create mode 100644 priv/resource_snapshots/repo/dsls/20230115062845.json diff --git a/lib/ash_hq/docs/resources/dsl/dsl.ex b/lib/ash_hq/docs/resources/dsl/dsl.ex index 9f24b41..a94abcd 100644 --- a/lib/ash_hq/docs/resources/dsl/dsl.ex +++ b/lib/ash_hq/docs/resources/dsl/dsl.ex @@ -33,6 +33,10 @@ defmodule AshHq.Docs.Dsl do attribute :examples, {:array, :string} attribute :args, {:array, :string} + attribute :optional_args, {:array, :string} do + default [] + end + attribute :arg_defaults, :map attribute :path, {:array, :string} attribute :recursive_as, :string attribute :order, :integer, allow_nil?: false @@ -86,6 +90,8 @@ defmodule AshHq.Docs.Dsl do references do reference :library_version, on_delete: :delete end + + migration_defaults optional_args: "[]" end actions do diff --git a/lib/ash_hq/docs/resources/dsl/types/arg.ex b/lib/ash_hq/docs/resources/dsl/types/arg.ex new file mode 100644 index 0000000..adb5276 --- /dev/null +++ b/lib/ash_hq/docs/resources/dsl/types/arg.ex @@ -0,0 +1,17 @@ +defmodule AshHq.Docs.Dsl.Types.Arg do + use Ash.Resource, + data_layer: :embedded + + attributes do + attribute :optional, :boolean do + default false + allow_nil? false + end + + attribute :name, :string do + allow_nil? false + end + + attribute :default, :string + end +end diff --git a/lib/ash_hq_web/pages/docs.ex b/lib/ash_hq_web/pages/docs.ex index ced10ff..293e47e 100644 --- a/lib/ash_hq_web/pages/docs.ex +++ b/lib/ash_hq_web/pages/docs.ex @@ -222,6 +222,9 @@ defmodule AshHqWeb.Pages.Docs do Name Type + {#if @dsl.arg_defaults not in [%{}, nil]} + Default + {/if} Doc Links @@ -234,13 +237,16 @@ defmodule AshHqWeb.Pages.Docs do
- {render_tags(assigns, option)} + {render_tags(assigns, %{option | required: option.required && !Map.has_key?(@dsl.arg_defaults, option.name)})}
{option.type} + {#if @dsl.arg_defaults not in [%{}, nil]} + {Map.get(@dsl.arg_defaults, option.name)} + {/if} {raw(render_replacements(@libraries, @selected_versions, option.html_for))} diff --git a/priv/repo/migrations/20230115062845_migrate_resources40.exs b/priv/repo/migrations/20230115062845_migrate_resources40.exs new file mode 100644 index 0000000..6b97f2b --- /dev/null +++ b/priv/repo/migrations/20230115062845_migrate_resources40.exs @@ -0,0 +1,23 @@ +defmodule AshHq.Repo.Migrations.MigrateResources40 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:dsls) do + add :optional_args, {:array, :text}, default: [] + add :arg_defaults, :map + end + end + + def down do + alter table(:dsls) do + remove :arg_defaults + remove :optional_args + end + end +end \ No newline at end of file diff --git a/priv/resource_snapshots/repo/dsls/20230115062845.json b/priv/resource_snapshots/repo/dsls/20230115062845.json new file mode 100644 index 0000000..989e80e --- /dev/null +++ b/priv/resource_snapshots/repo/dsls/20230115062845.json @@ -0,0 +1,295 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "sanitized_path", + "type": "text" + }, + { + "allow_nil?": false, + "default": "fragment(\"uuid_generate_v4()\")", + "generated?": false, + "primary_key?": true, + "references": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": false, + "default": "\"\"", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "doc", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "doc_html", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "imports", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "links", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "examples", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "args", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "[]", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "optional_args", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "arg_defaults", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "path", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "recursive_as", + "type": "text" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "order", + "type": "bigint" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "type", + "type": "text" + }, + { + "allow_nil?": false, + "default": "fragment(\"now()\")", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "inserted_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": false, + "default": "fragment(\"now()\")", + "generated?": false, + "primary_key?": false, + "references": null, + "size": null, + "source": "updated_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": { + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "dsls_library_version_id_fkey", + "on_delete": "delete", + "on_update": null, + "schema": "public", + "table": "library_versions" + }, + "size": null, + "source": "library_version_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": { + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "dsls_extension_id_fkey", + "on_delete": null, + "on_update": null, + "schema": "public", + "table": "extensions" + }, + "size": null, + "source": "extension_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "primary_key?": false, + "references": { + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "dsls_dsl_id_fkey", + "on_delete": null, + "on_update": null, + "schema": "public", + "table": "dsls" + }, + "size": null, + "source": "dsl_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [ + { + "code?": false, + "down": "DROP INDEX dsls_name_lower_index;", + "name": "name_index", + "up": "CREATE INDEX dsls_name_lower_index ON dsls(lower(name));\n" + }, + { + "code?": false, + "down": "DROP INDEX dsls_name_trigram_index;", + "name": "trigram_index", + "up": "CREATE INDEX dsls_name_trigram_index ON dsls USING GIST (name gist_trgm_ops);\n" + }, + { + "code?": false, + "down": "DROP INDEX dsls_search_index;", + "name": "search_index", + "up": "CREATE INDEX dsls_search_index ON dsls USING GIN((\n setweight(to_tsvector('english', name), 'A') ||\n setweight(to_tsvector('english', doc), 'D')\n));\n" + } + ], + "has_create_action": true, + "hash": "14B6D64A6B4DA6AACB6CD273F31980B22F8FF0D9FFE1BFFA590498D1A09A8BA4", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshHq.Repo", + "schema": null, + "table": "dsls" +} \ No newline at end of file diff --git a/priv/scripts/build_dsl_docs.exs b/priv/scripts/build_dsl_docs.exs index 7aae081..0275b40 100644 --- a/priv/scripts/build_dsl_docs.exs +++ b/priv/scripts/build_dsl_docs.exs @@ -154,7 +154,36 @@ defmodule Utils do doc: docs_with_examples(entity.describe || "", examples(entity.examples)), imports: [], links: Map.new(entity.links || []), - args: entity.args, + args: + Enum.map(entity.args, fn + {:optional, name, _} -> + name + + {:optional, name} -> + name + + name -> + name + end), + optional_args: + Enum.flat_map(entity.args, fn + {:optional, name, _} -> + [name] + + {:optional, name} -> + [name] + + _ -> + [] + end), + arg_defaults: + Enum.reduce(entity.args, %{}, + fn {:optional, name, default}, acc -> + Map.put(acc, name, inspect(default)) + + _, acc -> + acc + end), type: :entity, path: path, options: add_argument_indices(schema(option_schema, path ++ [entity.name]), entity.args) @@ -169,7 +198,15 @@ defmodule Utils do defp add_argument_indices(values, arguments) do Enum.map(values, fn value -> - case Enum.find_index(arguments, &(&1 == value.name)) do + case Enum.find_index(arguments, fn {:optional, name, _} -> + name == value.name + + {:optional, name} -> + name == value.name + + name -> + name == value.name + end) do nil -> value