From 7f0490820c12eb3ff81da05fc48ac6776f2bf923 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 14 Oct 2019 16:16:11 +0200 Subject: [PATCH 01/15] Only add undo snapshot in __init__ if we have a project to snapshot. (#1445) --- src/API.jl | 11 ++++++++++- test/pkg.jl | 23 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/API.jl b/src/API.jl index 0e4cd05bd0..be1d73538d 100644 --- a/src/API.jl +++ b/src/API.jl @@ -907,7 +907,16 @@ UndoState() = UndoState(0, UndoState[]) const undo_entries = Dict{String, UndoState}() const max_undo_limit = 50 -function add_snapshot_to_undo(env = EnvCache()) +function add_snapshot_to_undo(env=nothing) + # only attempt to take a snapshot if there is + # an active project to be found + if env === nothing + if Base.active_project() === nothing + return + else + env = EnvCache() + end + end state = get!(undo_entries, env.project_file) do UndoState() end diff --git a/test/pkg.jl b/test/pkg.jl index 0febb3d376..3ad5032d90 100644 --- a/test/pkg.jl +++ b/test/pkg.jl @@ -625,7 +625,7 @@ end # Example Pkg.add(TEST_PKG.name) @test haskey(Pkg.dependencies(), TEST_PKG.uuid) - # + # Pkg.undo() @test !haskey(Pkg.dependencies(), TEST_PKG.uuid) # Example @@ -653,7 +653,7 @@ end # Example, Unicode Pkg.redo() @test haskey(Pkg.dependencies(), unicode_uuid) - + # Example Pkg.undo() @@ -671,6 +671,25 @@ end Pkg.redo() @test haskey(Pkg.dependencies(), unicode_uuid) + # add_snapshot_to_undo from __init__ should + # not throw in case of no active project + mktempdir() do tmp + # Copy just whats necessary from Pkg to a custom package directory + dir = joinpath(tmp, "Pkg"); mkdir(dir) + cp(joinpath(@__DIR__, "..", "Project.toml"), joinpath(dir, "Project.toml")) + cp(joinpath(@__DIR__, "..", "src"), joinpath(dir, "src")) + cp(joinpath(@__DIR__, "..", "ext"), joinpath(dir, "ext")) # for TOML + withenv("JULIA_LOAD_PATH" => tmp, + "JULIA_PROJECT" => nothing) do + code = """ + @assert Base.active_project() === nothing + using Pkg # should not error + @assert isempty(Pkg.API.undo_entries) + """ + run(`$(Base.julia_cmd()) -e $(code)`) + end + end + end end end From f4bdf51d829f98b3cf26a5e4b1de9a21109d3dfa Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 16 Oct 2019 10:50:08 +0200 Subject: [PATCH 02/15] flus stdout before spawning new processes (#1431) --- src/Operations.jl | 2 ++ src/backwards_compatible_isolation.jl | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Operations.jl b/src/Operations.jl index 625002eef9..f08ce97642 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -827,6 +827,7 @@ function build_versions(ctx::Context, uuids::Vector{UUID}; might_need_to_resolve rpad(name * " ", max_name + 1, "─") * "→ " * Types.pathrepr(log_file)) sandbox(ctx, pkg, source_path, builddir(source_path)) do + flush(stdout) ok = open(log_file, "w") do log std = verbose ? ctx.io : log success(pipeline(gen_build_code(buildfile(source_path)), @@ -1363,6 +1364,7 @@ function test(ctx::Context, pkgs::Vector{PackageSpec}; println(ctx.io, "Running sandbox") test_fn !== nothing && test_fn() Display.status(Context(), mode=PKGMODE_PROJECT) + flush(stdout) try run(gen_test_code(testfile(source_path); coverage=coverage, julia_args=julia_args, test_args=test_args)) printpkgstyle(ctx, :Testing, pkg.name * " tests passed ") diff --git a/src/backwards_compatible_isolation.jl b/src/backwards_compatible_isolation.jl index ca462c23fd..dc8e91e065 100644 --- a/src/backwards_compatible_isolation.jl +++ b/src/backwards_compatible_isolation.jl @@ -560,7 +560,7 @@ function backwards_compatibility_for_test( if !Types.is_project_uuid(ctx, pkg.uuid) Display.status(localctx, mode=PKGMODE_MANIFEST) end - + flush(stdout) run_test() end end @@ -603,6 +603,7 @@ function backwards_compat_for_build(ctx::Context, pkg::PackageSpec, build_file:: end with_dependencies_loadable_at_toplevel(ctx, pkg; might_need_to_resolve=might_need_to_resolve) do localctx + flush(stdout) run_build() end end From c72c92670df59e90bbddecfc16c78fb0a48b3f4e Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 17 Oct 2019 12:14:53 +0200 Subject: [PATCH 03/15] Require name and uuid for package-projects. --- src/Types.jl | 10 ++++++---- test/new.jl | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Types.jl b/src/Types.jl index 290af57256..590ebdfbd0 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -280,8 +280,10 @@ function EnvCache(env::Union{Nothing,String}=nothing) git = ispath(joinpath(project_dir, ".git")) ? project_dir : nothing # read project file project = read_project(project_file) - # initiaze project package + # initialize project package if any(x -> x !== nothing, [project.name, project.uuid, project.version]) + project.name === nothing && pkgerror("project appears to be a package but has no name") + project.uuid === nothing && pkgerror("project appears to be a package but has no uuid") project_package = PackageSpec( name = project.name, uuid = project.uuid, @@ -490,12 +492,12 @@ function handle_repo_develop!(ctx::Context, pkg::PackageSpec, shared::Bool) uuid = get(ctx.env.project.deps, pkg.name, nothing) if uuid !== nothing entry = manifest_info(ctx, uuid) - if entry !== nothing + if entry !== nothing pkg.repo.source = entry.repo.source end end end - + # Still haven't found the source, try get it from the registry if pkg.repo.source === nothing set_repo_source_from_registry!(ctx, pkg) @@ -630,7 +632,7 @@ function handle_repo_add!(ctx::Context, pkg::PackageSpec) # check to see if the package exists at its canonical path. version_path = Pkg.Operations.source_path(pkg) isdir(version_path) && return false - + # Otherwise, move the temporary path into its correct place and set read only mkpath(version_path) mv(temp_path, version_path; force=true) diff --git a/test/new.jl b/test/new.jl index 57389ea025..491a0937a9 100644 --- a/test/new.jl +++ b/test/new.jl @@ -1740,6 +1740,20 @@ end @test isfile(joinpath(dir, "JuliaManifest.toml")) end end + # missing name/uuid for package project + isolate(loaded_depot=true) do; mktempdir() do tmp + project = joinpath(tmp, "Project.toml") + Base.ACTIVE_PROJECT[] = project + # missing name + write(project, "\"uuid\" = \"ed688b04-e580-4bf1-bc13-c3be32aba1f6\"") + @test_throws PkgError("project appears to be a package but has no name") Pkg.Types.EnvCache() + # missing uuid + write(project, "\"name\" = \"PackageName\"") + @test_throws PkgError("project appears to be a package but has no uuid") Pkg.Types.EnvCache() + # missing name and uuid + write(project, "\"version\" = \"1.0.0\"") + @test_throws PkgError("project appears to be a package but has no name") Pkg.Types.EnvCache() + end end end # From 66698f6a4e44f14a9cd4e0874ea2cd6e577aa3e2 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 17 Oct 2019 13:34:25 +0200 Subject: [PATCH 04/15] Make sure to start tests with a freshly cloned registry. --- .gitignore | 1 + test/project/good/pkg.toml | 1 + test/runtests.jl | 3 +++ 3 files changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 81a118f1dd..15252385a2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ docs/build /docs/src/repl.md .DS_Store /test/registries/* +/test/loaded_depot/* diff --git a/test/project/good/pkg.toml b/test/project/good/pkg.toml index ed4c5a33a1..81b14b5d7a 100644 --- a/test/project/good/pkg.toml +++ b/test/project/good/pkg.toml @@ -3,6 +3,7 @@ keywords = ["package", "management"] license = "MIT" desc = "The next-generation Julia package manager." version = "1.0.0" +uuid = "3ac81be6-66a4-43e7-a94c-2ce720faec7d" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/test/runtests.jl b/test/runtests.jl index 9f06b89d61..ffec3fa0f7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,9 @@ module PkgTests import Pkg +# Make sure to not start with an outdated registry +rm(joinpath(@__DIR__, "registries"); force = true, recursive = true) + include("utils.jl") include("new.jl") include("pkg.jl") From 0bca1f31f7a80e4a3226b76206f10f197ed82ba4 Mon Sep 17 00:00:00 2001 From: dehann Date: Mon, 21 Oct 2019 21:15:14 -0400 Subject: [PATCH 05/15] improvement on composite leading zero description in docs (#1456) Co-Authored-By: Stefan Karpinski --- docs/src/compatibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/compatibility.md b/docs/src/compatibility.md index a31ef52a3b..319dd35e0d 100644 --- a/docs/src/compatibility.md +++ b/docs/src/compatibility.md @@ -29,7 +29,7 @@ The union of multiple version specifiers can be formed by comma separating indiv [compat] Example = "1.2, 2" ``` -will result in `[1.2.0, 3.0.0)`. +will result in `[1.2.0, 3.0.0)`. Note leading zeros are treated differently, e.g. `Example = "0.2, 1"` would only result in `[0.2.0-0.3.0, 1.0.0-2.0.0]`. See the next section for more information on versions with leading zeros. ### Behavior of versions with leading zeros (0.0.x and 0.x.y) From ae851094d111e29ecddec45f1507be3a2bfaf43b Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 28 Oct 2019 12:30:49 +0100 Subject: [PATCH 06/15] Move save of initial snapshot to EnvCache constructor (#1448) instead of doing it from __init__. --- src/API.jl | 1 + src/Pkg.jl | 1 - src/Types.jl | 11 ++++++++++- test/pkg.jl | 19 ------------------- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/API.jl b/src/API.jl index be1d73538d..b033d4a730 100644 --- a/src/API.jl +++ b/src/API.jl @@ -906,6 +906,7 @@ end UndoState() = UndoState(0, UndoState[]) const undo_entries = Dict{String, UndoState}() const max_undo_limit = 50 +const saved_initial_snapshot = Ref(false) function add_snapshot_to_undo(env=nothing) # only attempt to take a snapshot if there is diff --git a/src/Pkg.jl b/src/Pkg.jl index f0d0f33ff1..a1b430ee24 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -507,7 +507,6 @@ function __init__() end end end - API.add_snapshot_to_undo() end ################## diff --git a/src/Types.jl b/src/Types.jl index 590ebdfbd0..0e633c30da 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -302,7 +302,8 @@ function EnvCache(env::Union{Nothing,String}=nothing) uuids = Dict{String,Vector{UUID}}() paths = Dict{UUID,Vector{String}}() names = Dict{UUID,Vector{String}}() - return EnvCache(env, + + env′ = EnvCache(env, git, project_file, manifest_file, @@ -314,6 +315,14 @@ function EnvCache(env::Union{Nothing,String}=nothing) uuids, paths, names,) + + # Save initial environment for undo/redo functionality + if !Pkg.API.saved_initial_snapshot[] + Pkg.API.add_snapshot_to_undo(env′) + Pkg.API.saved_initial_snapshot[] = true + end + + return env′ end include("project.jl") diff --git a/test/pkg.jl b/test/pkg.jl index 3ad5032d90..93789987a2 100644 --- a/test/pkg.jl +++ b/test/pkg.jl @@ -671,25 +671,6 @@ end Pkg.redo() @test haskey(Pkg.dependencies(), unicode_uuid) - # add_snapshot_to_undo from __init__ should - # not throw in case of no active project - mktempdir() do tmp - # Copy just whats necessary from Pkg to a custom package directory - dir = joinpath(tmp, "Pkg"); mkdir(dir) - cp(joinpath(@__DIR__, "..", "Project.toml"), joinpath(dir, "Project.toml")) - cp(joinpath(@__DIR__, "..", "src"), joinpath(dir, "src")) - cp(joinpath(@__DIR__, "..", "ext"), joinpath(dir, "ext")) # for TOML - withenv("JULIA_LOAD_PATH" => tmp, - "JULIA_PROJECT" => nothing) do - code = """ - @assert Base.active_project() === nothing - using Pkg # should not error - @assert isempty(Pkg.API.undo_entries) - """ - run(`$(Base.julia_cmd()) -e $(code)`) - end - end - end end end From 8b33993d9206e1d4a91376d2937605a3b25a6573 Mon Sep 17 00:00:00 2001 From: Peter <46059512+petershintech@users.noreply.github.com> Date: Mon, 28 Oct 2019 22:36:37 +1100 Subject: [PATCH 07/15] Update toml-files.md (#1473) --- docs/src/toml-files.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/src/toml-files.md b/docs/src/toml-files.md index 1001d8a8c8..e367b3297a 100644 --- a/docs/src/toml-files.md +++ b/docs/src/toml-files.md @@ -6,8 +6,8 @@ and `Manifest.toml` are written in [TOML](https://github.com/toml-lang/toml) (he UUIDs etc. !!! note - The `Project.toml` and `Manifest.toml` files are not only used by the package manager, - they are also used by Julia's code loading, and determines e.g. what `using Example` + The `Project.toml` and `Manifest.toml` files are not only used by the package manager; + they are also used by Julia's code loading, and determine e.g. what `using Example` should do. For more details see the section about [Code Loading](https://docs.julialang.org/en/v1/manual/code-loading/) in the Julia manual. @@ -74,7 +74,7 @@ Example = "7876af07-990d-54b4-ab0e-23690620f79a" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" ``` -Typically it is not needed to manually add entries to the `[deps]` section, this is instead +Typically it is not needed to manually add entries to the `[deps]` section; this is instead handled by Pkg operations such as `add`. @@ -105,10 +105,10 @@ julia = "1.1" ## `Manifest.toml` The manifest file is an absolute record of the state of the packages in the environment. -It includes exact information about (direct and indirect) dependencies of the project, and -given a `Project.toml` + `Manifest.toml` pair it is possible to instantiate the exact same -package environment, which is very useful for reproducibility, -see [`Pkg.instantiate`](@ref). +It includes exact information about (direct and indirect) dependencies of the project. +Given a `Project.toml` + `Manifest.toml` pair, it is possible to instantiate the exact same +package environment, which is very useful for reproducibility. +For the details, see [`Pkg.instantiate`](@ref). !!! note The `Manifest.toml` file is generated and maintained by Pkg and, in general, this file @@ -118,7 +118,7 @@ see [`Pkg.instantiate`](@ref). ### `Manifest.toml` entries Each dependency has its own section in the manifest file, and its content varies depending -on how the dependency was added to the environment, see the examples below. Every +on how the dependency was added to the environment. Every dependency section includes a combination of the following entries: * `uuid`: the [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) @@ -207,7 +207,7 @@ source tree is directly reflected. #### Pinned package -Pinned packages are also recorded in the manifest file, the resulting +Pinned packages are also recorded in the manifest file; the resulting dependency section for e.g. `pkg> add Example; pin Example` looks like: ```toml From 60770237802451c8e11a03b15cf3ed00457f86fa Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 31 Oct 2019 10:27:16 +0100 Subject: [PATCH 08/15] Add compat annotations for Artifacts API, fixes #1476. (#1479) --- docs/src/artifacts.md | 3 +++ src/Artifacts.jl | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/docs/src/artifacts.md b/docs/src/artifacts.md index b0f6dbe6b1..67aef4330f 100644 --- a/docs/src/artifacts.md +++ b/docs/src/artifacts.md @@ -1,5 +1,8 @@ # [**8.** Artifacts](@id Artifacts) +!!! compat "Julia 1.3" + Pkg's artifacts functionality requires at least Julia 1.3. + `Pkg` can install and manage containers of data that are not Julia packages. These containers can contain platform-specific binaries, datasets, text, or any other kind of data that would be convenient to place within an immutable, life-cycled datastore. These containers, (called "Artifacts") can be created locally, hosted anywhere, and automatically downloaded and unpacked upon installation of your Julia package. This mechanism is also used to provide the binary dependencies for packages built with [`BinaryBuilder.jl`](https://github.com/JuliaPackaging/BinaryBuilder.jl). diff --git a/src/Artifacts.jl b/src/Artifacts.jl index 4d6a15899f..50deb6ba2b 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -196,6 +196,9 @@ end Creates a new artifact by running `f(artifact_path)`, hashing the result, and moving it to the artifact store (`~/.julia/artifacts` on a typical installation). Returns the identifying tree hash of this artifact. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function create_artifact(f::Function) # Ensure the `artifacts` directory exists in our default depot @@ -257,6 +260,9 @@ end Given an artifact (identified by SHA1 git tree hash), return its installation path. If the artifact does not exist, returns the location it would be installed to. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function artifact_path(hash::SHA1; honor_overrides::Bool=true) # Get all possible paths (rooted in all depots) @@ -279,6 +285,9 @@ end Returns whether or not the given artifact (identified by its sha1 git tree hash) exists on-disk. Note that it is possible that the given artifact exists in multiple locations (e.g. within multiple depots). + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function artifact_exists(hash::SHA1; honor_overrides::Bool=true) return any(isdir.(artifact_paths(hash; honor_overrides=honor_overrides))) @@ -295,6 +304,9 @@ will never attempt to remove an overridden artifact. In general, we recommend that you use `Pkg.gc()` to manage artifact installations and do not use `remove_artifact()` directly, as it can be difficult to know if an artifact is being used by another package. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function remove_artifact(hash::SHA1) if query_override(hash) != nothing @@ -317,6 +329,9 @@ end Verifies that the given artifact (identified by its SHA1 git tree hash) is installed on- disk, and retains its integrity. If the given artifact is overridden, skips the verification unless `honor_overrides` is set to `true`. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function verify_artifact(hash::SHA1; honor_overrides::Bool=false) # Silently skip overridden artifacts unless we really ask for it @@ -341,6 +356,9 @@ end Archive an artifact into a tarball stored at `tarball_path`, returns the SHA256 of the resultant tarball as a hexidecimal string. Throws an error if the artifact does not exist. If the artifact is overridden, throws an error unless `honor_overrides` is set. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function archive_artifact(hash::SHA1, tarball_path::String; honor_overrides::Bool=false) if !honor_overrides @@ -485,6 +503,9 @@ end Get metadata about a given artifact (identified by name) stored within the given `(Julia)Artifacts.toml` file. If the artifact is platform-specific, use `platform` to choose the most appropriate mapping. If none is found, return `nothing`. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function artifact_meta(name::String, artifacts_toml::String; platform::Platform = platform_key_abi(), @@ -530,6 +551,9 @@ end Thin wrapper around `artifact_meta()` to return the hash of the specified, platform- collapsed artifact. Returns `nothing` if no mapping can be found. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function artifact_hash(name::String, artifacts_toml::String; platform::Platform = platform_key_abi(), @@ -560,6 +584,9 @@ URLs will be listed as possible locations where this artifact can be obtained. is set to `true`, even if download information is available, this artifact will not be downloaded until it is accessed via the `artifact"name"` syntax, or `ensure_artifact_installed()` is called upon it. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function bind_artifact!(artifacts_toml::String, name::String, hash::SHA1; platform::Union{Platform,Nothing} = nothing, @@ -638,6 +665,9 @@ end Unbind the given `name` from an `(Julia)Artifacts.toml` file. Silently fails if no such binding exists within the file. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function unbind_artifact!(artifacts_toml::String, name::String; platform::Union{Platform,Nothing} = nothing) @@ -666,6 +696,9 @@ end verbose::Bool = false) Download/install an artifact into the artifact store. Returns `true` on success. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function download_artifact(tree_hash::SHA1, tarball_url::String, tarball_hash::String; verbose::Bool = false) @@ -735,6 +768,9 @@ end Given the path to a `.jl` file, (such as the one returned by `__source__.file` in a macro context), find the `(Julia)Artifacts.toml` that is contained within the containing project (if it exists), otherwise return `nothing`. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function find_artifacts_toml(path::String) if !isdir(path) @@ -774,6 +810,9 @@ end Ensures an artifact is installed, downloading it via the download information stored in `artifacts_toml` if necessary. Throws an error if unable to install. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function ensure_artifact_installed(name::String, artifacts_toml::String; platform::Platform = platform_key_abi(), @@ -825,6 +864,9 @@ Installs all non-lazy artifacts from a given `(Julia)Artifacts.toml` file. `pack be provided to properly support overrides from `Overrides.toml` entries in depots. If `include_lazy` is set to `true`, then lazy packages will be installed as well. + +!!! compat "Julia 1.3" + This function requires at least Julia 1.3. """ function ensure_all_artifacts_installed(artifacts_toml::String; platform::Platform = platform_key_abi(), @@ -901,6 +943,9 @@ end Macro that is used to automatically ensure an artifact is installed, and return its location on-disk. Automatically looks the artifact up by name in the project's `(Julia)Artifacts.toml` file. Throws an error on inability to install the requested artifact. + +!!! compat "Julia 1.3" + This macro requires at least Julia 1.3. """ macro artifact_str(name) return quote From 82b9f16501fdba66cff7f231aba1415d9df09f9c Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Mon, 4 Nov 2019 20:07:11 +0100 Subject: [PATCH 09/15] doc: fix a typo in a version (#1483) --- docs/src/compatibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/compatibility.md b/docs/src/compatibility.md index 319dd35e0d..271d503f1f 100644 --- a/docs/src/compatibility.md +++ b/docs/src/compatibility.md @@ -46,7 +46,7 @@ minor versions are not considered compatible, so the version 0.3.0 might have br Example = "0.0.1" ``` -results in a versionbound on `Example` as `[0.0.1, 0.02)` (which is equivalent to only the version 0.0.1), while the +results in a versionbound on `Example` as `[0.0.1, 0.0.2)` (which is equivalent to only the version 0.0.1), while the `[compat]` entry: ```julia From b161404b582f75b17131b19ed109143ebf12a108 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 4 Nov 2019 19:02:24 -0500 Subject: [PATCH 10/15] use `===` for comparison to `nothing` and Symbols (#1486) --- ext/TOML/src/TOML.jl | 2 +- src/API.jl | 8 ++--- src/Artifacts.jl | 28 +++++++-------- src/BinaryPlatforms.jl | 50 +++++++++++++-------------- src/Display.jl | 20 +++++------ src/GitTools.jl | 8 ++--- src/Operations.jl | 10 +++--- src/Pkg.jl | 2 +- src/PlatformEngines.jl | 4 +-- src/REPLMode/REPLMode.jl | 4 +-- src/Resolve/graphtype.jl | 12 +++---- src/Types.jl | 6 ++-- src/backwards_compatible_isolation.jl | 12 +++---- src/generate.jl | 12 +++---- src/versions.jl | 8 ++--- 15 files changed, 93 insertions(+), 93 deletions(-) diff --git a/ext/TOML/src/TOML.jl b/ext/TOML/src/TOML.jl index 8d6ee145fc..3eced13ca1 100644 --- a/ext/TOML/src/TOML.jl +++ b/ext/TOML/src/TOML.jl @@ -12,7 +12,7 @@ module TOML "Convert `TOML.Table` to `Dict{String,Any}`" function table2dict(tbl::Union{Nothing,Table}) - tbl == nothing && return Dict{String,Any}() + tbl === nothing && return Dict{String,Any}() return table2dict(get(tbl)) end diff --git a/src/API.jl b/src/API.jl index b033d4a730..3dba7e15c9 100644 --- a/src/API.jl +++ b/src/API.jl @@ -394,7 +394,7 @@ function gc(ctx::Context=Context(); collect_delay::Period=Day(30), kwargs...) # Collect the locations of every package referred to in this manifest pkg_dir(uuid, entry) = Operations.find_installed(entry.name, uuid, entry.tree_hash) - return [pkg_dir(u, e) for (u, e) in manifest if e.tree_hash != nothing] + return [pkg_dir(u, e) for (u, e) in manifest if e.tree_hash !== nothing] end function process_artifacts_toml(path) @@ -434,7 +434,7 @@ function gc(ctx::Context=Context(); collect_delay::Period=Day(30), kwargs...) for index_file in index_files # Check to see if it's still alive paths = process_func(index_file) - if paths != nothing + if paths !== nothing # Print the path of this beautiful, extant file to the user println(" $(Types.pathrepr(index_file))") append!(marked_paths, paths) @@ -682,7 +682,7 @@ function precompile(ctx::Context) for pkg in pkgids paths = Base.find_all_in_cache_path(pkg) sourcepath = Base.locate_package(pkg) - sourcepath == nothing && continue + sourcepath === nothing && continue # Heuristic for when precompilation is disabled occursin(r"\b__precompile__\(\s*false\s*\)", read(sourcepath, String)) && continue stale = true @@ -939,7 +939,7 @@ function redo_undo(ctx, mode::Symbol, direction::Int) @assert direction == 1 || direction == -1 state = get(undo_entries, ctx.env.project_file, nothing) state === nothing && pkgerror("no undo state for current project") - state.idx == (mode == :redo ? 1 : length(state.entries)) && pkgerror("$mode: no more states left") + state.idx == (mode === :redo ? 1 : length(state.entries)) && pkgerror("$mode: no more states left") state.idx += direction snapshot = state.entries[state.idx] diff --git a/src/Artifacts.jl b/src/Artifacts.jl index 50deb6ba2b..e317a5659a 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -73,7 +73,7 @@ overriding to another artifact by its content-hash. """ const ARTIFACT_OVERRIDES = Ref{Union{Dict,Nothing}}(nothing) function load_overrides(;force::Bool = false) - if ARTIFACT_OVERRIDES[] != nothing && !force + if ARTIFACT_OVERRIDES[] !== nothing && !force return ARTIFACT_OVERRIDES[] end @@ -247,7 +247,7 @@ function artifact_paths(hash::SHA1; honor_overrides::Bool=true) # First, check to see if we've got an override: if honor_overrides override = query_override(hash) - if override != nothing + if override !== nothing return [override] end end @@ -309,7 +309,7 @@ being used by another package. This function requires at least Julia 1.3. """ function remove_artifact(hash::SHA1) - if query_override(hash) != nothing + if query_override(hash) !== nothing # We never remove overridden artifacts. return end @@ -336,7 +336,7 @@ verification unless `honor_overrides` is set to `true`. function verify_artifact(hash::SHA1; honor_overrides::Bool=false) # Silently skip overridden artifacts unless we really ask for it if !honor_overrides - if query_override(hash) != nothing + if query_override(hash) !== nothing return true end end @@ -362,7 +362,7 @@ exist. If the artifact is overridden, throws an error unless `honor_overrides` """ function archive_artifact(hash::SHA1, tarball_path::String; honor_overrides::Bool=false) if !honor_overrides - if query_override(hash) != nothing + if query_override(hash) !== nothing error("Will not archive an overridden artifact unless `honor_overrides` is set!") end end @@ -442,16 +442,16 @@ function pack_platform!(meta::Dict, p::Platform) ) meta["os"] = os_map[typeof(p)] meta["arch"] = string(arch(p)) - if libc(p) != nothing + if libc(p) !== nothing meta["libc"] = string(libc(p)) end - if libgfortran_version(p) != nothing + if libgfortran_version(p) !== nothing meta["libgfortran_version"] = string(libgfortran_version(p)) end - if libstdcxx_version(p) != nothing + if libstdcxx_version(p) !== nothing meta["libstdcxx_version"] = string(libstdcxx_version(p)) end - if cxxstring_abi(p) != nothing + if cxxstring_abi(p) !== nothing meta["cxxstring_abi"] = string(cxxstring_abi(p)) end end @@ -470,7 +470,7 @@ function load_artifacts_toml(artifacts_toml::String; # Insert just-in-time hash overrides by looking up the names of anything we need to # override for this UUID, and inserting new overrides for those hashes. overrides = load_overrides() - if pkg_uuid != nothing && haskey(overrides[:UUID], pkg_uuid) + if pkg_uuid !== nothing && haskey(overrides[:UUID], pkg_uuid) pkg_overrides = overrides[:UUID][pkg_uuid] for name in keys(artifact_dict) @@ -537,7 +537,7 @@ function artifact_meta(name::String, artifact_dict::Dict, artifacts_toml::String end # This is such a no-no, we are going to call it out right here, right now. - if meta != nothing && !haskey(meta, "git-tree-sha1") + if meta !== nothing && !haskey(meta, "git-tree-sha1") @error("Invalid artifacts file at $(artifacts_toml): artifact '$name' contains no `git-tree-sha1`!") return nothing end @@ -622,7 +622,7 @@ function bind_artifact!(artifacts_toml::String, name::String, hash::SHA1; # Integrate download info, if it is given. We represent the download info as a # vector of dicts, each with its own `url` and `sha256`, since different tarballs can # expand to the same tree hash. - if download_info != nothing + if download_info !== nothing meta["download"] = [ Dict("url" => dl[1], "sha256" => dl[2], @@ -630,7 +630,7 @@ function bind_artifact!(artifacts_toml::String, name::String, hash::SHA1; ] end - if platform == nothing + if platform === nothing artifact_dict[name] = meta else # Add platform-specific keys to our `meta` dict @@ -676,7 +676,7 @@ function unbind_artifact!(artifacts_toml::String, name::String; return end - if platform == nothing + if platform === nothing delete!(artifact_dict, name) else artifact_dict[name] = filter( diff --git a/src/BinaryPlatforms.jl b/src/BinaryPlatforms.jl index 46218293f8..6f3092005e 100644 --- a/src/BinaryPlatforms.jl +++ b/src/BinaryPlatforms.jl @@ -37,17 +37,17 @@ struct CompilerABI function CompilerABI(;libgfortran_version::Union{Nothing, VersionNumber} = nothing, libstdcxx_version::Union{Nothing, VersionNumber} = nothing, cxxstring_abi::Union{Nothing, Symbol} = nothing) - if libgfortran_version != nothing && (libgfortran_version < v"3" || + if libgfortran_version !== nothing && (libgfortran_version < v"3" || libgfortran_version >= v"6") throw(ArgumentError("Unsupported libgfortran '$libgfortran_version'")) end - if libstdcxx_version != nothing && (libstdcxx_version < v"3.4.0" || + if libstdcxx_version !== nothing && (libstdcxx_version < v"3.4.0" || libstdcxx_version >= v"3.5") throw(ArgumentError("Unsupported libstdc++ '$libstdcxx_version'")) end - if cxxstring_abi != nothing && !in(cxxstring_abi, [:cxx03, :cxx11]) + if cxxstring_abi !== nothing && !in(cxxstring_abi, [:cxx03, :cxx11]) throw(ArgumentError("Unsupported string ABI '$cxxstring_abi'")) end @@ -71,13 +71,13 @@ cxxstring_abi(cabi::CompilerABI) = cabi.cxxstring_abi function show(io::IO, cabi::CompilerABI) args = String[] - if cabi.libgfortran_version != nothing + if cabi.libgfortran_version !== nothing push!(args, "libgfortran_version=$(repr(cabi.libgfortran_version))") end - if cabi.libstdcxx_version != nothing + if cabi.libstdcxx_version !== nothing push!(args, "libstdcxx_version=$(repr(cabi.libstdcxx_version))") end - if cabi.cxxstring_abi != nothing + if cabi.cxxstring_abi !== nothing push!(args, "cxxstring_abi=$(repr(cabi.cxxstring_abi))") end write(io, "CompilerABI($(join(args, ", ")))") @@ -103,7 +103,7 @@ function gcc_version(cabi::CompilerABI, GCC_versions::Vector{VersionNumber}) # libgfortran3 -> GCC 4.X, 5.X, 6.X # libgfortran4 -> GCC 7.x # libgfortran5 -> GCC 8.X, 9.X - if cabi.libgfortran_version != nothing + if cabi.libgfortran_version !== nothing if cabi.libgfortran_version.major == 3 GCC_versions = filt_gcc_majver(4,5,6) elseif cabi.libgfortran_version.major == 4 @@ -117,7 +117,7 @@ function gcc_version(cabi::CompilerABI, GCC_versions::Vector{VersionNumber}) # mapping is conservative; it is often the case that we return a # version that is slightly lower than what is actually installed on # a system. - if cabi.libstdcxx_version != nothing + if cabi.libstdcxx_version !== nothing cxxvp = cabi.libstdcxx_version.patch # Is this platform so old that nothing is supported? if cxxvp < 19 @@ -148,7 +148,7 @@ function gcc_version(cabi::CompilerABI, GCC_versions::Vector{VersionNumber}) # :cxx03 binaries on GCC 5+, (although increasingly rare) so the only # filtering we do is that if the platform is explicitly :cxx11, we # disallow running on < GCC 5. - if cabi.cxxstring_abi != nothing && cabi.cxxstring_abi == :cxx11 + if cabi.cxxstring_abi !== nothing && cabi.cxxstring_abi === :cxx11 GCC_versions = filter(v -> v >= v"5", GCC_versions) end @@ -179,7 +179,7 @@ struct Linux <: Platform end # Auto-map the `call_abi` to be `eabihf` on armv7l - if call_abi === nothing && arch == :armv7l + if call_abi === nothing && arch === :armv7l call_abi = :eabihf end @@ -188,11 +188,11 @@ struct Linux <: Platform end # If we're constructing for armv7l, we MUST have the eabihf abi - if arch == :armv7l && call_abi != :eabihf + if arch === :armv7l && call_abi !== :eabihf throw(ArgumentError("armv7l Linux must use eabihf, not '$call_abi'")) end # ...and vice-versa - if arch != :armv7l && call_abi == :eabihf + if arch !== :armv7l && call_abi === :eabihf throw(ArgumentError("eabihf Linux is only on armv7l, not '$arch'!")) end @@ -280,7 +280,7 @@ struct FreeBSD <: Platform end # Auto-map the `call_abi` to be `eabihf` on armv7l - if call_abi === nothing && arch == :armv7l + if call_abi === nothing && arch === :armv7l call_abi = :eabihf end @@ -289,11 +289,11 @@ struct FreeBSD <: Platform end # If we're constructing for armv7l, we MUST have the eabihf abi - if arch == :armv7l && call_abi != :eabihf + if arch === :armv7l && call_abi !== :eabihf throw(ArgumentError("armv7l FreeBSD must use eabihf, not '$call_abi'")) end # ...and vice-versa - if arch != :armv7l && call_abi == :eabihf + if arch !== :armv7l && call_abi === :eabihf throw(ArgumentError("eabihf FreeBSD is only on armv7l, not '$arch'!")) end @@ -431,11 +431,11 @@ vendor_str(p::FreeBSD) = "-unknown-freebsd11.1" triplet(p::UnknownPlatform) = "unknown-unknown-unknown" # Helper functions for Linux and FreeBSD libc/abi mishmashes -arch_str(p::Platform) = (arch(p) == :armv7l) ? "arm" : string(arch(p)) +arch_str(p::Platform) = (arch(p) === :armv7l) ? "arm" : string(arch(p)) function libc_str(p::Platform) if libc(p) === nothing return "" - elseif libc(p) == :glibc + elseif libc(p) === :glibc return "-gnu" else return "-$(libc(p))" @@ -444,15 +444,15 @@ end call_abi_str(p::Platform) = (call_abi(p) === nothing) ? "" : string(call_abi(p)) function compiler_abi_str(cabi::CompilerABI) str = "" - if cabi.libgfortran_version != nothing + if cabi.libgfortran_version !== nothing str *= "-libgfortran$(cabi.libgfortran_version.major)" end - if cabi.libstdcxx_version != nothing + if cabi.libstdcxx_version !== nothing str *= "-libstdcxx$(libstdcxx_version(cabi).patch)" end - if cabi.cxxstring_abi != nothing + if cabi.cxxstring_abi !== nothing str *= "-$(cabi.cxxstring_abi)" end return str @@ -529,12 +529,12 @@ function platform_key_abi(machine::AbstractString) )) m = match(triplet_regex, machine) - if m != nothing + if m !== nothing # Helper function to find the single named field within the giant regex # that is not `nothing` for each mapping we give it. get_field(m, mapping) = begin for k in keys(mapping) - if m[k] != nothing + if m[k] !== nothing strk = string(k) # Convert our sentinel `nothing` values to actual `nothing` if endswith(strk, "_nothing") @@ -589,10 +589,10 @@ end function show(io::IO, p::Platform) write(io, "$(platform_name(p))($(repr(arch(p)))") - if libc(p) != nothing + if libc(p) !== nothing write(io, ", libc=$(repr(libc(p)))") end - if call_abi(p) != nothing + if call_abi(p) !== nothing write(io, ", call_abi=$(repr(call_abi(p)))") end if compiler_abi(p) != CompilerABI() @@ -724,7 +724,7 @@ function detect_libstdcxx_version() # Brute-force our way through GLIBCXX_* symbols to discover which version we're linked against hdl = Libdl.dlopen(first(libstdcxx_paths)) for minor_version in 26:-1:18 - if Libdl.dlsym(hdl, "GLIBCXX_3.4.$(minor_version)"; throw_error=false) != nothing + if Libdl.dlsym(hdl, "GLIBCXX_3.4.$(minor_version)"; throw_error=false) !== nothing Libdl.dlclose(hdl) return VersionNumber("3.4.$(minor_version)") end diff --git a/src/Display.jl b/src/Display.jl index 6e0f1a4d05..bd6a970607 100644 --- a/src/Display.jl +++ b/src/Display.jl @@ -153,10 +153,10 @@ end revstring(str::String) = occursin(r"\b([a-f0-9]{40})\b", str) ? str[1:7] : str vstring(ctx::Context, a::VerInfo) = - string((a.ver == nothing && a.hash != nothing) ? "[$(string(a.hash)[1:16])]" : "", - a.ver != nothing ? "v$(a.ver)" : "", - a.path != nothing ? " [$(pathrepr(a.path))]" : "", - a.repo != nothing ? " #$(revstring(a.repo.rev)) ($(a.repo.source))" : "", + string((a.ver === nothing && a.hash !== nothing) ? "[$(string(a.hash)[1:16])]" : "", + a.ver !== nothing ? "v$(a.ver)" : "", + a.path !== nothing ? " [$(pathrepr(a.path))]" : "", + a.repo !== nothing ? " #$(revstring(a.repo.rev)) ($(a.repo.source))" : "", a.pinned == true ? " ⚲" : "", ) @@ -165,9 +165,9 @@ Base.:(==)(a::VerInfo, b::VerInfo) = a.path == b.path ≈(a::VerInfo, b::VerInfo) = a.hash == b.hash && - (a.ver == nothing || b.ver == nothing || a.ver == b.ver) && + (a.ver === nothing || b.ver === nothing || a.ver == b.ver) && (a.pinned == b.pinned) && - (a.repo == nothing || b.repo == nothing || a.repo == b.repo) && + (a.repo === nothing || b.repo === nothing || a.repo == b.repo) && (a.path == b.path) struct DiffEntry @@ -193,12 +193,12 @@ function print_diff(io::IO, ctx::Context, diff::Vector{DiffEntry}, status=false) else if (x.old.hash === nothing || x.new.hash === nothing || x.old.hash != x.new.hash) && x.old.ver != x.new.ver - verb = x.old.ver == nothing || x.new.ver == nothing || + verb = x.old.ver === nothing || x.new.ver === nothing || x.old.ver == x.new.ver ? '~' : x.old.ver < x.new.ver ? '↑' : '↓' elseif x.old.ver == x.new.ver && x.old.pinned != x.new.pinned || x.old.path != x.new.path || - x.old.repo != nothing || x.new.repo != nothing + x.old.repo !== nothing || x.new.repo !== nothing verb = '~' else verb = '?' @@ -208,10 +208,10 @@ function print_diff(io::IO, ctx::Context, diff::Vector{DiffEntry}, status=false) vstring(ctx, x.new) : vstring(ctx, x.old) * " ⇒ " * vstring(ctx, x.new) end - elseif x.new != nothing + elseif x.new !== nothing verb = '+' vstr = vstring(ctx, x.new) - elseif x.old != nothing + elseif x.old !== nothing verb = '-' vstr = vstring(ctx, x.old) else diff --git a/src/GitTools.jl b/src/GitTools.jl index 4cfa13dba1..6da5b87b6c 100644 --- a/src/GitTools.jl +++ b/src/GitTools.jl @@ -124,7 +124,7 @@ end function clone(ctx, url, source_path; header=nothing, credentials=nothing, kwargs...) @assert !isdir(source_path) || isempty(readdir(source_path)) url = normalize_url(url) - Pkg.Types.printpkgstyle(ctx, :Cloning, header == nothing ? "git-repo `$url`" : header) + Pkg.Types.printpkgstyle(ctx, :Cloning, header === nothing ? "git-repo `$url`" : header) transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color()) callbacks = LibGit2.Callbacks( :transfer_progress => ( @@ -133,7 +133,7 @@ function clone(ctx, url, source_path; header=nothing, credentials=nothing, kwarg ) ) print(stdout, "\e[?25l") # disable cursor - if credentials == nothing + if credentials === nothing credentials = LibGit2.CachedCredentials() end mkpath(source_path) @@ -162,7 +162,7 @@ function fetch(ctx, repo::LibGit2.GitRepo, remoteurl=nothing; header=nothing, cr end end remoteurl = normalize_url(remoteurl) - Pkg.Types.printpkgstyle(ctx, :Updating, header == nothing ? "git-repo `$remoteurl`" : header) + Pkg.Types.printpkgstyle(ctx, :Updating, header === nothing ? "git-repo `$remoteurl`" : header) transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color()) callbacks = LibGit2.Callbacks( :transfer_progress => ( @@ -171,7 +171,7 @@ function fetch(ctx, repo::LibGit2.GitRepo, remoteurl=nothing; header=nothing, cr ) ) print(stdout, "\e[?25l") # disable cursor - if credentials == nothing + if credentials === nothing credentials = LibGit2.CachedCredentials() end try diff --git a/src/Operations.jl b/src/Operations.jl index f08ce97642..9027b19363 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -363,7 +363,7 @@ function deps_graph(ctx::Context, uuid_to_name::Dict{UUID,String}, reqs::Resolve if uuid in keys(ctx.stdlibs) path = Types.stdlib_path(ctx.stdlibs[uuid]) proj_file = projectfile_path(path; strict=true) - @assert proj_file != nothing + @assert proj_file !== nothing proj = Types.read_package(proj_file) v = something(proj.version, VERSION) @@ -445,7 +445,7 @@ end # Package installation # ######################## function get_archive_url_for_version(url::String, ref) - if (m = match(r"https://github.com/(.*?)/(.*?).git", url)) != nothing + if (m = match(r"https://github.com/(.*?)/(.*?).git", url)) !== nothing return "https://api.github.com/repos/$(m.captures[1])/$(m.captures[2])/tarball/$(ref)" end return nothing @@ -557,7 +557,7 @@ end function download_artifacts(pkgs::Vector{PackageSpec}; platform::Platform=platform_key_abi(), verbose::Bool=false) # Filter out packages that have no source_path() - pkg_roots = String[p for p in source_path.(pkgs) if p != nothing] + pkg_roots = String[p for p in source_path.(pkgs) if p !== nothing] return download_artifacts(pkg_roots; platform=platform, verbose=verbose) end @@ -654,7 +654,7 @@ function download_source(ctx::Context, pkgs::Vector{PackageSpec}, sprint(Base.showerror, exc_or_success, bt_or_path)) success, path = exc_or_success, bt_or_path if success - vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]" + vstr = pkg.version !== nothing ? "v$(pkg.version)" : "[$h]" printpkgstyle(ctx, :Installed, string(rpad(pkg.name * " ", max_name + 2, "─"), " ", vstr)) else push!(missed_packages, (pkg, path)) @@ -668,7 +668,7 @@ function download_source(ctx::Context, pkgs::Vector{PackageSpec}, uuid = pkg.uuid install_git(ctx, pkg.uuid, pkg.name, pkg.tree_hash, urls[uuid], pkg.version::VersionNumber, path) readonly && set_readonly(path) - vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]" + vstr = pkg.version !== nothing ? "v$(pkg.version)" : "[$h]" printpkgstyle(ctx, :Installed, string(rpad(pkg.name * " ", max_name + 2, "─"), " ", vstr)) end diff --git a/src/Pkg.jl b/src/Pkg.jl index a1b430ee24..95c78daf38 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -440,7 +440,7 @@ const PackageSpec = API.Package ) Set the protocol used to access hosted packages when `add`ing a url or `develop`ing a package. -Defaults to delegating the choice to the package developer (`protocol == nothing`). +Defaults to delegating the choice to the package developer (`protocol === nothing`). Other choices for `protocol` are `"https"` or `"git"`. # Examples diff --git a/src/PlatformEngines.jl b/src/PlatformEngines.jl index 2e510e9adb..0781cfd285 100644 --- a/src/PlatformEngines.jl +++ b/src/PlatformEngines.jl @@ -198,7 +198,7 @@ function probe_platform_engines!(;verbose::Bool = false) unpack_7z = (exe7z) -> begin return (tarball_path, out_path, excludelist = nothing) -> pipeline(pipeline(`$exe7z x $(tarball_path) -y -so`, - `$exe7z x -si -y -ttar -o$(out_path) $(excludelist == nothing ? [] : "-x@$(excludelist)")`); + `$exe7z x -si -y -ttar -o$(out_path) $(excludelist === nothing ? [] : "-x@$(excludelist)")`); stdout=devnull, stderr=devnull) end package_7z = (exe7z) -> begin @@ -320,7 +320,7 @@ function probe_platform_engines!(;verbose::Bool = false) elseif endswith(tarball_path, ".bz2") Jjz = "j" end - return `$tar_cmd -x$(Jjz)f $(tarball_path) -C$(out_path) $(excludelist == nothing ? [] : "-X$(excludelist)")` + return `$tar_cmd -x$(Jjz)f $(tarball_path) -C$(out_path) $(excludelist === nothing ? [] : "-X$(excludelist)")` end package_tar = (in_path, tarball_path) -> begin Jjz = "z" diff --git a/src/REPLMode/REPLMode.jl b/src/REPLMode/REPLMode.jl index 8bd4efb0a9..3d678e1294 100644 --- a/src/REPLMode/REPLMode.jl +++ b/src/REPLMode/REPLMode.jl @@ -141,7 +141,7 @@ struct Option Option(val::AbstractString) = new(val, nothing) Option(val::AbstractString, arg::Union{Nothing,String}) = new(val, arg) end -Base.show(io::IO, opt::Option) = print(io, "--$(opt.val)", opt.argument == nothing ? "" : "=$(opt.argument)") +Base.show(io::IO, opt::Option) = print(io, "--$(opt.val)", opt.argument === nothing ? "" : "=$(opt.argument)") wrap_option(option::String) = length(option) == 1 ? "-$option" : "--$option" is_opt(word::AbstractString) = first(word) == '-' && word != "-" @@ -542,7 +542,7 @@ function create_mode(repl, main) end repl_keymap = Dict() - if shell_mode != nothing + if shell_mode !== nothing repl_keymap[';'] = function (s,o...) if isempty(s) || position(LineEdit.buffer(s)) == 0 buf = copy(LineEdit.buffer(s)) diff --git a/src/Resolve/graphtype.jl b/src/Resolve/graphtype.jl index cbdb3c0ba9..2ff1f07d84 100644 --- a/src/Resolve/graphtype.jl +++ b/src/Resolve/graphtype.jl @@ -616,7 +616,7 @@ function log_event_req!(graph::Graph, rp::UUID, rvs::VersionSpec, reason) id = pkgID(rp, rlog) msg = "restricted to versions $rvs by " if reason isa Symbol - @assert reason == :explicit_requirement + @assert reason === :explicit_requirement other_entry = nothing msg *= "an explicit requirement" else @@ -749,10 +749,10 @@ function log_event_maxsumsolved!(graph::Graph, p0::Int, s0::Int, why::Symbol) p = pkgs[p0] id = pkgID(p, rlog) if s0 == spp[p0] - @assert why == :uninst + @assert why === :uninst msg = "determined to be unneeded by the solver" else - @assert why == :constr + @assert why === :constr if s0 == spp[p0] - 1 msg = "set by the solver to its maximum version: $(pvers[p0][s0])" else @@ -844,9 +844,9 @@ Show the full resolution log. The `view` keyword controls how the events are dis function showlog(io::IO, rlog::ResolveLog; view::Symbol = :plain) view ∈ [:plain, :tree, :chronological] || throw(ArgumentError("the view argument should be `:plain`, `:tree` or `:chronological`")) println(io, "Resolve log:") - view == :chronological && return showlogjournal(io, rlog) + view === :chronological && return showlogjournal(io, rlog) seen = IdDict() - recursive = (view == :tree) + recursive = (view === :tree) _show(io, rlog, rlog.globals, _logindent, seen, false) initentries = [event[1] for event in rlog.init.events] for entry in sort!(initentries, by=(entry->pkgID(entry.pkg, rlog))) @@ -872,7 +872,7 @@ the same as for `showlog(io, rlog)`); the default is `:tree`. function showlog(io::IO, rlog::ResolveLog, p::UUID; view::Symbol = :tree) view ∈ [:plain, :tree] || throw(ArgumentError("the view argument should be `:plain` or `:tree`")) entry = rlog.pool[p] - if view == :tree + if view === :tree _show(io, rlog, entry, _logindent, IdDict(entry=>true), true) else entries = ResolveLogEntry[entry] diff --git a/src/Types.jl b/src/Types.jl index 0e633c30da..f8191a24d1 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -181,7 +181,7 @@ function find_project_file(env::Union{Nothing,String}=nothing) project_file = nothing if env isa Nothing project_file = Base.active_project() - project_file == nothing && pkgerror("no active project") + project_file === nothing && pkgerror("no active project") elseif startswith(env, '@') project_file = Base.load_path_expand(env) project_file === nothing && pkgerror("package environment does not exist: $env") @@ -599,7 +599,7 @@ function handle_repo_add!(ctx::Context, pkg::PackageSpec) LibGit2.with(GitTools.ensure_clone(ctx, add_repo_cache_path(repo_source), repo_source; isbare=true)) do repo # If the user didn't specify rev, assume they want the default (master) branch if on a branch, otherwise the current commit - if pkg.repo.rev == nothing + if pkg.repo.rev === nothing pkg.repo.rev = LibGit2.isattached(repo) ? LibGit2.branch(repo) : string(LibGit2.GitHash(LibGit2.head(repo))) end @@ -1202,7 +1202,7 @@ function registered_name(ctx::Context, uuid::UUID)::Union{Nothing,String} values = registered_info(ctx, uuid, "name") name = nothing for value in values - name == nothing && (name = value[2]) + name === nothing && (name = value[2]) name != value[2] && pkgerror("package `$uuid` has multiple registered name values: $name, $(value[2])") end return name diff --git a/src/backwards_compatible_isolation.jl b/src/backwards_compatible_isolation.jl index dc8e91e065..a7c6da064d 100644 --- a/src/backwards_compatible_isolation.jl +++ b/src/backwards_compatible_isolation.jl @@ -1,7 +1,7 @@ function _update_manifest(ctx::Context, pkg::PackageSpec, hash::Union{SHA1, Nothing}) env = ctx.env uuid, name, version, path, special_action, repo = pkg.uuid, pkg.name, pkg.version, pkg.path, pkg.special_action, pkg.repo - hash === nothing && @assert (path != nothing || pkg.uuid in keys(ctx.stdlibs) || pkg.repo.source != nothing) + hash === nothing && @assert (path !== nothing || pkg.uuid in keys(ctx.stdlibs) || pkg.repo.source !== nothing) # TODO I think ^ assertion is wrong, add-repo should have a hash entry = get!(env.manifest, uuid, Types.PackageEntry()) entry.name = name @@ -81,7 +81,7 @@ function _resolve_versions!( else ver = VersionSpec() end - if uuid_idx != nothing + if uuid_idx !== nothing pkg = pkgs[uuid_idx] if entry !== nothing && pkg.special_action != PKGSPEC_FREED && entry.pinned # This is a pinned package, fix its version @@ -231,7 +231,7 @@ function apply_versions(ctx::Context, pkgs::Vector{PackageSpec}, hashes::Dict{UU end try success = install_archive(urls[pkg.uuid], hashes[pkg.uuid], path) - if success && mode == :add + if success && mode === :add set_readonly(path) # In add mode, files should be read-only end if ctx.use_only_tarballs_for_downloads && !success @@ -252,7 +252,7 @@ function apply_versions(ctx::Context, pkgs::Vector{PackageSpec}, hashes::Dict{UU sprint(Base.showerror, exc_or_success, bt_or_path)) success, path = exc_or_success, bt_or_path if success - vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]" + vstr = pkg.version !== nothing ? "v$(pkg.version)" : "[$h]" printpkgstyle(ctx, :Installed, string(rpad(pkg.name * " ", max_name + 2, "─"), " ", vstr)) else push!(missed_packages, (pkg, path)) @@ -265,10 +265,10 @@ function apply_versions(ctx::Context, pkgs::Vector{PackageSpec}, hashes::Dict{UU for (pkg, path) in missed_packages uuid = pkg.uuid install_git(ctx, pkg.uuid, pkg.name, hashes[uuid], urls[uuid], pkg.version::VersionNumber, path) - if mode == :add + if mode === :add set_readonly(path) end - vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]" + vstr = pkg.version !== nothing ? "v$(pkg.version)" : "[$h]" printpkgstyle(ctx, :Installed, string(rpad(pkg.name * " ", max_name + 2, "─"), " ", vstr)) end diff --git a/src/generate.jl b/src/generate.jl index d299995ce6..3959af2593 100644 --- a/src/generate.jl +++ b/src/generate.jl @@ -27,23 +27,23 @@ function project(ctx::Context, pkg::String, dir::String) gitmail = LibGit2.getconfig("user.email", "") isempty(gitmail) || (email = gitmail) - if name == nothing + if name === nothing for env in ["GIT_AUTHOR_NAME", "GIT_COMMITTER_NAME", "USER", "USERNAME", "NAME"] name = get(ENV, env, nothing) - name != nothing && break + name !== nothing && break end end - name == nothing && (name = "Unknown") + name === nothing && (name = "Unknown") - if email == nothing + if email === nothing for env in ["GIT_AUTHOR_EMAIL", "GIT_COMMITTER_EMAIL", "EMAIL"]; email = get(ENV, env, nothing) - email != nothing && break + email !== nothing && break end end - authors = ["$name " * (email == nothing ? "" : "<$email>")] + authors = ["$name " * (email === nothing ? "" : "<$email>")] uuid = UUIDs.uuid4() genfile(ctx, pkg, dir, "Project.toml") do io diff --git a/src/versions.jl b/src/versions.jl index 49fbe792fd..425e873433 100644 --- a/src/versions.jl +++ b/src/versions.jl @@ -111,9 +111,9 @@ VersionRange(v::VersionNumber) = VersionRange(VersionBound(v)) function VersionRange(s::AbstractString) m = match(r"^\s*v?((?:\d+(?:\.\d+)?(?:\.\d+)?)|\*)(?:\s*-\s*v?((?:\d+(?:\.\d+)?(?:\.\d+)?)|\*))?\s*$", s) - m == nothing && throw(ArgumentError("invalid version range: $(repr(s))")) + m === nothing && throw(ArgumentError("invalid version range: $(repr(s))")) lower = VersionBound(m.captures[1]) - upper = m.captures[2] != nothing ? VersionBound(m.captures[2]) : lower + upper = m.captures[2] !== nothing ? VersionBound(m.captures[2]) : lower return VersionRange(lower, upper) end @@ -157,7 +157,7 @@ function Base.union!(ranges::Vector{<:VersionRange}) k0 = 1 ks = findfirst(!isempty, ranges) - ks == nothing && return empty!(ranges) + ks === nothing && return empty!(ranges) lo, up, k0 = ranges[ks].lower, ranges[ks].upper, 1 for k = (ks + 1):l @@ -287,7 +287,7 @@ function semver_interval(m::RegexMatch) # Default type is :caret vertyp = (typ == "" || typ == "^") ? :caret : :tilde v0 = VersionBound((major, minor, patch)) - if vertyp == :caret + if vertyp === :caret if major != 0 return VersionRange(v0, VersionBound((v0[1],))) elseif minor != 0 From 70ec7b7ae1c72c664e2f5dadd9b5654a34162385 Mon Sep 17 00:00:00 2001 From: "Tamas K. Papp" Date: Fri, 8 Nov 2019 19:59:48 +0100 Subject: [PATCH 11/15] Document that uuid4 should be used by default. (#1494) Fixes #1493. --- docs/src/toml-files.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/src/toml-files.md b/docs/src/toml-files.md index e367b3297a..fc663af71f 100644 --- a/docs/src/toml-files.md +++ b/docs/src/toml-files.md @@ -41,6 +41,9 @@ uuid = "7876af07-990d-54b4-ab0e-23690620f79a" ``` The `uuid` field is mandatory for packages. +!!! note + It is recommended that `UUIDs.uuid4()` is used to generate random UUIDs. + ### The `version` field From 32389454bb3abf788d00da8e47f7477523950bf0 Mon Sep 17 00:00:00 2001 From: David Varela <00.varela.david@gmail.com> Date: Fri, 8 Nov 2019 16:28:15 -0800 Subject: [PATCH 12/15] do not throw errors when autocompleting (#1489) --- src/REPLMode/completions.jl | 15 +++++++++++---- test/repl.jl | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/REPLMode/completions.jl b/src/REPLMode/completions.jl index 9064d0e9b7..8f296175a8 100644 --- a/src/REPLMode/completions.jl +++ b/src/REPLMode/completions.jl @@ -145,10 +145,17 @@ function complete_argument(spec::CommandSpec, options::Vector{String}, end function _completions(input, final, offset, index) - words = tokenize(input)[end] - word_count = length(words) - statement, partial = core_parse(words) - final && (partial = "") # last token is finalized -> no partial + statement, word_count, partial = nothing, nothing, nothing + try + words = tokenize(input)[end] + word_count = length(words) + statement, partial = core_parse(words) + if final + partial = "" # last token is finalized -> no partial + end + catch + return String[], 0:-1, false + end # number of tokens which specify the command command_size = count([statement.super !== nothing, true]) command_is_focused() = !((word_count == command_size && final) || word_count > command_size) diff --git a/test/repl.jl b/test/repl.jl index 7a149ad43e..904f45ba31 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -391,6 +391,9 @@ temp_pkg_dir() do project_path; cd(project_path) do # invalid options c, r = test_complete("rm -rf ") @test isempty(c) + + # parse errors should not throw + _ = test_complete("add \"Foo") end # testset end end From 50f9c6c7c3a7c2072914f7b1aee8a4609174f361 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 8 Nov 2019 23:26:40 -0800 Subject: [PATCH 13/15] Use relative import everywhere (#1495) --- src/API.jl | 2 +- src/Types.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/API.jl b/src/API.jl index 3dba7e15c9..2952d50f3c 100644 --- a/src/API.jl +++ b/src/API.jl @@ -11,7 +11,7 @@ import LibGit2 import ..depots, ..depots1, ..logdir, ..devdir import ..Operations, ..Display, ..GitTools, ..Pkg, ..UPDATED_REGISTRY_THIS_SESSION using ..Types, ..TOML -using Pkg.Types: VersionTypes +using ..Types: VersionTypes using ..BinaryPlatforms using ..Artifacts: artifact_paths diff --git a/src/Types.jl b/src/Types.jl index f8191a24d1..abfe150018 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -12,7 +12,7 @@ using REPL.TerminalMenus using ..TOML import ..Pkg, ..UPDATED_REGISTRY_THIS_SESSION, ..DEFAULT_IO -import Pkg: GitTools, depots, depots1, logdir, set_readonly, safe_realpath +import ..Pkg: GitTools, depots, depots1, logdir, set_readonly, safe_realpath import ..BinaryPlatforms: Platform import Base: SHA1 From d1eae70e79e50caad3335d8e010bfe2592c83427 Mon Sep 17 00:00:00 2001 From: David Varela <00.varela.david@gmail.com> Date: Wed, 13 Nov 2019 19:56:01 -0800 Subject: [PATCH 14/15] Document IO redirection (#1499) --- docs/src/api.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/src/api.md b/docs/src/api.md index 8577b7e55e..15814b193c 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -4,6 +4,16 @@ This section describes the function interface, or "API mode", for interacting with Pkg.jl. The function API is recommended for non-interactive usage, for example in scripts. +## General API Reference + +Certain options are generally useful and can be specified in any API call. +You can specify these options by setting keyword arguments. + +### Redirecting output + +Use the `io::IOBuffer` keyword argument to redirect Pkg output. +For example, `Pkg.add("Example"; io=devnull)` will discard any output produced by the `add` call. + ## Package API Reference In the REPL mode, packages (with associated version, UUID, URL etc) are parsed from strings, From b16053f81367cf9074292b8d61cb0742820c385c Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Thu, 14 Nov 2019 09:36:51 -0800 Subject: [PATCH 15/15] Relocatable `@artifact_str` (#1485) * Insert compiler barrier within `@artifact_str` This greatly reduces the load time of JLL artifacts, as it severs all connection between user (JLL) code and Pkg; the compiler no longer needs to manage the large number of backedges within `Pkg.Artifacts` leading back to each and every JLL package. * Improve `@artifact_str` relocatability By moving some work to compile-time, we are able to avoid usage of `@__DIR__` and even parsing of `Artifacts.toml` files at all during module `__init__()`; this means that relocated `.ji` files should maintain all knowledge of artifacts without needing to hit baked filesystem paths, which is a definite plus. Error messages will continue to point to the wrong location, but that is forgivable. This may speed up JLL package load time by a small amount, however we still need to hit the disk for things like `Overrides.toml`, and we still need to `dlopen()` things, etc... so I do not expect this to have a large impact. * Invalidate `.ji` files if `Artifacts.toml` files are changed --- src/Artifacts.jl | 79 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/src/Artifacts.jl b/src/Artifacts.jl index e317a5659a..c023c85264 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -467,10 +467,26 @@ function load_artifacts_toml(artifacts_toml::String; pkg_uuid::Union{Base.UUID,Nothing} = nothing) artifact_dict = parse_toml(artifacts_toml) + # Process overrides for this `pkg_uuid` + process_overrides(artifact_dict, pkg_uuid) + return artifact_dict +end + +""" + process_overrides(artifact_dict::Dict, pkg_uuid::Base.UUID) + +When loading an `Artifacts.toml` file, we must check `Override.toml` files to see if any +of the artifacts within it have been overridden by UUID. If they have, we honor the +overrides by inspecting the hashes of the targeted artifacts, then overriding them to +point to the given override, punting the actual redirection off to the hash-based +override system. This does not modify the `artifact_dict` object, it merely dynamically +adds more hash-based overrides as `Artifacts.toml` files that are overridden are loaded. +""" +function process_overrides(artifact_dict::Dict, pkg_uuid::Base.UUID) # Insert just-in-time hash overrides by looking up the names of anything we need to # override for this UUID, and inserting new overrides for those hashes. overrides = load_overrides() - if pkg_uuid !== nothing && haskey(overrides[:UUID], pkg_uuid) + if haskey(overrides[:UUID], pkg_uuid) pkg_overrides = overrides[:UUID][pkg_uuid] for name in keys(artifact_dict) @@ -491,10 +507,12 @@ function load_artifacts_toml(artifacts_toml::String; end end end - return artifact_dict end +# If someone tries to call process_overrides() with `nothing`, do exactly that +process_overrides(artifact_dict::Dict, pkg_uuid::Nothing) = nothing + """ artifact_meta(name::String, artifacts_toml::String; platform::Platform = platform_key_abi(), @@ -936,6 +954,26 @@ function extract_all_hashes(artifacts_toml::String; return hashes end +function do_artifact_str(name, artifact_dict, artifacts_toml, __module__) + local pkg_uuid = nothing + if haskey(Base.module_keys, __module__) + # Process overrides for this UUID, if we know what it is + process_overrides(artifact_dict, Base.module_keys[__module__].uuid) + end + + # Get platform once to avoid extra work + platform = platform_key_abi() + + # Get the metadata about this name for the requested platform + meta = artifact_meta(name, artifact_dict, artifacts_toml; platform=platform) + + if meta === nothing + error("Cannot locate artifact '$(name)' in '$(artifacts_toml)'") + end + + # This is the resultant value at the end of all things + return ensure_artifact_installed(name, meta, artifacts_toml; platform=platform) +end """ macro artifact_str(name) @@ -948,25 +986,28 @@ location on-disk. Automatically looks the artifact up by name in the project's This macro requires at least Julia 1.3. """ macro artifact_str(name) + # Load Artifacts.toml at compile time, so that we don't have to use `__source__.file` + # at runtime, which gets stale if the `.ji` file is relocated. + local artifacts_toml = find_artifacts_toml(string(__source__.file)) + if artifacts_toml === nothing + error(string( + "Cannot locate '(Julia)Artifacts.toml' file when attempting to use artifact '", + name, + "' in '", + __module__, + "'", + )) + end + + local artifact_dict = load_artifacts_toml(artifacts_toml) return quote - local artifacts_toml = $(find_artifacts_toml)($(string(__source__.file))) - if artifacts_toml === nothing - error(string( - "Cannot locate '(Julia)Artifacts.toml' file when attempting to use artifact '", - $(esc(name)), - "' in '", - $(esc(__module__)), - "'", - )) - end - - local pkg_uuid = nothing - if haskey(Base.module_keys, $(__module__)) - pkg_uuid = Base.module_keys[$(__module__)].uuid - end + # Invalidate .ji file if Artifacts.toml file changes + Base.include_dependency($(artifacts_toml)) - # This is the resultant value at the end of all things - $(ensure_artifact_installed)($(esc(name)), artifacts_toml; pkg_uuid=pkg_uuid) + # Use invokelatest() to introduce a compiler barrier, preventing many backedges from being added + # and slowing down not only compile time, but also `.ji` load time. This is critical here, as + # artifact"" is used in other modules, so we don't want to be spreading backedges around everywhere. + Base.invokelatest(do_artifact_str, $name, $(artifact_dict), $(artifacts_toml), $__module__) end end