diff --git a/LICENSE b/LICENSE index 7651cf7..fbcdcb6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Adrian Hill +Copyright (c) 2024 Adrian Hill , Kristoffer Carlsson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Project.toml b/Project.toml index 02604a3..010d9f9 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,13 @@ name = "MethodURL" uuid = "461c4225-bb7a-4706-8416-467e5545dbd6" -authors = ["Adrian Hill "] -version = "1.0.0-DEV" +authors = ["Adrian Hill ", "Kristoffer Carlsson"] +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" diff --git a/src/MethodURL.jl b/src/MethodURL.jl index 71f6598..89b8d8f 100644 --- a/src/MethodURL.jl +++ b/src/MethodURL.jl @@ -1,5 +1,56 @@ +# Based on code by Kristoffer Carlsson: +# https://github.com/JuliaLang/julia/issues/47709#issuecomment-2388629772 + module MethodURL -# Write your package code here. +using RegistryInstances: reachable_registries, registry_info +using URIs: URI +using Base: PkgId + +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") + end +end + +function repos_package(uuid) + repos = String[] + for reg in reachable_registries() + entry = get(reg, uuid, nothing) + if entry !== nothing + info = registry_info(entry) + push!(repos, info.repo) + end + end + return repos +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 + 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) + push!(urls, url) + end + return urls end + +end # module