Skip to content

Commit 7f60411

Browse files
authored
Merge pull request #68 from JuliaComputing/mp/fix-windows-ci
test: fix line endings in tests on Windows
2 parents 20093b5 + b8d4ed2 commit 7f60411

File tree

5 files changed

+111
-15
lines changed

5 files changed

+111
-15
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,9 @@ Check [`.github/workflows/deploy.yml`](.github/workflows/deploy.yml) and [`docs/
8484
The result of that script is available at [https://juliacomputing.github.io/MultiDocumenter.jl/](https://juliacomputing.github.io/MultiDocumenter.jl/).
8585

8686
You can of course also just push the output artefact directly to S3 or some other hosting service.
87+
88+
> **Warning**
89+
> MultiDocumenter sites can not be deployed on Windows right now, and the `make()` function will throw an error.
90+
> See [#70](https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70).
91+
>
92+
> 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).

src/MultiDocumenter.jl

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,26 @@ function make(
140140
canonical_domain::Union{AbstractString,Nothing} = nothing,
141141
sitemap::Bool = false,
142142
sitemap_filename::AbstractString = "sitemap.xml",
143+
# This keyword is for internal test use only:
144+
_override_windows_isinteractive_check::Bool = false,
143145
)
146+
if Sys.iswindows() && !isinteractive()
147+
if _override_windows_isinteractive_check || isinteractive()
148+
@warn """
149+
Running a MultiDocumenter build interactively in Windows.
150+
This should only be used for development and testing, as it will lead to partial
151+
and broken builds. See https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
152+
"""
153+
else
154+
msg = """
155+
MultiDocumenter deployments are disabled on Windows due to difficulties
156+
with handling symlinks in documentation sources.
157+
You _can_ test this build locally by running it interactively (i.e. in the REPL).
158+
See also: https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
159+
"""
160+
error(msg)
161+
end
162+
end
144163
if isnothing(canonical_domain)
145164
(sitemap === true) &&
146165
throw(ArgumentError("When sitemap=true, canonical_domain must also be set"))
@@ -249,7 +268,8 @@ function maybe_clone(docs::Vector{MultiDocRef})
249268
`$(git()) clone --depth 1 $(doc.giturl) --branch $(doc.branch) --single-branch --no-tags $(doc.upstream)`,
250269
)
251270
else
252-
git_dir, git_worktree = abspath(joinpath(doc.upstream, ".git")), abspath(doc.upstream)
271+
git_dir, git_worktree =
272+
abspath(joinpath(doc.upstream, ".git")), abspath(doc.upstream)
253273
if !isdir(git_dir)
254274
@warn "Unable to update existing clone at $(doc.upstream): .git/ directory missing"
255275
continue
@@ -266,7 +286,8 @@ function maybe_clone(docs::Vector{MultiDocRef})
266286
catch e
267287
# We're only interested in catching `git` errors here
268288
isa(e, ProcessFailedException) || rethrow()
269-
@error "Unable to update existing clone at $(doc.upstream)" exception = (e, catch_backtrace())
289+
@error "Unable to update existing clone at $(doc.upstream)" exception =
290+
(e, catch_backtrace())
270291
end
271292
end
272293
end

src/documentertools/canonical_urls.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ function update_canonical_links(docs_directory::AbstractString; canonical::Abstr
101101
# We'll skip all files. This includes files such as index.html, which in this
102102
# directory will likely be the redirect. Also, links should be pointing to other
103103
# versions, so we'll skip them too.
104-
if !isdir(path) || islink(path)
104+
# Note: we need to check islink() first, because on windows, calling isdir() on a
105+
# symlink can make it throw a permissions IOError.
106+
if islink(path) || !isdir(path)
105107
continue
106108
end
107109
# Preview directory is should contain other Documenter directories, so we just add

test/documentertools.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import MultiDocumenter: DocumenterTools
33

44
FIXTURES = joinpath(@__DIR__, "fixtures")
55

6+
normalize_newlines(s::AbstractString) = replace(s, "\r\n" => "\n")
7+
68
@testset "walkdocs" begin
79
let fileinfos = DocumenterTools.FileInfo[]
810
rs = DocumenterTools.walkdocs(joinpath(FIXTURES, "pre")) do fileinfo
@@ -123,8 +125,8 @@ end
123125
canonical = "https://example.org/this-is-test",
124126
)
125127
DocumenterTools.walkdocs(joinpath(FIXTURES, "post")) do fileinfo
126-
post = read(fileinfo.fullpath, String)
127-
changed = read(joinpath(out, fileinfo.relpath), String)
128+
post = normalize_newlines(read(fileinfo.fullpath, String))
129+
changed = normalize_newlines(read(joinpath(out, fileinfo.relpath), String))
128130
if changed != post
129131
@error "update_canonical_links: change and post not matching" out fileinfo
130132
end

test/runtests.jl

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,30 @@ docs = [
8484
# giturl = "[email protected]:JuliaComputing/DataSets.jl.git",
8585
),
8686
]
87+
88+
# We do not support deploying docs on Windows at the moment, and MultiDocumenter
89+
# should throw an error if it's being run on Windows (in a non-interactive session).
90+
# See also: https://github.com/JuliaComputing/MultiDocumenter.jl/issues/70
91+
if Sys.iswindows() && !isinteractive()
92+
@test_throws ErrorException MultiDocumenter.make(
93+
outpath,
94+
docs;
95+
search_engine = MultiDocumenter.SearchConfig(
96+
index_versions = ["stable", "dev"],
97+
engine = MultiDocumenter.FlexSearch,
98+
),
99+
custom_scripts = [
100+
"foo/bar.js",
101+
"https://foo.com/bar.js",
102+
Docs.HTML("const foo = 'bar';"),
103+
],
104+
rootpath = rootpath,
105+
canonical_domain = "https://example.org/",
106+
sitemap = true,
107+
sitemap_filename = "sitemap-mydocs.xml",
108+
)
109+
end
110+
87111
MultiDocumenter.make(
88112
outpath,
89113
docs;
@@ -100,15 +124,25 @@ MultiDocumenter.make(
100124
canonical_domain = "https://example.org/",
101125
sitemap = true,
102126
sitemap_filename = "sitemap-mydocs.xml",
127+
# The following keyword is not standard:
128+
_override_windows_isinteractive_check = Sys.iswindows(),
103129
)
104130

105131
@testset "MultiDocumenter.jl" begin
106132

107133
@testset "structure" begin
108134
@test isdir(outpath, "inf")
109135
@test !isdir(outpath, "inf", "previews")
110-
@test isdir(outpath, "inf", "stable")
111-
@test isfile(outpath, "inf", "stable", "index.html")
136+
if Sys.iswindows()
137+
# On Windows, symlinks are either kept as simple files, or are in fact
138+
# symlinks, but then you would run into permission errors with isdir().
139+
# So we need to have platform-specific test logic here.
140+
path = joinpath(outpath, "inf", "stable")
141+
@test islink(path) || isfile(path)
142+
else
143+
@test isdir(outpath, "inf", "stable")
144+
@test isfile(outpath, "inf", "stable", "index.html")
145+
end
112146

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

123157

124158
@testset "custom scripts" begin
125-
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)
126-
159+
index = read(joinpath(outpath, "inf", "v1.6.4", "index.html"), String)
127160
@test occursin(
128161
"""<script charset="utf-8" type="text/javascript">window.MULTIDOCUMENTER_ROOT_PATH = '$rootpath'</script>""",
129162
index,
@@ -140,12 +173,36 @@ MultiDocumenter.make(
140173
"""<script charset="utf-8" type="text/javascript">const foo = 'bar';</script>""",
141174
index,
142175
)
176+
177+
if !Sys.iswindows()
178+
# Going through symlinks does not work on Windows
179+
index = read(joinpath(outpath, "inf", "stable", "index.html"), String)
180+
@test occursin(
181+
"""<script charset="utf-8" type="text/javascript">window.MULTIDOCUMENTER_ROOT_PATH = '$rootpath'</script>""",
182+
index,
183+
)
184+
@test occursin(
185+
"""<script charset="utf-8" src="../../foo/bar.js" type="text/javascript"></script>""",
186+
index,
187+
)
188+
@test occursin(
189+
"""<script charset="utf-8" src="https://foo.com/bar.js" type="text/javascript"></script>""",
190+
index,
191+
)
192+
@test occursin(
193+
"""<script charset="utf-8" type="text/javascript">const foo = 'bar';</script>""",
194+
index,
195+
)
196+
end
143197
end
144198

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

150207
index = read(joinpath(outpath, "inf", "v1.6.0", "index.html"), String)
151208
canonical_href = "<link href=\"https://example.org/MultiDocumenter.jl/inf/stable/\" rel=\"canonical\"/>"
@@ -158,9 +215,17 @@ MultiDocumenter.make(
158215
@test !isempty(store_content)
159216
@test occursin("Infiltrator.jl", store_content)
160217
@test occursin("@infiltrate", store_content)
161-
@test occursin("$(rootpath)inf/stable/", store_content)
162-
@test occursin("$(rootpath)inf/stable/", store_content)
163-
@test !occursin("/inf/dev/", store_content)
218+
# We can't traverse symlinks on Windows, so stable/ things do not get
219+
# written into the search index. Instead, it looks like we write dev/
220+
if Sys.iswindows()
221+
@test !occursin("$(rootpath)inf/stable/", store_content)
222+
@test !occursin("$(rootpath)inf/stable/", store_content)
223+
@test occursin("/inf/dev/", store_content)
224+
else
225+
@test occursin("$(rootpath)inf/stable/", store_content)
226+
@test occursin("$(rootpath)inf/stable/", store_content)
227+
@test !occursin("/inf/dev/", store_content)
228+
end
164229
end
165230

166231
@testset "sitemap" begin

0 commit comments

Comments
 (0)