diff --git a/README.md b/README.md index 244fb55..543c4f6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ +### Note: changes in v0.7 + +Requires now needs a UUID, and must be called from within your packages `__init__` function. For example: + +```julia +function __init__() + @require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" do_stuff() +end +``` + # Requires.jl [![Build Status](https://travis-ci.org/MikeInnes/Requires.jl.svg?branch=master)](https://travis-ci.org/MikeInnes/Requires.jl) diff --git a/src/Requires.jl b/src/Requires.jl index f70ce8a..8130cb2 100644 --- a/src/Requires.jl +++ b/src/Requires.jl @@ -3,7 +3,10 @@ __precompile__() module Requires include("init.jl") -include("getthing.jl") include("require.jl") +function __init__() + push!(package_callbacks, loadpkg) +end + end # module diff --git a/src/getthing.jl b/src/getthing.jl deleted file mode 100644 index 9eccc69..0000000 --- a/src/getthing.jl +++ /dev/null @@ -1,17 +0,0 @@ -function getthing(mod::Module, name::Vector{Symbol}, default = nothing) - thing = mod - for sym in name - if Base.isbindingresolved(thing, sym) - thing = getfield(thing, sym) - else - return default - end - end - return thing -end - -getthing(mod::Module, name::Symbol) = getthing(mod, string(name)) -getthing(mod::Module, name::AbstractString, default = nothing) = - name == "" ? - default : - getthing(mod, map(Symbol, split(name, ".", keep=false)), default) diff --git a/src/init.jl b/src/init.jl index 983e15c..48dcc91 100644 --- a/src/init.jl +++ b/src/init.jl @@ -22,8 +22,3 @@ end macro init(args...) initm(args...) end - -"Prevent init fns being called multiple times during precompilation." -macro guard(ex) - :(!isprecompiling() && $(esc(ex))) -end diff --git a/src/require.jl b/src/require.jl index 39a440c..e402421 100644 --- a/src/require.jl +++ b/src/require.jl @@ -5,10 +5,6 @@ export @require isprecompiling() = ccall(:jl_generating_output, Cint, ()) == 1 -@init begin - push!(package_callbacks, loadpkg) -end - loaded(pkg) = haskey(Base.loaded_modules, pkg) const _callbacks = Dict{PkgId, Vector{Function}}() @@ -52,7 +48,7 @@ function parsepkg(ex) isexpr(ex, :(=)) || @goto fail mod, id = ex.args (mod isa Symbol && id isa String) || @goto fail - return Base.PkgId(Base.UUID(id), String(mod)) + return id, String(mod) @label fail error("Requires syntax is: `@require Pkg=\"uuid\"`") end @@ -60,25 +56,20 @@ end macro require(pkg, expr) pkg isa Symbol && return Expr(:macrocall, Symbol("@warn"), __source__, - "Requires now needs a UUID: `@require $pkg=\"uuid\"`") - pkg = parsepkg(pkg) - ex = quote - listenpkg($pkg) do - withpath(@__FILE__) do - err($__module__, $(pkg.name)) do - $(esc(:(eval($(Expr(:quote, Expr(:block, - :(const $(Symbol(pkg.name)) = Base.require($pkg)), - expr))))))) + "Requires now needs a UUID; please see the readme for changes in 0.7.") + id, modname = parsepkg(pkg) + pkg = Base.PkgId(Base.UUID(id), modname) + quote + if !isprecompiling() + listenpkg(Base.PkgId(Base.UUID($id), $modname)) do + withpath($(string(__source__.file))) do + err($__module__, $(pkg.name)) do + $(esc(:(eval($(Expr(:quote, Expr(:block, + :(const $(Symbol(pkg.name)) = Base.require($pkg)), + expr))))))) + end end end end end - quote - if isprecompiling() - @init @guard $(ex) - else - $(ex) - end - nothing - end end diff --git a/test/runtests.jl b/test/runtests.jl index 87739e3..d6a21e0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,18 +1,67 @@ -module Foo +using Test -using Requires, Test +function writepkg(name, precomp::Bool) + open("$name.jl", "w") do io + println(io, """ +__precompile__($precomp) -beforeflag = false -afterflag = false +module $name -@require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" global beforeflag = true +using Requires -@test !beforeflag -using JSON -@test beforeflag +flag = false -@require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" global afterflag = true +function __init__() + @require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" global flag = true +end + +end +""") + end +end + +@testset "Requires" begin + mktempdir() do pkgsdir + cd(pkgsdir) do + npcdir = joinpath("FooNPC", "src") + mkpath(npcdir) + cd(npcdir) do + writepkg("FooNPC", false) + end + npcdir = joinpath("FooPC", "src") + mkpath(npcdir) + cd(npcdir) do + writepkg("FooPC", true) + end + end + push!(LOAD_PATH, pkgsdir) + + @eval using FooNPC + @test !FooNPC.flag + @eval using FooPC + @test !FooPC.flag + + @eval using JSON + + @test FooNPC.flag + @test FooPC.flag -@test afterflag + cd(pkgsdir) do + npcdir = joinpath("FooAfterNPC", "src") + mkpath(npcdir) + cd(npcdir) do + writepkg("FooAfterNPC", false) + end + pcidr = joinpath("FooAfterPC", "src") + mkpath(pcidr) + cd(pcidr) do + writepkg("FooAfterPC", true) + end + end + @eval using FooAfterNPC + @eval using FooAfterPC + @test FooAfterNPC.flag + @test FooAfterPC.flag + end end