From 19a641cd7b427ce92f68b8fd55a8cb2886326cb8 Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Thu, 25 Oct 2018 14:01:56 +0200 Subject: [PATCH 1/7] Autolink mix tasks --- lib/ex_doc/formatter/html/autolink.ex | 39 +++++++++++++++++++- test/ex_doc/formatter/html/autolink_test.exs | 32 ++++++++++++++++ test/ex_doc/formatter/html_test.exs | 3 ++ test/fixtures/README.md | 1 + 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/lib/ex_doc/formatter/html/autolink.ex b/lib/ex_doc/formatter/html/autolink.ex index aa8c3557f..331127828 100644 --- a/lib/ex_doc/formatter/html/autolink.ex +++ b/lib/ex_doc/formatter/html/autolink.ex @@ -106,7 +106,7 @@ defmodule ExDoc.Formatter.HTML.Autolink do language <- [:elixir, :erlang], kind <- [:module, :function] do {kind, language, link_type} - end) + end) ++ [{:mix_task, :elixir, :normal}] @doc """ Autolinks any documentation in the project. @@ -447,6 +447,37 @@ defmodule ExDoc.Formatter.HTML.Autolink do end end + defp replace_fun(:mix_task, :elixir, _link_type, options) do + extension = options[:extension] || ".html" + lib_dirs = options[:lib_dirs] || default_lib_dirs(:elixir) + module_id = options[:module_id] || nil + modules_refs = options[:modules_refs] || [] + + fn all, text, "mix " <> task_name -> + task_module = + task_name + |> String.split(".") + |> Enum.map(&Macro.camelize/1) + |> Enum.join(".") + + match = "Mix.Tasks." <> task_module + + cond do + match == module_id -> + "[#{text}](#{match}#{extension}#content)" + + match in modules_refs -> + "[#{text}](#{match}#{extension})" + + doc = module_docs(:elixir, match, lib_dirs) -> + "[#{text}](#{doc}#{match}.html)" + + true -> + all + end + end + end + ## Helpers defp default_text(_, :custom, _match, _pmfa, text), @@ -721,6 +752,12 @@ defmodule ExDoc.Formatter.HTML.Autolink do }x end + defp re_kind_language(:mix_task, :elixir) do + ~r{ + mix\ ([a-z]+[a-z0-9\._]*) + }x + end + defp re_kind_language_link_type(kind, language, link_type) do source = Regex.source(re_kind_language(kind, language)) diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index 9a280e9a6..c970ed8b4 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -327,6 +327,38 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end end + describe "mix tasks" do + test "autolinks built-in tasks" do + assert project_doc("`mix test`", %{}) == + "[`mix test`](#{@elixir_docs}mix/Mix.Tasks.Test.html)" + end + + test "autolinks custom tasks" do + assert project_doc("`mix foo.bar.baz`", %{modules_refs: ["Mix.Tasks.Foo.Bar.Baz"]}) == + "[`mix foo.bar.baz`](Mix.Tasks.Foo.Bar.Baz.html)" + end + + test "autolinks tasks from dependencies" do + # using hex (archive) as we don't depend on any packages with mix tasks + lib_dirs = [{Application.app_dir(:hex), "#{@elixir_docs}hex/"}] + + assert project_doc("`mix hex.publish`", %{ + docs_refs: ["MyModule"], + module_id: "MyModule", + extension: ".html", + lib_dirs: lib_dirs + }) == "[`mix hex.publish`](#{@elixir_docs}hex/Mix.Tasks.Hex.Publish.html)" + end + + test "does not autolink task with arguments" do + assert project_doc("`mix test test/`", %{}) == "`mix test test/`" + end + + test "does not autolink unknown task" do + assert project_doc("`mix foo`", %{}) == "`mix foo`" + end + end + describe "Erlang modules" do test "autolinks to Erlang modules" do assert project_doc("`:erlang`", %{}) == "[`:erlang`](#{@erlang_docs}erlang.html)" diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index 2d962f71f..3926b12ea 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -268,6 +268,9 @@ defmodule ExDoc.Formatter.HTMLTest do assert content =~ ~r{atom/0} + + assert content =~ + ~r{mix compile.elixir} end test "without any other content" do diff --git a/test/fixtures/README.md b/test/fixtures/README.md index b7a855250..e005988d3 100644 --- a/test/fixtures/README.md +++ b/test/fixtures/README.md @@ -5,6 +5,7 @@ `==/2` [`===`](`Kernel.===/2`) `t:atom/0` +`mix compile.elixir` ## `Header` sample From 7948f6f539476d3b457832e85f50dec10ae95c4b Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Thu, 25 Oct 2018 14:24:04 +0200 Subject: [PATCH 2/7] Add test for same module --- test/ex_doc/formatter/html/autolink_test.exs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index c970ed8b4..4cad75392 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -338,6 +338,11 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do "[`mix foo.bar.baz`](Mix.Tasks.Foo.Bar.Baz.html)" end + test "autolinks task in the same module" do + assert project_doc("`mix foo`", %{modules_refs: ["Mix.Tasks.Foo"], module_id: "Mix.Tasks.Foo"}) == + "[`mix foo`](Mix.Tasks.Foo.html#content)" + end + test "autolinks tasks from dependencies" do # using hex (archive) as we don't depend on any packages with mix tasks lib_dirs = [{Application.app_dir(:hex), "#{@elixir_docs}hex/"}] From 93a5e878a2834c9d77c562ec6f8de194700764bc Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Thu, 25 Oct 2018 14:36:24 +0200 Subject: [PATCH 3/7] Update kind/0 type --- lib/ex_doc/formatter/html/autolink.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ex_doc/formatter/html/autolink.ex b/lib/ex_doc/formatter/html/autolink.ex index 331127828..1221fec33 100644 --- a/lib/ex_doc/formatter/html/autolink.ex +++ b/lib/ex_doc/formatter/html/autolink.ex @@ -5,7 +5,7 @@ defmodule ExDoc.Formatter.HTML.Autolink do import ExDoc.Formatter.HTML.Templates, only: [h: 1, enc_h: 1] @type language :: :elixir | :erlang | :markdown - @type kind :: :function | :module + @type kind :: :function | :module | :mix_task @type link_type :: :normal | :custom @backtick_token "" From c113d853a9b9f98b5fae37712edcbb2a2aef7af2 Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Thu, 25 Oct 2018 14:53:37 +0200 Subject: [PATCH 4/7] Format --- test/ex_doc/formatter/html/autolink_test.exs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index 4cad75392..a1ffbbf74 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -339,8 +339,10 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks task in the same module" do - assert project_doc("`mix foo`", %{modules_refs: ["Mix.Tasks.Foo"], module_id: "Mix.Tasks.Foo"}) == - "[`mix foo`](Mix.Tasks.Foo.html#content)" + assert project_doc("`mix foo`", %{ + modules_refs: ["Mix.Tasks.Foo"], + module_id: "Mix.Tasks.Foo" + }) == "[`mix foo`](Mix.Tasks.Foo.html#content)" end test "autolinks tasks from dependencies" do From 5e00c0858aecdfa9506774316218162af25cd3f9 Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Thu, 25 Oct 2018 15:05:58 +0200 Subject: [PATCH 5/7] Update comment thanks @fertapric! --- lib/ex_doc/formatter/html/autolink.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ex_doc/formatter/html/autolink.ex b/lib/ex_doc/formatter/html/autolink.ex index 1221fec33..3114cd6f1 100644 --- a/lib/ex_doc/formatter/html/autolink.ex +++ b/lib/ex_doc/formatter/html/autolink.ex @@ -325,7 +325,7 @@ defmodule ExDoc.Formatter.HTML.Autolink do # # `language` can be: `:elixir`, `:erlang` or `:markdown`. # - # `kind` is either `:function` or `:module`. + # `kind` is either `:function`, `:module`, or `:mix_task`. # # It accepts a list of `options` used in the replacement functions. # - `:aliases From 2010e9fac4388c893f5fa1b87857730b6ce2ef31 Mon Sep 17 00:00:00 2001 From: Fernando Tapia Rico Date: Thu, 25 Oct 2018 16:41:37 +0200 Subject: [PATCH 6/7] Update test/ex_doc/formatter/html/autolink_test.exs Co-Authored-By: wojtekmach --- test/ex_doc/formatter/html/autolink_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index a1ffbbf74..951e8be32 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -346,7 +346,7 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks tasks from dependencies" do - # using hex (archive) as we don't depend on any packages with mix tasks + # Using Hex (archive) as we don't depend on any packages with Mix tasks lib_dirs = [{Application.app_dir(:hex), "#{@elixir_docs}hex/"}] assert project_doc("`mix hex.publish`", %{ From feaf03a14624c9dc364b021d4c0fc0bcc968334c Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Sat, 27 Oct 2018 19:09:45 +0200 Subject: [PATCH 7/7] Review feedback --- lib/ex_doc/formatter/html/autolink.ex | 4 ++-- test/ex_doc/formatter/html/autolink_test.exs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ex_doc/formatter/html/autolink.ex b/lib/ex_doc/formatter/html/autolink.ex index 3114cd6f1..21b094181 100644 --- a/lib/ex_doc/formatter/html/autolink.ex +++ b/lib/ex_doc/formatter/html/autolink.ex @@ -447,7 +447,7 @@ defmodule ExDoc.Formatter.HTML.Autolink do end end - defp replace_fun(:mix_task, :elixir, _link_type, options) do + defp replace_fun(:mix_task, :elixir, :normal, options) do extension = options[:extension] || ".html" lib_dirs = options[:lib_dirs] || default_lib_dirs(:elixir) module_id = options[:module_id] || nil @@ -754,7 +754,7 @@ defmodule ExDoc.Formatter.HTML.Autolink do defp re_kind_language(:mix_task, :elixir) do ~r{ - mix\ ([a-z]+[a-z0-9\._]*) + mix\ ([a-z][a-z0-9\._]*) }x end diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index 951e8be32..42e8d0247 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -327,7 +327,7 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end end - describe "mix tasks" do + describe "Mix tasks" do test "autolinks built-in tasks" do assert project_doc("`mix test`", %{}) == "[`mix test`](#{@elixir_docs}mix/Mix.Tasks.Test.html)"