diff --git a/src/server.jl b/src/server.jl index f1abab6..d4cc587 100644 --- a/src/server.jl +++ b/src/server.jl @@ -64,7 +64,14 @@ function _extract_timeout(merged_options) end function _exeflags_and_env(options) - exeflags = map(String, options["format"]["metadata"]["julia"]["exeflags"]) + env_exeflags = + JSON3.read(get(ENV, "QUARTONOTEBOOKRUNNER_EXEFLAGS", "[]"), Vector{String}) + options_exeflags = map(String, options["format"]["metadata"]["julia"]["exeflags"]) + # We want to be able to override exeflags that are defined via environment variable, + # but leave the remaining flags intact (for example override number of threads but leave sysimage). + # We can do this by adding the options exeflags after the env exeflags. + # Julia will ignore earlier uses of the same flag. + exeflags = [env_exeflags; options_exeflags] env = map(String, options["format"]["metadata"]["julia"]["env"]) # Use `--project=@.` if neither `JULIA_PROJECT=...` nor `--project=...` are specified if !any(startswith("JULIA_PROJECT="), env) && !any(startswith("--project="), exeflags) @@ -537,11 +544,10 @@ end function default_frontmatter() D = Dict{String,Any} - exeflags = JSON3.read(get(ENV, "QUARTONOTEBOOKRUNNER_EXEFLAGS", "[]"), Vector{String}) env = JSON3.read(get(ENV, "QUARTONOTEBOOKRUNNER_ENV", "[]"), Vector{String}) return D( "fig-format" => "png", - "julia" => D("exeflags" => exeflags, "env" => env), + "julia" => D("env" => env, "exeflags" => []), "execute" => D("error" => true), ) end diff --git a/test/examples/exeflags_merging.qmd b/test/examples/exeflags_merging.qmd new file mode 100644 index 0000000..a96cba2 --- /dev/null +++ b/test/examples/exeflags_merging.qmd @@ -0,0 +1,14 @@ +--- +title: Exeflags merging +engine: julia +julia: + exeflags: [] +--- + +```{julia} +print(Base.active_project()) +``` + +```{julia} +print(Threads.nthreads()) +``` \ No newline at end of file diff --git a/test/testsets/exeflags_merging.jl b/test/testsets/exeflags_merging.jl new file mode 100644 index 0000000..3aa51f7 --- /dev/null +++ b/test/testsets/exeflags_merging.jl @@ -0,0 +1,46 @@ +include("../utilities/prelude.jl") + +@testset "exeflags merging" begin + + function with_replacement_file(f, file, replacements...) + s = read(file, String) + mktempdir() do dir + tempfile = joinpath(dir, basename(file)) + open(tempfile, "w") do io + write(io, replace(s, replacements...)) + end + f(tempfile) + end + end + + file = joinpath(@__DIR__, "../examples/exeflags_merging.qmd") + + withenv( + "QUARTONOTEBOOKRUNNER_EXEFLAGS" => "[\"--project=/set_via_env\", \"--threads=3\"]", + ) do + server = QuartoNotebookRunner.Server() + json = QuartoNotebookRunner.run!(server, file; showprogress = false) + @test contains(json.cells[2].outputs[1].text, "set_via_env") + @test json.cells[4].outputs[1].text == "3" + close!(server) + + with_replacement_file( + file, + "[]" => "[\"--project=/override_via_frontmatter\"]", + ) do newfile + server = QuartoNotebookRunner.Server() + json = QuartoNotebookRunner.run!(server, newfile; showprogress = false) + @test contains(json.cells[2].outputs[1].text, "override_via_frontmatter") + @test json.cells[4].outputs[1].text == "3" + close!(server) + end + + with_replacement_file(file, "[]" => "[\"--threads=5\"]") do newfile + server = QuartoNotebookRunner.Server() + json = QuartoNotebookRunner.run!(server, newfile; showprogress = false) + @test contains(json.cells[2].outputs[1].text, "set_via_env") + @test json.cells[4].outputs[1].text == "5" + close!(server) + end + end +end