Force Revise.jl to Rerun Script

Example:

Contents of script named test.jl:

println("Hello")

I run the script with includet("test.jl") then change test.jl to be:

println("Hello2")

When running includet("test.jl"), the “Hello2” does not print.

Is there a way to force Revise.jl to rerun the script?

Revise.retry()

See the documentation for Revise.retry at this URL:

https://timholy.github.io/Revise.jl/stable/user_reference/#Revise.retry

That has the same problem unfortunately. I’m using Revise v3.4.0. Do you have a working example?

Oh I see, you are using a script. My best advice is to save yourself a lot of trouble and do not script.

That is use a function like the following.

hello() = println("Hello")

Here’s fully self contained example.

julia> write("test.jl", "hello() = println(\"Hello\")")
26

julia> using Revise

julia> includet("test.jl")

julia> hello()
Hello

julia> write("test.jl", "hello() = println(\"Hello 2\")")
28

julia> hello()
Hello 2

Generally you only call includet once on a script file; after that, Revise watches for changes and you shouldn’t need to reload it. Put your method definitions in the file that you includet, and the actual task you want to repeatedly re-run in a second file that you include (no t).

If that seems to be a pain, then why not put everything in one file and just include it? It will redefine all the methods, but that’s what you seem to want? The only thing you won’t get is automatic method deletion, but you can achieve that with the 2-file approach above.

It might be worth explaining my workflow which may indeed benefit if run differently:

I have a main.jl script which loads (via using) functions defined in other packages (say PackageA) I am actively developing. I call this script with includet("main.jl"). If my code crashes early on and I make corresponding fixes to PackageA, then re-running includet("main.jl") works as expected with the changes. If however the code runs to completion, followed by a change to PackageA, then re-running includet("main.jl") does nothing. In this case, include("main.jl") will only see the changes if they are within main.jl itself.

Let me know if there’s a better way to go about this!

That’s pretty much what’s intended. includet exists to support people who haven’t (yet) turned their code into a package; otherwise it mostly mimics how Revise works for packages. In particular, it’s targeted at automatically updating method definitions as you modify them in your editor, and not designed to rerun the “data” portions of a workflow (what I think of as “code” vs “script”). That’s why I recommend splitting your method definitions from your script into separate files. As a bonus, you’ll be that much closer to turning your reusable code into a package, which has numerous advantages even if you never intend to publish it for public consumption.

To rerun a script, use include.

2 Likes

Gotcha - I think I understand the proper workflow. Instead of pushing my package to my LOAD_PATH, then importing it, I can instead includet("/path/to/PackageA.jl"), followed by relative imports (e.g. using .PackageA). Or at least this accomplishes what I’d like on test scripts. Thanks!