Skip to content

Commit

Permalink
Do auto detection of both Exceptions and Deprecated
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Jan 30, 2020
1 parent b82d0b3 commit 1fd03cd
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 70 deletions.
56 changes: 30 additions & 26 deletions lib/ex_doc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,25 @@ defmodule ExDoc do
# Builds configuration by merging `options`, and normalizing the options.
@spec build_config(String.t(), String.t(), Keyword.t()) :: ExDoc.Config.t()
defp build_config(project, vsn, options) do
options = normalize_options(options)
{output, options} = Keyword.pop(options, :output, "./doc")
{groups_for_modules, options} = Keyword.pop(options, :groups_for_modules, [])
{nest_modules_by_prefix, options} = Keyword.pop(options, :nest_modules_by_prefix, [])

{source_url_pattern, options} =
Keyword.pop_lazy(options, :source_url_pattern, fn ->
guess_url(options[:source_url], options[:source_ref] || ExDoc.Config.default_source_ref())
end)

preconfig = %Config{
project: project,
version: vsn,
main: options[:main],
output: normalize_output(output),
homepage_url: options[:homepage_url],
source_root: options[:source_root] || File.cwd!()
source_root: options[:source_root] || File.cwd!(),
source_url_pattern: source_url_pattern,
nest_modules_by_prefix: normalize_nest_modules_by_prefix(nest_modules_by_prefix),
groups_for_modules: normalize_groups_for_modules(groups_for_modules)
}

struct(preconfig, options)
Expand Down Expand Up @@ -68,37 +79,30 @@ defmodule ExDoc do

# Helpers

defp normalize_options(options) do
pattern =
options[:source_url_pattern] ||
guess_url(options[:source_url], options[:source_ref] || ExDoc.Config.default_source_ref())

options
|> Keyword.put(:source_url_pattern, pattern)
|> normalize_output()
|> normalize_module_nesting_prefixes()
defp normalize_output(output) do
String.trim_trailing(output, "/")
end

defp normalize_output(options) do
if is_binary(options[:output]) do
Keyword.put(options, :output, String.trim_trailing(options[:output], "/"))
else
options
end
defp normalize_groups_for_modules(groups_for_modules) do
default_groups = [Deprecated: &deprecated?/1, Exceptions: &exception?/1]

groups_for_modules ++
Enum.reject(default_groups, fn {k, _} -> Keyword.has_key?(groups_for_modules, k) end)
end

defp normalize_module_nesting_prefixes(options) do
# sort in descending order to facilitate finding longest match
normalized_prefixes =
options
|> Keyword.get(:nest_modules_by_prefix, [])
|> Enum.map(&inspect/1)
|> Enum.sort()
|> Enum.reverse()
defp deprecated?(%{deprecated: deprecated}), do: is_binary(deprecated)
defp exception?(%{type: type}), do: type == :exception

Keyword.put(options, :nest_modules_by_prefix, normalized_prefixes)
defp normalize_nest_modules_by_prefix(nest_modules_by_prefix) do
nest_modules_by_prefix
|> Enum.map(&inspect_atoms/1)
|> Enum.sort()
|> Enum.reverse()
end

defp inspect_atoms(atom) when is_atom(atom), do: inspect(atom)
defp inspect_atoms(binary) when is_binary(binary), do: binary

defp guess_url(url, ref) do
with {:ok, host_with_path} <- http_or_https(url),
{:ok, pattern} <- known_pattern(host_with_path, ref) do
Expand Down
14 changes: 1 addition & 13 deletions lib/ex_doc/formatter/html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule ExDoc.Formatter.HTML do
search_items = generate_search_items(project_nodes, extras, config)

nodes_map = %{
modules: filter_list(:module, project_nodes) |> group_exceptions(),
modules: filter_list(:module, project_nodes),
tasks: filter_list(:task, project_nodes)
}

Expand Down Expand Up @@ -397,18 +397,6 @@ defmodule ExDoc.Formatter.HTML do
Enum.filter(nodes, &(&1.type == type))
end

@exceptions_group_name "Exceptions"
defp group_exceptions(module_nodes) do
module_nodes
|> Enum.map(fn module_node ->
case module_node.type do
:exception -> %{module_node | group: @exceptions_group_name}
_ -> module_node
end
end)
|> Enum.sort_by(&(&1.type == :exception))
end

