Skip to content

Commit

Permalink
Merge pull request #68 from JuliaComputing/mp/fix-windows-ci
Browse files Browse the repository at this point in the history
test: fix line endings in tests on Windows
  • Loading branch information
pfitzseb authored Sep 12, 2023
2 parents 20093b5 + b8d4ed2 commit 7f60411
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 15 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,9 @@ Check [`.github/workflows/deploy.yml`](.github/workflows/deploy.yml) and [`docs/
The result of that script is available at [https://juliacomputing.github.io/MultiDocumenter.jl/](https://juliacomputing.github.io/MultiDocumenter.jl/).

You can of course also just push the output artefact directly to S3 or some other hosting service.

> **Warning**
> MultiDocumenter sites can not be deployed on Windows right now, and the `make()` function will throw an error.
> See [#70](https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70).
>
> It is still possible to develop and debug MultiDocumenter sites on Windows if the build script is run interactively (e.g. by `include`-ing it into a REPL session).
25 changes: 23 additions & 2 deletions src/MultiDocumenter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,26 @@ function make(
canonical_domain::Union{AbstractString,Nothing} = nothing,
sitemap::Bool = false,
sitemap_filename::AbstractString = "sitemap.xml",
# This keyword is for internal test use only:
_override_windows_isinteractive_check::Bool = false,
)
if Sys.iswindows() && !isinteractive()
if _override_windows_isinteractive_check || isinteractive()
@warn """
Running a MultiDocumenter build interactively in Windows.
This should only be used for development and testing, as it will lead to partial
and broken builds. See https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
"""
else
msg = """
MultiDocumenter deployments are disabled on Windows due to difficulties
with handling symlinks in documentation sources.
You _can_ test this build locally by running it interactively (i.e. in the REPL).
See also: https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
"""
error(msg)
end
end
if isnothing(canonical_domain)
(sitemap === true) &&
throw(ArgumentError("When sitemap=true, canonical_domain must also be set"))
Expand Down Expand Up @@ -249,7 +268,8 @@ function maybe_clone(docs::Vector{MultiDocRef})
`$(git()) clone --depth 1 $(doc.giturl) --branch $(doc.branch) --single-branch --no-tags $(doc.upstream)`,
)
else
git_dir, git_worktree = abspath(joinpath(doc.upstream, ".git")), abspath(doc.upstream)
git_dir, git_worktree =
abspath(joinpath(doc.upstream, ".git")), abspath(doc.upstream)
if !isdir(git_dir)
@warn "Unable to update existing clone at $(doc.upstream): .git/ directory missing"
continue
Expand All @@ -266,7 +286,8 @@ function maybe_clone(docs::Vector{MultiDocRef})
catch e
# We're only interested in catching `git` errors here
isa(e, ProcessFailedException) || rethrow()
@error "Unable to update existing clone at $(doc.upstream)" exception = (e, catch_backtrace())
@error "Unable to update existing clone at $(doc.upstream)" exception =
(e, catch_backtrace())
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion src/documentertools/canonical_urls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ function update_canonical_links(docs_directory::AbstractString; canonical::Abstr
# We'll skip all files. This includes files such as index.html, which in this
# directory will likely be the redirect. Also, links should be pointing to other
# versions, so we'll skip them too.
if !isdir(path) || islink(path)
# Note: we need to check islink() first, because on windows, calling isdir() on a
# symlink can make it throw a permissions IOError.
if islink(path) || !isdir(path)
continue
end
# Preview directory is should contain other Documenter directories, so we just add
Expand Down
6 changes: 4 additions & 2 deletions test/documentertools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import MultiDocumenter: DocumenterTools

FIXTURES = joinpath(@__DIR__, "fixtures")

normalize_newlines(s::AbstractString) = replace(s, "\r\n" => "\n")

@testset "walkdocs" begin
let fileinfos = DocumenterTools.FileInfo[]
rs = DocumenterTools.walkdocs(joinpath(FIXTURES, "pre")) do fileinfo
Expand Down Expand Up @@ -123,8 +125,8 @@ end
canonical = "https://example.org/this-is-test",
)
DocumenterTools.walkdocs(joinpath(FIXTURES, "post")) do fileinfo
post = read(fileinfo.fullpath, String)
changed = read(joinpath(out, fileinfo.relpath), String)
post = normalize_newlines(read(fileinfo.fullpath, String))
changed = normalize_newlines(read(joinpath(out, fileinfo.relpath), String))
if changed != post
@error "update_canonical_links: change and post not matching" out fileinfo
end
Expand Down
85 changes: 75 additions & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ docs = [
# giturl = "git@github.com:JuliaComputing/DataSets.jl.git",
),
]

# We do not support deploying docs on Windows at the moment, and MultiDocumenter
# should throw an error if it's being run on Windows (in a non-interactive session).
# See also: https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
if Sys.iswindows() && !isinteractive()
@test_throws ErrorException MultiDocumenter.make(
outpath,
docs;
search_engine = MultiDocumenter.SearchConfig(
index_versions = ["stable", "dev"],
engine = MultiDocumenter.FlexSearch,
),
custom_scripts = [
"foo/bar.js",
"https://foo.com/bar.js",
Docs.HTML("const foo = 'bar';"),
],
rootpath = rootpath,
canonical_domain = "https://example.org/",
sitemap = true,
sitemap_filename = "sitemap-mydocs.xml",
)
end

MultiDocumenter.make(
outpath,
docs;
Expand All @@ -100,15 +124,25 @@ MultiDocumenter.make(
canonical_domain = "https://example.org/",
sitemap = true,
sitemap_filename = "sitemap-mydocs.xml",
# The following keyword is not standard:
_override_windows_isinteractive_check = Sys.iswindows(),
)

@testset "MultiDocumenter.jl" begin

@testset "structure" begin
@test isdir(outpath, "inf")
@test !isdir(outpath, "inf", "previews")
@test isdir(outpath, "inf", "stable")
@test isfile(outpath, "inf", "stable", "index.html")
if Sys.iswindows()
# On Windows, symlinks are either kept as simple files, or are in fact
# symlinks, but then you would run into permission errors with isdir().
# So we need to have platform-specific test logic here.
path = joinpath(outpath, "inf", "stable")
@test islink(path) || isfile(path)
else
@test isdir(outpath, "inf", "stable")
@test isfile(outpath, "inf", "stable", "index.html")
end

@test read(joinpath(outpath, "inf", "index.html"), String) == """
<!--This file is automatically generated by Documenter.jl-->
Expand All @@ -122,8 +156,7 @@ MultiDocumenter.make(


@testset "custom scripts" begin
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)

index = read(joinpath(outpath, "inf", "v1.6.4", "index.html"), String)
@test occursin(
"""<script charset="utf-8" type="text/javascript">window.MULTIDOCUMENTER_ROOT_PATH = '$rootpath'</script>""",
index,
Expand All @@ -140,12 +173,36 @@ MultiDocumenter.make(
"""<script charset="utf-8" type="text/javascript">const foo = 'bar';</script>""",
index,
)

if !Sys.iswindows()
# Going through symlinks does not work on Windows
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)
@test occursin(
"""<script charset="utf-8" type="text/javascript">window.MULTIDOCUMENTER_ROOT_PATH = '$rootpath'</script>""",
index,
)
@test occursin(
"""<script charset="utf-8" src="../../foo/bar.js" type="text/javascript"></script>""",
index,
)
@test occursin(
"""<script charset="utf-8" src="https://foo.com/bar.js" type="text/javascript"></script>""",
index,
)
@test occursin(
"""<script charset="utf-8" type="text/javascript">const foo = 'bar';</script>""",
index,
)
end
end

@testset "canonical URLs" begin
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)
canonical_href = "<link href=\"https://example.org/MultiDocumenter.jl/inf/stable/\" rel=\"canonical\"/>"
@test occursin(canonical_href, index)
# We can't traverse symlinks on Windows, so we ignore this case
if !Sys.iswindows()
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)
canonical_href = "<link href=\"https://example.org/MultiDocumenter.jl/inf/stable/\" rel=\"canonical\"/>"
@test occursin(canonical_href, index)
end

index = read(joinpath(outpath, "inf", "v1.6.0", "index.html"), String)
canonical_href = "<link href=\"https://example.org/MultiDocumenter.jl/inf/stable/\" rel=\"canonical\"/>"
Expand All @@ -158,9 +215,17 @@ MultiDocumenter.make(
@test !isempty(store_content)
@test occursin("Infiltrator.jl", store_content)
@test occursin("@infiltrate", store_content)
@test occursin("$(rootpath)inf/stable/", store_content)
@test occursin("$(rootpath)inf/stable/", store_content)
@test !occursin("/inf/dev/", store_content)
# We can't traverse symlinks on Windows, so stable/ things do not get
# written into the search index. Instead, it looks like we write dev/
if Sys.iswindows()
@test !occursin("$(rootpath)inf/stable/", store_content)
@test !occursin("$(rootpath)inf/stable/", store_content)
@test occursin("/inf/dev/", store_content)
else
@test occursin("$(rootpath)inf/stable/", store_content)
@test occursin("$(rootpath)inf/stable/", store_content)
@test !occursin("/inf/dev/", store_content)
end
end

@testset "sitemap" begin
Expand Down

0 comments on commit 7f60411

Please sign in to comment.