defmodule Dragon.Data.File do @moduledoc """ Tools for loading data files (yml) """ use Dragon.Context import Dragon.Tools.File, only: [drop_root: 2] import Dragon.Tools.File.WalkTree import Dragon.Tools.Dict import Dragon.Data, only: [get_into: 2, data_path: 2] # def load(dragon, args, rest, forward) do def load(%Dragon{} = dragon, %{type: "file", path: path} = args) do stdout([:green, "Loading data", :reset, " from ", :bright, drop_root(dragon.root, path)]) prefix = get_into(dragon, args) %Dragon{dragon | data_paths: Map.put(dragon.data_paths, Path.join(dragon.root, path), [])} |> walk_tree(path, match: %{~r/\.(ya?ml|json)$/ => &load_data_file/3}, follow_meta: true, prefix: prefix ) end ############################################################################## def load_data_file(dragon, path, opts) do # strip off the first parts of the name... meh? datapath = case {Map.get(opts, :prefix), data_path(dragon.root, path)} do {nil, [_ | path]} -> path {prefix, path} when is_list(prefix) -> prefix ++ path end stdout([ :green, "Loading ", :reset, :bright, drop_root(dragon.root, path), :reset, :light_black, " into data path: ", :light_blue, "@", Enum.join(datapath, ".") ]) with {:ok, data} <- get_file_data(path), do: put_into(dragon, [:data | datapath], data) end def get_file_data(path) do case Path.extname(path) do ".json" -> File.read!(path) |> Jason.decode() ".yml" -> YamlElixir.read_all_from_file(path) ".yaml" -> YamlElixir.read_all_from_file(path) end |> case do {:ok, [data]} -> {:ok, data} {:ok, [_ | _] = list} -> {:ok, list} {:ok, data} when is_map(data) -> {:ok, data} error -> IO.inspect(error, label: "Error parsing Data") abort("Cannot continue") end end end