How to test an app at the REPL

Say, I want to develop a standalone, compiled application; after reading about various options, I settled on creating a project via Pkg.generate.

Now, I have a project structure with Manifest.toml and Project.toml files, and the program entry point under MyProgram/src/MyProgram.jl

At this very moment, all the program does is parse command line arguments; let’s say MyProgram.jl looks like this:

module MyProgram
    using ArgParse
    function main()
    ...
    end
end

This minimal program:

  • compiles fine with PackageCompiler.create_app()
  • runs from the command line just fine and correctly processes command line arguments

What are the steps that I need to take to end up at the REPL with the correct environment, so that I can easily edit my program and test it over and over? Meaning, without having to re-start Julia?

In particular, I would like to change the “comand line arguments” (while in REPL) and call main() over and over.

There may be a way to do what you want, but when faced with this problem in the past, I have changed the structure of the code to make REPL work simpler.

module MyProgram
using ArgParse

function do_stuff(args)
  # This function is the top-level of the program's functionality
  # and is easily called from the REPL
end

function parse_args()
  # Argument parsing happens here, this returns a parsed args structure
  # that can be passed to do_stuff()
end

function main()
  args = parse_args()
  do_stuff(args)
end

end

If creating args manually get tedious, it is often helpful to write some tools to create a starting point, I often create a test/REPL_tests.jl that has functions to mock up useful sets of args and then includet that file.

If you want to change the command line arguments while Julia is running, you can edit the variable ARGS.
Trying to assign a value to the variable probably won’t do what you want, but this should work:

clear!(ARGS)
append!(ARGS, ["foo", "--bar"])

For an example:

julia> using ArgMacros

julia> function main()
           @beginarguments begin
               @argumentflag verbose "-v"
               @positionaldefault Int 1 x
           end

           println(x, verbose)
       end
main (generic function with 1 method)

julia> ARGS
0-element Array{String,1}

julia> main()
1false

julia> append!(ARGS, ["3", "-v"])
2-element Array{String,1}:
 "3"
 "-v"

julia> main()
3true

julia> empty!(ARGS)
0-element Array{String,1}

julia> push!(ARGS, "4")
1-element Array{String,1}:
 "4"

julia> main()
4false
1 Like