Skip to content

Use GracefulPkg.jl #3185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
ExpressionExplorer = "21656369-7473-754a-2065-74616d696c43"
FileWatching = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
FuzzyCompletions = "fb4132e2-a121-4a70-b8a1-d5b831dcdcc2"
GracefulPkg = "828d9ff0-206c-6161-646e-6576656f7244"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Expand Down Expand Up @@ -44,6 +45,7 @@ Downloads = "1"
ExpressionExplorer = "0.5, 0.6, 1"
FileWatching = "1"
FuzzyCompletions = "=0.5.5"
GracefulPkg = "2"
HTTP = "^1.5.2"
HypertextLiteral = "0.7, 0.8, 0.9"
InteractiveUtils = "1"
Expand Down
80 changes: 32 additions & 48 deletions src/packages/Packages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import .PkgCompat: select, is_stdlib
import Logging
import LoggingExtras
import .Configuration: CompilerOptions, _merge_notebook_compiler_options, _convert_to_flags
import GracefulPkg

const tiers = unique((
Pkg.PRESERVE_ALL_INSTALLED,
Expand Down Expand Up @@ -166,26 +167,16 @@ function sync_nbpkg_core(

should_precompile_later = true

# First, we instantiate. This will:
# - Verify that the Manifest can be parsed and is in the correct format (important for compat across Julia versions). If not, we will fix it by deleting the Manifest.
# - If no Manifest exists, resolve the environment and create one.
# - Start downloading all registered packages, artifacts.
# - Start downloading all unregistered packages, which are added through a URL. This also makes the Project.tomls of those packages available.
# - Precompile all packages.
Status.report_business!(pkg_status, :instantiate1) do
with_auto_fixes(notebook) do
_instantiate(notebook, iolistener)
end
end

# Second, we resolve. This will:
# - Verify that the Manifest contains a correct dependency tree (e.g. all versions exists in a registry). If not, we will fix it using `with_auto_fixes`
# - If we are tracking local packages by path (] dev), their Project.tomls are reparsed and everything is updated.
# Resolve the package environment, using GracefulPkg.jl to solve any issues
Status.report_business!(pkg_status, :resolve) do
with_auto_fixes(notebook) do
_resolve(notebook, iolistener)
end
end

Status.report_business!(pkg_status, :instantiate1) do
_instantiate(notebook, iolistener)
end
end

to_add = filter(PkgCompat.package_exists, added)
Expand Down Expand Up @@ -476,43 +467,39 @@ function _resolve(notebook::Notebook, iolistener::IOListener)
end


const gracefulpkg_strats = filter!(collect(GracefulPkg.DEFAULT_STRATEGIES)) do strat
!(strat isa GracefulPkg.StrategyRemoveProject)
end


"""
Run `f` (e.g. `Pkg.instantiate`) on the notebook's package environment. Keep trying more and more invasive strategies to fix problems until the operation succeeds.
"""
function with_auto_fixes(f::Function, notebook::Notebook)
try
f()
catch e
@info "Operation failed. Updating registries and trying again..." exception=e

PkgCompat.update_registries(; force=true)

# TODO: check for resolver errors around stdlibs and fix them by doing `up Statistics`




env_dir = PkgCompat.env_dir(notebook.nbpkg_ctx)

is_first = Ref(true)
report = GracefulPkg.gracefully(; env_dir, throw=false, strategies=gracefulpkg_strats) do
try
f()
catch e
# this is identical to Pkg.update, right?
@warn "Operation failed. Removing Manifest and trying again..." exception=e

reset_nbpkg!(notebook; keep_project=true, save=false, backup=false)
notebook.nbpkg_ctx_instantiated = false
try
f()
catch e
@warn "Operation failed. Removing Project compat entries and Manifest and trying again..." exception=(e, catch_backtrace())

reset_nbpkg!(notebook; keep_project=true, save=false, backup=false)
PkgCompat.clear_compat_entries!(notebook.nbpkg_ctx)
notebook.nbpkg_ctx_instantiated = false

f()
if !is_first[]
PkgCompat.load_ctx!(notebook.nbpkg_ctx, env_dir)
end

f()
finally
is_first[] = false
end
end

steps = report.strategy_reports

if any(x -> x.strategy isa GracefulPkg.StrategyLoosenCompat, steps)
notebook.nbpkg_ctx_instantiated = false
end

if !GracefulPkg.is_success(report)
throw(GracefulPkg.NothingWorked(report))
end
end

"""
Expand Down Expand Up @@ -573,13 +560,10 @@ function update_nbpkg_core(
PkgCompat.clear_stdlib_compat_entries!(notebook.nbpkg_ctx)

if !notebook.nbpkg_ctx_instantiated
with_auto_fixes(notebook) do
_instantiate(notebook, iolistener)
end

with_auto_fixes(notebook) do
_resolve(notebook, iolistener)
end
_instantiate(notebook, iolistener)
end

with_io_setup(notebook, iolistener) do
Expand Down
13 changes: 0 additions & 13 deletions src/packages/PkgCompat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,6 @@ function write_auto_compat_entries!(ctx::PkgContext)::PkgContext
end


# ✅ Public API
"""
Remove all [`compat`](https://pkgdocs.julialang.org/v1/compatibility/) entries from the `Project.toml`.
"""
function clear_compat_entries!(ctx::PkgContext)::PkgContext
if isfile(project_file(ctx))
_modify_compat!(empty!, ctx)
else
ctx
end
end


# ✅ Public API
"""
Remove any automatically-generated [`compat`](https://pkgdocs.julialang.org/v1/compatibility/) entries from the `Project.toml`. This will undo the effects of [`write_auto_compat_entries!`](@ref) but leave other (e.g. manual) compat entries intact. Return the new `PkgContext`.
Expand Down
Loading