diff --git a/CHANGELOG.md b/CHANGELOG.md index c96d556..5c3116d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # DocumenterTools.jl changelog +## Unreleased + +* ![Enhancement][badge-enhancement] DocumenterTools now provides a `DocumenterTools.walkdocs` function. ([#75][github-75]) + ## Version `v0.1.17` * ![Enhancement][badge-enhancement] The compiled CSS files generated by DocumenterTools are now minified. ([#71][github-71]) @@ -102,6 +106,7 @@ Maintenance release declaring compatibility with Documenter 0.25. ([#39][github- [github-64]: https://github.com/JuliaDocs/DocumenterTools.jl/issues/64 [github-65]: https://github.com/JuliaDocs/DocumenterTools.jl/pull/65 [github-71]: https://github.com/JuliaDocs/DocumenterTools.jl/pull/71 +[github-75]: https://github.com/JuliaDocs/DocumenterTools.jl/pull/75 [badge-breaking]: https://img.shields.io/badge/BREAKING-red.svg diff --git a/src/DocumenterTools.jl b/src/DocumenterTools.jl index bb36c83..375c3c1 100644 --- a/src/DocumenterTools.jl +++ b/src/DocumenterTools.jl @@ -174,6 +174,7 @@ function package_devpath(pkg::Module) return normpath(joinpath(path, "..", "..")) end +include("walkdocs.jl") include("genkeys.jl") include("Generator.jl") include("Themes.jl") diff --git a/src/OutdatedWarning.jl b/src/OutdatedWarning.jl index e3314bc..c272a1c 100644 --- a/src/OutdatedWarning.jl +++ b/src/OutdatedWarning.jl @@ -1,6 +1,7 @@ export OutdatedWarning module OutdatedWarning +import ..DocumenterTools using Gumbo, AbstractTrees, Documenter OLD_VERSION_CSS = replace(""" @@ -168,20 +169,18 @@ function generate(io::IO, root::String;force = false) end print(io, "Processing $(dir): ") - for (root, _, files) in walkdir(path) - for file in files - _, ext = splitext(file) - if ext == ".html" - try - did_change = add_old_docs_notice(joinpath(root, file), force) - print(io, did_change ? "✓" : ".") - catch err - if err isa InterruptException - rethrow() - end - @debug "Fatally failed to add a outdated warning" exception = (err, catch_backtrace()) - print(io, "!") + DocumenterTools.walkdocs(path) do fileinfo + _, ext = splitext(fileinfo.filename) + if ext == ".html" + try + did_change = add_old_docs_notice(fileinfo.fullpath, force) + print(io, did_change ? "✓" : ".") + catch err + if err isa InterruptException + rethrow() end + @debug "Fatally failed to add a outdated warning" exception = (err, catch_backtrace()) + print(io, "!") end end end diff --git a/src/walkdocs.jl b/src/walkdocs.jl new file mode 100644 index 0000000..1f9343b --- /dev/null +++ b/src/walkdocs.jl @@ -0,0 +1,41 @@ +""" + walkdocs(f, dir::AbstractString; collect::Bool=false) + +Takes a directory `dir`, which is assumed to contain Documenter-generated HTML documentation, +walks over all the files and calls `f` on each of the HTML files it find. `f` will be called +with a single object that has the following fields (all strings): + +- `root`: the root directory of the walk, i.e. `dir` (but as an absolute path) +- `filename`: file name +- `relpath`: path to the file, relative to `dir` +- `fullpath`: absolute path to the file + +If `collect = true` is set, the function also "collects" all the return values from `f` +from each of the function calls, essentially making `walkdocs` behave like a `map` function +applied on each of the HTML files. +""" +function walkdocs(f, dir::AbstractString; collect::Bool=false) + dir = abspath(dir) + isdir(dir) || error("docwalker: dir is not a directory\n dir = $(dir)") + + mapped_collection = collect ? Any[] : nothing + for (root, _, files) in walkdir(dir) + for file in files + _, ext = splitext(file) + (ext == ".html") || continue + file_fullpath = joinpath(root, file) + file_relpath = Base.relpath(file_fullpath, dir) + fileinfo = (; + root = dir, + filename = file, + relpath = file_relpath, + fullpath = file_fullpath, + ) + r = f(fileinfo) + if collect + push!(mapped_collection, r) + end + end + end + return mapped_collection +end diff --git a/test/outdated.jl b/test/outdated.jl index d5d71e9..6620b78 100644 --- a/test/outdated.jl +++ b/test/outdated.jl @@ -16,12 +16,13 @@ mktempdir() do TMP cp(joinpath(TMP, "fixtures", "pre"), transient_path, force=true) OutdatedWarning.generate(transient_path) - for (root, _, files) in walkdir(transient_path) - for file in files - content = read(joinpath(root, file), String) - expected = read(joinpath(replace(root, "transient" => "post"), file), String) - @test replace(content, "\r\n" => "\n") == replace(expected, "\r\n" => "\n") - end + DocumenterTools.walkdocs(transient_path) do fileinfo + content = read(fileinfo.fullpath, String) + expected = read( + joinpath(replace(dirname(fileinfo.fullpath), "transient" => "post"), fileinfo.filename), + String + ) + @test replace(content, "\r\n" => "\n") == replace(expected, "\r\n" => "\n") end rm(joinpath(TMP, "fixtures"), recursive=true) diff --git a/test/runtests.jl b/test/runtests.jl index ee4d22f..7edd11d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,6 +19,10 @@ import Documenter DocumenterTools.genkeys(DocumenterMarkdown) end + @testset "walkdocs" begin + include("walkdocs.jl") + end + @testset "outdated warnings" begin include("outdated.jl") end diff --git a/test/walkdocs.jl b/test/walkdocs.jl new file mode 100644 index 0000000..0864802 --- /dev/null +++ b/test/walkdocs.jl @@ -0,0 +1,19 @@ +let fileinfos = [] + rs = DocumenterTools.walkdocs(joinpath(@__DIR__, "fixtures")) do fileinfo + push!(fileinfos, fileinfo) + + @test isabspath(fileinfo.root) + @test isabspath(fileinfo.fullpath) + @test !isabspath(fileinfo.relpath) + @test joinpath(fileinfo.root, fileinfo.relpath) == fileinfo.fullpath + end + @test rs === nothing + @test length(fileinfos) == 10 +end + +let rs = DocumenterTools.walkdocs(joinpath(@__DIR__, "fixtures"), collect=true) do fileinfo + fileinfo.root + end + @test length(rs) == 10 + @test all(s -> isa(s, String), rs) +end