@@ -177,6 +177,16 @@ function set_compat(proj::Project, name::String, compat::String)
177177 proj. compat[name] = Types. Compat (Types. semver_spec (compat), compat)
178178end
179179
180+ function reset_all_compat! (proj:: Project )
181+ for name in keys (proj. compat)
182+ compat = proj. compat[name]
183+ if compat. val != Types. semver_spec (compat. str)
184+ proj. compat[name] = Types. Compat (Types. semver_spec (compat. str), compat. str)
185+ end
186+ end
187+ return nothing
188+ end
189+
180190function collect_project! (pkg:: PackageSpec , path:: String ,
181191 deps_map:: Dict{UUID,Vector{PackageSpec}} )
182192 deps_map[pkg. uuid] = PackageSpec[]
@@ -1218,7 +1228,8 @@ function up_load_manifest_info!(pkg::PackageSpec, entry::PackageEntry)
12181228 # `pkg.version` and `pkg.tree_hash` is set by `up_load_versions!`
12191229end
12201230
1221- function up (ctx:: Context , pkgs:: Vector{PackageSpec} , level:: UpgradeLevel )
1231+ function up (ctx:: Context , pkgs:: Vector{PackageSpec} , level:: UpgradeLevel ;
1232+ skip_writing_project:: Bool = false )
12221233 new_git = Set {UUID} ()
12231234 # TODO check all pkg.version == VersionSpec()
12241235 # set version constraints according to `level`
@@ -1236,7 +1247,7 @@ function up(ctx::Context, pkgs::Vector{PackageSpec}, level::UpgradeLevel)
12361247 update_manifest! (ctx. env, pkgs, deps_map, ctx. julia_version)
12371248 new_apply = download_source (ctx)
12381249 download_artifacts (ctx. env, julia_version= ctx. julia_version, io= ctx. io)
1239- write_env (ctx. env) # write env before building
1250+ write_env (ctx. env; skip_writing_project ) # write env before building
12401251 show_update (ctx. env; io= ctx. io)
12411252 build_versions (ctx, union (new_apply, new_git))
12421253end
@@ -1435,19 +1446,30 @@ function sandbox(fn::Function, ctx::Context, target::PackageSpec, target_path::S
14351446 with_temp_env (tmp) do
14361447 temp_ctx = Context ()
14371448 temp_ctx. env. project. deps[target. name] = target. uuid
1449+
1450+ if force_latest_compatible_version
1451+ apply_force_latest_compatible_version! (
1452+ temp_ctx;
1453+ target_name = target. name,
1454+ allow_earlier_backwards_compatible_versions,
1455+ )
1456+ end
1457+
14381458 try
1439- Pkg. resolve (temp_ctx; io= devnull )
1459+ Pkg. resolve (temp_ctx; io= devnull , skip_writing_project = true )
14401460 @debug " Using _parent_ dep graph"
14411461 catch err# TODO
14421462 err isa Resolve. ResolverError || rethrow ()
14431463 allow_reresolve || rethrow ()
14441464 @debug err
14451465 @warn " Could not use exact versions of packages in manifest, re-resolving"
14461466 temp_ctx. env. manifest = Dict (uuid => entry for (uuid, entry) in temp_ctx. env. manifest if isfixed (entry))
1447- Pkg. resolve (temp_ctx; io= devnull )
1467+ Pkg. resolve (temp_ctx; io= devnull , skip_writing_project = true )
14481468 @debug " Using _clean_ dep graph"
14491469 end
14501470
1471+ reset_all_compat! (temp_ctx. env. project)
1472+
14511473 # Absolutify stdlibs paths
14521474 for (uuid, entry) in temp_ctx. env. manifest
14531475 if is_stdlib (uuid)
@@ -1456,17 +1478,6 @@ function sandbox(fn::Function, ctx::Context, target::PackageSpec, target_path::S
14561478 end
14571479 write_env (temp_ctx. env, update_undo = false )
14581480
1459- if force_latest_compatible_version
1460- result = check_force_latest_compatible_version (
1461- temp_ctx;
1462- target_name = target. name,
1463- allow_earlier_backwards_compatible_versions,
1464- )
1465- if ! result
1466- pkgerror (" One or more direct dependencies is not at the latest compatible version" )
1467- end
1468- end
1469-
14701481 # Run sandboxed code
14711482 path_sep = Sys. iswindows () ? ' ;' : ' :'
14721483 withenv (fn, " JULIA_LOAD_PATH" => " @$(path_sep)$(tmp) " , " JULIA_PROJECT" => nothing )
@@ -1813,64 +1824,60 @@ function status(env::EnvCache, pkgs::Vector{PackageSpec}=PackageSpec[];
18131824 end
18141825end
18151826
1816- function check_force_latest_compatible_version (ctx:: Types.Context ;
1817- target_name = nothing ,
1818- allow_earlier_backwards_compatible_versions:: Bool = true )
1827+ function apply_force_latest_compatible_version! (ctx:: Types.Context ;
1828+ target_name = nothing ,
1829+ allow_earlier_backwards_compatible_versions:: Bool = true )
18191830 direct_deps = load_direct_deps (ctx. env)
18201831 direct_deps_uuids = [dep. uuid for dep in direct_deps]
18211832 uuid_list = filter (! is_stdlib, direct_deps_uuids)
1822- isempty (uuid_list) && return true
1823- results = check_force_latest_compatible_version .(
1824- Ref (ctx),
1825- uuid_list;
1826- target_name,
1827- allow_earlier_backwards_compatible_versions,
1828- )
1829- return all (results)
1833+ for uuid in uuid_list
1834+ apply_force_latest_compatible_version! (
1835+ ctx,
1836+ uuid;
1837+ target_name,
1838+ allow_earlier_backwards_compatible_versions,
1839+ )
1840+ end
1841+ return nothing
18301842end
18311843
1832- function check_force_latest_compatible_version (ctx:: Types.Context ,
1833- uuid:: Base.UUID ;
1834- target_name= nothing ,
1835- allow_earlier_backwards_compatible_versions:: Bool = true )
1844+ function apply_force_latest_compatible_version! (ctx:: Types.Context ,
1845+ uuid:: Base.UUID ;
1846+ target_name= nothing ,
1847+ allow_earlier_backwards_compatible_versions:: Bool = true )
18361848 dep = ctx. env. manifest[uuid]
18371849 name = dep. name
18381850 active_version = dep. version
18391851 has_compat = haskey (ctx. env. project. compat, name)
18401852 if ! has_compat
18411853 if name != target_name
18421854 @warn (
1843- " Package does not have a [compat] entry" ,
1855+ " Dependency does not have a [compat] entry" ,
18441856 name, uuid, active_version, target_name,
18451857 )
18461858 end
1847- return true
1859+ return nothing
18481860 end
1849- compat_entry = ctx. env. project. compat[name]. val
1861+ old_compat_spec = ctx. env. project. compat[name]. val
18501862 latest_compatible_version = get_latest_compatible_version (
18511863 ctx,
18521864 uuid,
1853- compat_entry ,
1865+ old_compat_spec ,
18541866 )
18551867 earliest_backwards_compatible_version = get_earliest_backwards_compatible_version (latest_compatible_version)
18561868 if allow_earlier_backwards_compatible_versions
1857- result = active_version >= earliest_backwards_compatible_version
1869+ version_for_intersect = only_major_minor_patch ( earliest_backwards_compatible_version)
18581870 else
1859- result = active_version >= latest_compatible_version
1860- end
1861- if ! result
1862- @error (
1863- " Package is not at the latest compatible version" ,
1864- name,
1865- uuid,
1866- compat_entry,
1867- active_version,
1868- latest_compatible_version,
1869- earliest_backwards_compatible_version,
1870- allow_earlier_backwards_compatible_versions,
1871- )
1871+ version_for_intersect = only_major_minor_patch (latest_compatible_version)
18721872 end
1873- return result
1873+ compat_for_intersect = Pkg. Types. semver_spec (" ≥ $(version_for_intersect) " )
1874+ new_compat_spec = Base. intersect (old_compat_spec, compat_for_intersect)
1875+ ctx. env. project. compat[name]. val = new_compat_spec
1876+ return nothing
1877+ end
1878+
1879+ function only_major_minor_patch (ver:: Base.VersionNumber )
1880+ return Base. VersionNumber (ver. major, ver. minor, ver. patch)
18741881end
18751882
18761883function get_earliest_backwards_compatible_version (ver:: Base.VersionNumber )
0 commit comments