From 37a3b484d6538632eaec86920e3d1f212cee5959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 25 Jul 2024 09:55:29 +0100 Subject: [PATCH 1/3] Make `should_show_banner` work with julia 1.11 and nightly --- src/utils.jl | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 05aedd621..a899f0452 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,4 +1,5 @@ -function should_show_banner() +function is_loaded_directly() + @static if VERSION < v"1.11.0-" # Check if were loaded from another package # if VERSION < 1.7.*, only the "other" package will have the # _tryrequire_from_serialized in the backtrace. @@ -11,12 +12,26 @@ function should_show_banner() # 'using Package' serialized will have a version with less arguments bt = Base.process_backtrace(Base.backtrace()) Base.filter!(sf -> sf[1].func === :_tryrequire_from_serialized, bt) - isinteractive_manual = - length(bt) == 0 || (length(bt) == 1 && length(only(bt)[1].linfo.specTypes.parameters) < 4) + return length(bt) == 0 || + (length(bt) == 1 && length(only(bt)[1].linfo.specTypes.parameters) < 4) + else + # Starting with julia 1.11, the package loading was completely revamped. + # The only difference in the callstack is the line number of the call to _include_from_serialized + # inside of the _require_search_from_serialized function. + # To make it a bit more robust, we check the difference between the line number of the beginning + # of _require_search_from_serialized and the call to _include_from_serialized. + # For `using OtherPackage`, the difference is 61, while for `using Package`, the difference is 75 or 78 + # (on all 1.11 pre-releases up to 1.11.0-rc1 and 1.12.0-DEV.896, which are the newest at the time of writing this). + bt = Base.process_backtrace(Base.backtrace()) + Base.filter!(sf -> contains(string(sf[1].func), "_require_search_from_serialized"), bt) + bt_entry = only(bt)[1] + return bt_entry.line - bt_entry.linfo.def.line >= 70 + end +end - # Respect the -q flag - isquiet = Bool(Base.JLOptions().quiet) - show_banner = !isquiet && isinteractive_manual && isinteractive() && - Base.JLOptions().banner != 0 - return show_banner +function should_show_banner() + # Respect the -q flag + isquiet = Bool(Base.JLOptions().quiet) + show_banner = !isquiet && is_loaded_directly() && isinteractive() && Base.JLOptions().banner != 0 + return show_banner end From be6d4acc23dee532feb753d4811590f420fe278f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 25 Jul 2024 09:56:01 +0100 Subject: [PATCH 2/3] Enable banner tests on now working versions --- test/utils/Banners/banners.jl | 130 +++++++++++++++++----------------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/test/utils/Banners/banners.jl b/test/utils/Banners/banners.jl index 496f6bbc3..83b60f6a3 100644 --- a/test/utils/Banners/banners.jl +++ b/test/utils/Banners/banners.jl @@ -1,77 +1,75 @@ using Pkg -if VERSION>=v"1.9" - @testset "Banners" begin +@testset "Banners" begin - function run_repl_code(code::String, proj::String) - bin = Base.julia_cmd() - opts = ["--project=$proj", "-i", "-e", "$code; exit();"] - cmd = Cmd(`$bin $opts`, ignorestatus=true) - outs = IOBuffer() - errs = IOBuffer() - proc = run(pipeline(`$cmd`, stderr=errs, stdout=outs)) - result = String(take!(outs)) - err = String(take!(errs)) - return result, err, proc.exitcode - end + function run_repl_code(code::String, proj::String) + bin = Base.julia_cmd() + opts = ["--project=$proj", "-i", "-e", "$code; exit();"] + cmd = Cmd(`$bin $opts`, ignorestatus=true) + outs = IOBuffer() + errs = IOBuffer() + proc = run(pipeline(`$cmd`, stderr=errs, stdout=outs)) + result = String(take!(outs)) + err = String(take!(errs)) + return result, err, proc.exitcode + end - # Set up a separate temporary project for some modules that depend on each - # other with some of them showing banners. Chain is - # AA -> ModA -> ModB -> ModC - path = dirname(@__FILE__) - aadir = dirname(dirname(pathof(AbstractAlgebra))) - modadir = joinpath(path, "ModA") - modbdir = joinpath(path, "ModB") - modcdir = joinpath(path, "ModC") + # Set up a separate temporary project for some modules that depend on each + # other with some of them showing banners. Chain is + # AA -> ModA -> ModB -> ModC + path = dirname(@__FILE__) + aadir = dirname(dirname(pathof(AbstractAlgebra))) + modadir = joinpath(path, "ModA") + modbdir = joinpath(path, "ModB") + modcdir = joinpath(path, "ModC") - # generate temp project - td = mktempdir() - code = """ - using Pkg; - Pkg.develop(path=raw"$aadir"); - Pkg.develop(path=raw"$modadir"); - Pkg.develop(path=raw"$modbdir"); - Pkg.develop(path=raw"$modcdir"); - Pkg.precompile(); - """ - out,err,exitcode = run_repl_code(code, td) - res = @test exitcode == 0 - if res isa Test.Fail - println("out\n$out") - println("err\n$err") - end + # generate temp project + td = mktempdir() + code = """ + using Pkg; + Pkg.develop(path=raw"$aadir"); + Pkg.develop(path=raw"$modadir"); + Pkg.develop(path=raw"$modbdir"); + Pkg.develop(path=raw"$modcdir"); + Pkg.precompile(); + """ + out,err,exitcode = run_repl_code(code, td) + res = @test exitcode == 0 + if res isa Test.Fail + println("out\n$out") + println("err\n$err") + end - # Banner of ModA shows - out, err = run_repl_code("using ModA;", td) - res = @test strip(out) == "Banner of ModA" - if res isa Test.Fail - println("out\n$out") - println("err\n$err") - end + # Banner of ModA shows + out, err = run_repl_code("using ModA;", td) + res = @test strip(out) == "Banner of ModA" + if res isa Test.Fail + println("out\n$out") + println("err\n$err") + end - # Banner of ModB shows, but ModA is supressed - out, err = run_repl_code("using ModB;", td) - res = @test strip(out) == "Banner of ModB" broken=VERSION>=v"1.11.0-DEV" - if res isa Test.Fail - println("out\n$out") - println("err\n$err") - end + # Banner of ModB shows, but ModA is supressed + out, err = run_repl_code("using ModB;", td) + res = @test strip(out) == "Banner of ModB" + if res isa Test.Fail + println("out\n$out") + println("err\n$err") + end - # Banner of ModB shows, but ModA is supressed, even if ModA is specifically - # used after ModB - out, err = run_repl_code("using ModB; using ModA;", td) - res = @test strip(out) == "Banner of ModB" broken=VERSION>=v"1.11.0-DEV" - if res isa Test.Fail - println("out\n$out") - println("err\n$err") - end + # Banner of ModB shows, but ModA is supressed, even if ModA is specifically + # used after ModB + out, err = run_repl_code("using ModB; using ModA;", td) + res = @test strip(out) == "Banner of ModB" + if res isa Test.Fail + println("out\n$out") + println("err\n$err") + end - # Banner does not show when our module is a dependency - out, err = run_repl_code("using ModC;", td) - res = @test strip(out) == "" broken=VERSION>=v"1.11.0-DEV" - if res isa Test.Fail - println("out\n$out") - println("err\n$err") - end + # Banner does not show when our module is a dependency + out, err = run_repl_code("using ModC;", td) + res = @test strip(out) == "" + if res isa Test.Fail + println("out\n$out") + println("err\n$err") end end From ef41b00353ceb089b2d7b09a231d66be8f6f283d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Mon, 19 Aug 2024 14:51:24 +0200 Subject: [PATCH 3/3] Add try-catch --- src/utils.jl | 59 ++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index a899f0452..a9c5fe6e7 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,31 +1,36 @@ function is_loaded_directly() - @static if VERSION < v"1.11.0-" - # Check if were loaded from another package - # if VERSION < 1.7.*, only the "other" package will have the - # _tryrequire_from_serialized in the backtrace. - # if VERSION >= 1.8, also doing 'using Package' will have - # _tryrequire_from_serialized the backtrace. - # - # To still distinguish both scenarios, notice that - # 'using OtherPackage' will either have _tryrequire_from_serialized at least twice, - # or one with four arguments (hence five as the function name is the first argument) - # 'using Package' serialized will have a version with less arguments - bt = Base.process_backtrace(Base.backtrace()) - Base.filter!(sf -> sf[1].func === :_tryrequire_from_serialized, bt) - return length(bt) == 0 || - (length(bt) == 1 && length(only(bt)[1].linfo.specTypes.parameters) < 4) - else - # Starting with julia 1.11, the package loading was completely revamped. - # The only difference in the callstack is the line number of the call to _include_from_serialized - # inside of the _require_search_from_serialized function. - # To make it a bit more robust, we check the difference between the line number of the beginning - # of _require_search_from_serialized and the call to _include_from_serialized. - # For `using OtherPackage`, the difference is 61, while for `using Package`, the difference is 75 or 78 - # (on all 1.11 pre-releases up to 1.11.0-rc1 and 1.12.0-DEV.896, which are the newest at the time of writing this). - bt = Base.process_backtrace(Base.backtrace()) - Base.filter!(sf -> contains(string(sf[1].func), "_require_search_from_serialized"), bt) - bt_entry = only(bt)[1] - return bt_entry.line - bt_entry.linfo.def.line >= 70 + try + @static if VERSION < v"1.11.0-" + # Check if were loaded from another package + # if VERSION < 1.7.*, only the "other" package will have the + # _tryrequire_from_serialized in the backtrace. + # if VERSION >= 1.8, also doing 'using Package' will have + # _tryrequire_from_serialized the backtrace. + # + # To still distinguish both scenarios, notice that + # 'using OtherPackage' will either have _tryrequire_from_serialized at least twice, + # or one with four arguments (hence five as the function name is the first argument) + # 'using Package' serialized will have a version with less arguments + bt = Base.process_backtrace(Base.backtrace()) + Base.filter!(sf -> sf[1].func === :_tryrequire_from_serialized, bt) + return length(bt) == 0 || + (length(bt) == 1 && length(only(bt)[1].linfo.specTypes.parameters) < 4) + else + # Starting with julia 1.11, the package loading was completely revamped. + # The only difference in the callstack is the line number of the call to _include_from_serialized + # inside of the _require_search_from_serialized function. + # To make it a bit more robust, we check the difference between the line number of the beginning + # of _require_search_from_serialized and the call to _include_from_serialized. + # For `using OtherPackage`, the difference is 61, while for `using Package`, the difference is 75 or 78 + # (on all 1.11 pre-releases up to 1.11.0-rc1 and 1.12.0-DEV.896, which are the newest at the time of writing this). + bt = Base.process_backtrace(Base.backtrace()) + Base.filter!(sf -> contains(string(sf[1].func), "_require_search_from_serialized"), bt) + bt_entry = only(bt)[1] + return bt_entry.line - bt_entry.linfo.def.line >= 70 + end + catch e + @debug "Error while checking if loaded directly" exception=(e, Base.catch_backtrace()) + return true end end