diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index 4ce5a44cb..cd356f7f4 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -239,30 +239,22 @@ defmodule Mix.Tasks.Docs do @doc false def run(args, config \\ Mix.Project.config(), generator \\ &ExDoc.generate_docs/3) do Mix.Task.run("compile") + {cli_opts, args, _} = OptionParser.parse(args, aliases: @aliases, switches: @switches) - if args != [] do - Mix.raise("Extraneous arguments on the command line") - end + if args != [], do: Mix.raise("Extraneous arguments on the command line") project = to_string(config[:name] || config[:app]) version = config[:version] || "dev" - - options = - config - |> get_docs_opts() - |> Keyword.merge(cli_opts) - # accepted at root level config - |> normalize_source_url(config) - # accepted at root level config - |> normalize_homepage_url(config) - |> normalize_source_beam(config) - |> normalize_main() - |> normalize_deps() + options = get_docs_opts(config, cli_opts) + # def'd after `get_formatters/1` for formatter <- get_formatters(options) do index = generator.(project, version, Keyword.put(options, :formatter, formatter)) - log(index) + + Mix.shell().info([:green, "Docs successfully generated."]) + Mix.shell().info([:green, "View them at #{inspect(index)}."]) + index end end @@ -274,7 +266,17 @@ defmodule Mix.Tasks.Docs do end end - defp get_docs_opts(config) do + # Table of Contents: + # + # config + # |> get_docs_opts() + # |> Keyword.merge(cli_opts) + # |> normalize_urls(config, [:source_url, :homepage_url]) # accepted at root level config + # |> normalize_source_beam(config) + # |> normalize_main() + # |> normalize_deps() + # + defp get_docs_opts(config, cli_opts) do docs = config[:docs] cond do @@ -282,81 +284,68 @@ defmodule Mix.Tasks.Docs do is_nil(docs) -> [] true -> docs end + |> Keyword.merge(cli_opts) + # accepted at root level config + |> normalize_urls(config, [:source_url, :homepage_url]) end - defp log(index) do - Mix.shell().info([:green, "Docs successfully generated."]) - Mix.shell().info([:green, "View them at #{inspect(index)}."]) + defp normalize_urls(options, config, keys) do + Enum.reduce(keys, options, fn key, options_ -> + case Keyword.get(config, key) do + nil -> options_ + value -> Keyword.put(options_, key, value) + end + end) + |> normalize_source_beam(config) end - defp normalize_source_url(options, config) do - if source_url = config[:source_url] do - Keyword.put(options, :source_url, source_url) - else - options - end - end + def normalize_source_beam(options, config) do + source_beam = + case Mix.Project.umbrella?(config) do + false -> + Mix.Project.compile_path() - defp normalize_homepage_url(options, config) do - if homepage_url = config[:homepage_url] do - Keyword.put(options, :homepage_url, homepage_url) - else - options - end - end + true -> + ignored_apps = Keyword.get(options, :ignore_apps, []) + build = Mix.Project.build_path() - defp normalize_source_beam(options, config) do - compile_path = - if Mix.Project.umbrella?(config) do - umbrella_compile_paths(Keyword.get(options, :ignore_apps, [])) - else - Mix.Project.compile_path() + for {app, _} <- Mix.Project.apps_paths(), + app not in ignored_apps, + do: Path.join([build, "lib", Atom.to_string(app), "ebin"]) end - Keyword.put_new(options, :source_beam, compile_path) - end - - defp umbrella_compile_paths(ignored_apps) do - build = Mix.Project.build_path() - - for {app, _} <- Mix.Project.apps_paths(), - app not in ignored_apps do - Path.join([build, "lib", Atom.to_string(app), "ebin"]) - end + Keyword.put_new(options, :source_beam, source_beam) + |> normalize_main() end defp normalize_main(options) do main = options[:main] cond do - is_nil(main) -> - Keyword.delete(options, :main) - - is_atom(main) -> - Keyword.put(options, :main, inspect(main)) - - is_binary(main) -> - options + is_nil(main) -> Keyword.delete(options, :main) + is_atom(main) -> Keyword.put(options, :main, inspect(main)) + is_binary(main) -> options end + |> normalize_deps() end defp normalize_deps(options) do - user_deps = Keyword.get(options, :deps, []) - deps = - for {app, doc} <- Keyword.merge(get_deps(), user_deps), + for {app, doc} <- Keyword.merge(get_deps(), Keyword.get(options, :deps, [])), lib_dir = :code.lib_dir(app), is_list(lib_dir), do: {List.to_string(lib_dir), doc} Keyword.put(options, :deps, deps) + # call stack returns to `run/1` end - defp get_deps do - for {key, _} <- Mix.Project.deps_paths(), + defp get_deps, + do: + for( + {key, _} <- Mix.Project.deps_paths(), _ = Application.load(key), - vsn = Application.spec(key, :vsn) do - {key, "https://hexdocs.pm/#{key}/#{vsn}/"} - end - end + vsn = Application.spec(key, :vsn), + do: {key, "https://hexdocs.pm/#{key}/#{vsn}/"} + ) end