Skip to content

Commit

Permalink
Handle Base methods
Browse files Browse the repository at this point in the history
  • Loading branch information
adrhill committed Oct 21, 2024
1 parent 0a163d9 commit 8e661aa
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 20 deletions.
2 changes: 0 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ version = "0.1.0-DEV"

[deps]
RegistryInstances = "2792f1a3-b283-48e8-9a74-f99dce5104f3"
URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"

[compat]
RegistryInstances = "0.1"
URIs = "1"
julia = "1.10"
61 changes: 45 additions & 16 deletions src/MethodURL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@

module MethodURL

using Base: PkgId, UUID, inbase
using RegistryInstances: reachable_registries, registry_info
using URIs: URI
using Base: PkgId

export url

function repo_and_path_to_url(repo, version, path, line)
repo = chopsuffix(repo, ".git")
# TODO: Handle more git forges
if startswith(repo, "https://github.com")
return join([repo, "blob", "v" * version, path * "#L$line"], "/")
else
error("failed to handle $repo")
error("Failed to construct URL for repository $repo.")
end
end

function repos_package(uuid)
# Find repository in reachable registries by looking up UUID
function repos_package(uuid::UUID)
repos = String[]
for reg in reachable_registries()
entry = get(reg, uuid, nothing)
Expand All @@ -29,26 +31,53 @@ function repos_package(uuid)
return repos
end

# Return errors instead of `nothing`
function _uuid(M::Module)
uuid = PkgId(M).uuid
isnothing(uuid) && error("Failed to find UUID of package $M.")
return uuid
end

# Return errors instead of `nothing`
function _pkgdir(M::Module)
dir = pkgdir(M)
isnothing(dir) && error("Failed to find directory of package $M.")
return dir
end

# TODO: If package is devved use local path
# TODO: If package is added by URL, use that
function url(m::Method)
M = parentmodule(m)
uuid = PkgId(M).uuid
file = String(m.file)
line = m.line

pkg_splitpath = splitpath(pkgdir(M))
file_splitpath = splitpath(String(m.file))
while !isempty(pkg_splitpath) && first(pkg_splitpath) == first(file_splitpath)
popfirst!(pkg_splitpath)
popfirst!(file_splitpath)
end
local_dir = join(file_splitpath, "/")

v = string(pkgversion(M))
urls = String[]
for repo in repos_package(uuid)
url = repo_and_path_to_url(repo, v, local_dir, line)
if inbase(M)
# adapted from https://github.com/JuliaLang/julia/blob/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/methodshow.jl#L382-L388
commit = Base.GIT_VERSION_INFO.commit
if isempty(commit)
url = "https://github.com/JuliaLang/julia/tree/v$VERSION/base/$file#L$line"
else
url = "https://github.com/JuliaLang/julia/tree/$commit/base/$file#L$line"
end
push!(urls, url)
else
uuid = _uuid(M)
pkg_splitpath = splitpath(_pkgdir(M))
file_splitpath = splitpath(file)
while !isempty(pkg_splitpath) && first(pkg_splitpath) == first(file_splitpath)
popfirst!(pkg_splitpath)
popfirst!(file_splitpath)
end
local_dir = join(file_splitpath, "/")
# @info M file uuid _pkgdir(M) local_dir

v = string(pkgversion(M))
for repo in repos_package(uuid)
url = repo_and_path_to_url(repo, v, local_dir, line)
push!(urls, url)
end
end
return urls
end
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
48 changes: 46 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using MethodURL

using Test
using JuliaFormatter: JuliaFormatter
using Aqua: Aqua
Expand All @@ -12,6 +13,18 @@ using ExplicitImports:
check_all_qualified_accesses_via_owners,
check_all_qualified_accesses_are_public

using HTTP: request

function url_exists(url)
response = request("GET", url; status_exception=false, redirect=true, retry=true)
if 200 response.status < 400
return true
else
@warn "Failed to request URL" url response.status response
return false
end
end

@testset verbose = true "MethodURL.jl" begin
@testset verbose = true "Linting" begin
@testset "Code formatting (JuliaFormatter.jl)" begin
Expand All @@ -31,13 +44,44 @@ using ExplicitImports:
@testset "Improper explicit imports" begin
@test isnothing(check_no_stale_explicit_imports(MethodURL))
@test isnothing(check_all_explicit_imports_via_owners(MethodURL))
@test isnothing(check_all_explicit_imports_are_public(MethodURL))
@test isnothing(
check_all_explicit_imports_are_public(
MethodURL; ignore=(:PkgId, :inbase)
),
)
end
@testset "Improper qualified accesses" begin
@test isnothing(check_all_qualified_accesses_via_owners(MethodURL))
@test isnothing(check_no_self_qualified_accesses(MethodURL))
@test isnothing(check_all_qualified_accesses_are_public(MethodURL))
@test isnothing(
check_all_qualified_accesses_are_public(
MethodURL; ignore=(:GIT_VERSION_INFO,)
),
)
end
end
end
@testset verbose = true "URL" begin
@testset "Base" begin
m1 = @which sqrt(1.0)
u1 = first(@inferred url(m1))
# @test url_exists(u1)
end
# @testset "Stdlib" begin
# m2 = @which @test true
# u2 = first(@inferred url(m2))
# # @test url_exists(u2)
# end
# @testset "Local" begin
# _m = @which sqrt(1.0)
# m3 = @which url(_m)
# u3 = first(@inferred url(m3))
# # @test url_exists(u3)
# end
@testset "External" begin
m4 = @which Aqua.test_all(MethodURL)
u4 = first(@inferred url(m4))
# @test url_exists(u4)
end
end
end

0 comments on commit 8e661aa

Please sign in to comment.