From ebda4678385b17904efd29695ea9d50bc42e4238 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 17 Jan 2022 10:03:34 -0500 Subject: [PATCH 1/4] add preference for version named manifest files Co-Authored-By: Dilum Aluthge --- base/loading.jl | 7 ++++++- stdlib/Artifacts/src/Artifacts.jl | 2 +- stdlib/Artifacts/test/runtests.jl | 2 +- test/loading.jl | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 25f75c9086589..fbd50d4d7f95b 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -566,7 +566,12 @@ end ## generic project & manifest API ## const project_names = ("JuliaProject.toml", "Project.toml") -const manifest_names = ("JuliaManifest.toml", "Manifest.toml") +const manifest_names = ( + "JuliaManifest-v$(VERSION.major).$(VERSION.minor).toml", + "Manifest-v$(VERSION.major).$(VERSION.minor).toml", + "JuliaManifest.toml", + "Manifest.toml", +) const preferences_names = ("JuliaLocalPreferences.toml", "LocalPreferences.toml") function locate_project_file(env::String) diff --git a/stdlib/Artifacts/src/Artifacts.jl b/stdlib/Artifacts/src/Artifacts.jl index 5daf994bfbf10..348d0d8990f58 100644 --- a/stdlib/Artifacts/src/Artifacts.jl +++ b/stdlib/Artifacts/src/Artifacts.jl @@ -18,7 +18,7 @@ function parse_toml(path::String) Base.parsed_toml(path) end -# keep in sync with Base.project_names and Base.manifest_names +# keep in sync with Base.project_names const artifact_names = ("JuliaArtifacts.toml", "Artifacts.toml") const ARTIFACTS_DIR_OVERRIDE = Ref{Union{String,Nothing}}(nothing) diff --git a/stdlib/Artifacts/test/runtests.jl b/stdlib/Artifacts/test/runtests.jl index 57b7e018e327a..db0d5d4c53ab1 100644 --- a/stdlib/Artifacts/test/runtests.jl +++ b/stdlib/Artifacts/test/runtests.jl @@ -258,6 +258,6 @@ end @testset "`Artifacts.artifact_names` and friends" begin n = length(Artifacts.artifact_names) @test length(Base.project_names) == n - @test length(Base.manifest_names) == n + @test length(Base.manifest_names) == 2n # there are two manifest names per project name @test length(Base.preferences_names) == n end diff --git a/test/loading.jl b/test/loading.jl index d39bdceb53341..c15eb184fe479 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -795,8 +795,10 @@ end @testset "`Base.project_names` and friends" begin # Some functions in Pkg assumes that these tuples have the same length n = length(Base.project_names) - @test length(Base.manifest_names) == n @test length(Base.preferences_names) == n + + # there are two manifest names per project name + @test length(Base.manifest_names) == 2n end @testset "Manifest formats" begin From 57ab245083e24ef8b98ebd8f401c55d1b062fd3a Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 13 Dec 2023 21:05:41 -0500 Subject: [PATCH 2/4] add news and docs --- NEWS.md | 5 +++++ doc/src/manual/code-loading.md | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index feb51b0fa40ad..28be243e568a4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,11 @@ New language features particularly useful for holding styling information, and is used extensively in the new `StyledStrings` standard library. There is also a new `AnnotatedChar` type, that is the equivalent new `AbstractChar` type. +* `Manifest.toml` files can now be renamed in the format `Manifest-v{major}.{minor}.toml` + to be preferentially picked up by the given julia version. i.e. in the same folder, + a `Manifest-v1.11.toml` would be used by v1.11 and `Manifest.toml` by every other julia + version. This makes managing environments for multiple julia versions at the same time + easier ([#43845]). Language changes ---------------- diff --git a/doc/src/manual/code-loading.md b/doc/src/manual/code-loading.md index 743ee83c333a4..25ebf3475f34c 100644 --- a/doc/src/manual/code-loading.md +++ b/doc/src/manual/code-loading.md @@ -14,7 +14,7 @@ Code inclusion is quite straightforward and simple: it evaluates the given sourc A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`—which results from loading the package code—available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. Thus, handling of `import X` happens in two stages: first, it determines **what** package is defined to be `X` in this context; second, it determines **where** that particular `X` package is found. -These questions are answered by searching through the project environments listed in [`LOAD_PATH`](@ref) for project files (`Project.toml` or `JuliaProject.toml`), manifest files (`Manifest.toml` or `JuliaManifest.toml`), or folders of source files. +These questions are answered by searching through the project environments listed in [`LOAD_PATH`](@ref) for project files (`Project.toml` or `JuliaProject.toml`), manifest files (`Manifest.toml` or `JuliaManifest.toml`, or the same names suffixed by `-v{major}.{minor}.toml` for specific versions), or folders of source files. ## Federation of packages @@ -63,7 +63,7 @@ Each kind of environment defines these three maps differently, as detailed in th ### Project environments -A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. However, from Julia v1.11 onwards, `(Julia)Manifest-v{major}.{minor}.toml` is recognized as a format to make a given julia version use a specific manifest file i.e. in the same folder, a `Manifest-v1.11.toml` would be used by v1.11 and `Manifest.toml` by any other julia version. The roots, graph and paths maps of a project environment are defined as follows: From 7effd1bf3dd515331288e3cc2a8bc9b4b1adf367 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 13 Dec 2023 21:29:09 -0500 Subject: [PATCH 3/4] add test --- test/loading.jl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/loading.jl b/test/loading.jl index c15eb184fe479..28f4f61211146 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -827,6 +827,28 @@ end end end +@testset "Manifest name preferential loading" begin + exename = `$(Base.julia_cmd()) --compiled-modules=yes --startup-file=no --color=no` + mktempdir() do tmp + proj = joinpath(tmp, "Project.toml") + touch(proj) + for man_name in ( + "Manifest.toml", + "JuliaManifest.toml", + "Manifest-v$(VERSION.major).$(VERSION.minor).toml", + "JuliaManifest-v$(VERSION.major).$(VERSION.minor).toml" + ) + touch(joinpath(tmp, man_name)) + man = readchomp(`$exename -E "Base.project_file_manifest_path($(repr(proj)))"`) + @test occursin(man_name, man) + end + # check that another version isn't preferred + touch(joinpath(tmp, "JuliaManifest-v1.5.toml")) + man = readchomp(`$exename -E "Base.project_file_manifest_path($(repr(proj)))"`) + @test occursin("JuliaManifest-v$(VERSION.major).$(VERSION.minor).toml", man) + end +end + @testset "error message loading pkg bad module name" begin mktempdir() do tmp old_loadpath = copy(LOAD_PATH) From 66ab1d8a98cf341cb96280ad2158b24fa87959f9 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 14 Dec 2023 10:27:54 -0500 Subject: [PATCH 4/4] simplify & expand tests --- test/loading.jl | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/loading.jl b/test/loading.jl index 28f4f61211146..c3bdce3890795 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -828,7 +828,6 @@ end end @testset "Manifest name preferential loading" begin - exename = `$(Base.julia_cmd()) --compiled-modules=yes --startup-file=no --color=no` mktempdir() do tmp proj = joinpath(tmp, "Project.toml") touch(proj) @@ -839,13 +838,19 @@ end "JuliaManifest-v$(VERSION.major).$(VERSION.minor).toml" ) touch(joinpath(tmp, man_name)) - man = readchomp(`$exename -E "Base.project_file_manifest_path($(repr(proj)))"`) - @test occursin(man_name, man) + man = basename(Base.project_file_manifest_path(proj)) + @test man == man_name end + end + mktempdir() do tmp # check that another version isn't preferred - touch(joinpath(tmp, "JuliaManifest-v1.5.toml")) - man = readchomp(`$exename -E "Base.project_file_manifest_path($(repr(proj)))"`) - @test occursin("JuliaManifest-v$(VERSION.major).$(VERSION.minor).toml", man) + proj = joinpath(tmp, "Project.toml") + touch(proj) + touch(joinpath(tmp, "Manifest-v1.5.toml")) + @test Base.project_file_manifest_path(proj) == nothing + touch(joinpath(tmp, "Manifest.toml")) + man = basename(Base.project_file_manifest_path(proj)) + @test man == "Manifest.toml" end end