diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a7ab5d3ff..ae31e39e12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * The `User-Agent` header set in the linkcheck HTTP(S) requests can now be customized with the `linkcheck_useragent` option to `makedocs`. ([#2557], [#2562]) * Admonitions with category `todo` are now colored purple. Previously they were default-colored like all other unknown admonitions categories. ([#2526]) +* A `checkdocs_ignored_modules` keyword argument to `makedocs(...)`, which prevents `checkdocs` from warning about missing documentation in certain modules. ([#2233]) ### Changed @@ -1821,6 +1822,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#2216]: https://github.com/JuliaDocs/Documenter.jl/issues/2216 [#2217]: https://github.com/JuliaDocs/Documenter.jl/issues/2217 [#2232]: https://github.com/JuliaDocs/Documenter.jl/issues/2232 +[#2233]: https://github.com/JuliaDocs/Documenter.jl/issues/2233 [#2236]: https://github.com/JuliaDocs/Documenter.jl/issues/2236 [#2237]: https://github.com/JuliaDocs/Documenter.jl/issues/2237 [#2245]: https://github.com/JuliaDocs/Documenter.jl/issues/2245 diff --git a/src/documents.jl b/src/documents.jl index 1638b02aaf..05e9cf6b89 100644 --- a/src/documents.jl +++ b/src/documents.jl @@ -314,6 +314,7 @@ struct User linkcheck_timeout::Real # ..but only wait this many seconds for each one. linkcheck_useragent::String # User agent to use for linkchecks. checkdocs::Symbol # Check objects missing from `@docs` blocks. `:none`, `:exports`, or `:all`. + checkdocs_ignored_modules::Vector{Module} # ..and then ignore (some of) them. doctestfilters::Vector{Regex} # Filtering for doctests warnonly::Vector{Symbol} # List of docerror groups that should only warn, rather than cause a build failure pages :: Vector{Any} # Ordering of document pages specified by the user. @@ -388,6 +389,7 @@ function Document(; linkcheck_timeout :: Real = 10, linkcheck_useragent :: String= _LINKCHECK_DEFAULT_USERAGENT, checkdocs::Symbol = :all, + checkdocs_ignored_modules::Vector{Module} = Module[], doctestfilters::Vector{Regex}= Regex[], warnonly :: Union{Bool,Symbol,Vector{Symbol}} = Symbol[], modules :: Union{Module, Vector{Module}} = Module[], @@ -454,6 +456,7 @@ function Document(; linkcheck_timeout, linkcheck_useragent, checkdocs, + checkdocs_ignored_modules, doctestfilters, warnonly, pages, @@ -494,7 +497,7 @@ function Document(; blueprint = DocumentBlueprint( Dict{String, Page}(), - submodules(modules), + submodules(modules; ignore=Set(checkdocs_ignored_modules)), ) Document(user, internal, plugin_dict, blueprint) end diff --git a/src/makedocs.jl b/src/makedocs.jl index 33f4893618..dc3d44e737 100644 --- a/src/makedocs.jl +++ b/src/makedocs.jl @@ -178,7 +178,15 @@ are `:all` (check all names; the default), `:exports` (check only exported names `:none` (no checks are performed). By default, if the document check detect any errors, it will fail the documentation build. -This behavior can be relaxed with the `warnonly` keyword. +This behavior can be relaxed with the `warnonly` or `checkdocs_ignored_modules` keywords. + +**`checkdocs_ignored_modules`** prevents `checkdocs` from checking modules supplied as a list +of module objects. It will also cause all submodules of these module to be ignored. It can be +useful for completely private modules including modules which have been vendored from +elsewhere. + +Note that `checkdocs_ignored_modules` does not conversely verify that these docstrings are *not* +included in the documentation. **`linkcheck`** -- if set to `true` [`makedocs`](@ref) uses `curl` to check the status codes of external-pointing links, to make sure that they are up-to-date. The links and their diff --git a/src/utilities/utilities.jl b/src/utilities/utilities.jl index 1abbdb337e..66c2307fc0 100644 --- a/src/utilities/utilities.jl +++ b/src/utilities/utilities.jl @@ -201,19 +201,19 @@ end """ Returns the set of submodules of a given root module/s. """ -function submodules(modules::Vector{Module}) +function submodules(modules::Vector{Module}; ignore = Set{Module}()) out = Set{Module}() for each in modules - submodules(each, out) + submodules(each, out; ignore=ignore) end out end -function submodules(root::Module, seen = Set{Module}()) +function submodules(root::Module, seen = Set{Module}(); ignore = Set{Module}()) push!(seen, root) for name in names(root, all=true) if Base.isidentifier(name) && isdefined(root, name) && !isdeprecated(root, name) object = getfield(root, name) - if isa(object, Module) && !(object in seen) && parentmodule(object::Module) == root + if isa(object, Module) && !(object in seen) && !(object in ignore) && parentmodule(object::Module) == root submodules(object, seen) end end diff --git a/test/missingdocs/make.jl b/test/missingdocs/make.jl index 4399ea2aa9..40be86e1bf 100644 --- a/test/missingdocs/make.jl +++ b/test/missingdocs/make.jl @@ -13,6 +13,15 @@ module MissingDocs g(x) = x end +module MissingDocsSubmodule + module UndocumentedSubmodule + export f + + "exported" + f(x) = x + end +end + @testset "missing docs" begin for (sym, n_expected) in zip([:none, :exports, :all], [0, 1, 2]) kwargs = ( @@ -38,6 +47,23 @@ end checkdocs = :all, sitename = "MissingDocs Checks", ) + + for (ignore, n_expected) in zip([false, true] , [1, 0]) + kwargs = ( + root = dirname(@__FILE__), + source = joinpath("src", "none"), + build = joinpath("build", "submodule"), + modules = MissingDocsSubmodule, + checkdocs = :all, + sitename = "MissingDocsSubmodule Checks", + warnonly = true, + checkdocs_ignored_modules = ignore ? Module[MissingDocsSubmodule.UndocumentedSubmodule] : Module[], + ) + @quietly @test makedocs(; kwargs...) === nothing + + doc = Documenter.Document(; kwargs...) + @quietly @test Documenter.missingdocs(doc) == n_expected + end end end