Skip to content

Commit

Permalink
Use doc environment if requested (#87)
Browse files Browse the repository at this point in the history
* experimental doc_env keyword and skip_dirs for servedocs
  • Loading branch information
tlienart authored Nov 24, 2019
1 parent 084756d commit 0bd3042
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 10 deletions.
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
name = "LiveServer"
uuid = "16fef848-5104-11e9-1b77-fb7a48bbb589"
authors = ["Jonas Asprion <jonas.asprion@gmx.ch", "Thibaut Lienart <tlienart@me.com>"]
version = "0.3.3"
version = "0.3.4"

This comment has been minimized.

Copy link
@tlienart

tlienart Nov 24, 2019

Author Collaborator

[deps]
Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FileWatching = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

Expand Down
18 changes: 18 additions & 0 deletions docs/src/man/functionalities.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,21 @@ Upon modifying a `.md` file (e.g. updating `docs/src/index.md`), the `make.jl` w
The first pass collects all information in the code (i.e. docstrings), while
subsequent passes only consider changes in the markdown (`.md`) files. This
restriction is necessary to achieve a fast update behavior.

### Additional keywords

The `servedocs` function now takes two extra keywords which may, in some cases, make your life easier:

* `doc_env=false`, if set to true, the `Project.toml` available in `docs/` will be activated (note 1),
* `skip_dir=""`, indicates a directory to skip when looking at the docs folder for change, this can be useful when using packages like Literate or Weave that may generate files inside your `src` folder.

Note that in both cases these keywords are there for your convenience but would be best not used. See also the discussion in [this issue](https://github.com/asprionj/LiveServer.jl/issues/85).
In the first case, doing

```
julia --project=docs -e 'using LiveServer; servedocs()'
```

is more robust.

In the second case, it would be best if you made sure that all generated files are saved in `docs/build/...`.
2 changes: 1 addition & 1 deletion src/LiveServer.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module LiveServer

# from stdlib
using Sockets
using Sockets, Pkg
# the only dependency (see the patch in http_patch.jl)
using HTTP

Expand Down
39 changes: 31 additions & 8 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,25 @@ triggered to regenerate the documents, subsequently the LiveServer will render t
in `docs/build`.
"""
function servedocs_callback!(dw::SimpleWatcher, fp::AbstractString, makejl::AbstractString,
literate::String="")
literate::String="", skip_dirs::Vector{String}=String[])
# ignore things happening in build (generated files etc)
startswith(fp, joinpath("docs", "build")) && return nothing
if !isempty(skip_dirs)
for dir in skip_dirs
startswith(fp, dir) && return nothing
end
end
# if the file that was changed is the `make.jl` file, assume that maybe new files are # referenced and so refresh the vector of watched files as a result.
if fp == makejl
# it's easier to start from scratch (takes negligible time)
empty!(dw.watchedfiles)
scan_docs!(dw, literate)
end
fext = splitext(fp)[2]
P1 = fext (".md", ".jl")
P1 = fext (".md", ".jl", ".css")
# the second condition is for CSS files, we want to track it but not the output
# if we track the output then there's an infinite loop being triggered (see docstring)
if P1 || (fext == ".css" && !occursin(joinpath("docs", "build", "assets"), fp))
if P1
Main.include(makejl)
file_changed_callback(fp)
end
Expand Down Expand Up @@ -97,31 +104,47 @@ end


"""
servedocs(; verbose=false, literate="")
servedocs(; verbose=false, literate="", doc_env=false)
Can be used when developing a package to run the `docs/make.jl` file from Documenter.jl and
then serve the `docs/build` folder with LiveServer.jl. This function assumes you are in the
directory `[MyPackage].jl` with a subfolder `docs`.
* `verbose` is a boolean switch to make the server print information about file changes and
* `verbose=false` is a boolean switch to make the server print information about file changes and
connections.
* `literate` is the path to the folder containing the literate scripts, if left empty, it will be
* `literate=""` is the path to the folder containing the literate scripts, if left empty, it will be
assumed that they are in `docs/src`.
* `doc_env=false` is a boolean switch to make the server start by activating the doc environment or not (i.e. the `Project.toml` in `docs/`).
* `skip_dir=""` is a subpath of `docs/` where modifications should not trigger the generation of the docs, this is useful for instance if you're using Weave and Weave generates some files in `docs/src/examples` in which case you should give `skip_dir=joinpath("docs","src","examples")`.
* `skip_dirs=[]` same as `skip_dir` but for a vector of such dirs. Takes precedence over `skip_dir`.
"""
function servedocs(; verbose::Bool=false, literate::String="")
function servedocs(; verbose::Bool=false, literate::String="", doc_env::Bool=false,
skip_dir::String="", skip_dirs::Vector{String}=String[])
# Custom file watcher: it's the standard `SimpleWatcher` but with a custom callback.
docwatcher = SimpleWatcher()
set_callback!(docwatcher, fp->servedocs_callback!(docwatcher, fp, makejl, literate))

if isempty(skip_dirs) && !isempty(skip_dir)
skip_dirs = [skip_dir]
end

set_callback!(docwatcher,
fp->servedocs_callback!(docwatcher, fp, makejl, literate, skip_dirs))

# Retrieve files to watch
makejl = scan_docs!(docwatcher, literate)

if doc_env
Pkg.activate("docs/Project.toml")
end
# trigger a first pass of Documenter (& possibly Literate)
Main.include(makejl)

# note the `docs/build` exists here given that if we're here it means the documenter
# pass did not error and therefore that a docs/build has been generated.
serve(docwatcher, dir=joinpath("docs", "build"), verbose=verbose)
if doc_env
Pkg.activate()
end
return nothing
end

Expand Down
2 changes: 2 additions & 0 deletions test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ end
dw = LS.SimpleWatcher()

# error if there's no docs/ folder
cray = Crayon(foreground=:cyan, bold=true)
println(cray, "\n⚠ Deliberately causing an error to be displayed and handled...\n")
@test_throws SystemError LS.scan_docs!(dw, "docs")

empty!(dw.watchedfiles)
Expand Down

1 comment on commit 0bd3042

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/5815

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.4 -m "<description of version>" 0bd3042da2fcb5a75577e2eb6dbe3e581ca5496c
git push origin v0.3.4

Please sign in to comment.