diff --git a/lib/ex_doc.ex b/lib/ex_doc.ex index 0f62a351c..c108c3560 100644 --- a/lib/ex_doc.ex +++ b/lib/ex_doc.ex @@ -22,7 +22,7 @@ defmodule ExDoc do end {module_nodes, filtered_nodes} = config.retriever.docs_from_dir(config.source_beam, config) - find_formatter(config.formatter).run({module_nodes, filtered_nodes}, config) + find_formatter(config.formatter).run(module_nodes, filtered_nodes, config) end # Short path for programmatic interface diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex index 800bbfc3b..2db45ba35 100644 --- a/lib/ex_doc/formatter/epub.ex +++ b/lib/ex_doc/formatter/epub.ex @@ -8,12 +8,8 @@ defmodule ExDoc.Formatter.EPUB do @doc """ Generate EPUB documentation for the given modules. """ - @spec run(list, ExDoc.Config.t()) :: String.t() - def run(project_nodes, config) when is_list(project_nodes) and is_map(config) do - run({project_nodes, []}, config) - end - - def run({project_nodes, filtered_modules}, config) when is_map(config) do + @spec run([ExDoc.ModuleNode.t()], [ExDoc.ModuleNode.t()], ExDoc.Config.t()) :: String.t() + def run(project_nodes, filtered_modules, config) when is_map(config) do parent = config.output config = normalize_config(config) diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 723fee3f6..75f7c323b 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -10,17 +10,8 @@ defmodule ExDoc.Formatter.HTML do @doc """ Generate HTML documentation for the given modules. """ - @spec run( - [ExDoc.ModuleNode.t()] - | {[ExDoc.ModuleNode.t()], [ExDoc.ModuleNode.t()]}, - ExDoc.Config.t() - ) :: String.t() - - def run(project_nodes, config) when is_list(project_nodes) and is_map(config) do - run({project_nodes, []}, config) - end - - def run({project_nodes, filtered_modules}, config) when is_map(config) do + @spec run([ExDoc.ModuleNode.t()], [ExDoc.ModuleNode.t()], ExDoc.Config.t()) :: String.t() + def run(project_nodes, filtered_modules, config) when is_map(config) do config = normalize_config(config) config = %{config | output: Path.expand(config.output)} diff --git a/lib/ex_doc/retriever.ex b/lib/ex_doc/retriever.ex index 5be588d0e..7a5bcf509 100644 --- a/lib/ex_doc/retriever.ex +++ b/lib/ex_doc/retriever.ex @@ -19,18 +19,25 @@ defmodule ExDoc.Retriever do @spec docs_from_dir(Path.t() | [Path.t()], ExDoc.Config.t()) :: {[ExDoc.ModuleNode.t()], [ExDoc.ModuleNode.t()]} def docs_from_dir(dir, config) when is_binary(dir) do - files = Path.wildcard(Path.expand("*.beam", dir)) - - files - |> Enum.map(&filename_to_module/1) - |> docs_from_modules(config) + dir + |> docs_from_dir({[], []}, config) + |> sort_modules(config) end def docs_from_dir(dirs, config) when is_list(dirs) do - Enum.flat_map(dirs, &docs_from_dir(&1, config)) + dirs + |> Enum.reduce({[], []}, &docs_from_dir(&1, &2, config)) |> sort_modules(config) end + defp docs_from_dir(dir, acc, config) do + files = Path.wildcard(Path.expand("*.beam", dir)) + + files + |> Enum.map(&filename_to_module/1) + |> docs_from_modules(acc, config) + end + @doc """ Extract documentation from all modules and returns a tuple containing `{modules, filtered}`, two lists of modules that were extracted and filtered @@ -39,8 +46,11 @@ defmodule ExDoc.Retriever do @spec docs_from_modules([atom], ExDoc.Config.t()) :: {[ExDoc.ModuleNode.t()], [ExDoc.ModuleNode.t()]} def docs_from_modules(modules, config) when is_list(modules) do - modules - |> Enum.reduce({[], []}, fn module_name, {modules, filtered} = acc -> + modules |> docs_from_modules({[], []}, config) |> sort_modules(config) + end + + defp docs_from_modules(modules, acc, config) do + Enum.reduce(modules, acc, fn module_name, {modules, filtered} = acc -> case get_module(module_name, config) do {:error, _module} -> acc @@ -51,7 +61,6 @@ defmodule ExDoc.Retriever do else: {modules, [module_node | filtered]} end end) - |> sort_modules(config) end defp sort_modules({modules, filtered}, config) do diff --git a/test/ex_doc/formatter/html/search_data_test.exs b/test/ex_doc/formatter/html/search_data_test.exs index 15a4c2302..b2ee448e0 100644 --- a/test/ex_doc/formatter/html/search_data_test.exs +++ b/test/ex_doc/formatter/html/search_data_test.exs @@ -245,7 +245,7 @@ defmodule ExDoc.Formatter.HTML.SearchDataTest do defp search_data(modules, config) do {modules, []} = ExDoc.Retriever.docs_from_modules(modules, config) - ExDoc.Formatter.HTML.run(modules, config) + ExDoc.Formatter.HTML.run(modules, [], config) [path] = Path.wildcard(Path.join([config.output, "dist", "search_data-*.js"])) "searchData=" <> json = File.read!(path) Jason.decode!(json) diff --git a/test/ex_doc/retriever_test.exs b/test/ex_doc/retriever_test.exs index c2b842bd0..c138c0e07 100644 --- a/test/ex_doc/retriever_test.exs +++ b/test/ex_doc/retriever_test.exs @@ -206,6 +206,11 @@ defmodule ExDoc.RetrieverTest do [%{id: "A"}, %{id: "A.A"}], [%{id: "B"}] } = Retriever.docs_from_dir(ebin_dir, config) + + assert { + [%{id: "A"}, %{id: "A.A"}], + [%{id: "B"}] + } = Retriever.docs_from_dir([ebin_dir], config) end test "natural sorting", c do diff --git a/test/ex_doc_test.exs b/test/ex_doc_test.exs index be412ff31..525b60f70 100644 --- a/test/ex_doc_test.exs +++ b/test/ex_doc_test.exs @@ -12,7 +12,7 @@ defmodule ExDocTest do # Simple formatter that returns whatever is passed into it defmodule IdentityFormatter do - def run(modules, config) do + def run(modules, _filtered, config) do {modules, config} end end @@ -63,7 +63,7 @@ defmodule ExDocTest do source_beam: "beam_dir" ] - assert {{source_dir, _retr_config}, _config} = ExDoc.generate_docs("Elixir", "1", options) + assert {source_dir, _config} = ExDoc.generate_docs("Elixir", "1", options) assert source_dir == options[:source_beam] end