diff --git a/Project.toml b/Project.toml index 4ca0288..9f480a5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Checkpoints" uuid = "b4a3413d-e481-5afc-88ff-bdfbd6a50dce" authors = "Invenia Technical Computing Corporation" -version = "0.3.17" +version = "0.3.18" [deps] AWSS3 = "1c724243-ef5b-51ab-93f4-b0a88ac62a95" diff --git a/src/Checkpoints.jl b/src/Checkpoints.jl index 077b52b..8893617 100644 --- a/src/Checkpoints.jl +++ b/src/Checkpoints.jl @@ -18,7 +18,7 @@ using Memento using OrderedCollections export checkpoint, with_checkpoint_tags # creating stuff -export enabled_checkpoints +export enabled_checkpoints, deprecated_checkpoints # indexing stuff export IndexEntry, index_checkpoint_files, index_files export checkpoint_fullname, checkpoint_name, checkpoint_path, prefixes, tags @@ -29,7 +29,7 @@ __init__() = Memento.register(LOGGER) include("handler.jl") -const CHECKPOINTS = Dict{String, Union{Nothing, Handler}}() +const CHECKPOINTS = Dict{String, Union{Nothing, String, Handler}}() @contextvar CONTEXT_TAGS::Tuple{Vararg{Pair{Symbol, Any}}} = Tuple{}() include("session.jl") @@ -72,9 +72,19 @@ available() = collect(keys(CHECKPOINTS)) """ enabled_checkpoints() -> Vector{String} -Returns a vector of all enabled ([`config`](@ref)ured) checkpoints. +Returns a vector of all enabled ([`config`](@ref)ured) and not [`deprecate`](@ref)d checkpoints. +Use [`deprecated_checkpoints`](@ref) to retrieve a mapping of old / deprecated checkpoints. """ -enabled_checkpoints() = filter(k -> CHECKPOINTS[k] !== nothing, available()) +enabled_checkpoints() = filter(k -> CHECKPOINTS[k] isa Handler, available()) + +""" + deprecated_checkpoints() -> Dict{String, String} + +Returns a Dict mapping deprecated checkpoints to the corresponding new names. +""" +function deprecated_checkpoints() + return Dict{String, String}(filter(p -> last(p) isa String, CHECKPOINTS)) +end """ checkpoint([prefix], name, data) @@ -131,9 +141,7 @@ If the first argument is not a `Handler` then all `args` and `kwargs` are passed """ function config(handler::Handler, names::Vector{String}) for n in names - haskey(CHECKPOINTS, n) || warn(LOGGER, "$n is not a registered checkpoint") - debug(LOGGER, "Checkpoint $n set to use $(handler)") - CHECKPOINTS[n] = handler + _config(handler, n) end end @@ -149,6 +157,20 @@ function config(prefix::Union{Module, String}, args...; kwargs...) config(Handler(args...; kwargs...), prefix) end +# To avoid collisions with `prefix` method above, which should probably use +# a regex / glob syntax +function _config(handler, name::String) + haskey(CHECKPOINTS, name) || warn(LOGGER, "$name is not a registered checkpoint") + + # Warn about deprecated checkpoints and recurse if necessary + if CHECKPOINTS[name] isa String + Base.depwarn("$name has been deprecated to $(CHECKPOINTS[name])", :config) + return _config(handler, CHECKPOINTS[name]) + else + debug(LOGGER, "Checkpoint $name set to use $(handler)") + return setindex!(CHECKPOINTS, handler, name) + end +end """ register([prefix], labels) @@ -171,4 +193,18 @@ function register(prefix::Union{Module, String}, labels::Vector{String}) register(map(l -> join([prefix, l], "."), labels)) end + +""" + deprecate([prefix], prev, curr) + +Deprecate a checkpoint that has been renamed. +""" +function deprecate end + +deprecate(prev, curr) = setindex!(CHECKPOINTS, curr, prev) + +function deprecate(prefix::Union{Module, String}, prev, curr) + deprecate(join([prefix, prev], "."), join([prefix, curr], ".")) +end + end # module diff --git a/test/runtests.jl b/test/runtests.jl index 9e310e4..3509119 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -28,6 +28,25 @@ Distributed.addprocs(5) Checkpoints.config("c2", path) @test enabled_checkpoints() == ["c1", "c2"] + + # Manually disable the checkpoint again + Checkpoints.CHECKPOINTS["c1"] = nothing + Checkpoints.CHECKPOINTS["c2"] = nothing + end + end + + @testset "deprecated" begin + mktempdir() do path + @test deprecated_checkpoints() == Dict( + "TestPkg.quux" => "TestPkg.qux_a", + "TestPkg.quuz" => "TestPkg.qux_b", + ) + + @test_deprecated Checkpoints.config("TestPkg.quux", path) + @test enabled_checkpoints() == ["TestPkg.qux_a"] + + # Manually disable the checkpoint again + Checkpoints.CHECKPOINTS["TestPkg.qux_a"] = nothing end end diff --git a/test/testpkg.jl b/test/testpkg.jl index 8687e04..cf3a3e5 100644 --- a/test/testpkg.jl +++ b/test/testpkg.jl @@ -1,11 +1,15 @@ module TestPkg -using Checkpoints: register, checkpoint, with_checkpoint_tags, Session +using Checkpoints: deprecate, register, checkpoint, with_checkpoint_tags, Session # We aren't using `@__MODULE__` because that would return TestPkg on 0.6 and Main.TestPkg on 0.7 const MODULE = "TestPkg" -__init__() = register(MODULE, ["foo", "bar", "baz", "qux_a", "qux_b", "deprecated"]) +function __init__() + register(MODULE, ["foo", "bar", "baz", "qux_a", "qux_b", "deprecated"]) + deprecate(MODULE, "quux", "qux_a") + deprecate(MODULE, "quuz", "qux_b") +end function foo(x::Matrix, y::Matrix) # Save multiple variables to 1 foo.jlso file by passing in pairs of variables