defp generate_list(nodes, nodes_map, config) do
nodes
|> Task.async_stream(&generate_module_page(&1, nodes_map, config), timeout: :infinity)
Expand Down
9 changes: 6 additions & 3 deletions lib/ex_doc/group_matcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ defmodule ExDoc.GroupMatcher do
@doc """
Finds a matching group for the given module name or id.
"""
@spec match_module(group_patterns, module(), String.t()) :: atom() | nil
def match_module(group_patterns, module, id) do
@spec match_module(group_patterns, ExDoc.ModuleNode.t()) :: atom() | nil
def match_module(group_patterns, node) do
%{id: id, module: module} = node

match_group_patterns(group_patterns, fn pattern ->
case pattern do
%Regex{} = regex -> Regex.match?(regex, id)
string when is_binary(string) -> id == string
atom -> atom == module
atom when is_atom(atom) -> atom == module
function when is_function(function) -> function.(node)
end
end)
end
Expand Down
37 changes: 19 additions & 18 deletions lib/ex_doc/retriever.ex
Original file line number Diff line number Diff line change
Expand Up @@ -132,26 +132,27 @@ defmodule ExDoc.Retriever do
docs = function_docs ++ get_callbacks(module_data, source)
types = get_types(module_data, source)
{title, id} = module_title_and_id(module_data)
module_group = GroupMatcher.match_module(config.groups_for_modules, module, id)
{nested_title, nested_context} = nesting_info(title, config.nest_modules_by_prefix)

%ExDoc.ModuleNode{
id: id,
title: title,
nested_title: nested_title,
nested_context: nested_context,
module: module_data.name,
group: module_group,
type: module_data.type,
deprecated: metadata[:deprecated],
function_groups: function_groups,
docs: Enum.sort_by(docs, &{&1.name, &1.arity}),
doc: moduledoc,
doc_line: doc_line,
typespecs: Enum.sort_by(types, &{&1.name, &1.arity}),
source_path: source_path,
source_url: source_link(source, line)
}
node =
%ExDoc.ModuleNode{
id: id,
title: title,
nested_title: nested_title,
nested_context: nested_context,
module: module,
type: module_data.type,
deprecated: metadata[:deprecated],
function_groups: function_groups,
docs: Enum.sort_by(docs, &{&1.name, &1.arity}),
doc: moduledoc,
doc_line: doc_line,
typespecs: Enum.sort_by(types, &{&1.name, &1.arity}),
source_path: source_path,
source_url: source_link(source, line)
}

put_in(node.group, GroupMatcher.match_module(config.groups_for_modules, node))
end

# Module Helpers
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%{
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"cmark": {:hex, :cmark, "0.7.0", "cf20106714b35801df3a2250a8ca478366f93ad6067df9d6815c80b2606ae01e", [:make, :mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.3.3", "5e8be428fcef362692b6dbd7dc55bdc7023da26d995cb3fb19aa4bd682bfd3f9", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
Expand Down
18 changes: 9 additions & 9 deletions test/ex_doc/group_matcher_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,29 @@ defmodule ExDoc.GroupMatcherTest do
Group: [MyApp.SomeModule, :lists]
]

assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group
assert match_module(patterns, :lists, ":lists") == :Group
assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == nil
assert match_module(patterns, %{module: MyApp.SomeModule, id: "MyApp.SomeModule"}) == :Group
assert match_module(patterns, %{module: :lists, id: ":lists"}) == :Group
assert match_module(patterns, %{module: MyApp.SomeOtherModule, id: "MyApp.SomeOtherModule"}) == nil
end

test "it can match modules by their string names" do
patterns = [
Group: ["MyApp.SomeModule", ":lists"]
]

assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group
assert match_module(patterns, :lists, ":lists") == :Group
assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == nil
assert match_module(patterns, %{module: MyApp.SomeModule, id: "MyApp.SomeModule"}) == :Group
assert match_module(patterns, %{module: :lists, id: ":lists"}) == :Group
assert match_module(patterns, %{module: MyApp.SomeOtherModule, id: "MyApp.SomeOtherModule"}) == nil
end

test "it can match modules by regular expressions" do
patterns = [
Group: ~r/MyApp\..?/
]

assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group
assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == :Group
assert match_module(patterns, MyAppWeb.SomeOtherModule, "MyAppWeb.SomeOtherModule") == nil
assert match_module(patterns, %{module: MyApp.SomeModule, id: "MyApp.SomeModule"}) == :Group
assert match_module(patterns, %{module: MyApp.SomeOtherModule, id: "MyApp.SomeOtherModule"}) == :Group
assert match_module(patterns, %{module: MyAppWeb.SomeOtherModule, id: "MyAppWeb.SomeOtherModule"}) == nil
end
end

Expand Down

0 comments on commit 1fd03cd

Please sign in to comment.