How to execute a script in the current project?

I have many packages that include examples on how to use them in an example folder. In addition I have a terminal menu to execute the examples.

If you want to try it out:

git clone https://github.com/ufechner7/KiteModels.jl
cd KiteModels.jl
julia --project

and then in Julia

include("examples/menu.jl)

(If you do that the first time it will take a long time to precompile.)
You will see a nice menu:

Choose function to execute or `q` to quit: 
 > bench = include("bench.jl")
   bench_4p = include("bench_4p.jl")
   test_init_1p = include("test_init_1p.jl")
   test_init_4p = include("test_init_4p.jl")
   plot_cl_cd_plate = include("plot_cl_cd_plate.jl")
   plot_side_cl = include("plot_side_cl.jl")
   compare_kps3_kps4 = include("compare_kps3_kps4.jl")
v  reel_out_1p = include("reel_out_1p.jl")

Now I thought this is too much to type, and I wrote a function to show the menu:

function menu()
    include("examples/menu.jl")
end

I put this function in the package KiteUtils.jl which is a dependency of most of my packages. But it does not work:

julia> menu()
ERROR: LoadError: ArgumentError: Package KiteUtils does not have KiteModels in its dependencies:
- You may have a partially installed environment. Try `Pkg.instantiate()`
  to ensure all packages in the environment are installed.
- Or, if you have KiteUtils checked out for development and have
  added KiteModels as a dependency but haven't updated your primary
  environment's manifest file, try `Pkg.resolve()`.
- Otherwise you may need to report an issue with KiteUtils
Stacktrace:
  [1] macro expansion
    @ ./loading.jl:1776 [inlined]
  [2] macro expansion
    @ ./lock.jl:267 [inlined]
  [3] __require(into::Module, mod::Symbol)
    @ Base ./loading.jl:1753
  [4] #invoke_in_world#3
    @ ./essentials.jl:926 [inlined]
  [5] invoke_in_world
    @ ./essentials.jl:923 [inlined]
  [6] require(into::Module, mod::Symbol)
    @ Base ./loading.jl:1746
  [7] include(mod::Module, _path::String)
    @ Base ./Base.jl:495
  [8] include
    @ ~/.julia/packages/KiteUtils/yC4td/src/KiteUtils.jl:12 [inlined]
  [9] menu()
    @ KiteUtils ~/.julia/packages/KiteUtils/yC4td/src/KiteUtils.jl:470
 [10] top-level scope
    @ REPL[2]:1
in expression starting at /home/ufechner/repos/KiteModels.jl/examples/menu.jl:1

julia>

What is going on here, and how can I fix that?

How can I call a function from the REPL that is doing an include of a script and uses the currently active environment?

Does writing

function menu()
    Main.include("examples/menu.jl")
end

solve the problem?

1 Like

Yes, this fixed my problem! Thank you!

1 Like

The explanation is that KiteUtils.jl is a dependency of your main project, but KiteModels.jl is not a dependency of KiteUtils.jl. The include function is always inside a module. Without explicitly stating which module, it is the current module. In your case, the default was KiteUtils. Hence, when the included file attempted to load KiteModels as a dependency, it failed. That’s why adding Main explicitly when calling the include function solved the issue: the KiteModels dependency is reachable from there.

4 Likes