From 1dfb8d76d68373590b27517969db368fe2ffa470 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 12 Jun 2021 09:21:20 +0100 Subject: [PATCH] Make assets `PackageCompiler`-friendly A possible solution to relocatablilty issues with the hardcoded paths. Embeds the asset folder contents into the precompiled files. When the original folder isn't available (due to relocation) creates a scratchspace containing the original folder contents as uses that instead. --- Project.toml | 3 +++ src/RelocatableFolders.jl | 57 +++++++++++++++++++++++++++++++++++++++ src/Weave.jl | 8 +++--- 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/RelocatableFolders.jl diff --git a/Project.toml b/Project.toml index 22f5caf..8e314d4 100644 --- a/Project.toml +++ b/Project.toml @@ -13,6 +13,8 @@ Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" Requires = "ae029012-a4dd-5104-9daa-d747884805df" +SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" +Scratch = "6c6a2e73-6563-6170-7368-637461726353" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" @@ -22,6 +24,7 @@ JSON = "0.21" Mustache = "0.4.1, 0.5, 1" Plots = "0.28, 0.29, 1.0" Requires = "1.0" +Scratch = "1.1" YAML = "0.3, 0.4" julia = "1.2" diff --git a/src/RelocatableFolders.jl b/src/RelocatableFolders.jl new file mode 100644 index 0000000..9fd94e8 --- /dev/null +++ b/src/RelocatableFolders.jl @@ -0,0 +1,57 @@ +module RelocatableFolders + +import Scratch, SHA + +export @folder_str + +macro folder_str(path) + dir = string(__source__.file) + dir = isfile(dir) ? dirname(dir) : pwd() + return :($(Folder)($__module__, $dir, $(esc(path)))) +end + +struct Folder <: AbstractString + mod::Module + path::String + hash::String + files::Dict{String,Vector{UInt8}} + + function Folder(mod::Module, dir, path::AbstractString) + path = isabspath(path) ? path : normpath(joinpath(dir, path)) + isdir(path) || throw(ArgumentError("not a directory: `$path`")) + files = Dict{String,Vector{UInt8}}() + ctx = SHA.SHA1_CTX() + for (root, _, fs) in walkdir(path), f in fs + fullpath = joinpath(root, f) + include_dependency(fullpath) + SHA.update!(ctx, codeunits(fullpath)) + content = read(fullpath) + SHA.update!(ctx, content) + files[relpath(fullpath, path)] = content + end + return new(mod, path, string(Base.SHA1(SHA.digest!(ctx))), files) + end +end + +Base.show(io::IO, path::Folder) = print(io, repr(path.path)) +Base.ncodeunits(f::Folder) = ncodeunits(getpath(f)) +Base.isvalid(f::Folder, index::Integer) = isvalid(getpath(f), index) +Base.iterate(f::Folder) = iterate(getpath(f)) +Base.iterate(f::Folder, state::Integer) = iterate(getpath(f), state) +Base.String(f::Folder) = String(getpath(f)) + +function getpath(f::Folder) + isdir(f.path) && return f.path + dir = Scratch.get_scratch!(f.mod, f.hash) + if !isempty(f.files) && !ispath(joinpath(dir, first(keys(f.files)))) + cd(dir) do + for (file, blob) in f.files + mkpath(dirname(file)) + write(file, blob) + end + end + end + return dir +end + +end # module diff --git a/src/Weave.jl b/src/Weave.jl index c58640a..c3483ae 100644 --- a/src/Weave.jl +++ b/src/Weave.jl @@ -2,13 +2,15 @@ module Weave using Highlights, Mustache, Requires, Pkg, REPL +include("RelocatableFolders.jl") +using .RelocatableFolders # directories const PKG_DIR = normpath(@__DIR__, "..") -const TEMPLATE_DIR = normpath(PKG_DIR, "templates") -const STYLESHEET_DIR = normpath(PKG_DIR, "stylesheets") +const TEMPLATE_DIR = folder"../templates" +const STYLESHEET_DIR = folder"../stylesheets" # keeps paths of sample documents for easy try -const EXAMPLE_FOLDER = normpath(PKG_DIR, "examples") +const EXAMPLE_FOLDER = folder"../examples" # constant names const WEAVE_OPTION_NAME = "weave_options"