From 1d6433a42a2c2bdb378760115a77b82eb1417ffa Mon Sep 17 00:00:00 2001 From: Bastien CHAMAGNE Date: Wed, 1 Mar 2023 09:22:55 +0100 Subject: [PATCH] SC: remove semantic versionning and use an int instead for @version --- lib/archethic/contracts/contract.ex | 4 +- lib/archethic/contracts/interpreter.ex | 46 ++++++------------- .../contracts/interpreter/version0.ex | 2 +- .../contracts/interpreter/version1.ex | 6 +-- test/archethic/contracts/interpreter_test.exs | 29 +++++------- test/support/contract_factory.ex | 2 +- 6 files changed, 33 insertions(+), 56 deletions(-) diff --git a/lib/archethic/contracts/contract.ex b/lib/archethic/contracts/contract.ex index 0989a6894..6e5aea4f2 100644 --- a/lib/archethic/contracts/contract.ex +++ b/lib/archethic/contracts/contract.ex @@ -14,7 +14,7 @@ defmodule Archethic.Contracts.Contract do alias Archethic.TransactionChain.TransactionData defstruct triggers: %{}, - version: {0, 0, 1}, + version: 0, conditions: %{ transaction: %Conditions{}, inherit: %Conditions{}, @@ -32,7 +32,7 @@ defmodule Archethic.Contracts.Contract do triggers: %{ trigger_type() => Macro.t() }, - version: {integer(), integer(), integer()}, + version: integer(), conditions: %{ transaction: Conditions.t(), inherit: Conditions.t(), diff --git a/lib/archethic/contracts/interpreter.ex b/lib/archethic/contracts/interpreter.ex index 9771faf50..c74f8457c 100644 --- a/lib/archethic/contracts/interpreter.ex +++ b/lib/archethic/contracts/interpreter.ex @@ -11,7 +11,7 @@ defmodule Archethic.Contracts.Interpreter do alias Archethic.TransactionChain.Transaction - @type version() :: {integer(), integer(), integer()} + @type version() :: integer() @doc """ Dispatch through the correct interpreter. @@ -20,10 +20,10 @@ defmodule Archethic.Contracts.Interpreter do @spec parse(code :: binary()) :: {:ok, Contract.t()} | {:error, String.t()} def parse(code) when is_binary(code) do case version(code) do - {{0, 0, 1}, code_without_version} -> + {0, code_without_version} -> Version0.parse(code_without_version) - {version = {1, _, _}, code_without_version} -> + {version = 1, code_without_version} -> Version1.parse(code_without_version, version) _ -> @@ -51,34 +51,23 @@ defmodule Archethic.Contracts.Interpreter do def version(code) do regex_opts = [capture: :all_but_first] - version_attr_regex = ~r/^\s*@version\s+"(\S+)"/ + version_attr_regex = ~r/^\s*@version\s+(\d+)\s/ if Regex.match?(~r/^\s*@version/, code) do case Regex.run(version_attr_regex, code, regex_opts) do nil -> - # there is a @version but syntax is invalid (probably the quotes missing) + # there is a @version but syntax is invalid (probably the not an integer) :error - [capture] -> - case Regex.run(semver_regex(), capture, regex_opts) do - nil -> - # there is a @version but semver syntax is wrong - :error - - ["0", "0", "0"] -> - # there is a @version but it's 0.0.0 - :error - - [major, minor, patch] -> - { - {String.to_integer(major), String.to_integer(minor), String.to_integer(patch)}, - Regex.replace(version_attr_regex, code, "") - } - end + [version] -> + { + String.to_integer(version), + Regex.replace(version_attr_regex, code, "") + } end else # no @version at all - {{0, 0, 1}, code} + {0, code} end end @@ -86,11 +75,11 @@ defmodule Archethic.Contracts.Interpreter do Return true if the given conditions are valid on the given constants """ @spec valid_conditions?(version(), Conditions.t(), map()) :: bool() - def valid_conditions?({0, _, _}, conditions, constants) do + def valid_conditions?(0, conditions, constants) do Version0.valid_conditions?(conditions, constants) end - def valid_conditions?({1, _, _}, conditions, constants) do + def valid_conditions?(1, conditions, constants) do Version1.valid_conditions?(conditions, constants) end @@ -99,11 +88,11 @@ defmodule Archethic.Contracts.Interpreter do May return a new transaction or nil """ @spec execute_trigger(version(), Macro.t(), map()) :: Transaction.t() | nil - def execute_trigger({0, _, _}, ast, constants) do + def execute_trigger(0, ast, constants) do Version0.execute_trigger(ast, constants) end - def execute_trigger({1, _, _}, ast, constants) do + def execute_trigger(1, ast, constants) do Version1.execute_trigger(ast, constants) end @@ -165,9 +154,4 @@ defmodule Archethic.Contracts.Interpreter do {:ok, {:atom, atom}} end end - - # source: https://semver.org/ - defp semver_regex() do - ~r/(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/ - end end diff --git a/lib/archethic/contracts/interpreter/version0.ex b/lib/archethic/contracts/interpreter/version0.ex index 0e6d5a98c..5c4827984 100644 --- a/lib/archethic/contracts/interpreter/version0.ex +++ b/lib/archethic/contracts/interpreter/version0.ex @@ -170,7 +170,7 @@ defmodule Archethic.Contracts.Interpreter.Version0 do def parse(code) when is_binary(code) do with {:ok, ast} <- Interpreter.sanitize_code(code), {:ok, contract} <- parse_contract(ast, %Contract{}) do - {:ok, %{contract | version: {0, 0, 1}}} + {:ok, %{contract | version: 0}} else {:error, {meta, {_, info}, token}} -> {:error, Interpreter.format_error_reason({token, meta, []}, info)} diff --git a/lib/archethic/contracts/interpreter/version1.ex b/lib/archethic/contracts/interpreter/version1.ex index 71a1c9785..0f024c16a 100644 --- a/lib/archethic/contracts/interpreter/version1.ex +++ b/lib/archethic/contracts/interpreter/version1.ex @@ -9,10 +9,10 @@ defmodule Archethic.Contracts.Interpreter.Version1 do @doc """ Parse the code and return the parsed contract. """ - @spec parse(binary(), {integer(), integer(), integer()}) :: + @spec parse(binary(), integer()) :: {:ok, Contract.t()} | {:error, String.t()} - def parse(code, {1, 0, 0}) when is_binary(code) do - {:ok, %Contract{version: {1, 0, 0}}} + def parse(code, version = 1) when is_binary(code) do + {:ok, %Contract{version: version}} end def parse(_, _), do: {:error, "@version not supported"} diff --git a/test/archethic/contracts/interpreter_test.exs b/test/archethic/contracts/interpreter_test.exs index 46650c3fd..c39a9cae7 100644 --- a/test/archethic/contracts/interpreter_test.exs +++ b/test/archethic/contracts/interpreter_test.exs @@ -15,12 +15,12 @@ defmodule Archethic.Contracts.InterpreterTest do test "should return an error if version does not exist yet" do code_v0 = ~s""" - @version "0.144.233" + @version 20 #{ContractFactory.valid_version0_contract()} """ code_v1 = ~s""" - @version "1.377.610" + @version 20 #{ContractFactory.valid_version1_contract(version_attribute: false)} """ @@ -30,7 +30,7 @@ defmodule Archethic.Contracts.InterpreterTest do test "should return an error if version is invalid" do code_v0 = ~s""" - @version 12 + @version 1.5 #{ContractFactory.valid_version0_contract()} """ @@ -39,34 +39,27 @@ defmodule Archethic.Contracts.InterpreterTest do end describe "version/1" do - test "should return 0.0.1 if there is no interpreter tag" do + test "should return 0 if there is no interpreter tag" do code = ~s(some code) - assert {{0, 0, 1}, ^code} = Interpreter.version(code) + assert {0, ^code} = Interpreter.version(code) end test "should return the correct version if specified" do - assert {{0, 0, 1}, "\n my_code"} = Interpreter.version(~s(@version "0.0.1"\n my_code)) - assert {{0, 1, 0}, " \n my_code"} = Interpreter.version(~s(@version "0.1.0" \n my_code)) - assert {{0, 1, 1}, ""} = Interpreter.version(~s(@version "0.1.1")) - assert {{1, 0, 0}, _} = Interpreter.version(~s(@version "1.0.0")) - assert {{1, 0, 1}, _} = Interpreter.version(~s(@version "1.0.1")) - assert {{1, 1, 0}, _} = Interpreter.version(~s(@version "1.1.0")) - assert {{1, 1, 1}, _} = Interpreter.version(~s(@version "1.1.1")) + assert {0, "my_code"} = Interpreter.version(~s(@version 0\nmy_code)) + assert {1, "my_code"} = Interpreter.version(~s(@version 1\nmy_code)) end test "should work even if there are some whitespaces" do - assert {{0, 1, 0}, _} = Interpreter.version(~s(\n \n @version "0.1.0" \n \n)) - assert {{1, 1, 2}, _} = Interpreter.version(~s(\n \n @version "1.1.2" \n \n)) - assert {{3, 105, 0}, _} = Interpreter.version(~s(\n \n @version "3.105.0" \n \n)) + assert {0, _} = Interpreter.version(~s(\n \n @version 0 \n \n)) + assert {1, _} = Interpreter.version(~s(\n \n @version 1 \n \n)) end test "should return error if version is not formatted as expected" do assert :error = Interpreter.version(~s(@version "0")) assert :error = Interpreter.version(~s(@version "1")) - assert :error = Interpreter.version(~s(@version "0.0")) + assert :error = Interpreter.version(~s(@version 1.1)) assert :error = Interpreter.version(~s(@version "1.1")) - assert :error = Interpreter.version(~s(@version "0.0.0")) - assert :error = Interpreter.version(~s(@version 1.1.1)) + assert :error = Interpreter.version(~s(@version "1.1.1")) end end end diff --git a/test/support/contract_factory.ex b/test/support/contract_factory.ex index 4f3c58105..ca902031b 100644 --- a/test/support/contract_factory.ex +++ b/test/support/contract_factory.ex @@ -18,7 +18,7 @@ defmodule Archethic.ContractFactory do if Keyword.get(opts, :version_attribute, true) do """ - @version "1.0.0" + @version 1 #{code} """ else