diff --git a/lib/mix/tasks/docs.ex b/lib/mix/tasks/docs.ex index 29992a3f6..f89971224 100644 --- a/lib/mix/tasks/docs.ex +++ b/lib/mix/tasks/docs.ex @@ -114,6 +114,9 @@ defmodule Mix.Tasks.Docs do * `:output` - Output directory for the generated docs; default: "doc". May be overridden by command line argument. + + *`:ignore_apps` - Apps to be ignored when generating documentation in an umbrella project. + Receives a list of atoms. Example: `[:first_app, :second_app]`. ## Groups @@ -158,7 +161,8 @@ defmodule Mix.Tasks.Docs do ## Umbrella project ExDoc can be used in an umbrella project and generates a single documentation - for all child apps. + for all child apps. You can use the `:ignore_apps` configuration to exclude + certain projects in the umbrella from documentation. Generating documentation per each child app can be achieved by running: @@ -249,7 +253,7 @@ defmodule Mix.Tasks.Docs do defp normalize_source_beam(options, config) do compile_path = if Mix.Project.umbrella?(config) do - umbrella_compile_paths() + umbrella_compile_paths(Keyword.get(options, :ignore_apps, [])) else Mix.Project.compile_path() end @@ -257,10 +261,11 @@ defmodule Mix.Tasks.Docs do Keyword.put_new(options, :source_beam, compile_path) end - defp umbrella_compile_paths do + defp umbrella_compile_paths(ignored_apps) do build = Mix.Project.build_path() - for {app, _} <- Mix.Project.apps_paths() do + for {app, _} <- Mix.Project.apps_paths(), + app not in ignored_apps do Path.join([build, "lib", Atom.to_string(app), "ebin"]) end end diff --git a/test/mix/tasks/docs_test.exs b/test/mix/tasks/docs_test.exs index c2b084e1f..da99ad857 100644 --- a/test/mix/tasks/docs_test.exs +++ b/test/mix/tasks/docs_test.exs @@ -11,80 +11,117 @@ defmodule Mix.Tasks.DocsTest do test "inflects values from app and version" do assert [{"ex_doc", "0.1.0", [formatter: "html", deps: _, source_beam: _]}] = - run([], [app: :ex_doc, version: "0.1.0"]) + run([], app: :ex_doc, version: "0.1.0") end test "accepts multiple formatters from CLI" do - assert [{"ex_doc", "0.1.0", [formatter: "html", deps: _, source_beam: _]}, - {"ex_doc", "0.1.0", [formatter: "epub", deps: _, source_beam: _]}] = - run(["-f", "html", "-f", "epub"], [app: :ex_doc, version: "0.1.0"]) + assert [ + {"ex_doc", "0.1.0", [formatter: "html", deps: _, source_beam: _]}, + {"ex_doc", "0.1.0", [formatter: "epub", deps: _, source_beam: _]} + ] = run(["-f", "html", "-f", "epub"], app: :ex_doc, version: "0.1.0") end test "accepts multiple formatters from config" do - assert [{"ex_doc", "0.1.0", [formatter: "html", deps: _, source_beam: _, formatters: _]}, - {"ex_doc", "0.1.0", [formatter: "epub", deps: _, source_beam: _, formatters: _]}] = - run([], [app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]]]) + assert [ + {"ex_doc", "0.1.0", [formatter: "html", deps: _, source_beam: _, formatters: _]}, + {"ex_doc", "0.1.0", [formatter: "epub", deps: _, source_beam: _, formatters: _]} + ] = run([], app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]]) end test "uses the given name" do assert [{"ExDoc", "0.1.0", [formatter: "html", deps: _, source_beam: _]}] = - run([], [app: :ex_doc, version: "0.1.0", name: "ExDoc"]) + run([], app: :ex_doc, version: "0.1.0", name: "ExDoc") end test "accepts modules in :main" do - assert [{"ex_doc", "dev", [formatter: "html", deps: _, main: "Sample", source_beam: _, ]}] = - run([], [app: :ex_doc, docs: [main: Sample]]) + assert [{"ex_doc", "dev", [formatter: "html", deps: _, main: "Sample", source_beam: _]}] = + run([], app: :ex_doc, docs: [main: Sample]) end test "accepts files in :main" do assert [{"ex_doc", "dev", [formatter: "html", deps: _, source_beam: _, main: "another"]}] = - run([], [app: :ex_doc, docs: [main: "another"]]) + run([], app: :ex_doc, docs: [main: "another"]) end test "accepts output in :output" do assert [{"ex_doc", "dev", [formatter: "html", deps: _, source_beam: _, output: "hello"]}] = - run([], [app: :ex_doc, docs: [output: "hello"]]) + run([], app: :ex_doc, docs: [output: "hello"]) end test "parses output with lower preference than options" do assert [{"ex_doc", "dev", [formatter: "html", deps: _, source_beam: _, output: "world"]}] = - run(~w(-o world), [app: :ex_doc, docs: [output: "world"]]) + run(~w(-o world), app: :ex_doc, docs: [output: "world"]) end test "includes dependencies" do assert [{"ex_doc", "dev", [formatter: "html", deps: deps, source_beam: _]}] = - run([], [app: :ex_doc, docs: []]) + run([], app: :ex_doc, docs: []) + assert List.keyfind(deps, Application.app_dir(:earmark), 0) == - {Application.app_dir(:earmark), "https://hexdocs.pm/earmark/#{Application.spec(:earmark, :vsn)}/"} + {Application.app_dir(:earmark), + "https://hexdocs.pm/earmark/#{Application.spec(:earmark, :vsn)}/"} end test "allows custom dependency paths" do assert [{"ex_doc", "dev", [formatter: "html", deps: deps, source_beam: _]}] = - run([], [app: :ex_doc, docs: [deps: [earmark: "foo"]]]) + run([], app: :ex_doc, docs: [deps: [earmark: "foo"]]) + assert List.keyfind(deps, Application.app_dir(:earmark), 0) == - {Application.app_dir(:earmark), "foo"} + {Application.app_dir(:earmark), "foo"} end test "accepts lazy docs" do assert [{"ex_doc", "dev", [formatter: "html", deps: _, source_beam: _, main: "another"]}] = - run([], [app: :ex_doc, docs: fn -> [main: "another"] end]) + run([], app: :ex_doc, docs: fn -> [main: "another"] end) end test "accepts options from root" do # accepted options are: `app`, `name`, `source_url`, `homepage_url`, `version` - assert [{"ExDoc", "1.2.3-dev", - [formatter: "html", - deps: _, source_beam: _, - homepage_url: "http://elixir-lang.org", - source_url: "https://github.com/elixir-lang/ex_doc", - ]}] = - run([], [app: :ex_doc, - name: "ExDoc", - source_url: "https://github.com/elixir-lang/ex_doc", - homepage_url: "http://elixir-lang.org", - version: "1.2.3-dev", - ]) - - assert [{"ex_doc", "dev", _}] = run([], [app: :ex_doc]) + assert [ + {"ExDoc", "1.2.3-dev", + [ + formatter: "html", + deps: _, + source_beam: _, + homepage_url: "http://elixir-lang.org", + source_url: "https://github.com/elixir-lang/ex_doc" + ]} + ] = + run([], + app: :ex_doc, + name: "ExDoc", + source_url: "https://github.com/elixir-lang/ex_doc", + homepage_url: "http://elixir-lang.org", + version: "1.2.3-dev" + ) + + assert [{"ex_doc", "dev", _}] = run([], app: :ex_doc) + end + + test "supports umbrella project" do + Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod -> + [ + {"umbrella", "dev", + [ + formatter: "html", + deps: _, + source_beam: _ + ]} + ] = run([], app: :umbrella, apps_path: "apps/", docs: []) + end) + end + + test "supports umbrella project with ignore_apps" do + Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod -> + [ + {"umbrella", "dev", + [ + formatter: "html", + deps: _, + source_beam: _, + ignore_apps: [:foo] + ]} + ] = run([], app: :umbrella, apps_path: "apps/", docs: [ignore_apps: [:foo]]) + end) end end