From a1e3ad6bbab718d4c046d7c8a92130a5a349e2eb Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 14 Aug 2024 14:11:22 +0200 Subject: [PATCH 01/10] fix flickering of progress bar on package installation (#3993) (cherry picked from commit a7179007182046b28ec9933fa2eaa1c8283a6e00) --- src/MiniProgressBars.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MiniProgressBars.jl b/src/MiniProgressBars.jl index 4a90e237b4..564a803917 100644 --- a/src/MiniProgressBars.jl +++ b/src/MiniProgressBars.jl @@ -40,7 +40,7 @@ function show_progress(io::IO, p::MiniProgressBar; termwidth=nothing, carriagere return end t = time() - if p.has_shown && (t - p.time_shown) < PROGRESS_BAR_TIME_GRANULARITY[] + if !p.always_reprint && p.has_shown && (t - p.time_shown) < PROGRESS_BAR_TIME_GRANULARITY[] return end p.time_shown = t From e26f8451b6751b25ef29b52e61cc625337b3e71e Mon Sep 17 00:00:00 2001 From: Markus Hauru Date: Sun, 1 Sep 2024 00:17:47 +0200 Subject: [PATCH 02/10] Allow comma separated packages for ]dev (#3997) (cherry picked from commit 299a356100f54215388502148979189aff760822) --- src/REPLMode/REPLMode.jl | 2 +- test/repl.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/REPLMode/REPLMode.jl b/src/REPLMode/REPLMode.jl index 032a1b90be..09c3ba47de 100644 --- a/src/REPLMode/REPLMode.jl +++ b/src/REPLMode/REPLMode.jl @@ -167,7 +167,7 @@ Base.@kwdef mutable struct Statement end function lex(cmd::String)::Vector{QString} - replace_comma = (nothing!=match(r"^(add|rm|remove|status|precompile)+\s", cmd)) + replace_comma = (nothing!=match(r"^(add|dev|develop|rm|remove|status|precompile)+\s", cmd)) in_doublequote = false in_singlequote = false qstrings = QString[] diff --git a/test/repl.jl b/test/repl.jl index 542baffbd0..4c66849e6c 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -120,6 +120,8 @@ temp_pkg_dir(;rm=false) do project_path; cd(project_path) do; mktempdir() do tmp_dev_dir withenv("JULIA_PKG_DEVDIR" => tmp_dev_dir) do pkg"develop Example" + pkg"develop Example,PackageCompiler" + pkg"develop Example PackageCompiler" # Copy the manifest + project and see that we can resolve it in a new environment # and get all the packages installed From 36609b575007911af643e4fd2813d58dc7c54a81 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 3 Sep 2024 20:22:17 -0400 Subject: [PATCH 03/10] fix precompiling packages specifically (#4014) (cherry picked from commit 8597c4ef32d96952b498a06d735d9a822fbbdd07) --- src/REPLMode/command_declarations.jl | 1 + test/new.jl | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/REPLMode/command_declarations.jl b/src/REPLMode/command_declarations.jl index 1dce353744..b82b6f5900 100644 --- a/src/REPLMode/command_declarations.jl +++ b/src/REPLMode/command_declarations.jl @@ -364,6 +364,7 @@ Create a minimal project called `pkgname` in the current folder. For more featur ], PSA[:name => "precompile", :api => API.precompile, + :should_splat => false, :arg_count => 0 => Inf, :completions => complete_installed_packages, :description => "precompile all the project dependencies", diff --git a/test/new.jl b/test/new.jl index fe9845fe5f..098a85736c 100644 --- a/test/new.jl +++ b/test/new.jl @@ -2185,19 +2185,17 @@ end api, arg, opts = first(Pkg.pkg"precompile Foo") @test api == Pkg.precompile - @test arg == "Foo" + @test arg == ["Foo"] @test isempty(opts) - api, arg1, arg2, opts = first(Pkg.pkg"precompile Foo Bar") + api, arg, opts = first(Pkg.pkg"precompile Foo Bar") @test api == Pkg.precompile - @test arg1 == "Foo" - @test arg2 == "Bar" + @test arg == ["Foo", "Bar"] @test isempty(opts) - api, arg1, arg2, opts = first(Pkg.pkg"precompile Foo, Bar") + api, arg, opts = first(Pkg.pkg"precompile Foo, Bar") @test api == Pkg.precompile - @test arg1 == "Foo" - @test arg2 == "Bar" + @test arg == ["Foo", "Bar"] @test isempty(opts) end end From b6cc7956924af383a697b200d047a45a1cd31a85 Mon Sep 17 00:00:00 2001 From: Peter Simon Date: Sat, 14 Sep 2024 06:17:04 -0700 Subject: [PATCH 04/10] Tweak sentence syntax in getting-started.md (#4020) (cherry picked from commit e5f400b2490d5c29c43754dbeb404783050cf451) --- docs/src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/getting-started.md b/docs/src/getting-started.md index 54aef78604..6e20560b07 100644 --- a/docs/src/getting-started.md +++ b/docs/src/getting-started.md @@ -154,7 +154,7 @@ We can see that the `tutorial` environment now contains `Example` and `JSON`. If you have the same package (at the same version) installed in multiple environments, the package will only be downloaded and stored on the hard drive once. This makes environments - very lightweight and effectively free to create. Only using the default + very lightweight and effectively free to create. Using only the default environment with a huge number of packages in it is a common beginners mistake in Julia. Learning how to use environments effectively will improve your experience with Julia packages. From f51704c7fdbd826239bf22aa53dc132abd4eea88 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 22 Sep 2024 08:13:41 -0400 Subject: [PATCH 05/10] warn if General is installed via the old slow methods (#4022) * warn if General is installed via the old slow methods * add env var disable (cherry picked from commit acc54fc02d313c4917c9b3bb782c0d9e92e0555b) --- src/Registry/Registry.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Registry/Registry.jl b/src/Registry/Registry.jl index d98807e02d..5ce11c96af 100644 --- a/src/Registry/Registry.jl +++ b/src/Registry/Registry.jl @@ -429,6 +429,15 @@ function update(regs::Vector{RegistrySpec} = RegistrySpec[]; io::IO=stderr_f(), registry_update_log[string(reg.uuid)] = now() @label done_tarball_read else + if reg.name == "General" && Base.get_bool_env("JULIA_PKG_GEN_REG_FMT_CHECK", true) + @info """ + The General registry is installed via unpacked tarball. + Consider reinstalling it via the newer faster direct from + tarball format by running: + pkg> registry rm General; registry add General + + """ maxlog=1 + end mktempdir() do tmp try download_verify_unpack(url, nothing, tmp, ignore_existence = true, io=io) @@ -447,6 +456,14 @@ function update(regs::Vector{RegistrySpec} = RegistrySpec[]; io::IO=stderr_f(), end elseif isdir(joinpath(reg.path, ".git")) printpkgstyle(io, :Updating, "registry at " * regpath) + if reg.name == "General" && Base.get_bool_env("JULIA_PKG_GEN_REG_FMT_CHECK", true) + @info """ + The General registry is installed via git. Consider reinstalling it via + the newer faster direct from tarball format by running: + pkg> registry rm General; registry add General + + """ maxlog=1 + end LibGit2.with(LibGit2.GitRepo(reg.path)) do repo if LibGit2.isdirty(repo) push!(errors, (regpath, "registry dirty")) From ad6ec0f1c72d76c728f475ed742d77f4138fcf92 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 26 Sep 2024 17:20:14 -0400 Subject: [PATCH 06/10] test fixes because Example v0.5.4 and v0.5.5 were registered (#4029) (cherry picked from commit 51d4910c114a863d888659cb8962c1e161b2a421) --- test/new.jl | 2 +- test/pkg.jl | 21 +++++++++++++++++++-- test/repl.jl | 3 ++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/test/new.jl b/test/new.jl index 098a85736c..0d6f3e7f3d 100644 --- a/test/new.jl +++ b/test/new.jl @@ -800,7 +800,7 @@ end @test Pkg.dependencies()[exuuid].version == v"0.3.0" @test Pkg.dependencies()[pngjll_uuid].version == v"1.6.37+4" Pkg.add(Pkg.PackageSpec(;name="JSON", version="0.18.0"); preserve=Pkg.PRESERVE_NONE) - @test Pkg.dependencies()[exuuid].version == v"0.5.3" + @test Pkg.dependencies()[exuuid].version > v"0.3.0" @test Pkg.dependencies()[json_uuid].version == v"0.18.0" @test Pkg.dependencies()[pngjll_uuid].version > v"1.6.37+4" end diff --git a/test/pkg.jl b/test/pkg.jl index e7e2b299a3..13e2a0ab96 100644 --- a/test/pkg.jl +++ b/test/pkg.jl @@ -268,8 +268,9 @@ temp_pkg_dir() do project_path end @testset "develop / freeing" begin - Pkg.add(TEST_PKG.name) + Pkg.add(name=TEST_PKG.name, version=v"0.5.3") old_v = Pkg.dependencies()[TEST_PKG.uuid].version + @test old_v == v"0.5.3" Pkg.rm(TEST_PKG.name) mktempdir() do devdir withenv("JULIA_PKG_DEVDIR" => devdir) do @@ -298,11 +299,27 @@ temp_pkg_dir() do project_path touch("deps.jl") """ ) + exa_proj = joinpath(devdir, TEST_PKG.name, "Project.toml") + proj_str = read(exa_proj, String) + compat_onwards = split(proj_str, "[compat]")[2] + open(exa_proj, "w") do io + println(io, """ + name = "Example" + uuid = "$(TEST_PKG.uuid)" + version = "100.0.0" + + [compat] + $compat_onwards + """) + end + Pkg.resolve() + @test Pkg.dependencies()[TEST_PKG.uuid].version == v"100.0.0" Pkg.build(TEST_PKG.name) @test isfile(joinpath(devdir, TEST_PKG.name, "deps", "deps.jl")) Pkg.test(TEST_PKG.name) Pkg.free(TEST_PKG.name) - @test Pkg.dependencies()[TEST_PKG.uuid].version == old_v + @test Pkg.dependencies()[TEST_PKG.uuid].version < v"100.0.0" + @test Pkg.dependencies()[TEST_PKG.uuid].version >= old_v end end end diff --git a/test/repl.jl b/test/repl.jl index 4c66849e6c..ca86943614 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -55,9 +55,10 @@ temp_pkg_dir(;rm=false) do project_path; cd(project_path) do; tmp_pkg_path = mktempdir() pkg"activate ." - pkg"add Example@0.5" + pkg"add Example@0.5.3" @test isinstalled(TEST_PKG) v = Pkg.dependencies()[TEST_PKG.uuid].version + @test v == v"0.5.3" pkg"rm Example" pkg"add Example, Random" pkg"rm Example Random" From ada705ee02ba5b870bda8c3f548bcec000ad8d0d Mon Sep 17 00:00:00 2001 From: Carlo Baldassi Date: Tue, 1 Oct 2024 08:11:20 +0200 Subject: [PATCH 07/10] Fix the greedy resolver (#4032) Fix #4030 (cherry picked from commit e06588db6cc95ab686bf16885ee0081a9087adb6) --- src/Resolve/Resolve.jl | 2 ++ test/resolve.jl | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Resolve/Resolve.jl b/src/Resolve/Resolve.jl index 980454ddba..090cc42924 100644 --- a/src/Resolve/Resolve.jl +++ b/src/Resolve/Resolve.jl @@ -341,6 +341,8 @@ function greedysolver(graph::Graph) return (false, Int[]) elseif old_v1 == spp[p1] sol[p1] = v1 + fill!(gconstr[p1], false) + gconstr[p1][v1] = true push!(staged_next, p1) end end diff --git a/test/resolve.jl b/test/resolve.jl index f45e12b20f..27e4480ad2 100644 --- a/test/resolve.jl +++ b/test/resolve.jl @@ -611,7 +611,6 @@ end ) @test resolve_tst(deps_data, reqs_data, want_data) - # require A, D, and lower version of Y reqs_data = Any[ ["A", "*"], @@ -632,6 +631,39 @@ end ) @test resolve_tst(deps_data, reqs_data, want_data) + + VERBOSE && @info("SCHEME 15") + ## DEPENDENCY SCHEME 15: A GRAPH WITH A WEAK DEPENDENCE + ## (REDUCED VERSION OF A REALISTIC SCHEME, ref Pkg.jl issue #4030) + deps_data = Any[ + ["A", v"1"], + ["A", v"2", "C", "*"], + ["B", v"1", "D", "1", :weak], + ["C", v"1", "E", "*"], + ["C", v"2", "E", "*"], + ["C", v"2", "B", "1"], + ["E", v"1", "D", "1"], + ["E", v"2", "F", "1"], + ["F", v"1", "D", "*"], + ["D", v"1"], + ["D", v"2"], + ] + + @test sanity_tst(deps_data) + + reqs_data = Any[ + ["A", "*"], + ] + want_data = Dict( + "A" => v"2", + "B" => v"1", + "C" => v"2", + "D" => v"1", + "E" => v"2", + "F" => v"1", + ) + @test resolve_tst(deps_data, reqs_data, want_data) + end @testset "realistic" begin From cab7300f3827011d2eebb1e362d0a2282e07e97d Mon Sep 17 00:00:00 2001 From: tecosaur Date: Fri, 10 Nov 2023 07:11:29 +0800 Subject: [PATCH 08/10] More informative missing weakdep error (#3610) (cherry picked from commit b70857cbc6ec2d2109d5d84a79107606291b8ba0) --- src/Operations.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Operations.jl b/src/Operations.jl index cd338ba7ed..4e9eaed55f 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -2210,6 +2210,9 @@ function status_ext_info(pkg::PackageSpec, env::EnvCache) # Check if deps are loaded extdeps_info= Tuple{String, Bool}[] for extdep in extdeps + haskey(weakdepses, extdep) || + pkgerror(isnothing(pkg.name) ? "M" : "$(pkg.name) has a m", + "alformed Project.toml, the extension package $extdep is not listed in [weakdeps]") uuid = weakdepses[extdep] loaded = haskey(Base.loaded_modules, Base.PkgId(uuid, extdep)) push!(extdeps_info, (extdep, loaded)) From a7e9bcc97d8b33944b0ccfa0f6f7e5156e8abe9b Mon Sep 17 00:00:00 2001 From: Nathan Zimmerberg <39104088+nhz2@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:14:19 -0400 Subject: [PATCH 09/10] retry rename (#4001) (cherry picked from commit bc51db730550fe67d9f85131eee44b8b15628e4e) --- src/Artifacts.jl | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Artifacts.jl b/src/Artifacts.jl index ae47811e06..9f236ddb9d 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -65,20 +65,42 @@ Either rename the directory at `temp_dir` to `new_path` and set it to read-only or if `new_path` artifact already exists try to do nothing. """ function _mv_temp_artifact_dir(temp_dir::String, new_path::String)::Nothing - if !isdir(new_path) + # Sometimes a rename can fail because the temp_dir is locked by + # anti-virus software scanning the new files. + # In this case we want to sleep and try again. + # I am using the list of error codes to retry from: + # https://github.com/isaacs/node-graceful-fs/blob/234379906b7d2f4c9cfeb412d2516f42b0fb4953/polyfills.js#L87 + # Retry for up to about 60 seconds by retrying 20 times with exponential backoff. + retry = 0 + max_num_retries = 20 # maybe this should be configurable? + sleep_amount = 0.01 # seconds + max_sleep_amount = 5.0 # seconds + while true + isdir(new_path) && return # This next step is like # `mv(temp_dir, new_path)`. # However, `mv` defaults to `cp` if `rename` returns an error. # `cp` is not atomic, so avoid the potential of calling it. err = ccall(:jl_fs_rename, Int32, (Cstring, Cstring), temp_dir, new_path) - # Ignore rename error, but ensure `new_path` exists. - if !isdir(new_path) - error("$(repr(new_path)) could not be made") + if err ≥ 0 + # rename worked + chmod(new_path, filemode(dirname(new_path))) + set_readonly(new_path) + return + else + # Ignore rename error if `new_path` exists. + isdir(new_path) && return + if retry < max_num_retries && err ∈ (Base.UV_EACCES, Base.UV_EPERM, Base.UV_EBUSY) + sleep(sleep_amount) + sleep_amount = min(sleep_amount*2.0, max_sleep_amount) + retry += 1 + else + Base.uv_error("rename of $(repr(temp_dir)) to $(repr(new_path))", err) + end end chmod(new_path, filemode(dirname(new_path))) set_readonly(new_path) end - nothing end """ @@ -485,7 +507,7 @@ function with_show_download_info(f, io, name, quiet_download) if !quiet_download fancyprint && print(io, "\033[1A") # move cursor up one line fancyprint && print(io, "\033[2K") # clear line - if success + if success fancyprint && printpkgstyle(io, :Downloaded, "artifact: $name") else printpkgstyle(io, :Failure, "artifact: $name", color = :red) From 69da35493ce078cf0770d655d120267a189c514c Mon Sep 17 00:00:00 2001 From: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:59:26 -0300 Subject: [PATCH 10/10] Fix julia#55850 by using safe_realpath instead of abspath in projname (#4025) (#4027) --- src/REPLMode/REPLMode.jl | 4 ++-- test/repl.jl | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/REPLMode/REPLMode.jl b/src/REPLMode/REPLMode.jl index 09c3ba47de..f6311324f7 100644 --- a/src/REPLMode/REPLMode.jl +++ b/src/REPLMode/REPLMode.jl @@ -10,7 +10,7 @@ import REPL: TerminalMenus import ..casesensitive_isdir, ..OFFLINE_MODE, ..linewrap, ..pathrepr using ..Types, ..Operations, ..API, ..Registry, ..Resolve -import ..stdout_f, ..stderr_f +import ..stdout_f, ..stderr_f, ..safe_realpath const TEST_MODE = Ref{Bool}(false) const PRINTED_REPL_WARNING = Ref{Bool}(false) @@ -497,7 +497,7 @@ function projname(project_file::String) end for depot in Base.DEPOT_PATH envdir = joinpath(depot, "environments") - if startswith(abspath(project_file), abspath(envdir)) + if startswith(safe_realpath(project_file), safe_realpath(envdir)) return "@" * name end end diff --git a/test/repl.jl b/test/repl.jl index ca86943614..06f647171b 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -726,4 +726,15 @@ end end end +@testset "JuliaLang/julia #55850" begin + tmp_55850 = mktempdir() + tmp_sym_link = joinpath(tmp_55850, "sym") + symlink(tmp_55850, tmp_sym_link; dir_target=true) + # DEPOT_PATH must stay only the temp directory otherwise the bug is hidden + withenv("JULIA_DEPOT_PATH" => tmp_sym_link, "JULIA_LOAD_PATH" => nothing) do + prompt = readchomp(`$(Base.julia_cmd()[1]) --project=$(dirname(@__DIR__)) --startup-file=no -e "using Pkg: Pkg, REPLMode; Pkg.activate(io=devnull); print(REPLMode.promptf())"`) + @test prompt == "(@v$(VERSION.major).$(VERSION.minor)) pkg> " + end +end + end # module