From 91f826a95919d331945a87f1feccf0e1970bce4b Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Thu, 14 Apr 2022 15:17:50 +0200 Subject: [PATCH 01/10] [messages - elixir] create proof of concept writer for module generation --- .../mix/tasks/generate_json_structs.ex | 155 ++++++++++++++++++ .../elixir/lib/cucumber_messages/writer.ex | 119 +------------- messages/elixir/mix.exs | 5 +- messages/elixir/mix.lock | 20 ++- messages/elixir/priv/json_schemas/.gitignore | 2 + 5 files changed, 176 insertions(+), 125 deletions(-) create mode 100644 messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex create mode 100644 messages/elixir/priv/json_schemas/.gitignore diff --git a/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex b/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex new file mode 100644 index 0000000000..75dd19544d --- /dev/null +++ b/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex @@ -0,0 +1,155 @@ +defmodule Mix.Tasks.GenerateJsonStructs do + use Mix.Task + require IEx + require Logger + + @application_name :cucumber_messages + @priv_dir :code.priv_dir(@application_name) + @app_dir File.cwd!() + @lib_dir Path.join([@app_dir, "lib", Atom.to_string(@application_name)]) + + defmodule ModuleData do + defstruct [:module_name, :fields] + end + + def run([]) do + clean_generated_folder() + json_files = [@priv_dir, "json_schemas", "*.json"] |> Path.join() |> Path.wildcard() + + json_files + |> Enum.map(fn filename -> + clean_filename = Path.basename(filename) + content = filename |> File.read!() |> Jason.decode!() + {clean_filename, content} + end) + |> Enum.each(fn {filename, decoded} -> + Logger.debug("Starting parsing file: \"#{filename}\"") + forced_decoded = Map.put(decoded, "$id", filename) + metadata = %{definitions: nil, full_decoded: forced_decoded, modules: [], parent: nil} + list_of_modules = create_moduledata_structs(metadata, forced_decoded) + textual_modules = output_module(list_of_modules, []) + + write_files(textual_modules) + Logger.debug("File \"#{filename}\" finished! ✔") + end) + + # path_json = [@priv_dir, "json_schemas", "Pickle.json"] |> Path.join() + # decoded = path_json |> File.read!() |> Jason.decode!() + # metadata = %{definitions: nil, full_decoded: decoded, modules: [], parent: nil} + # list_of_modules = create_moduledata_structs(metadata, decoded) + # textual_modules = output_module(list_of_modules, []) + # write_files(textual_modules) + end + + # Clean generated folder + defp clean_generated_folder() do + generated_files = [@lib_dir, "generated", "*.ex"] |> Path.join() |> Path.wildcard() + Enum.each(generated_files, &File.rm!/1) + end + + # ############################################################# # + # Converts [ModuleData, ...] to [{filename, filecontents}, ...] # + # ############################################################# # + + defp output_module([], acc) when is_list(acc), do: acc + defp output_module([], acc), do: [acc] + + defp output_module(%ModuleData{} = moduledata, acc) do + atom_fields = + moduledata.fields + |> Enum.map(fn {fieldname, _ignore_details} -> ":" <> Macro.underscore(fieldname) end) + |> Enum.intersperse(", ") + + entry = """ + defmodule CucumberMessages.#{moduledata.module_name} do + defstruct [#{atom_fields}] + end + """ + + filename = Macro.underscore(moduledata.module_name) <> ".ex" + [{filename, entry} | acc] + end + + defp output_module([module | rest], acc) do + new_acc = output_module(module, acc) + output_module(rest, new_acc) + end + + # ############################################################# # + # Converts json schema to list of [ModuleData, ...] # + # ############################################################# # + + defp create_moduledata_structs( + %{definitions: nil, parent: nil} = metadata, + %{"definitions" => dfs} = data + ) + when dfs != nil do + {definitions, remaining_data} = Map.pop!(data, "definitions") + + metadata + |> Map.put(:definitions, definitions) + |> create_moduledata_structs(remaining_data) + end + + defp create_moduledata_structs( + %{parent: nil, definitions: dfs} = metadata, + %{"$id" => id, "properties" => properties} = data + ) + when dfs != nil do + module_name = String.trim_trailing(id, ".json") + properties = properties + parent = %ModuleData{module_name: module_name, fields: properties} + + metadata + |> Map.put(:parent, parent) + |> Map.put(:modules, [parent | metadata.modules]) + |> create_moduledata_structs(data) + end + + # If PARENT and DEFINITIONS, create children. + defp create_moduledata_structs(%{parent: p, definitions: dfs} = metadata, _data) + when p != nil and dfs != nil do + childs = + Enum.map(dfs, fn {name, child_member} -> + empty_metadata = %{definitions: nil, full_decoded: child_member, modules: [], parent: nil} + + # case create_moduledata_structs(empty_metadata, {name, child_member}) do + # %ModuleData{} = submodule -> submodule + # other -> raise "unexpected" + # end + updated_child_member_data = Map.put(child_member, "$id", name) + + case create_moduledata_structs(empty_metadata, updated_child_member_data) do + %ModuleData{} = submodule -> submodule + other -> raise "unexpected" + end + end) + + Enum.reduce(childs, metadata.modules, fn %ModuleData{} = child, acc -> + updated_child = %{child | module_name: "#{p.module_name}.#{child.module_name}"} + [updated_child | acc] + end) + end + + defp create_moduledata_structs( + %{parent: nil, definitions: nil} = _metadata, + %{"properties" => properties, "$id" => id} + ) + when id != nil do + module_name = String.trim_trailing(id, ".json") + %ModuleData{module_name: module_name, fields: properties} + end + + # ############################################################# # + # Creates files based on [{filename, filecontents}, ...] # + # ############################################################# # + + defp write_files([]), do: :ok + + defp write_files([{filename, filecontent} | rest]) do + cleaned_filename = String.replace(filename, "/", "_") + path = Path.join([@lib_dir, "generated", cleaned_filename]) + File.write!(path, filecontent) + write_files(rest) + end +end diff --git a/messages/elixir/lib/cucumber_messages/writer.ex b/messages/elixir/lib/cucumber_messages/writer.ex index 615923f481..8497bcde4f 100644 --- a/messages/elixir/lib/cucumber_messages/writer.ex +++ b/messages/elixir/lib/cucumber_messages/writer.ex @@ -1,124 +1,7 @@ defmodule CucumberMessages.Writer do - @moduledoc false - # This is a temporary writer up until Protox supports json encoding - alias CucumberMessages.Envelope - alias CucumberMessages.Location - alias CucumberMessages.Pickle.PickleStep - alias CucumberMessages.GherkinDocument.Feature.FeatureChild - alias CucumberMessages.PickleStepArgument.{PickleDocString, PickleTable} - - defp unstruct(%Location{column: 0} = map, acc) do - map |> Map.from_struct() |> Map.delete(:column) |> unstruct(acc) - end - - defp unstruct(%{__struct__: _} = map, acc) when is_map(map) do - map |> Map.from_struct() |> unstruct(acc) - end - - defp unstruct(%{__uf__: _} = map, acc) when is_map(map) do - map |> Map.delete(:__uf__) |> unstruct(acc) - end - - defp unstruct(map, acc) when is_map(map) do - Enum.reduce(map, acc, fn - :ignore, acc -> - acc - - {_k, nil}, acc -> - acc - - {_k, ""}, acc -> - acc - - {_k, :ignore}, acc -> - acc - - {_k, []}, acc -> - acc - - {_k, {new_key, v}}, acc when is_map(v) or is_list(v) or new_key == :uri -> - Map.put(acc, lower_camelcase(new_key), unstruct(v, %{})) - - {k, v}, acc when is_map(v) or is_list(v) -> - Map.put(acc, lower_camelcase(k), unstruct(v, %{})) - - {k, data}, acc -> - Map.put(acc, lower_camelcase(k), unstruct(data, %{})) - end) - end - - defp unstruct([], %{}) do - :ignore - end - - defp unstruct(list, acc) when is_list(list) do - list - |> Enum.map(fn - %FeatureChild{} = el -> - el.value - - %PickleStep{argument: %PickleTable{}} = el -> - Map.put(el, :argument, %{dataTable: el.argument}) |> Map.delete(:__struct__) - - %PickleStep{argument: %PickleDocString{}} = el -> - Map.put(el, :argument, %{docString: el.argument}) |> Map.delete(:__struct__) - - other_el -> - other_el - end) - |> Enum.reduce(acc, fn - {_new_key, nil}, acc -> - acc - - {new_key, value}, acc when is_map(acc) -> - # Map.put(acc, lower_camelcase(new_key), unstruct(value, %{})) - [Map.put(acc, lower_camelcase(new_key), unstruct(value, %{}))] - - {new_key, value}, acc when is_list(acc) -> - unstructed = unstruct(value, %{}) - - case unstructed do - :ignore -> acc - _ -> acc ++ [Map.put(%{}, lower_camelcase(new_key), unstructed)] - end - - map, acc when is_map(acc) and acc == %{} -> - unstructed = unstruct(map, %{}) - - case unstructed do - :ignore -> acc - _ -> [unstruct(map, %{})] - end - - map, acc -> - unstructed = unstruct(map, %{}) - - case unstructed do - :ignore -> acc - _ -> acc ++ [unstruct(map, %{})] - end - end) - end - - defp unstruct({k, v}, acc) when not is_tuple(v), - do: Map.put(acc, lower_camelcase(k), unstruct(v, %{})) - - defp unstruct(just_data, _acc) when not is_tuple(just_data), do: just_data def envelope_to_ndjson!(%Envelope{} = message) do - # This is sort of a sanity check to see whether the constructed message is - # proto compliant - # As soon as Protox supports json encoding, this is no longer necessary - message |> Protox.Encode.encode!() - - unstruct(message, %{}) - end - - defp lower_camelcase(atom) when is_atom(atom), do: atom |> Atom.to_string() |> lower_camelcase() - - defp lower_camelcase(string) when is_binary(string) do - {to_be_downcased, camelcased} = string |> Macro.camelize() |> String.split_at(1) - String.downcase(to_be_downcased) <> camelcased + Jason.encode!(message) end end diff --git a/messages/elixir/mix.exs b/messages/elixir/mix.exs index ea6fb4a631..5eb5a5eee6 100644 --- a/messages/elixir/mix.exs +++ b/messages/elixir/mix.exs @@ -29,7 +29,10 @@ defmodule CucumberMessages.MixProject do [ {:protox, "~> 1.4.0"}, {:jason, "~> 1.2"}, - {:ex_doc, "~> 0.24", only: :dev, runtime: false} + {:ex_doc, "~> 0.24", only: :dev, runtime: false}, + # {:ex_json_schema, "~> 0.9.1"}, + {:json_xema, "~> 0.3"}, + {:tesla, "~> 1.4"} ] end diff --git a/messages/elixir/mix.lock b/messages/elixir/mix.lock index 1cd90f55a0..02e295e130 100644 --- a/messages/elixir/mix.lock +++ b/messages/elixir/mix.lock @@ -1,9 +1,17 @@ %{ - "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, - "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"}, + "conv_case": {:hex, :conv_case, "0.2.2", "5a98b74ab8f7ddbad670e5c7bb39ff280e60699aa3b25c7062ceccf48137433c", [:mix], [], "hexpm", "561c550ab6d55b2a4d4c14449e58c9957798613eb26ea182e14a962965377bca"}, + "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.19", "de0d033d5ff9fc396a24eadc2fcf2afa3d120841eb3f1004d138cbf9273210e8", [:mix], [], "hexpm", "527ab6630b5c75c3a3960b75844c314ec305c76d9899bb30f71cb85952a9dc45"}, + "ex_doc": {:hex, :ex_doc, "0.28.0", "7eaf526dd8c80ae8c04d52ac8801594426ae322b52a6156cd038f30bafa8226f", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e55cdadf69a5d1f4cfd8477122ebac5e1fadd433a8c1022dafc5025e48db0131"}, + "ex_json_schema": {:hex, :ex_json_schema, "0.9.1", "1de550a267198aa833f4ad043b97241f2b0a3671bb5869581efef0f165b58694", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "7041222de29d33308cef68ec81da9025d141951197bd9bb6e49dc945d195cd69"}, "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, - "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, - "protox": {:hex, :protox, "1.3.1", "49d65092f83dbe73098a79d8b091e38035ba929fde3d2b111cd16f0f1af9a78d", [:mix], [], "hexpm", "a7458c24f7e2f6295688b3f0113525a8d0c0487334c063e2e7b2d7da30521b86"}, + "json_xema": {:hex, :json_xema, "0.6.0", "e76a0138030b13369151691b1ff0f6f3eabc9926f1e734356c0305302a5b7a65", [:mix], [{:conv_case, "~> 0.2", [hex: :conv_case, repo: "hexpm", optional: false]}, {:xema, "~> 0.13", [hex: :xema, repo: "hexpm", optional: false]}], "hexpm", "7b80b3196f8bdbe4a09199a26a448a00a9ac01c86786dd3817688b2b6334f0c7"}, + "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.2", "b99ca56bbce410e9d5ee4f9155a212e942e224e259c7ebbf8f2c86ac21d4fa3c", [:mix], [], "hexpm", "98d51bd64d5f6a2a9c6bb7586ee8129e27dfaab1140b5a4753f24dac0ba27d2f"}, + "protox": {:hex, :protox, "1.4.0", "2fc940fd8b10c07b935cff4a447b0b57b45d0cb747a9c66df3757e0850d53a82", [:mix], [], "hexpm", "871f3038939c947159fc00e3b79127ea57c896204448bb5517fd666a4cca5313"}, + "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"}, + "xema": {:hex, :xema, "0.15.0", "747c83ccdd666b3b6b8f8cdb5834c976bb361beecc8eea6a9c10fb1dd40d5f07", [:mix], [{:conv_case, "~> 0.2.2", [hex: :conv_case, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "7aeb7a8206da128dce30a57b72153752172487cbf4b38ce54aad47602ca1a439"}, } diff --git a/messages/elixir/priv/json_schemas/.gitignore b/messages/elixir/priv/json_schemas/.gitignore new file mode 100644 index 0000000000..24d442baf1 --- /dev/null +++ b/messages/elixir/priv/json_schemas/.gitignore @@ -0,0 +1,2 @@ +/*.json +/*.sh \ No newline at end of file From 4173fdcfbaa52a0257b641043c123104f1060423 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Thu, 14 Apr 2022 15:23:40 +0200 Subject: [PATCH 02/10] [messages - elixir] remove unused dependencies in --- messages/elixir/mix.exs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/messages/elixir/mix.exs b/messages/elixir/mix.exs index 5eb5a5eee6..0a04d191b9 100644 --- a/messages/elixir/mix.exs +++ b/messages/elixir/mix.exs @@ -27,12 +27,8 @@ defmodule CucumberMessages.MixProject do defp deps do [ - {:protox, "~> 1.4.0"}, {:jason, "~> 1.2"}, - {:ex_doc, "~> 0.24", only: :dev, runtime: false}, - # {:ex_json_schema, "~> 0.9.1"}, - {:json_xema, "~> 0.3"}, - {:tesla, "~> 1.4"} + {:ex_doc, "~> 0.24", only: :dev, runtime: false} ] end From 080b499fd2d7a395bcec43a062dcdcff6cb0f991 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Thu, 14 Apr 2022 15:44:41 +0200 Subject: [PATCH 03/10] [messages - elixir] remove unnecessary compile time struct dependency. Just forward to default json encoder --- messages/elixir/lib/cucumber_messages/writer.ex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/messages/elixir/lib/cucumber_messages/writer.ex b/messages/elixir/lib/cucumber_messages/writer.ex index 8497bcde4f..1433ef4d65 100644 --- a/messages/elixir/lib/cucumber_messages/writer.ex +++ b/messages/elixir/lib/cucumber_messages/writer.ex @@ -1,7 +1,5 @@ defmodule CucumberMessages.Writer do - alias CucumberMessages.Envelope - - def envelope_to_ndjson!(%Envelope{} = message) do + def envelope_to_ndjson!(message) do Jason.encode!(message) end end From 1c57e0033f80b1009227beaa54364e73ca672aac Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Fri, 13 May 2022 15:44:44 +0200 Subject: [PATCH 04/10] [messages-elixir + gherkin-elixir] resolve compile-time issues with new messages. Still runtime issues considering some struct values are by default nil instead of empty list --- gherkin/elixir/lib/gherkin.ex | 14 ++--- .../lib/gherkin/ast_builder/ast_builder.ex | 41 +++++++------- .../pickle_compiler/pickle_compiler.ex | 55 ++++++++++--------- gherkin/elixir/mix.lock | 10 ++-- .../cucumber_gherkin_bad_testdata_test.exs | 7 ++- messages/elixir/lib/cucumber_message.ex | 1 - .../elixir/lib/cucumber_messages/writer.ex | 19 ++++++- messages/elixir/mix.exs | 2 +- 8 files changed, 88 insertions(+), 61 deletions(-) diff --git a/gherkin/elixir/lib/gherkin.ex b/gherkin/elixir/lib/gherkin.ex index d8a83b84f1..fc4d7a8582 100644 --- a/gherkin/elixir/lib/gherkin.ex +++ b/gherkin/elixir/lib/gherkin.ex @@ -81,7 +81,7 @@ defmodule CucumberGherkin do {:ok, binary} -> hardcoded_mtype = "text/x.cucumber.gherkin+plain" source_message = %Source{data: binary, uri: path, media_type: hardcoded_mtype} - source_envelope = %Envelope{message: {:source, source_message}} + source_envelope = %Envelope{source: source_message} {:ok, source_envelope} {:error, message} -> @@ -89,7 +89,7 @@ defmodule CucumberGherkin do end end - defp parse_messages(%Envelope{message: {:source, %Source{} = s}} = envelope, opts) do + defp parse_messages(%Envelope{source: %Source{} = s} = envelope, opts) do %{messages: [], parsable?: true, source: s, ast_builder: nil} |> add_source_envelope(envelope, opts) |> add_gherkin_doc_envelope(opts) @@ -119,7 +119,7 @@ defmodule CucumberGherkin do parsed_meta <- parse_and_update_func.(), {:only_ast, false, _} <- {:only_ast, no_ast?, parsed_meta}, %{parsable?: true} <- parsed_meta do - new_msg = put_msg_envelope(:gherkin_document, parsed_meta.ast_builder.gherkin_doc) + new_msg = %Envelope{gherkin_document: parsed_meta.ast_builder.gherkin_doc} prepend_msg_to_meta(parsed_meta, new_msg) else {:skip?, true} -> meta @@ -135,9 +135,9 @@ defmodule CucumberGherkin do Enum.map(errors, fn error -> message = CucumberGherkin.ParserException.get_message(error) location = CucumberGherkin.ParserException.get_location(error) - source_ref = %CucumberMessages.SourceReference{location: location, reference: {:uri, uri}} + source_ref = %CucumberMessages.SourceReference{location: location, uri: uri} to_be_wrapped = %CucumberMessages.ParseError{message: message, source: source_ref} - put_msg_envelope(:parse_error, to_be_wrapped) + %Envelope{parse_error: to_be_wrapped} end) {:error, result} @@ -151,8 +151,6 @@ defmodule CucumberGherkin do defp update_meta({:error, messages}, %{messages: m} = meta, :ast_builder), do: %{meta | parsable?: false, messages: Enum.reduce(messages, m, &[&1 | &2])} - defp put_msg_envelope(type, m), do: %Envelope{message: {type, m}} - defp prepend_msg_to_meta(%{messages: m} = meta, new), do: %{meta | messages: [new | m]} defp add_pickles_envelopes(%{ast_builder: builder, parsable?: true} = meta, opts) do @@ -163,7 +161,7 @@ defmodule CucumberGherkin do false -> messages = CucumberGherkin.PickleCompiler.compile(builder, meta.source.uri) - |> Enum.map(&put_msg_envelope(:pickle, &1)) + |> Enum.map(fn pickle -> %Envelope{pickle: pickle} end) %{meta | messages: List.flatten([messages | meta.messages])} end diff --git a/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex b/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex index 0cec7566e4..650dd3baa8 100644 --- a/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex +++ b/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex @@ -2,19 +2,19 @@ defmodule CucumberGherkin.AstBuilder do @moduledoc false alias CucumberGherkin.{ParserContext, AstNode, Token, AstBuilderError, ParserException} alias CucumberMessages.GherkinDocument.Comment, as: CommentMessage - alias CucumberMessages.GherkinDocument.Feature.Tag, as: MessageTag - alias CucumberMessages.GherkinDocument.Feature.Scenario, as: MessageScenario - alias CucumberMessages.GherkinDocument.Feature.Step, as: StepMessage - alias CucumberMessages.GherkinDocument.Feature.Step.DataTable, as: DataTableMessage - alias CucumberMessages.GherkinDocument.Feature.TableRow, as: TableRowMessage - alias CucumberMessages.GherkinDocument.Feature.TableRow.TableCell, as: TableCellMessage + alias CucumberMessages.GherkinDocument.Tag, as: MessageTag + alias CucumberMessages.GherkinDocument.Scenario, as: MessageScenario + alias CucumberMessages.GherkinDocument.Step, as: StepMessage + alias CucumberMessages.GherkinDocument.DataTable, as: DataTableMessage + alias CucumberMessages.GherkinDocument.TableRow, as: TableRowMessage + alias CucumberMessages.GherkinDocument.TableCell, as: TableCellMessage alias CucumberMessages.GherkinDocument.Feature, as: FeatureMessage - alias CucumberMessages.GherkinDocument.Feature.FeatureChild, as: FeatureChildMessage + alias CucumberMessages.GherkinDocument.FeatureChild, as: FeatureChildMessage alias CucumberMessages.GherkinDocument, as: GherkinDocumentMessage - alias CucumberMessages.GherkinDocument.Feature.Step.DocString, as: DocStringMessage - alias CucumberMessages.GherkinDocument.Feature.Background, as: BackgroundMessage - alias CucumberMessages.GherkinDocument.Feature.Scenario.Examples, as: ExamplesMessage - alias CucumberMessages.GherkinDocument.Feature.FeatureChild.Rule, as: RuleMessage + alias CucumberMessages.GherkinDocument.DocString, as: DocStringMessage + alias CucumberMessages.GherkinDocument.Background, as: BackgroundMessage + alias CucumberMessages.GherkinDocument.Examples, as: ExamplesMessage + alias CucumberMessages.GherkinDocument.Rule, as: RuleMessage @me __MODULE__ @@ -281,9 +281,12 @@ defmodule CucumberGherkin.AstBuilder do |> add_scen_def_children_to(scenarios) |> tuplize(updated_context) else - {:header?, _} -> nil - {:rule_line?, _} -> nil - |> tuplize(context) + {:header?, _} -> + nil + + {:rule_line?, _} -> + nil + |> tuplize(context) end end @@ -393,15 +396,15 @@ defmodule CucumberGherkin.AstBuilder do defp add_mediatype_to(%DocStringMessage{} = m, d), do: %{m | media_type: d} defp add_datatable_to(%StepMessage{} = m, nil), do: m - defp add_datatable_to(%StepMessage{} = m, d), do: %{m | argument: {:data_table, d}} + defp add_datatable_to(%StepMessage{} = m, d), do: %{m | data_table: d} defp add_docstring_to(%StepMessage{} = m, nil), do: m - defp add_docstring_to(%StepMessage{} = m, d), do: %{m | argument: {:doc_string, d}} + defp add_docstring_to(%StepMessage{} = m, d), do: %{m | doc_string: d} defp add_background_to(m, nil), do: m defp add_background_to(%{__struct__: t} = m, d) when t in [FeatureMessage, RuleMessage] do - child = %FeatureChildMessage{value: {:background, d}} + child = %FeatureChildMessage{background: d} %{m | children: m.children ++ [child]} end @@ -409,7 +412,7 @@ defmodule CucumberGherkin.AstBuilder do when t in [FeatureMessage, RuleMessage] do scenario_definition_items |> Enum.reduce(m, fn scenario_def, feature_message_acc -> - child = %FeatureChildMessage{value: {:scenario, scenario_def}} + child = %FeatureChildMessage{scenario: scenario_def} %{feature_message_acc | children: feature_message_acc.children ++ [child]} end) end @@ -417,7 +420,7 @@ defmodule CucumberGherkin.AstBuilder do defp add_rule_children_to(%FeatureMessage{} = m, rule_items) do rule_items |> Enum.reduce(m, fn rule, feature_message_acc -> - child = %FeatureChildMessage{value: {:rule, rule}} + child = %FeatureChildMessage{rule: rule} %{feature_message_acc | children: feature_message_acc.children ++ [child]} end) end diff --git a/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex b/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex index 73f0519b00..934b00ab34 100644 --- a/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex +++ b/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex @@ -3,23 +3,26 @@ defmodule CucumberGherkin.PickleCompiler do defstruct id_gen: nil, pickles: [], language: nil, uri: nil alias CucumberMessages.GherkinDocument.Feature, as: FeatureMessage - alias CucumberMessages.GherkinDocument.Feature.Scenario, as: ScenarioMessage - alias CucumberMessages.GherkinDocument.Feature.Step, as: StepMessage - alias CucumberMessages.GherkinDocument.Feature.TableRow, as: TableRowMessage + alias CucumberMessages.GherkinDocument.Scenario, as: ScenarioMessage + alias CucumberMessages.GherkinDocument.Step, as: StepMessage + alias CucumberMessages.GherkinDocument.TableRow, as: TableRowMessage alias CucumberMessages.Pickle, as: PickleMessage alias CucumberMessages.Pickle.PickleStep, as: PickleStepMessage alias CucumberMessages.Pickle.PickleTag, as: PickleTagMessage - alias CucumberMessages.GherkinDocument.Feature.Tag, as: TagMessage - alias CucumberMessages.GherkinDocument.Feature.FeatureChild, as: FeatureChildMessage - alias CucumberMessages.GherkinDocument.Feature.FeatureChild.Rule, as: RuleMessage - alias CucumberMessages.GherkinDocument.Feature.Scenario.Examples, as: ExampleMessage - alias CucumberMessages.PickleStepArgument.PickleTable, as: PickleTableMessage + alias CucumberMessages.GherkinDocument.Tag, as: TagMessage + alias CucumberMessages.GherkinDocument.FeatureChild, as: FeatureChildMessage + alias CucumberMessages.GherkinDocument.Rule, as: RuleMessage + alias CucumberMessages.GherkinDocument.Examples, as: ExampleMessage + alias CucumberMessages.Pickle.PickleTable, as: PickleTableMessage - alias CucumberMessages.PickleStepArgument.PickleTable.PickleTableRow.PickleTableCell, + alias CucumberMessages.Pickle.PickleTableCell, as: PickleTableCellMessage - alias CucumberMessages.PickleStepArgument.PickleTable.PickleTableRow, as: PickleTableRowMessage - alias CucumberMessages.GherkinDocument.Feature.Step.DataTable, as: DataTableMessage + alias CucumberMessages.Pickle.PickleTableRow, as: PickleTableRowMessage + alias CucumberMessages.GherkinDocument.DataTable, as: DataTableMessage + + alias CucumberMessages.Pickle.PickleDocString, as: PickleDocStringMessage + alias CucumberMessages.GherkinDocument.DocString, as: DocStringMessage @me __MODULE__ @@ -62,10 +65,10 @@ defmodule CucumberGherkin.PickleCompiler do rule_tags = meta_info.feature_tags ++ r.tags Enum.reduce(r.children, resetted_meta_info, fn - %FeatureChildMessage{value: {:background, bg}}, m_acc -> + %FeatureChildMessage{background: bg}, m_acc -> %{m_acc | rule_backgr_steps: m_acc.rule_backgr_steps ++ bg.steps} - %FeatureChildMessage{value: {:scenario, s}}, m_acc -> + %FeatureChildMessage{scenario: s}, m_acc -> %{m_acc | feature_tags: rule_tags} |> compile_scenario(s, :rule_backgr_steps) end) end @@ -213,9 +216,6 @@ defmodule CucumberGherkin.PickleCompiler do %PickleTableMessage{rows: table_row_messages} end - alias CucumberMessages.PickleStepArgument.PickleDocString, as: PickleDocStringMessage - alias CucumberMessages.GherkinDocument.Feature.Step.DocString, as: DocStringMessage - defp pickle_doc_string_creator(%DocStringMessage{} = d, variable_cells, value_cells) do content = interpolate(d.content, variable_cells, value_cells) @@ -237,32 +237,37 @@ defmodule CucumberGherkin.PickleCompiler do defp add_ast_node_id(%PickleStepMessage{ast_node_ids: ids} = m, %TableRowMessage{} = row), do: %{m | ast_node_ids: ids ++ [row.id]} - defp add_datatable(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m + # TODO: see if this breaks stuff + # defp add_datatable(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m - defp add_datatable(%PickleStepMessage{} = m, %StepMessage{argument: {:doc_string, _}}, _, _), + defp add_datatable(%PickleStepMessage{} = m, %StepMessage{doc_string: ds}, _, _) when ds != nil, do: m defp add_datatable( %PickleStepMessage{} = m, - %StepMessage{argument: {:data_table, d}}, + %StepMessage{data_table: d}, variable_cells, value_cells - ) do + ) + when d != nil do result = pickle_data_table_creator(d, variable_cells, value_cells) %{m | argument: result} end - defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m + # TODO: see if this breaks stuff + # defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m - defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{argument: {:data_table, _}}, _, _), - do: m + defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{data_table: dt}, _, _) + when dt != nil, + do: m defp add_doc_string( %PickleStepMessage{} = m, - %StepMessage{argument: {:doc_string, d}}, + %StepMessage{doc_string: d}, variable_cells, value_cells - ) do + ) + when d != nil do result = pickle_doc_string_creator(d, variable_cells, value_cells) %{m | argument: result} end diff --git a/gherkin/elixir/mix.lock b/gherkin/elixir/mix.lock index b0544b434c..bd311f4d38 100644 --- a/gherkin/elixir/mix.lock +++ b/gherkin/elixir/mix.lock @@ -1,13 +1,13 @@ %{ "cucumber_messages": {:hex, :cucumber_messages, "15.0.0", "0c873193e55192d6f7c6fa58f311151d746ec2c8378adba384d3807a1a4c9a44", [:make, :mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:protox, "~> 1.3.0", [hex: :protox, repo: "hexpm", optional: false]}], "hexpm", "c26d123328661d8ec92333770bb017375497d16ca1d5913c07184645f5f27e24"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.19", "de0d033d5ff9fc396a24eadc2fcf2afa3d120841eb3f1004d138cbf9273210e8", [:mix], [], "hexpm", "527ab6630b5c75c3a3960b75844c314ec305c76d9899bb30f71cb85952a9dc45"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, - "ex_doc": {:hex, :ex_doc, "0.28.0", "7eaf526dd8c80ae8c04d52ac8801594426ae322b52a6156cd038f30bafa8226f", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e55cdadf69a5d1f4cfd8477122ebac5e1fadd433a8c1022dafc5025e48db0131"}, + "ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"}, "jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"}, - "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, + "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "protox": {:hex, :protox, "1.6.7", "2805eb14885a2d9efa6bf1fb4170ca6c950e56f7f42bd236d284bd09538e858f", [:mix], [{:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "02f3fcb9e94d5de3b2b880847b7d4cf57fa8553e039b715db17186d67add6cca"}, } diff --git a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs index a80cb94017..a245dc095d 100644 --- a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs +++ b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs @@ -11,11 +11,16 @@ defmodule CucumberGherkinBadTestdataTest do @tag :bad test "BAD: compare all bad testdata" do opts = [:no_source, :no_pickles, :predictable_ids] + files = @files + require IEx results = Enum.map(@files, fn path -> correct_output = File.read!(path <> ".errors.ndjson") - result = CucumberGherkin.parse_path(path, opts) |> CucumberGherkin.print_messages(:ndjson) + IEx.pry() + parsed = CucumberGherkin.parse_path(path, opts) + IEx.pry() + result = parsed |> CucumberGherkin.print_messages(:ndjson) {path, correct_output == result} end) diff --git a/messages/elixir/lib/cucumber_message.ex b/messages/elixir/lib/cucumber_message.ex index 4d1573cf4a..60bff605ba 100644 --- a/messages/elixir/lib/cucumber_message.ex +++ b/messages/elixir/lib/cucumber_message.ex @@ -10,7 +10,6 @@ defmodule CucumberMessages do """ def convert_envelopes_to(envelopes, :ndjson) do Enum.map(envelopes, &CucumberMessages.Writer.envelope_to_ndjson!/1) - |> Enum.map(&Jason.encode!(&1)) |> Enum.join("\n") |> case do "" -> "" diff --git a/messages/elixir/lib/cucumber_messages/writer.ex b/messages/elixir/lib/cucumber_messages/writer.ex index 1433ef4d65..2b720fb43d 100644 --- a/messages/elixir/lib/cucumber_messages/writer.ex +++ b/messages/elixir/lib/cucumber_messages/writer.ex @@ -1,5 +1,22 @@ defmodule CucumberMessages.Writer do def envelope_to_ndjson!(message) do - Jason.encode!(message) + message + |> destructify() + |> Jason.encode!() + end + + def destructify(%{} = struct) do + struct + |> Map.from_struct() + |> Enum.map(fn {k, v} -> + possible_new_value = + case is_struct(v) do + true -> destructify(v) + false -> v + end + + {k, possible_new_value} + end) + |> Enum.into(%{}) end end diff --git a/messages/elixir/mix.exs b/messages/elixir/mix.exs index d04d6e616f..7b72366792 100644 --- a/messages/elixir/mix.exs +++ b/messages/elixir/mix.exs @@ -33,7 +33,7 @@ defmodule CucumberMessages.MixProject do end defp description() do - "Elixir implementation of the cucumber messages protobuf schema" + "Elixir implementation of the cucumber messages json schemas" end defp package() do From 6864a7c83b60d9d8f56be70e19fbace8fac9b2a9 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Thu, 19 May 2022 14:19:32 +0200 Subject: [PATCH 05/10] adjusted gherkin parser so that tests pass --- .../lib/gherkin/ast_builder/ast_builder.ex | 28 ++++++++++ .../lib/gherkin/errors/unexpected_eof.ex | 2 +- .../pickle_compiler/pickle_compiler.ex | 52 +++++++++++++------ gherkin/elixir/mix.lock | 3 -- .../cucumber_gherkin_bad_testdata_test.exs | 14 ++++- .../mix/tasks/generate_json_structs.ex | 9 +++- .../elixir/lib/cucumber_messages/writer.ex | 46 ++++++++++++---- 7 files changed, 122 insertions(+), 32 deletions(-) diff --git a/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex b/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex index 650dd3baa8..6347bddd11 100644 --- a/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex +++ b/gherkin/elixir/lib/gherkin/ast_builder/ast_builder.ex @@ -58,7 +58,15 @@ defmodule CucumberGherkin.AstBuilder do Comment -> loc = Token.get_location(token) comment_message = %CommentMessage{location: loc, text: token.line.content} + # TODO: Normally your struct should default to an empty list instead of nil. + # Due to the limited converter in the messages library, we make a case clause and "catch" this unexpected `nil` value. + # updated_comments = + # case builder.gherkin_doc.comments do + # nil -> [comment_message] + # list -> list ++ [comment_message] + # end updated_comments = builder.gherkin_doc.comments ++ [comment_message] + updated_gherkin_doc = %{builder.gherkin_doc | comments: updated_comments} updated_builder = %{builder | gherkin_doc: updated_gherkin_doc} %{context | ast_builder: updated_builder} @@ -405,6 +413,13 @@ defmodule CucumberGherkin.AstBuilder do defp add_background_to(%{__struct__: t} = m, d) when t in [FeatureMessage, RuleMessage] do child = %FeatureChildMessage{background: d} + # TODO: Normally your struct should default to an empty list instead of nil. + # Due to the limited converter in the messages library, we make a case clause and "catch" this unexpected `nil` value. + # case m.children do + # nil -> %{m | children: [child]} + # list -> %{m | children: list ++ [child]} + # end + %{m | children: m.children ++ [child]} end @@ -413,6 +428,12 @@ defmodule CucumberGherkin.AstBuilder do scenario_definition_items |> Enum.reduce(m, fn scenario_def, feature_message_acc -> child = %FeatureChildMessage{scenario: scenario_def} + # TODO: Normally your struct should default to an empty list instead of nil. + # Due to the limited converter in the messages library, we make a case clause and "catch" this unexpected `nil` value. + # case feature_message_acc.children do + # nil -> %{feature_message_acc | children: [child]} + # list -> %{feature_message_acc | children: list ++ [child]} + # end %{feature_message_acc | children: feature_message_acc.children ++ [child]} end) end @@ -421,6 +442,13 @@ defmodule CucumberGherkin.AstBuilder do rule_items |> Enum.reduce(m, fn rule, feature_message_acc -> child = %FeatureChildMessage{rule: rule} + + # TODO: Normally your struct should default to an empty list instead of nil. + # Due to the limited converter in the messages library, we make a case clause and "catch" this unexpected `nil` value. + # case feature_message_acc.children do + # nil -> %{feature_message_acc | children: [child]} + # list -> %{feature_message_acc | children: list ++ [child]} + # end %{feature_message_acc | children: feature_message_acc.children ++ [child]} end) end diff --git a/gherkin/elixir/lib/gherkin/errors/unexpected_eof.ex b/gherkin/elixir/lib/gherkin/errors/unexpected_eof.ex index 4e5ff6ec4a..a97b4e0a00 100644 --- a/gherkin/elixir/lib/gherkin/errors/unexpected_eof.ex +++ b/gherkin/elixir/lib/gherkin/errors/unexpected_eof.ex @@ -18,6 +18,6 @@ defmodule CucumberGherkin.UnexpectedEOFError do do: struct!(CucumberGherkin.Token, line: me.line) |> CucumberGherkin.Token.get_location() - |> Map.put(:column, 0) + |> Map.put(:column, nil) end end diff --git a/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex b/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex index 934b00ab34..5a8f5663c9 100644 --- a/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex +++ b/gherkin/elixir/lib/gherkin/pickle_compiler/pickle_compiler.ex @@ -47,16 +47,27 @@ defmodule CucumberGherkin.PickleCompiler do } Enum.reduce(f.children, meta_info, fn child, m_acc -> - case child.value do - {:background, bg} -> - %{m_acc | feature_backgr_steps: bg.steps} + cond do + child.background != nil -> + %{m_acc | feature_backgr_steps: child.background.steps} - {:rule, rule} -> - compile_rule(m_acc, rule) + child.rule != nil -> + compile_rule(m_acc, child.rule) - {:scenario, s} -> - compile_scenario(m_acc, s, :feature_backgr_steps) + child.scenario != nil -> + compile_scenario(m_acc, child.scenario, :feature_backgr_steps) end + + # case child.value do + # {:background, bg} -> + # %{m_acc | feature_backgr_steps: bg.steps} + + # {:rule, rule} -> + # compile_rule(m_acc, rule) + + # {:scenario, s} -> + # compile_scenario(m_acc, s, :feature_backgr_steps) + # end end) end @@ -65,10 +76,10 @@ defmodule CucumberGherkin.PickleCompiler do rule_tags = meta_info.feature_tags ++ r.tags Enum.reduce(r.children, resetted_meta_info, fn - %FeatureChildMessage{background: bg}, m_acc -> + %FeatureChildMessage{background: bg}, m_acc when not is_nil(bg) -> %{m_acc | rule_backgr_steps: m_acc.rule_backgr_steps ++ bg.steps} - %FeatureChildMessage{scenario: s}, m_acc -> + %FeatureChildMessage{scenario: s}, m_acc when not is_nil(s) -> %{m_acc | feature_tags: rule_tags} |> compile_scenario(s, :rule_backgr_steps) end) end @@ -221,6 +232,7 @@ defmodule CucumberGherkin.PickleCompiler do media_type = case d.media_type do + nil -> nil "" -> "" media_type -> interpolate(media_type, variable_cells, value_cells) end @@ -237,8 +249,13 @@ defmodule CucumberGherkin.PickleCompiler do defp add_ast_node_id(%PickleStepMessage{ast_node_ids: ids} = m, %TableRowMessage{} = row), do: %{m | ast_node_ids: ids ++ [row.id]} - # TODO: see if this breaks stuff - # defp add_datatable(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m + defp add_datatable( + %PickleStepMessage{} = m, + %StepMessage{doc_string: nil, data_table: nil}, + _, + _ + ), + do: m defp add_datatable(%PickleStepMessage{} = m, %StepMessage{doc_string: ds}, _, _) when ds != nil, do: m @@ -251,11 +268,16 @@ defmodule CucumberGherkin.PickleCompiler do ) when d != nil do result = pickle_data_table_creator(d, variable_cells, value_cells) - %{m | argument: result} + %{m | argument: %{data_table: result}} end - # TODO: see if this breaks stuff - # defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{argument: nil}, _, _), do: m + defp add_doc_string( + %PickleStepMessage{} = m, + %StepMessage{doc_string: nil, data_table: nil}, + _, + _ + ), + do: m defp add_doc_string(%PickleStepMessage{} = m, %StepMessage{data_table: dt}, _, _) when dt != nil, @@ -269,7 +291,7 @@ defmodule CucumberGherkin.PickleCompiler do ) when d != nil do result = pickle_doc_string_creator(d, variable_cells, value_cells) - %{m | argument: result} + %{m | argument: %{doc_string: result}} end defp get_id_and_update_compiler_acc(%@me{id_gen: gen} = compiler_acc) do diff --git a/gherkin/elixir/mix.lock b/gherkin/elixir/mix.lock index bd311f4d38..f666b8ab73 100644 --- a/gherkin/elixir/mix.lock +++ b/gherkin/elixir/mix.lock @@ -1,6 +1,4 @@ %{ - "cucumber_messages": {:hex, :cucumber_messages, "15.0.0", "0c873193e55192d6f7c6fa58f311151d746ec2c8378adba384d3807a1a4c9a44", [:make, :mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:protox, "~> 1.3.0", [hex: :protox, repo: "hexpm", optional: false]}], "hexpm", "c26d123328661d8ec92333770bb017375497d16ca1d5913c07184645f5f27e24"}, - "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"}, @@ -9,5 +7,4 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, - "protox": {:hex, :protox, "1.6.7", "2805eb14885a2d9efa6bf1fb4170ca6c950e56f7f42bd236d284bd09538e858f", [:mix], [{:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "02f3fcb9e94d5de3b2b880847b7d4cf57fa8553e039b715db17186d67add6cca"}, } diff --git a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs index a245dc095d..578486499c 100644 --- a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs +++ b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs @@ -17,10 +17,20 @@ defmodule CucumberGherkinBadTestdataTest do results = Enum.map(@files, fn path -> correct_output = File.read!(path <> ".errors.ndjson") - IEx.pry() parsed = CucumberGherkin.parse_path(path, opts) - IEx.pry() result = parsed |> CucumberGherkin.print_messages(:ndjson) + # For debugging purposes, write temporary json file so that you can compare + File.rm("temp.json") + File.rm("correct.json") + File.write!("temp.json", result) + File.write!("correct.json", correct_output) + + if correct_output != result do + IEx.pry() + end + + File.rm("temp.json") + File.rm("correct.json") {path, correct_output == result} end) diff --git a/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex b/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex index 75dd19544d..e088163aa4 100644 --- a/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex +++ b/messages/elixir/lib/cucumber_messages/mix/tasks/generate_json_structs.ex @@ -57,7 +57,12 @@ defmodule Mix.Tasks.GenerateJsonStructs do defp output_module(%ModuleData{} = moduledata, acc) do atom_fields = moduledata.fields - |> Enum.map(fn {fieldname, _ignore_details} -> ":" <> Macro.underscore(fieldname) end) + |> Enum.map(fn {fieldname, %{} = details} -> + case details["type"] do + "array" -> Macro.underscore(fieldname) <> ": []" + _ -> Macro.underscore(fieldname) <> ": nil" + end + end) |> Enum.intersperse(", ") entry = """ @@ -121,7 +126,7 @@ defmodule Mix.Tasks.GenerateJsonStructs do case create_moduledata_structs(empty_metadata, updated_child_member_data) do %ModuleData{} = submodule -> submodule - other -> raise "unexpected" + _other -> raise "unexpected" end end) diff --git a/messages/elixir/lib/cucumber_messages/writer.ex b/messages/elixir/lib/cucumber_messages/writer.ex index 2b720fb43d..b421096525 100644 --- a/messages/elixir/lib/cucumber_messages/writer.ex +++ b/messages/elixir/lib/cucumber_messages/writer.ex @@ -5,18 +5,46 @@ defmodule CucumberMessages.Writer do |> Jason.encode!() end - def destructify(%{} = struct) do + defp destructify(%{} = struct) when is_struct(struct) do struct |> Map.from_struct() - |> Enum.map(fn {k, v} -> - possible_new_value = - case is_struct(v) do - true -> destructify(v) - false -> v + |> Enum.reduce(%{}, fn {k, v}, acc -> update_value(acc, k, v) end) + end + + defp update_value(acc, _, v) when is_nil(v), do: acc + defp update_value(acc, k, v) when is_struct(v), do: update_value(acc, k, destructify(v)) + + defp update_value(acc, k, v) when is_list(v) do + new_values = + Enum.map(v, fn possible_struct -> + case is_struct(possible_struct) do + true -> destructify(possible_struct) + false -> possible_struct end + end) + + Map.put(acc, lower_camelize(k), new_values) + end + + defp update_value(acc, k, v) when is_map(v) do + new_values = + Enum.map(v, fn {subkey, possible_struct} -> + case is_struct(possible_struct) do + true -> {lower_camelize(subkey), destructify(possible_struct)} + false -> {lower_camelize(subkey), possible_struct} + end + end) + |> Enum.into(%{}) + + Map.put(acc, lower_camelize(k), new_values) + end + + defp update_value(acc, k, v), do: Map.put(acc, lower_camelize(k), v) + + defp lower_camelize(atom) when is_atom(atom), do: atom |> Atom.to_string() |> lower_camelize() - {k, possible_new_value} - end) - |> Enum.into(%{}) + defp lower_camelize(string) when is_binary(string) do + {first_letter, rest} = string |> Macro.camelize() |> String.split_at(1) + "#{String.downcase(first_letter)}#{rest}" end end From bf9e23f711da30939e3b9e65a9d0a51dd0e3d5e2 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Fri, 20 May 2022 13:08:27 +0200 Subject: [PATCH 06/10] [elixir] Makefile + circleci conf attempt --- .circleci/config.yml | 26 +++++++++++++------------- messages/elixir/Makefile | 17 +++++++++-------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 48b49e25c9..f02a085bd5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -556,16 +556,16 @@ jobs: paths: - messages/elixir/lib/cucumber_messages/generated/ - # gherkin-elixir: - # executor: docker-cucumber-build - # steps: - # - attach_workspace: - # at: "~/cucumber" - # - run: - # name: gherkin/elixir - # command: | - # cd gherkin/elixir - # make + gherkin-elixir: + executor: docker-cucumber-build + steps: + - attach_workspace: + at: "~/cucumber" + - run: + name: gherkin/elixir + command: | + cd gherkin/elixir + make ### PHP @@ -768,9 +768,9 @@ workflows: requires: - prepare-parallel - # - gherkin-elixir: - # requires: - # - messages-elixir + - gherkin-elixir: + requires: + - messages-elixir ### PHP diff --git a/messages/elixir/Makefile b/messages/elixir/Makefile index b1de9b46a7..e402e36765 100644 --- a/messages/elixir/Makefile +++ b/messages/elixir/Makefile @@ -4,7 +4,8 @@ clean: rm -rf _build deps .deps .tested rm -rf lib/cucumber_messages/generated/* -.deps: setup_mix_and_get_dependencies update_proto_file compile_messages revert_proto_file +# .deps: setup_mix_and_get_dependencies update_proto_file compile_messages revert_proto_file +.deps: setup_mix_and_get_dependencies compile_messages touch .deps setup_mix_and_get_dependencies: @@ -12,14 +13,14 @@ setup_mix_and_get_dependencies: mix deps.get .PHONY: setup_mix_and_get_dependencies -update_proto_file: messages.proto - mv $< $<.bak - cat $<.bak | sed "s/package io.cucumber.messages/package cucumber_messages/" > $< +# update_proto_file: messages.proto +# mv $< $<.bak +# cat $<.bak | sed "s/package io.cucumber.messages/package cucumber_messages/" > $< compile_messages: - MIX_ENV=prod mix protox.generate --multiple-files --output-path=lib/cucumber_messages/generated messages.proto + mix generate_json_structs .PHONY: compile_messages -revert_proto_file: messages.proto.bak - mv messages.proto.bak messages.proto -.PHONY: revert_proto_file +# revert_proto_file: messages.proto.bak +# mv messages.proto.bak messages.proto +# .PHONY: revert_proto_file From fd215576db5b1367d8e3ce7489c6cd286b544a22 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Fri, 20 May 2022 13:35:03 +0200 Subject: [PATCH 07/10] [elixir] merge + implement unsynced testdata --- gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs | 2 +- gherkin/elixir/test/cucumber_gherkin_good_testdata_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs index 578486499c..4f5dc0f399 100644 --- a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs +++ b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs @@ -4,7 +4,7 @@ defmodule CucumberGherkinBadTestdataTest do @moduletag timeout: :infinity - @files ["testdata", "bad", "*.feature"] + @files ["..", "testdata", "bad", "*.feature"] |> Path.join() |> Path.wildcard() diff --git a/gherkin/elixir/test/cucumber_gherkin_good_testdata_test.exs b/gherkin/elixir/test/cucumber_gherkin_good_testdata_test.exs index 52fd201f26..3fc9c36702 100644 --- a/gherkin/elixir/test/cucumber_gherkin_good_testdata_test.exs +++ b/gherkin/elixir/test/cucumber_gherkin_good_testdata_test.exs @@ -4,7 +4,7 @@ defmodule CucumberGherkinGoodTestdataTest do @moduletag timeout: :infinity - @files ["testdata", "good", "*.feature"] + @files ["..", "testdata", "good", "*.feature"] |> Path.join() |> Path.wildcard() From 3e922b14b9c9c2fea1fc0be115b44849df268ce6 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Fri, 20 May 2022 13:36:25 +0200 Subject: [PATCH 08/10] [elixir] remove debugging code in tests --- .../test/cucumber_gherkin_bad_testdata_test.exs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs index 4f5dc0f399..1fcc1095a3 100644 --- a/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs +++ b/gherkin/elixir/test/cucumber_gherkin_bad_testdata_test.exs @@ -19,18 +19,6 @@ defmodule CucumberGherkinBadTestdataTest do correct_output = File.read!(path <> ".errors.ndjson") parsed = CucumberGherkin.parse_path(path, opts) result = parsed |> CucumberGherkin.print_messages(:ndjson) - # For debugging purposes, write temporary json file so that you can compare - File.rm("temp.json") - File.rm("correct.json") - File.write!("temp.json", result) - File.write!("correct.json", correct_output) - - if correct_output != result do - IEx.pry() - end - - File.rm("temp.json") - File.rm("correct.json") {path, correct_output == result} end) From 60070427fe02b753b28723d5cc1379c51a818551 Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Mon, 23 May 2022 10:31:53 +0200 Subject: [PATCH 09/10] [elixir messages] manually copy json schema files (assuming that there's no longer a "synchronization" script in place) --- messages/elixir/.gitignore | 1 + messages/elixir/Makefile | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/messages/elixir/.gitignore b/messages/elixir/.gitignore index 3817bcd29a..6ea8af6095 100644 --- a/messages/elixir/.gitignore +++ b/messages/elixir/.gitignore @@ -28,5 +28,6 @@ erl_crash.dump .deps .tested +.json_schemas .compile_messages .setup_mix_and_get_dependencies diff --git a/messages/elixir/Makefile b/messages/elixir/Makefile index e402e36765..d19a593b15 100644 --- a/messages/elixir/Makefile +++ b/messages/elixir/Makefile @@ -1,13 +1,17 @@ include default.mk clean: - rm -rf _build deps .deps .tested + rm -rf _build deps .deps .tested .json_schemas priv/json_schemas/*.json rm -rf lib/cucumber_messages/generated/* # .deps: setup_mix_and_get_dependencies update_proto_file compile_messages revert_proto_file -.deps: setup_mix_and_get_dependencies compile_messages +.deps: .json_schemas setup_mix_and_get_dependencies compile_messages touch .deps +.json_schemas: + cp ../jsonschema/*.json priv/json_schemas/ + touch .json_schemas + setup_mix_and_get_dependencies: mix local.hex --force mix deps.get From c305c72b07648978c1719e70a90978e50795de7d Mon Sep 17 00:00:00 2001 From: Wannes Fransen Date: Mon, 23 May 2022 10:51:24 +0200 Subject: [PATCH 10/10] [elixir] attempt to avoid rsync conflict --- messages/elixir/.gitignore | 1 - messages/elixir/Makefile | 8 ++++---- messages/elixir/priv/json_schemas/.gitignore | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/messages/elixir/.gitignore b/messages/elixir/.gitignore index 6ea8af6095..3817bcd29a 100644 --- a/messages/elixir/.gitignore +++ b/messages/elixir/.gitignore @@ -28,6 +28,5 @@ erl_crash.dump .deps .tested -.json_schemas .compile_messages .setup_mix_and_get_dependencies diff --git a/messages/elixir/Makefile b/messages/elixir/Makefile index d19a593b15..32c1798ec0 100644 --- a/messages/elixir/Makefile +++ b/messages/elixir/Makefile @@ -1,16 +1,16 @@ include default.mk clean: - rm -rf _build deps .deps .tested .json_schemas priv/json_schemas/*.json + rm -rf _build deps .deps .tested priv/json_schemas/.copy_schema priv/json_schemas/*.json rm -rf lib/cucumber_messages/generated/* # .deps: setup_mix_and_get_dependencies update_proto_file compile_messages revert_proto_file -.deps: .json_schemas setup_mix_and_get_dependencies compile_messages +.deps: priv/json_schemas/.copy_schema setup_mix_and_get_dependencies compile_messages touch .deps -.json_schemas: +priv/json_schemas/.copy_schema: cp ../jsonschema/*.json priv/json_schemas/ - touch .json_schemas + touch priv/json_schemas/.copy_schema setup_mix_and_get_dependencies: mix local.hex --force diff --git a/messages/elixir/priv/json_schemas/.gitignore b/messages/elixir/priv/json_schemas/.gitignore index 24d442baf1..bde576d166 100644 --- a/messages/elixir/priv/json_schemas/.gitignore +++ b/messages/elixir/priv/json_schemas/.gitignore @@ -1,2 +1,3 @@ /*.json -/*.sh \ No newline at end of file +/*.sh +/*.copy_schema \ No newline at end of file