From 12ea0a2fcb14c49a0b8885f0eb26680301f2853c Mon Sep 17 00:00:00 2001 From: Alexander Marks-Katz Date: Fri, 7 Dec 2018 15:33:57 -0800 Subject: [PATCH 1/6] =?UTF-8?q?=CE=94=20docs.ex,=20>=20TODO's?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/mix/tasks/docs.ex | 143 +++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 87 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index 4ce5a44cb..d77d97754 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -238,125 +238,94 @@ defmodule Mix.Tasks.Docs do @doc false def run(args, config \\ Mix.Project.config(), generator \\ &ExDoc.generate_docs/3) do - Mix.Task.run("compile") + Mix.Task.run("compile") # needed to gen source code that will be used for docs? + {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 = config[:docs] + |> get_docs_opts + |> Keyword.merge(cli_opts) + |> normalize(config, [:source_url, :homepage_url]) # accepted at root level config + |> normalize_source_beam(config) + |> normalize_main + |> normalize_deps() for formatter <- get_formatters(options) do index = generator.(project, version, Keyword.put(options, :formatter, formatter)) - log(index) - index - end - end - - defp get_formatters(options) do - case Keyword.get_values(options, :formatter) do - [] -> options[:formatters] || [ExDoc.Config.default_formatter()] - values -> values - end - end - - defp get_docs_opts(config) do - docs = config[:docs] - - cond do - is_function(docs, 0) -> docs.() - is_nil(docs) -> [] - true -> docs - end - end - defp log(index) do - Mix.shell().info([:green, "Docs successfully generated."]) - Mix.shell().info([:green, "View them at #{inspect(index)}."]) - end + Mix.shell().info([:green, "Docs successfully generated."]) + Mix.shell().info([:green, "View them at #{inspect(index)}."]) - defp normalize_source_url(options, config) do - if source_url = config[:source_url] do - Keyword.put(options, :source_url, source_url) - else - options + index end end - 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 + defp get_docs_opts(docs) when is_function(docs, 0), do: docs.() + defp get_docs_opts(docs) when is_nil(docs), do: [] + defp get_docs_opts(docs), do: docs - 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() + defp normalize(options, config, keys) do + Enum.reduce(keys, options, fn key, options_ -> + case config[key] do + nil -> options + value -> Keyword.put(options_, key, value) end - - Keyword.put_new(options, :source_beam, compile_path) + end) end - defp umbrella_compile_paths(ignored_apps) do - build = Mix.Project.build_path() + def normalize_source_beam(options, config) do + source_beam = compile_path(opts, Mix.Project.umbrella?(config)) - 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) end - defp normalize_main(options) do - main = options[:main] + defp compile_path(_options, false), do: Mix.Project.compile_path() + defp compile_path(options, true) do + ignored_apps = Keyword.get(options, :ignore_apps, []) + build = Mix.Project.build_path() - cond do - is_nil(main) -> - Keyword.delete(options, :main) + for {app, _} <- Mix.Project.apps_paths(), app not in ignored_apps, + do: Path.join([build, "lib", Atom.to_string(app), "ebin"]) + end - is_atom(main) -> - Keyword.put(options, :main, inspect(main)) + defp normalize_main(options), do: normalize_main(options, options[:main]) - is_binary(main) -> - options - end - end + defp normalize_main(options, nil), do: Keyword.delete(options, :main) + defp normalize_main(options, main) when is_atom(main), do: Keyword.put(options, :main, inspect(main)) + defp normalize_main(options, main) when is_binary(main), do: options defp normalize_deps(options) do user_deps = Keyword.get(options, :deps, []) - deps = - for {app, doc} <- Keyword.merge(get_deps(), user_deps), - lib_dir = :code.lib_dir(app), - is_list(lib_dir), - do: {List.to_string(lib_dir), doc} + deps = for {app, doc} <- Keyword.merge(get_deps(), user_deps), + lib_dir = :code.lib_dir(app), + is_list(lib_dir), + do: {List.to_string(lib_dir), doc} Keyword.put(options, :deps, deps) end - defp get_deps do + 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}/"} + _ = Application.load(key), + vsn = Application.spec(key, :vsn), + do: {key, "https://hexdocs.pm/#{key}/#{vsn}/"} + + defp get_formatters(options) do + case Keyword.get_values(options, :formatter) do + [] -> options[:formatters] || [ExDoc.Config.default_formatter()] + values -> values end end end + +# TODO: Review docs. +# TODO: Add commit message w/ explanation. +# THEN, put up a PR. Also, offer to just work on the fork and PR the finished product... +# Explain that I tried to create a PR a few months ago, but got lost in the code. +# As the team didn't have the bandwidth to provide documentation, +# I'm trying to do that (along with cleaning up the code) in my fork. From 2dc1c7c297c2b14a1cda7650faf24b33bbd13ba2 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 8 Dec 2018 19:26:01 -0800 Subject: [PATCH 2/6] + readability --- lib/mix/tasks/docs.ex | 84 ++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index d77d97754..ec1cc9049 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -238,7 +238,7 @@ defmodule Mix.Tasks.Docs do @doc false def run(args, config \\ Mix.Project.config(), generator \\ &ExDoc.generate_docs/3) do - Mix.Task.run("compile") # needed to gen source code that will be used for docs? + Mix.Task.run("compile") {cli_opts, args, _} = OptionParser.parse(args, aliases: @aliases, switches: @switches) @@ -246,13 +246,7 @@ defmodule Mix.Tasks.Docs do project = to_string(config[:name] || config[:app]) version = config[:version] || "dev" - options = config[:docs] - |> get_docs_opts - |> Keyword.merge(cli_opts) - |> normalize(config, [:source_url, :homepage_url]) # accepted at root level 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)) @@ -264,39 +258,62 @@ defmodule Mix.Tasks.Docs do end end - defp get_docs_opts(docs) when is_function(docs, 0), do: docs.() - defp get_docs_opts(docs) when is_nil(docs), do: [] - defp get_docs_opts(docs), do: docs + defp get_formatters(options) do + case Keyword.get_values(options, :formatter) do + [] -> options[:formatters] || [ExDoc.Config.default_formatter()] + values -> values + end + end + + + defp get_docs_opts(config, cli_opts) do + docs = config[:docs] + + cond do + is_function(docs, 0) -> docs.() + is_nil(docs) -> [] + true -> docs + end + |> Keyword.merge(cli_opts) + |> normalize(config, [:source_url, :homepage_url]) # accepted at root level config + end defp normalize(options, config, keys) do Enum.reduce(keys, options, fn key, options_ -> - case config[key] do - nil -> options + case Keyword.get(config, key) do + nil -> options_ value -> Keyword.put(options_, key, value) end end) + |> normalize_source_beam(config) end def normalize_source_beam(options, config) do - source_beam = compile_path(opts, Mix.Project.umbrella?(config)) + source_beam = + case Mix.Project.umbrella?(config) do + false -> Mix.Project.compile_path() - Keyword.put_new(options, :source_beam, source_beam) - end + true -> ignored_apps = Keyword.get(options, :ignore_apps, []) + build = Mix.Project.build_path() - defp compile_path(_options, false), do: Mix.Project.compile_path() - defp compile_path(options, true) do - ignored_apps = Keyword.get(options, :ignore_apps, []) - 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 - for {app, _} <- Mix.Project.apps_paths(), app not in ignored_apps, - do: Path.join([build, "lib", Atom.to_string(app), "ebin"]) + Keyword.put_new(options, :source_beam, source_beam) + |> normalize_main() end - defp normalize_main(options), do: normalize_main(options, options[:main]) + defp normalize_main(options) do + main = options[:main] - defp normalize_main(options, nil), do: Keyword.delete(options, :main) - defp normalize_main(options, main) when is_atom(main), do: Keyword.put(options, :main, inspect(main)) - defp normalize_main(options, main) when is_binary(main), do: options + cond do + is_binary(main) -> options + is_atom(main) -> Keyword.put(options, :main, inspect(main)) + is_nil(main) -> Keyword.delete(options, :main) + end + |> normalize_deps() + end defp normalize_deps(options) do user_deps = Keyword.get(options, :deps, []) @@ -307,6 +324,7 @@ defmodule Mix.Tasks.Docs do do: {List.to_string(lib_dir), doc} Keyword.put(options, :deps, deps) + # call stack returns to `run/1` end defp get_deps, do: @@ -314,18 +332,4 @@ defmodule Mix.Tasks.Docs do _ = Application.load(key), vsn = Application.spec(key, :vsn), do: {key, "https://hexdocs.pm/#{key}/#{vsn}/"} - - defp get_formatters(options) do - case Keyword.get_values(options, :formatter) do - [] -> options[:formatters] || [ExDoc.Config.default_formatter()] - values -> values - end - end end - -# TODO: Review docs. -# TODO: Add commit message w/ explanation. -# THEN, put up a PR. Also, offer to just work on the fork and PR the finished product... -# Explain that I tried to create a PR a few months ago, but got lost in the code. -# As the team didn't have the bandwidth to provide documentation, -# I'm trying to do that (along with cleaning up the code) in my fork. From 8f420166332303dcdae4f59286c05472f0efdef9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 8 Dec 2018 19:48:39 -0800 Subject: [PATCH 3/6] + Table of Contents --- lib/mix/tasks/docs.ex | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index ec1cc9049..daf94ff42 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -265,7 +265,16 @@ defmodule Mix.Tasks.Docs do end end - + # 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] @@ -275,10 +284,10 @@ defmodule Mix.Tasks.Docs do true -> docs end |> Keyword.merge(cli_opts) - |> normalize(config, [:source_url, :homepage_url]) # accepted at root level config + |> normalize_urls(config, [:source_url, :homepage_url]) # accepted at root level config end - defp normalize(options, config, keys) do + defp normalize_urls(options, config, keys) do Enum.reduce(keys, options, fn key, options_ -> case Keyword.get(config, key) do nil -> options_ From d93c1d35c1c4d3c48aa53c2e604fbc32bfb3fc6f Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 8 Dec 2018 20:15:53 -0800 Subject: [PATCH 4/6] - bug, + all tests passing --- lib/mix/tasks/docs.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index daf94ff42..e3f6b521a 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -317,9 +317,9 @@ defmodule Mix.Tasks.Docs do main = options[:main] cond do - is_binary(main) -> options - is_atom(main) -> Keyword.put(options, :main, inspect(main)) is_nil(main) -> Keyword.delete(options, :main) + is_atom(main) -> Keyword.put(options, :main, inspect(main)) + is_binary(main) -> options end |> normalize_deps() end From 7e5c587c7b626f5afcce82aa5ea4fa8f8cf8a04a Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 8 Dec 2018 20:22:25 -0800 Subject: [PATCH 5/6] ... --- lib/mix/tasks/docs.ex | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index e3f6b521a..035ed1392 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -260,7 +260,7 @@ defmodule Mix.Tasks.Docs do defp get_formatters(options) do case Keyword.get_values(options, :formatter) do - [] -> options[:formatters] || [ExDoc.Config.default_formatter()] + [] -> options[:formatters] || [ExDoc.Config.default_formatter()] values -> values end end @@ -290,7 +290,7 @@ defmodule Mix.Tasks.Docs do defp normalize_urls(options, config, keys) do Enum.reduce(keys, options, fn key, options_ -> case Keyword.get(config, key) do - nil -> options_ + nil -> options_ value -> Keyword.put(options_, key, value) end end) @@ -325,12 +325,10 @@ defmodule Mix.Tasks.Docs do end defp normalize_deps(options) do - user_deps = Keyword.get(options, :deps, []) - - deps = for {app, doc} <- Keyword.merge(get_deps(), user_deps), - lib_dir = :code.lib_dir(app), - is_list(lib_dir), - do: {List.to_string(lib_dir), doc} + 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` From eed582aa1868228ea0f6eccc10b3278d5ea08db5 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 8 Dec 2018 22:06:32 -0800 Subject: [PATCH 6/6] ... mix format --- lib/mix/tasks/docs.ex | 51 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index 035ed1392..cd356f7f4 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -246,7 +246,8 @@ defmodule Mix.Tasks.Docs do project = to_string(config[:name] || config[:app]) version = config[:version] || "dev" - options = get_docs_opts(config, cli_opts) # def'd after `get_formatters/1` + 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)) @@ -260,7 +261,7 @@ defmodule Mix.Tasks.Docs do defp get_formatters(options) do case Keyword.get_values(options, :formatter) do - [] -> options[:formatters] || [ExDoc.Config.default_formatter()] + [] -> options[:formatters] || [ExDoc.Config.default_formatter()] values -> values end end @@ -280,17 +281,18 @@ defmodule Mix.Tasks.Docs do cond do is_function(docs, 0) -> docs.() - is_nil(docs) -> [] - true -> docs + is_nil(docs) -> [] + true -> docs end |> Keyword.merge(cli_opts) - |> normalize_urls(config, [:source_url, :homepage_url]) # accepted at root level config + # accepted at root level config + |> normalize_urls(config, [:source_url, :homepage_url]) end defp normalize_urls(options, config, keys) do Enum.reduce(keys, options, fn key, options_ -> case Keyword.get(config, key) do - nil -> options_ + nil -> options_ value -> Keyword.put(options_, key, value) end end) @@ -300,13 +302,16 @@ defmodule Mix.Tasks.Docs do def normalize_source_beam(options, config) do source_beam = case Mix.Project.umbrella?(config) do - false -> Mix.Project.compile_path() + false -> + Mix.Project.compile_path() - true -> ignored_apps = Keyword.get(options, :ignore_apps, []) - build = Mix.Project.build_path() + true -> + ignored_apps = Keyword.get(options, :ignore_apps, []) + 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"]) + 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) @@ -317,26 +322,30 @@ defmodule Mix.Tasks.Docs do main = options[:main] cond do - is_nil(main) -> Keyword.delete(options, :main) - is_atom(main) -> Keyword.put(options, :main, inspect(main)) + 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 - 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} + 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(), - _ = Application.load(key), + 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}/"} + do: {key, "https://hexdocs.pm/#{key}/#{vsn}/"} + ) end