Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ jobs:
run: julia -e 'using Pkg; Pkg.develop(PackageSpec(path=".")); Pkg.add(PackageSpec(url="https://github.com/timholy/Revise.jl")); Pkg.test("Revise")'
- name: Test while running Revise
if: ${{ matrix.os == 'ubuntu-latest' && matrix.version != '1.0' }}
run: julia --project -e 'using Pkg;
Pkg.add("Revise");
Pkg.test("CodeTracking"; coverage=true, test_args=["revise"])'
run: TERM="xterm" julia --project -i --code-coverage -e 'using InteractiveUtils, REPL, Revise, Pkg;
Pkg.add("ColorTypes");
@async(Base.run_main_repl(true, true, false, true, false));
sleep(2);
cd("test");
include("runtests.jl");
REPL.eval_user_input(:(exit()), Base.active_repl_backend)'
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ julia = "1"
[extras]
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["ColorTypes", "LinearAlgebra", "SparseArrays", "Test"]
test = ["ColorTypes", "LinearAlgebra", "REPL", "SparseArrays", "Test"]
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CodeTracking

[![Build status](https://github.com/timholy/CodeTracking.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/timholy/CodeTracking.jl/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/timholy/CodeTracking.jl/branch/master/graph/badge.svg?token=bBzCYyj19O)](https://codecov.io/gh/timholy/CodeTracking.jl)

CodeTracking can be thought of as an extension of Julia's
[InteractiveUtils library](https://docs.julialang.org/en/latest/stdlib/InteractiveUtils/).
It provides an interface for obtaining:
Expand Down
12 changes: 11 additions & 1 deletion src/CodeTracking.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
"""
CodeTracking can be thought of as an extension of InteractiveUtils, and pairs well with Revise.jl.

- `code_string`, `@code_string`: fetch the source code (as a string) for a method definition
- `code_expr`, `@code_expr`: fetch the expression for a method definition
- `definition`: a lower-level variant of the above
- `pkgfiles`: return information about the source files that define a package
- `whereis`: Return location information about methods (with Revise, it updates as you edit files)
- `signatures_at`: return the signatures of all methods whose definition spans the specified location
"""
module CodeTracking

using Base: PkgId
Expand Down Expand Up @@ -159,7 +169,7 @@ function signatures_at(filename::AbstractString, line::Integer)
end
end
end
error("$filename not found in internal data, perhaps the package is not loaded (or not loaded with `includet`)")
throw(ArgumentError("$filename not found in internal data, perhaps the package is not loaded (or not loaded with `includet`)"))
end

"""
Expand Down
2 changes: 2 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# This should stay as the first method because it's used in a test
# (or change the test)
function checkname(fdef::Expr, name)
fproto = fdef.args[1]
fdef.head === :where && return checkname(fproto, name)
Expand Down
50 changes: 38 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Note: some of CodeTracking's functionality can only be tested by Revise

using CodeTracking
using Test, InteractiveUtils, LinearAlgebra, SparseArrays
using Test, InteractiveUtils, REPL, LinearAlgebra, SparseArrays
# Note: ColorTypes needs to be installed, but note the intentional absence of `using ColorTypes`

using CodeTracking: line_is_decl
Expand Down Expand Up @@ -67,6 +67,10 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
show(io, info)
str = String(take!(io))
@test startswith(str, "PkgFiles(CodeTracking [da1fd8a2-8d9e-5ec2-8556-3022fb5608a2]):\n basedir:")
ioctx = IOContext(io, :compact=>true)
show(ioctx, info)
str = String(take!(io))
@test match(r"PkgFiles\(CodeTracking, .*CodeTracking(\.jl)?, String\[\]\)", str) !== nothing

@test pkgfiles("ColorTypes") === nothing
@test_throws ErrorException pkgfiles("NotAPkg")
Expand All @@ -86,17 +90,6 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
oldlookup = CodeTracking.method_lookup_callback[]
CodeTracking.method_lookup_callback[] = m -> error("oops")
@test whereis(m) == ("REPL[1]", 1)
# Test with definition(String, m)
if isdefined(Base, :active_repl)
hp = Base.active_repl.interface.modes[1].hist
fstr = "__fREPL__(x::Int16) = 0"
histidx = length(hp.history) + 1 - hp.start_idx
ex = Base.parse_input_line(fstr; filename="REPL[$histidx]")
f = Core.eval(Main, ex)
push!(hp.history, fstr)
@test definition(String, first(methods(f))) == (fstr, 1)
pop!(hp.history)
end
CodeTracking.method_lookup_callback[] = oldlookup

m = first(methods(Test.eval))
Expand All @@ -109,6 +102,10 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
end
m = first(methods(f150))
src = Base.uncompressed_ast(m)
idx = findfirst(lin -> String(lin.file) == @__FILE__, src.linetable)
lin = src.linetable[idx]
file, line = whereis(lin, m)
@test endswith(file, String(lin.file))
idx = findfirst(lin -> String(lin.file) != @__FILE__, src.linetable)
lin = src.linetable[idx]
file, line = whereis(lin, m)
Expand Down Expand Up @@ -167,6 +164,35 @@ end

# issue #23
@test !isempty(signatures_at("script.jl", 9))

@test_throws ArgumentError signatures_at("nofile.jl", 1)

if isdefined(Revise, :add_revise_deps)
Revise.add_revise_deps()
sigs = signatures_at(CodeTracking, "src/utils.jl", 5)
@test length(sigs) == 1 # only isn't available on julia 1.0
@test first(sigs) == Tuple{typeof(CodeTracking.checkname), Expr, Any}
@test pkgfiles(CodeTracking).id == Base.PkgId(CodeTracking)
end

# REPL (test copied from Revise)
if isdefined(Base, :active_repl)
hp = Base.active_repl.interface.modes[1].hist
fstr = "__fREPL__(x::Int16) = 0"
histidx = length(hp.history) + 1 - hp.start_idx
ex = Base.parse_input_line(fstr; filename="REPL[$histidx]")
f = Core.eval(Main, ex)
if ex.head === :toplevel
ex = ex.args[end]
end
push!(hp.history, fstr)
m = first(methods(f))
@test definition(String, first(methods(f))) == (fstr, 1)
@test !isempty(signatures_at(String(m.file), m.line))
pop!(hp.history)
elseif haskey(ENV, "CI")
error("CI Revise tests must be run with -i")
end
end
end

Expand Down