From 888eeb3356842d2af4e415359e2eb460016b76b6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sat, 14 Jul 2018 13:05:18 +0200 Subject: [PATCH 01/16] Bump version to 0.1.2-dev --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 9161ea5..b228959 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule TypedStruct.MixProject do use Mix.Project - @version "0.1.1" + @version "0.1.2-dev" @repo_url "https://github.com/ejpcmac/typed_struct" def project do From 0015bde2fcd9afa5b1776df452e17ffc5c4a94c8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sat, 14 Jul 2018 13:07:09 +0200 Subject: [PATCH 02/16] Make Credo and Dialyxir dev-only dependencies --- mix.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index b228959..d47d651 100644 --- a/mix.exs +++ b/mix.exs @@ -47,8 +47,8 @@ defmodule TypedStruct.MixProject do defp deps do [ # Development and test dependencies - {:credo, "~> 0.9.3", only: [:dev, :test], runtime: false}, - {:dialyxir, ">= 0.0.0", only: [:dev, :test], runtime: false}, + {:credo, "~> 0.9.3", only: :dev, runtime: false}, + {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:excoveralls, ">= 0.0.0", only: :test, runtime: false}, {:mix_test_watch, ">= 0.0.0", only: :dev, runtime: false}, {:ex_unit_notifier, ">= 0.0.0", only: :test, runtime: false}, From 8b32fd8b7b43b169cd15f92bc20e82c9f6737043 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sat, 14 Jul 2018 13:08:11 +0200 Subject: [PATCH 03/16] =?UTF-8?q?Remove=20the=20maintainers=20field=20sinc?= =?UTF-8?q?e=20it=E2=80=99s=20deprecated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mix.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/mix.exs b/mix.exs index d47d651..392d21b 100644 --- a/mix.exs +++ b/mix.exs @@ -84,7 +84,6 @@ defmodule TypedStruct.MixProject do defp package do [ - maintainers: ["Jean-Philippe Cugnet"], licenses: ["MIT"], links: %{"GitHub" => @repo_url} ] From c2a75fd93226b135f21b48c89ec0675387fbacbc Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sat, 14 Jul 2018 13:08:45 +0200 Subject: [PATCH 04/16] Update dependencies --- mix.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mix.lock b/mix.lock index eefa49f..d07a77b 100644 --- a/mix.lock +++ b/mix.lock @@ -4,13 +4,13 @@ "credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.18.4", "4406b8891cecf1352f49975c6d554e62e4341ceb41b9338949077b0d4a97b949", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, "ex_unit_notifier": {:hex, :ex_unit_notifier, "0.1.4", "36a2dcab829f506e01bf17816590680dd1474407926d43e64c1263e627c364b8", [:mix], [], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.9.1", "14fd20fac51ab98d8e79615814cc9811888d2d7b28e85aa90ff2e30dcf3191d6", [:mix], [{:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "file_system": {:hex, :file_system, "0.2.5", "a3060f063b116daf56c044c273f65202e36f75ec42e678dc10653056d3366054", [:mix], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, + "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mix_test_watch": {:hex, :mix_test_watch, "0.6.0", "5e206ed04860555a455de2983937efd3ce79f42bd8536fc6b900cc286f5bb830", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, From 60c16985181e0967992ab74d7effe9427099cd71 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sat, 14 Jul 2018 13:17:11 +0200 Subject: [PATCH 05/16] Update the tests to handle the Elixir 1.7 Typespec API --- test/typed_struct_test.exs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/typed_struct_test.exs b/test/typed_struct_test.exs index 7b2c758..278f7b1 100644 --- a/test/typed_struct_test.exs +++ b/test/typed_struct_test.exs @@ -118,11 +118,27 @@ defmodule TypedStructTest do ## Helpers ## + @elixir_version System.version() |> Version.parse!() + @min_version Version.parse!("1.7.0-rc") + # Extracts the first type from a module. - defp extract_first_type(bytecode) do - bytecode - |> Kernel.Typespec.beam_types() - |> Keyword.get(:type) + # NOTE: We define the function differently depending on the Elixir version to + # avoid compiler warnings. + if Version.compare(@elixir_version, @min_version) == :lt do + # API for Elixir 1.6 (TODO: Remove when 1.6 compatibility is dropped.) + defp extract_first_type(bytecode) do + bytecode + |> Kernel.Typespec.beam_types() + |> Keyword.get(:type) + end + else + # API for Elixir 1.7 + defp extract_first_type(bytecode) do + case Code.Typespec.fetch_types(bytecode) do + {:ok, types} -> Keyword.get(types, :type) + _ -> nil + end + end end # Standardises a type (removes line numbers and renames the struct). From 267783a26f47cd9c0d9a0832a04fabaeb632d540 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Thu, 26 Jul 2018 23:12:46 +0200 Subject: [PATCH 06/16] Update dependencies (incl. ex_doc for Elixir 1.7) --- mix.lock | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index d07a77b..96a7b6b 100644 --- a/mix.lock +++ b/mix.lock @@ -4,16 +4,19 @@ "credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.18.4", "4406b8891cecf1352f49975c6d554e62e4341ceb41b9338949077b0d4a97b949", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.19.0", "e22b6434373b4870ea77b24df069dbac7002c1f483615e9ebfc0c37497e1c75c", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_unit_notifier": {:hex, :ex_unit_notifier, "0.1.4", "36a2dcab829f506e01bf17816590680dd1474407926d43e64c1263e627c364b8", [:mix], [], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.9.1", "14fd20fac51ab98d8e79615814cc9811888d2d7b28e85aa90ff2e30dcf3191d6", [:mix], [{:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, + "makeup": {:hex, :makeup, "0.5.1", "966c5c2296da272d42f1de178c1d135e432662eca795d6dc12e5e8787514edf7", [:mix], [{:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.8.0", "1204a2f5b4f181775a0e456154830524cf2207cf4f9112215c05e0b76e4eca8b", [:mix], [{:makeup, "~> 0.5.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "mix_test_watch": {:hex, :mix_test_watch, "0.6.0", "5e206ed04860555a455de2983937efd3ce79f42bd8536fc6b900cc286f5bb830", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, + "mix_test_watch": {:hex, :mix_test_watch, "0.7.0", "205f77063ed9b81ca41a2ab78486c653f9bfb1e5a341b5cf8fc2747dae67b0df", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, From 64b2c6aaec858b62cf4d8262ee5e686d98861ef9 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Thu, 16 Aug 2018 12:50:22 +0200 Subject: [PATCH 07/16] Do not use `runtime: false` by default in the docs Using `runtime: false` prevents to define a module using TypedStruct at runtime. Fixes #4. --- README.md | 2 +- lib/typed_struct.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3bc335c..fc19a1d 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Thanks to TypedStruct, this is now possible :) To use TypedStruct in your project, add this to you Mix dependencies: ```elixir -{:typed_struct, "~> 0.1.1", runtime: false} +{:typed_struct, "~> 0.1.1"} ``` If you want to avoid `mix format` putting parentheses on field definitions, diff --git a/lib/typed_struct.ex b/lib/typed_struct.ex index fb828ce..b869fa9 100644 --- a/lib/typed_struct.ex +++ b/lib/typed_struct.ex @@ -75,7 +75,7 @@ defmodule TypedStruct do To use TypedStruct in your project, add this to you Mix dependencies: - {:typed_struct, "~> #{Mix.Project.config()[:version]}", runtime: false} + {:typed_struct, "~> #{Mix.Project.config()[:version]}"} If you want to avoid `mix format` putting parentheses on field definitions, you can write in your `.formatter.exs`: From 33f35ae77728ee6fb8cc2b1a62a8940fe84b71cb Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Tue, 4 Sep 2018 20:06:58 +0200 Subject: [PATCH 08/16] Clarify a bit the documentation about `runtime: false` --- README.md | 4 ++++ lib/typed_struct.ex | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fc19a1d..3b9e713 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ To use TypedStruct in your project, add this to you Mix dependencies: {:typed_struct, "~> 0.1.1"} ``` +If you do not plan to compile modules using TypedStruct at runtime, you can add +`runtime: false` to the dependency tuple as TypedStruct is only used during +compilation. + If you want to avoid `mix format` putting parentheses on field definitions, you can write in your `.formatter.exs`: diff --git a/lib/typed_struct.ex b/lib/typed_struct.ex index b869fa9..1936443 100644 --- a/lib/typed_struct.ex +++ b/lib/typed_struct.ex @@ -77,6 +77,10 @@ defmodule TypedStruct do {:typed_struct, "~> #{Mix.Project.config()[:version]}"} + If you do not plan to compile modules using TypedStruct at runtime, you can + add `runtime: false` to the dependency tuple as TypedStruct is only used + during compilation. + If you want to avoid `mix format` putting parentheses on field definitions, you can write in your `.formatter.exs`: @@ -219,9 +223,9 @@ defmodule TypedStruct do @enforce_keys [:name] defstruct name: nil - In both cases, the type has no reason to be nullable anymore by default. In one - case the field is filled with its default value and not `nil`, and in the other - case it is enforced. Both options would generate the following type: + In both cases, the type has no reason to be nullable anymore by default. In + one case the field is filled with its default value and not `nil`, and in the + other case it is enforced. Both options would generate the following type: @type t() :: %__MODULE__{ name: String.t() # Not nullable From 98f983eb9c87dd1ba90f7c88c2d66aab2d05802e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Tue, 4 Sep 2018 20:09:34 +0200 Subject: [PATCH 09/16] Use Nix to manage the development environment --- .envrc | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 27 +++++++++++++++--- shell.nix | 49 +++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 .envrc create mode 100644 shell.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..e2e9592 --- /dev/null +++ b/.envrc @@ -0,0 +1,84 @@ +#################################### +# Environment setup for Nix shells # +#################################### + +# From https://github.com/direnv/direnv/wiki/Nix#persistent-cached-shell +# +# Usage: use_nix [...] +# +# Load environment variables from `nix-shell`. +# If you have a `default.nix` or `shell.nix` one of these will be used and +# the derived environment will be stored at ./.direnv/env- +# and symlink to it will be created at ./.direnv/default. +# Dependencies are added to the GC roots, such that the environment remains persistent. +# +# Packages can also be specified directly via e.g `use nix -p ocaml`, +# however those will not be added to the GC roots. +# +# The resulting environment is cached for better performance. +# +# To trigger switch to a different environment: +# `rm -f .direnv/default` +# +# To derive a new environment: +# `rm -rf .direnv/env-$(md5sum {shell,default}.nix 2> /dev/null | cut -c -32)` +# +# To remove cache: +# `rm -f .direnv/dump-*` +# +# To remove all environments: +# `rm -rf .direnv/env-*` +# +# To remove only old environments: +# `find .direnv -name 'env-*' -and -not -name `readlink .direnv/default` -exec rm -rf {} +` +# +use_nix() { + set -e + + local shell="shell.nix" + if [[ ! -f "${shell}" ]]; then + shell="default.nix" + fi + + if [[ ! -f "${shell}" ]]; then + fail "use nix: shell.nix or default.nix not found in the folder" + fi + + local dir="${PWD}"/.direnv + local default="${dir}/default" + if [[ ! -L "${default}" ]] || [[ ! -d `readlink "${default}"` ]]; then + local wd="${dir}/env-`md5sum "${shell}" | cut -c -32`" # TODO: Hash also the nixpkgs version? + mkdir -p "${wd}" + + local drv="${wd}/env.drv" + if [[ ! -f "${drv}" ]]; then + log_status "use nix: deriving new environment" + IN_NIX_SHELL=1 nix-instantiate --add-root "${drv}" --indirect "${shell}" > /dev/null + nix-store -r `nix-store --query --references "${drv}"` --add-root "${wd}/dep" --indirect > /dev/null + fi + + rm -f "${default}" + ln -s `basename "${wd}"` "${default}" + fi + + local drv=`readlink -f "${default}/env.drv"` + local dump="${dir}/dump-`md5sum ".envrc" | cut -c -32`-`md5sum ${drv} | cut -c -32`" + + if [[ ! -f "${dump}" ]] || [[ "${XDG_CONFIG_DIR}/direnv/direnvrc" -nt "${dump}" ]]; then + log_status "use nix: updating cache" + + old=`find ${dir} -name 'dump-*'` + nix-shell "${drv}" --show-trace "$@" --run 'direnv dump' > "${dump}" + rm -f ${old} + fi + + direnv_load cat "${dump}" + + watch_file "${default}" + watch_file shell.nix + if [[ ${shell} == "default.nix" ]]; then + watch_file default.nix + fi +} + +use nix diff --git a/.gitignore b/.gitignore index 0e20bb6..3d10eed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,37 @@ -# Application artifacts (Elixir) +## +## Application artifacts +## + +# direnv cache for Nix shells +/.direnv/ + +# Elixir build directory /_build/ + +# Elixir dependencies /deps/ /.fetch + +# Elixir binary files *.beam *.ez -typed_struct-*.tar +/typed_struct-*.tar +/typed_struct # Test coverage and documentation /cover/ /doc/ -# Editor artifacts +## +## Editor artifacts +## + /.elixir_ls/ /.history/ -# Crash dumps +## +## Crash dumps +## + +# Erang VM erl_crash.dump diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..b87fb41 --- /dev/null +++ b/shell.nix @@ -0,0 +1,49 @@ +{ pkgs ? import {} }: + +with pkgs; + +let + inherit (lib) optional optionals; + + erlangDrv = { mkDerivation }: + mkDerivation rec { + version = "21.0"; + # Use `nix-prefetch-github --rev OTP- erlang otp` to update. + sha256 = "0khprgawmbdpn9b8jw2kksmvs6b45mibpjralsc0ggxym1397vm8"; + + prePatch = '' + substituteInPlace configure.in --replace '`sw_vers -productVersion`' '10.10' + ''; + }; + + elixirDrv = { mkDerivation }: + mkDerivation rec { + version = "1.7.3"; + # Use `nix-prefetch-github --rev v elixir-lang elixir` to update. + sha256 = "0d7rj4khmvy76z12njzwzknm1j9rhjadgj9k1chjd4gnjffkb1aa"; + minimumOTPVersion = "19"; + }; + + erlang = (beam.lib.callErlang erlangDrv { wxGTK = wxGTK30; }).override { + # Temporary fix to enable use on OS X El Capitan. + enableKernelPoll = if stdenv.isDarwin then false else true; + }; + + rebar = pkgs.rebar.override { inherit erlang; }; + + elixir = beam.lib.callElixir elixirDrv { + inherit erlang rebar; + debugInfo = true; + }; +in + +mkShell { + buildInputs = [ elixir git ] + ++ optional stdenv.isLinux libnotify # For ExUnit Notifier on Linux. + ++ optional stdenv.isDarwin terminal-notifier # For ExUnit Notifier on macOS. + ++ optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ + # For file_system on macOS. + CoreFoundation + CoreServices + ]); +} From 74d0bf3a9420bb94806a9e2947c6345c78316b0d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Tue, 4 Sep 2018 20:13:01 +0200 Subject: [PATCH 10/16] Update dependencies --- .credo.exs | 7 ++++--- mix.exs | 4 ++-- mix.lock | 11 +++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.credo.exs b/.credo.exs index ab6b967..c966f58 100644 --- a/.credo.exs +++ b/.credo.exs @@ -21,8 +21,8 @@ # You can give explicit globs or simply directories. # In the latter case `**/*.{ex,exs}` will be used. # - included: ["lib/", "test/"], - excluded: [~r"/_build/", ~r"/deps/"] + included: ["lib/", "src/", "test/", "web/", "apps/"], + excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"] }, # # If you create your own checks, you must specify the source files for @@ -72,7 +72,6 @@ # set the `excluded_macros` parameter to `[:schema, :setup, :test]`. # {Credo.Check.Design.DuplicatedCode, excluded_macros: []}, - # You can also customize the exit_status of each check. # If you don't want TODO comments to cause `mix credo` to fail, just # set this value to 0 (zero). @@ -83,6 +82,7 @@ # ## Readability Checks # + {Credo.Check.Readability.AliasOrder}, {Credo.Check.Readability.FunctionNames}, {Credo.Check.Readability.LargeNumbers}, {Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 80}, @@ -109,6 +109,7 @@ {Credo.Check.Refactor.CyclomaticComplexity}, {Credo.Check.Refactor.FunctionArity}, {Credo.Check.Refactor.LongQuoteBlocks}, + {Credo.Check.Refactor.MapInto}, {Credo.Check.Refactor.MatchInCondition}, {Credo.Check.Refactor.NegatedConditionsInUnless}, {Credo.Check.Refactor.NegatedConditionsWithElse}, diff --git a/mix.exs b/mix.exs index 392d21b..8c0d398 100644 --- a/mix.exs +++ b/mix.exs @@ -47,7 +47,7 @@ defmodule TypedStruct.MixProject do defp deps do [ # Development and test dependencies - {:credo, "~> 0.9.3", only: :dev, runtime: false}, + {:credo, "~> 0.10.0", only: :dev, runtime: false}, {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:excoveralls, ">= 0.0.0", only: :test, runtime: false}, {:mix_test_watch, ">= 0.0.0", only: :dev, runtime: false}, @@ -56,7 +56,7 @@ defmodule TypedStruct.MixProject do # Project dependencies # Documentation dependencies - {:ex_doc, ">= 0.0.0", only: :dev, runtime: false} + {:ex_doc, "~> 0.19", only: :dev, runtime: false} ] end diff --git a/mix.lock b/mix.lock index 96a7b6b..03f7b4a 100644 --- a/mix.lock +++ b/mix.lock @@ -1,12 +1,12 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "0.10.0", "66234a95effaf9067edb19fc5d0cd5c6b461ad841baac42467afed96c78e5e9e", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.19.0", "e22b6434373b4870ea77b24df069dbac7002c1f483615e9ebfc0c37497e1c75c", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_unit_notifier": {:hex, :ex_unit_notifier, "0.1.4", "36a2dcab829f506e01bf17816590680dd1474407926d43e64c1263e627c364b8", [:mix], [], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.9.1", "14fd20fac51ab98d8e79615814cc9811888d2d7b28e85aa90ff2e30dcf3191d6", [:mix], [{:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.10.0", "a4508bdd408829f38e7b2519f234b7fd5c83846099cda348efcb5291b081200c", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, @@ -15,10 +15,9 @@ "makeup_elixir": {:hex, :makeup_elixir, "0.8.0", "1204a2f5b4f181775a0e456154830524cf2207cf4f9112215c05e0b76e4eca8b", [:mix], [{:makeup, "~> 0.5.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "mix_test_watch": {:hex, :mix_test_watch, "0.7.0", "205f77063ed9b81ca41a2ab78486c653f9bfb1e5a341b5cf8fc2747dae67b0df", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, + "mix_test_watch": {:hex, :mix_test_watch, "0.8.0", "acf97da2abc66532e7dc1aa66a5d6c9fc4442d7992d5d7eb4faeaeb964c2580e", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, } From feddbb484eb004f6319665eebed023ad830d5257 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Tue, 4 Sep 2018 21:54:40 +0200 Subject: [PATCH 11/16] Simplify the shell.nix --- shell.nix | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/shell.nix b/shell.nix index b87fb41..ac33355 100644 --- a/shell.nix +++ b/shell.nix @@ -5,36 +5,12 @@ with pkgs; let inherit (lib) optional optionals; - erlangDrv = { mkDerivation }: - mkDerivation rec { - version = "21.0"; - # Use `nix-prefetch-github --rev OTP- erlang otp` to update. - sha256 = "0khprgawmbdpn9b8jw2kksmvs6b45mibpjralsc0ggxym1397vm8"; - - prePatch = '' - substituteInPlace configure.in --replace '`sw_vers -productVersion`' '10.10' - ''; - }; - - elixirDrv = { mkDerivation }: - mkDerivation rec { - version = "1.7.3"; - # Use `nix-prefetch-github --rev v elixir-lang elixir` to update. - sha256 = "0d7rj4khmvy76z12njzwzknm1j9rhjadgj9k1chjd4gnjffkb1aa"; - minimumOTPVersion = "19"; - }; - - erlang = (beam.lib.callErlang erlangDrv { wxGTK = wxGTK30; }).override { + erlang = beam.interpreters.erlangR21.override { # Temporary fix to enable use on OS X El Capitan. enableKernelPoll = if stdenv.isDarwin then false else true; }; - rebar = pkgs.rebar.override { inherit erlang; }; - - elixir = beam.lib.callElixir elixirDrv { - inherit erlang rebar; - debugInfo = true; - }; + elixir = (beam.packages.erlangR21.override { inherit erlang; }).elixir_1_7; in mkShell { From b8a6a348c1ce367e8745d70266288fb6d5f7138f Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Wed, 5 Sep 2018 20:17:12 +0200 Subject: [PATCH 12/16] Add the ability to enforce keys by default (#6) --- README.md | 20 ++++++++++++ lib/typed_struct.ex | 62 ++++++++++++++++++++++++++++++++++++-- test/typed_struct_test.exs | 24 +++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3b9e713..1c0bdff 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,26 @@ end Each field is defined through the `field/2` macro. +If you want to enforce all the keys by default, you can do: + +```elixir +defmodule MyStruct do + use TypedStruct + + # Enforce keys by default. + typedstruct enforce: true do + # This key is enforced. + field :enforced_by_default, term() + + # You can override the default behaviour. + field :not_enforced, term(), enforce: false + + # A key with a default value is not enforced. + field :not_enforced_either, integer(), default: 1 + end +end +``` + ### Documentation To add a `@typedoc` to the struct type, just add the attribute above the diff --git a/lib/typed_struct.ex b/lib/typed_struct.ex index 1936443..965e0b3 100644 --- a/lib/typed_struct.ex +++ b/lib/typed_struct.ex @@ -112,6 +112,24 @@ defmodule TypedStruct do Each field is defined through the `field/2` macro. + If you want to enforce all the keys by default, you can do: + + defmodule MyStruct do + use TypedStruct + + # Enforce keys by default. + typedstruct enforce: true do + # This key is enforced. + field :enforced_by_default, term() + + # You can override the default behaviour. + field :not_enforced, term(), enforce: false + + # A key with a default value is not enforced. + field :not_enforced_either, integer(), default: 1 + end + end + ### Documentation To add a `@typedoc` to the struct type, just add the attribute above the @@ -235,7 +253,7 @@ defmodule TypedStruct do @doc false defmacro __using__(_) do quote do - import TypedStruct, only: [typedstruct: 1] + import TypedStruct, only: [typedstruct: 1, typedstruct: 2] end end @@ -244,12 +262,45 @@ defmodule TypedStruct do Inside a `typedstruct` block, each field is defined through the `field/2` macro. + + ## Options + + * `enforce` - if set to true, sets `enforce: true` to all fields by default. + This can be overridden by setting `enforce: false` or a default value on + individual fields. + + ## Examples + + defmodule MyStruct do + use TypedStruct + + typedstruct do + field :field_one, String.t() + field :field_two, integer(), enforce: true + field :field_three, boolean(), enforce: true + field :field_four, atom(), default: :hey + end + end + + This is the same as writing: + + defmodule MyStruct do + use TypedStruct + + typedstruct enforce: true do + field :field_one, String.t(), enforce: false + field :field_two, integer() + field :field_three, boolean() + field :field_four, atom(), default: :hey + end + end """ - defmacro typedstruct(do: block) do + defmacro typedstruct(opts \\ [], do: block) do quote do Module.register_attribute(__MODULE__, :fields, accumulate: true) Module.register_attribute(__MODULE__, :types, accumulate: true) Module.register_attribute(__MODULE__, :keys_to_enforce, accumulate: true) + Module.put_attribute(__MODULE__, :enforce?, unquote(!!opts[:enforce])) import TypedStruct unquote(block) @@ -301,7 +352,12 @@ defmodule TypedStruct do end default = opts[:default] - enforce? = !!opts[:enforce] + + enforce? = + if is_nil(opts[:enforce]), + do: Module.get_attribute(mod, :enforce?) && !default, + else: !!opts[:enforce] + nullable? = !default && !enforce? Module.put_attribute(mod, :fields, {name, default}) diff --git a/test/typed_struct_test.exs b/test/typed_struct_test.exs index 278f7b1..6bfb557 100644 --- a/test/typed_struct_test.exs +++ b/test/typed_struct_test.exs @@ -16,6 +16,18 @@ defmodule TypedStructTest do def enforce_keys, do: @enforce_keys end + defmodule EnforcedTypedStruct do + use TypedStruct + + typedstruct enforce: true do + field :enforced_by_default, term() + field :not_enforced, term(), enforce: false + field :with_default, integer(), default: 1 + end + + def enforce_keys, do: @enforce_keys + end + @bytecode bytecode ## Standard cases @@ -33,6 +45,18 @@ defmodule TypedStructTest do assert TestStruct.enforce_keys() == [:mandatory_int] end + test "enforces keys by default if `enforce: true` is set at top-level" do + assert :enforced_by_default in EnforcedTypedStruct.enforce_keys() + end + + test "does not enforce keys for fields explicitely setting `enforce: false" do + refute :not_enforced in EnforcedTypedStruct.enforce_keys() + end + + test "does not enforce keys for fields with a default value" do + refute :with_default in EnforcedTypedStruct.enforce_keys() + end + test "generates a type for the struct" do # Define a second struct with the type expected for TestStruct. {:module, _name, bytecode2, _exports} = From 6b3223f17aff1601f1e38980ca94522aef88a4ec Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Wed, 5 Sep 2018 20:19:15 +0200 Subject: [PATCH 13/16] Documentation corrections --- README.md | 15 ++++++++------- lib/typed_struct.ex | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1c0bdff..a4bc4df 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Thanks to TypedStruct, this is now possible :) ### Setup -To use TypedStruct in your project, add this to you Mix dependencies: +To use TypedStruct in your project, add this to your Mix dependencies: ```elixir {:typed_struct, "~> 0.1.1"} @@ -89,10 +89,11 @@ If you do not plan to compile modules using TypedStruct at runtime, you can add compilation. If you want to avoid `mix format` putting parentheses on field definitions, -you can write in your `.formatter.exs`: +you can add to your `.formatter.exs`: ```elixir [ + ..., import_deps: [:typed_struct] ] ``` @@ -104,18 +105,18 @@ To define a typed struct, use `TypedStruct`, then define your struct within a ```elixir defmodule MyStruct do - # Use TypedStruct to import the typedstruct macro + # Use TypedStruct to import the typedstruct macro. use TypedStruct - # Define your struct + # Define your struct. typedstruct do - # Define each field with the field macro + # Define each field with the field macro. field :a_string, String.t() - # You can set a default value + # You can set a default value. field :string_with_default, String.t(), default: "default" - # You can enforce a field + # You can enforce a field. field :enforced_field, integer(), enforce: true end end diff --git a/lib/typed_struct.ex b/lib/typed_struct.ex index 965e0b3..bd8876a 100644 --- a/lib/typed_struct.ex +++ b/lib/typed_struct.ex @@ -73,7 +73,7 @@ defmodule TypedStruct do ### Setup - To use TypedStruct in your project, add this to you Mix dependencies: + To use TypedStruct in your project, add this to your Mix dependencies: {:typed_struct, "~> #{Mix.Project.config()[:version]}"} @@ -82,9 +82,10 @@ defmodule TypedStruct do during compilation. If you want to avoid `mix format` putting parentheses on field definitions, - you can write in your `.formatter.exs`: + you can add to your `.formatter.exs`: [ + ..., import_deps: [:typed_struct] ] @@ -94,18 +95,18 @@ defmodule TypedStruct do `typedstruct` block: defmodule MyStruct do - # Use TypedStruct to import the typedstruct macro + # Use TypedStruct to import the typedstruct macro. use TypedStruct - # Define your struct + # Define your struct. typedstruct do - # Define each field with the field macro + # Define each field with the field macro. field :a_string, String.t() - # You can set a default value + # You can set a default value. field :string_with_default, String.t(), default: "default" - # You can enforce a field + # You can enforce a field. field :enforced_field, integer(), enforce: true end end From 70a2705fae2163965327127ad54ee34ca1b0ecf5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Wed, 5 Sep 2018 20:25:48 +0200 Subject: [PATCH 14/16] Remove logger from extra_applications --- mix.exs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mix.exs b/mix.exs index 8c0d398..ac71dd2 100644 --- a/mix.exs +++ b/mix.exs @@ -35,9 +35,7 @@ defmodule TypedStruct.MixProject do end def application do - [ - extra_applications: [:logger] - ] + [extra_applications: []] end # Specifies which paths to compile per environment. From 4c3407e8633d16a51b48ec3d9f1771d1dc44dd8a Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Wed, 5 Sep 2018 21:30:12 +0200 Subject: [PATCH 15/16] Bump version to 0.1.2 --- README.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4bc4df..41d11c8 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Thanks to TypedStruct, this is now possible :) To use TypedStruct in your project, add this to your Mix dependencies: ```elixir -{:typed_struct, "~> 0.1.1"} +{:typed_struct, "~> 0.1.2"} ``` If you do not plan to compile modules using TypedStruct at runtime, you can add diff --git a/mix.exs b/mix.exs index ac71dd2..67d8f47 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule TypedStruct.MixProject do use Mix.Project - @version "0.1.2-dev" + @version "0.1.2" @repo_url "https://github.com/ejpcmac/typed_struct" def project do From 08679cb1709113ae7930fa9f7b77c9200f8ea18d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Wed, 5 Sep 2018 21:31:56 +0200 Subject: [PATCH 16/16] Update the changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f192d00..5437ef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.1.2 + +* Add the ability to enforce keys by default (#6) +* Clarify the documentation about `runtime: false` + ## v0.1.1 * Do not make the type nullable when there is a default value