From 88646341b764df69541b2e32115d0869da5cf6a1 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 5 Oct 2023 11:51:20 -0400 Subject: [PATCH] highlight bad manifests when erroring --- base/loading.jl | 70 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/base/loading.jl b/base/loading.jl index df0252f3d695b6..5fd7f5f0e10a2c 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1774,9 +1774,10 @@ function __require(into::Module, mod::Symbol) Package $mod not found in current path$hint_message. - $start_sentence `import Pkg; Pkg.add($(repr(String(mod))))` to install the $mod package.""")) else + manifest_warnings = collect_manifest_warnings() throw(ArgumentError(""" Package $(where.name) does not have $mod in its dependencies: - - You may have a partially installed environment. Try `Pkg.instantiate()` + $manifest_warnings- You may have a partially installed environment. Try `Pkg.instantiate()` to ensure all packages in the environment are installed. - Or, if you have $(where.name) checked out for development and have added $mod as a dependency but haven't updated your primary @@ -1795,6 +1796,73 @@ function __require(into::Module, mod::Symbol) end end +function find_unsuitable_manifests_versions() + unsuitable_manifests = String[] + dev_manifests = String[] + for env in load_path() + project_file = env_project_file(env) + project_file || continue # no project file + manifest_file = project_file_manifest_path(project_file) + manifest_file isa String || continue # no manifest file + m = parsed_toml(manifest_file) + man_julia_version = get(m, "julia_version", nothing) + man_julia_version isa String || @goto mark + man_julia_version = VersionNumber(man_julia_version) + thispatch(man_julia_version) != thispatch(VERSION) && @goto mark + isempty(man_julia_version.prerelease) != isempty(VERSION.prerelease) && @goto mark + isempty(man_julia_version.prerelease) && continue + man_julia_version.prerelease[1] != VERSION.prerelease[1] && @goto mark + if VERSION.prerelease[1] == "DEV" + # manifests don't store the 2nd part of prerelease, so cannot check further + # so treat them specially in the warning + push!(dev_manifests, string(manifest_file, " (v", man_julia_version, ")")) + end + continue + @label mark + push!(unsuitable_manifests, string(manifest_file, " (v", man_julia_version, ")")) + end + return unsuitable_manifests, dev_manifests +end + +function collect_manifest_warnings() + unsuitable_manifests, dev_manifests = find_unsuitable_manifests_versions() + msg = if isempty(unsuitable_manifests) + "" + elseif length(unsuitable_manifests) == 1 + """ + - Note that a manifest in the load path was resolved with a different + julia version, which may be the cause of the error: + $(only(unsuitable_manifests)) + + """ + else + """ + - Note that manifests in the load path were resolved with a different + julia version, which may be the cause of the error: + $(join(unsuitable_manifests, "\n ")) + + """ + end + if length(dev_manifests) == 1 + msg *= """ + - Note that a manifest in the load path was resolved a potentially + different DEV version of the current version, which may be the cause + of the error: + $(only(dev_manifests)) + + """ + else + msg *= """ + - Note that manifests in the load path were resolved with potentially + different DEV versions of the current version, which may be the cause + of the error: + $(join(dev_manifests, "\n ")) + + """ + end + return msg +end + require(uuidkey::PkgId) = @lock require_lock _require_prelocked(uuidkey) const REPL_PKGID = PkgId(UUID("3fa0cd96-eef1-5676-8a61-b3b8758bbffb"), "REPL")