Skip to content

Commit 04d2d20

Browse files
authored
Add filename option for produce_or_load (#324)
* Add `filename` option to produce_or_load Closes #322 * Update changelog and version * Refactoring and docs as discussed in review * Use "possibly overriding..." in CHANGELOG * Add discussion of use case to doc of `filename` argument * Rename output `filename` to `file`, with `file = joinpath(path, filename`)
1 parent 4a92f3e commit 04d2d20

File tree

4 files changed

+59
-22
lines changed

4 files changed

+59
-22
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# 2.9.0
2+
* Add `filename` option in `produce_or_load`, possibly overriding the default filename generated by `savename`
13
# 2.8.0
24
* Add filtering of `collect_results` using `rinclude` and `rexclude` keyword arguments.
35
# 2.7.2

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DrWatson"
22
uuid = "634d3b9d-ee7a-5ddf-bec9-22491ea816e1"
33
repo = "https://github.com/JuliaDynamics/DrWatson.jl.git"
4-
version = "2.8.0"
4+
version = "2.9.0"
55

66
[deps]
77
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"

src/saving_files.jl

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
export produce_or_load, @produce_or_load, tagsave, @tagsave, safesave
22

33
"""
4-
produce_or_load([path="",] config, f; kwargs...) -> data, filename
5-
Let `filename = joinpath(path, savename(prefix, config, suffix))` where
6-
`config` is some kind of named parameter container.
7-
If `filename` exists then load it and return the contained `data`, along
8-
with the global path that it is saved at (`filename`).
4+
produce_or_load([path="",] config, f; kwargs...) -> data, file
5+
Let `file = joinpath(path, savename(prefix, config, suffix))` by default,
6+
where `config` is some kind of named parameter container.
7+
If `file` exists then load it and return the contained `data`, along
8+
with the global path that it is saved at (`file`).
99
1010
If the file does not exist then call `data = f(config)`, with `f` your function
11-
that produces your data. Then save the `data` as `filename` and then return
12-
`data, filename`.
11+
that produces your data. Then save the `data` as `file` and then return
12+
`data, file`.
1313
1414
The function `f` should return a dictionary if the data are saved in the default
1515
format of JLD2.jl., the macro [`@strdict`](@ref) can help with that.
@@ -24,15 +24,19 @@ end
2424
```
2525
2626
## Keywords
27+
* `filename = savename(prefix, config, suffix; kwargs...)` : Name of the file
28+
to produce or load, relative to `path`. This may be useful in situations
29+
where `config` has too many parameters for [`savename`](@ref) to be useful, and an
30+
explicitly specified name is more suitable.
2731
* `suffix = "jld2", prefix = default_prefix(config)` : Used in [`savename`](@ref).
2832
* `tag::Bool = DrWatson.readenv("DRWATSON_TAG", istaggable(suffix))` : Save the file
2933
using [`tagsave`](@ref) if `true` (which is the default).
3034
* `gitpath, storepatch` : Given to [`tagsave`](@ref) if `tag` is `true`.
31-
* `force = false` : If `true` then don't check if `filename` exists and produce
35+
* `force = false` : If `true` then don't check if `file` exists and produce
3236
it and save it anyway.
3337
* `loadfile = true` : If `false`, this function does not actually load the
3438
file, but only checks if it exists. The return value in this case is always
35-
`nothing, filename`, regardless of whether the file exists or not. If it doesn't
39+
`nothing, file`, regardless of whether the file exists or not. If it doesn't
3640
exist it is still produced and saved.
3741
* `verbose = true` : print info about the process, if the file doesn't exist.
3842
* `wsave_kwargs = Dict()` : Keywords to pass to `wsave` (e.g. to enable
@@ -48,40 +52,42 @@ function produce_or_load(path, c, f::Function;
4852
gitpath = projectdir(), loadfile = true,
4953
storepatch::Bool = readenv("DRWATSON_STOREPATCH", false),
5054
force = false, verbose = true, wsave_kwargs = Dict(),
55+
filename::Union{Nothing, AbstractString} = nothing,
5156
kwargs...
5257
)
5358

54-
filename = joinpath(path, savename(prefix, c, suffix; kwargs...))
59+
isnothing(filename) && (filename = savename(prefix, c, suffix; kwargs...))
60+
file = joinpath(path, filename)
5561

56-
if !force && isfile(filename)
62+
if !force && isfile(file)
5763
if loadfile
58-
data = wload(filename)
59-
return data, filename
64+
data = wload(file)
65+
return data, file
6066
else
61-
return nothing, filename
67+
return nothing, file
6268
end
6369
else
6470
if force
65-
verbose && @info "Producing file $filename now..."
71+
verbose && @info "Producing file $file now..."
6672
else
67-
verbose && @info "File $filename does not exist. Producing it now..."
73+
verbose && @info "File $file does not exist. Producing it now..."
6874
end
6975
data = f(c)
7076
try
7177
if tag
72-
tagsave(filename, data; safe = false, gitpath = gitpath, storepatch = storepatch, wsave_kwargs...)
78+
tagsave(file, data; safe = false, gitpath = gitpath, storepatch = storepatch, wsave_kwargs...)
7379
else
74-
wsave(filename, copy(data); wsave_kwargs...)
80+
wsave(file, copy(data); wsave_kwargs...)
7581
end
76-
verbose && @info "File $filename saved."
82+
verbose && @info "File $file saved."
7783
catch er
7884
@warn "Could not save file. Error stacktrace:"
7985
Base.showerror(stderr, er, stacktrace(catch_backtrace()))
8086
end
8187
if loadfile
82-
return data, filename
88+
return data, file
8389
else
84-
return nothing, filename
90+
return nothing, file
8591
end
8692
end
8793
end

test/savefiles_tests.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,35 @@ end
164164
rm(path)
165165
end
166166

167+
@testset "Produce or Load with manual filename ($ending)" for ending ["bson", "jld2"]
168+
169+
# test with empty `path`
170+
filename = joinpath(mktempdir(), "out.$ending")
171+
@test !isfile(filename)
172+
sim, file = @produce_or_load(simulation, filename=filename) do config
173+
f(config)
174+
end
175+
@test file == filename
176+
@test isfile(filename)
177+
@test sim["simulation"].T == T
178+
@test "script" keys(sim)
179+
rm(filename)
180+
181+
# test with both `path` and filename
182+
path = mktempdir()
183+
filename = joinpath("sub", "out.$ending")
184+
@test !isfile(joinpath(path, filename))
185+
sim, file = @produce_or_load(path, simulation, filename=filename) do config
186+
f(config)
187+
end
188+
@test file == joinpath(path, filename)
189+
@test isfile(file)
190+
@test sim["simulation"].T == T
191+
@test "script" keys(sim)
192+
rm(file)
193+
194+
end
195+
167196
@testset "Produce or Load wsave keyword pass through" begin
168197
# Create some highly compressible data
169198
data = Dict("data" => fill(1, 10000))

0 commit comments

Comments
 (0)