I made a little package to make it easier to set and get preferences (in the sense of Preferences.jl) interactively. It hooks into the Pkg REPL so you can do this:
It provides a single consistent interface for modifying preferences. Many packages have functions to set their preferences, but with varying interfaces and levels of functionality. Package authors could instead instruct their users to set preferences with this package.
The commands (add, remove, status) are consistent with the rest of the Pkg REPL so easy to remember.
It allows you to set preferences before first loading the package - which may be important to avoid downloading a large unwanted default binary, or to avoid unnecessary precompilation. You can only do this with Preferences.jl if you know the UUID of the package.
You can conveniently set global preferences with the -g flag, and export them with the -x flag.
Fewer keystrokes - installed packages and existing preference names can be tab-completed.
List-valued preferences can be modified with += and -=, which is particularly useful for SnoopPrecompile.skip_precompile.
Why not use it?
Preferences are not validated at all - this does not check that the package name exists, or that a given preference name or value is valid for the package.
Packages which consume preferences should still use Preferences.jl directly. This package is for interactive use.
Personally, I’m going to migrate some of my own packages (PythonCall, CondaPkg, Bokeh) to use preferences, instructing users to set preferences with this package.
Have you considered a PR to Preferences.jl instead of having a separate package? This seems like the sort of thing that we want standardized in the long run (at least for simple set/get operations).
Sure, there are certainly some things that could be immediately “upstreamed” to Preferences.jl, like the ability to specify the package by name.
The REPL mode is sufficiently new and different though (and relies on undocumented internals) that I was expecting some push-back on that. Having a separate package makes it easier to iterate and get to an acceptable implementation. It’s also possible the REPL mode might make the package load time a lot worse for people not using that functionality - though I imagine it can be avoided by only enabling it in interactive sessions.
Why does Preferences.jl have a comparatively long load time, actually? It indirectly affects the load time of SnoopPrecompile, which I imagine will be used by a lot of packages in the future. Preferences.jl should have a lot of invalidations, etc., right?
julia> @time_imports import Pkg, SnoopPrecompile
42.5 ms Preferences
0.6 ms SnoopPrecompile
If the problem is adding Pkg as a dependency for BinaryBuilder.jl, maybe we can upstream all of this to Preferences.jl, then spin off a PreferencesLite.jl for BinaryBuilder?
Right, so what I’m saying is you can carve out the parts of Preferences.jl and PreferenceTools.jl that don’t require Pkg.jl and put them in a PreferencesCore.jl, which people who don’t want to use Pkg can use instead.
Mostly I’m trying to make this easy on the user end, by having one package for normal users with a simple name (Preferences.jl).
Separately, for the kinds of people who care a lot about minimizing dependencies, we can have a package that includes any preference-related features that don’t require Pkg.