Skip to content

Commit 46fb9b9

Browse files
authored
Shift Cthulhu to extension (#239)
- Require Julia 1.10+ - Add tests for registered error hints - Test the Cthulhu extension
1 parent f57bcd1 commit 46fb9b9

File tree

6 files changed

+112
-31
lines changed

6 files changed

+112
-31
lines changed

.github/workflows/ci.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ jobs:
2121
fail-fast: false
2222
matrix:
2323
os: [ubuntu-latest, windows-latest, macOS-latest]
24-
version: ['1.6', '1', 'pre']
24+
version: ['1.10', '1', 'pre']
2525
arch: [x64]
2626
include:
2727
- os: ubuntu-latest
2828
prefix: xvfb-run
2929
exclude:
3030
- os: windows-latest
31-
version: '1.6' # slow registry cloning on CI
31+
version: '1.10' # slow registry cloning on CI
3232
steps:
3333
- uses: actions/checkout@v4
3434
- uses: julia-actions/setup-julia@v2

Project.toml

+19-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ProfileView"
22
uuid = "c46f51b8-102a-5cf2-8d2c-8597cb0e0da7"
33
author = ["Tim Holy <[email protected]>"]
4-
version = "1.8.1"
4+
version = "1.9.0"
55

66
[deps]
77
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
@@ -18,27 +18,40 @@ MethodAnalysis = "85b6ec6f-f7df-4429-9514-a64bcd9ee824"
1818
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
1919
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
2020
Profile = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
21-
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
2221
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
2322

23+
[weakdeps]
24+
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
25+
26+
[extensions]
27+
ProfileViewCthulhuExt = "Cthulhu"
28+
2429
[compat]
2530
Cairo = "0.6, 0.8, 1"
26-
Colors = "0.9, 0.10, 0.11, 0.12, 0.13"
31+
Colors = "0.12, 0.13"
32+
Dates = "1"
33+
Cthulhu = "2"
2734
FileIO = "1.6"
2835
FlameGraphs = "0.2.10, 1"
2936
Graphics = "0.4, 1"
3037
Gtk4 = "0.5, 0.6, 0.7"
3138
GtkObservables = "2"
39+
InteractiveUtils = "1"
3240
IntervalSets = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7"
3341
MethodAnalysis = "0.4"
3442
PrecompileTools = "1"
3543
Preferences = "1.2"
36-
Requires = "1"
37-
julia = "1.6"
44+
REPL = "1"
45+
Profile = "1"
46+
Test = "1"
47+
UUIDs = "1"
48+
julia = "1.10"
3849

3950
[extras]
4051
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
52+
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
53+
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
4154
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4255

4356
[targets]
44-
test = ["AbstractTrees", "Test"]
57+
test = ["AbstractTrees", "Cthulhu", "REPL", "Test"]

ext/ProfileViewCthulhuExt.jl

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module ProfileViewCthulhuExt
2+
3+
using ProfileView
4+
using Cthulhu: Cthulhu
5+
6+
function ProfileView.descend_clicked(; optimize=false, iswarn=true, hide_type_stable=true, kwargs...)
7+
st = ProfileView.clicked[]
8+
if st === nothing || st.linfo === nothing
9+
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
10+
return nothing
11+
end
12+
return Cthulhu.descend(st.linfo; optimize, iswarn, hide_type_stable, kwargs...)
13+
end
14+
function ProfileView.ascend_clicked(; hide_type_stable=true, terminal=Cthulhu.default_terminal(), kwargs...)
15+
st = ProfileView.clicked[]
16+
if st === nothing || st.linfo === nothing
17+
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
18+
return nothing
19+
end
20+
if hasmethod(Cthulhu.buildframes, Tuple{Vector{StackTraces.StackFrame}})
21+
return Cthulhu.ascend(terminal, ProfileView.clicked_trace[]; hide_type_stable, kwargs...)
22+
else
23+
return Cthulhu.ascend(terminal, st.linfo; hide_type_stable, kwargs...)
24+
end
25+
end
26+
27+
end

src/ProfileView.jl

-23
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import GtkObservables: Canvas
1616
import Cairo
1717
using Graphics
1818
using Preferences
19-
using Requires
2019

2120
using FlameGraphs: Node, NodeData
2221
const CONTROL = Gtk4.ModifierType_CONTROL_MASK
@@ -564,28 +563,6 @@ discardfirstcol(A) = A[:,2:end]
564563
discardfirstcol(A::IndirectArray) = IndirectArray(A.index[:,2:end], A.values)
565564

566565
function __init__()
567-
@require Cthulhu="f68482b8-f384-11e8-15f7-abe071a5a75f" begin
568-
function descend_clicked(; optimize=false, iswarn=true, hide_type_stable=true, kwargs...)
569-
st = clicked[]
570-
if st === nothing || st.linfo === nothing
571-
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
572-
return nothing
573-
end
574-
return Cthulhu.descend(st.linfo; optimize, iswarn, hide_type_stable, kwargs...)
575-
end
576-
function ascend_clicked(; hide_type_stable=true, kwargs...)
577-
st = clicked[]
578-
if st === nothing || st.linfo === nothing
579-
@warn "the bar you clicked on might have been inlined and unavailable for inspection. Click on a non-inlined bar to `descend`."
580-
return nothing
581-
end
582-
if hasmethod(Cthulhu.buildframes, Tuple{Vector{StackTraces.StackFrame}})
583-
return Cthulhu.ascend(clicked_trace[]; hide_type_stable, kwargs...)
584-
else
585-
return Cthulhu.ascend(st.linfo; hide_type_stable, kwargs...)
586-
end
587-
end
588-
end
589566
Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs
590567
if (exc.f === descend_clicked || exc.f === ascend_clicked) && isempty(argtypes)
591568
printstyled(io, "\n`using Cthulhu` is required for `$(exc.f)`"; color=:yellow)

test/extensions.jl

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using ProfileView
2+
using Cthulhu
3+
if !isdefined(@__MODULE__, :fake_terminal)
4+
@eval (@__MODULE__) begin
5+
include(joinpath(pkgdir(Cthulhu), "test", "FakeTerminals.jl"))
6+
using .FakeTerminals
7+
macro with_try_stderr(out, expr)
8+
quote
9+
try
10+
$(esc(expr))
11+
catch err
12+
bt = catch_backtrace()
13+
Base.display_error(stderr, err, bt)
14+
#close($(esc(out)))
15+
end
16+
end
17+
end
18+
end
19+
end
20+
using Test
21+
22+
@testset "Extensions" begin
23+
@testset "Cthulhu" begin
24+
cread1(io) = readuntil(io, ''; keep=true)
25+
cread(io) = cread1(io) * cread1(io)
26+
27+
# profile_test(1) # defined in test/runtests.jl
28+
# @profile profile_test(10)
29+
_, bt = add2(Any[1,2])
30+
st = stacktrace(bt)
31+
ProfileView.clicked[] = st[1]
32+
fake_terminal() do term, in, out, _
33+
t = @async begin
34+
@with_try_stderr out descend_clicked(; interruptexc=false, terminal=term)
35+
end
36+
lines = cread(out)
37+
@test occursin("Select a call to descend into", lines)
38+
write(in, 'q')
39+
wait(t)
40+
end
41+
ProfileView.clicked_trace[] = st
42+
fake_terminal() do term, in, out, _
43+
t = @async begin
44+
@with_try_stderr out ascend_clicked(; interruptexc=false, terminal=term)
45+
end
46+
lines = readuntil(out, 'q'; keep=true) # up to the "q to quit" prompt
47+
@test occursin("Choose a call for analysis", lines)
48+
write(in, 'q')
49+
write(in, 'q')
50+
wait(t)
51+
end
52+
end
53+
end

test/runtests.jl

+11
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ end
8888

8989
@test isa(ProfileView.view(nothing), ProfileView.GtkWindow)
9090

91+
ProfileView.closeall()
92+
9193
# Interactivity
9294
stackframe(func, file, line; C=false) = ProfileView.StackFrame(Symbol(func), Symbol(file), line, nothing, C, false, 0)
9395

@@ -180,4 +182,13 @@ end
180182
ProfileView.clicked[] = st[idx]
181183
@test_logs (:warn, "click on a non-inlined bar to see `code_warntype` info") warntype_clicked(io) === nothing
182184
end
185+
186+
@testset "error hints" begin
187+
if !isdefined(@__MODULE__, :Cthulhu)
188+
@test_throws "`using Cthulhu` is required" ProfileView.descend_clicked()
189+
@test_throws "`using Cthulhu` is required" ProfileView.ascend_clicked()
190+
end
191+
end
183192
end
193+
194+
include("extensions.jl")

0 commit comments

Comments
 (0)