defmodule SplitClient.DataSourceYAML do @moduledoc """ A DataSource intended for local development. Will consume a YAML file that developers can use to test feature flags without having to modify global data on the Split.IO web portal See also: [Local Feature Development](README.md#local-feature-development) """ alias SplitClient.Boundary.DataSource.SplitStub @behaviour SplitClient.Boundary.DataSourceBehaviour @impl true def get_treatment(key, split_name, opts \\ []) do treatment = read_split_file(opts) |> SplitStub.find_treatment(key, split_name) {:ok, treatment} end @impl true def get_treatments(key, split_names, opts \\ []) when is_list(split_names) do treatments = read_split_file(opts) |> SplitStub.find_treatments(key, split_names) {:ok, treatments} end @impl true def get_all_treatments(keys, opts \\ []) when is_list(keys) do treatments = read_split_file(opts) |> SplitStub.find_all_treatments(keys) {:ok, treatments} end def read_split_file(opts) do yaml(opts).read_from_file!(split_file_path()) |> process_yaml() end # an empty file will return an empty map. we're expecting a list. defp process_yaml(%{} = _yaml) do process_yaml([]) end defp process_yaml(yaml) when is_list(yaml) do SplitStub.from_list(yaml) end defp split_file_path do Application.get_env(:split_client, :split_file, Path.join(File.cwd!(), "/split.yml")) end # Most tests we want to use a mock, however there are some integration-type # testing experience tests where we want to use a real split file. We don't # want mox setup for those and so we don't want to always use the application # config defp yaml(opts) do Keyword.get(opts, :yaml_module, SplitClient.Boundary.YAML) end end