A Config Package with No “Con”
To install latest available version from GitHub use remotes package:
# install.packages("remotes")
::install_github("TymekDev/fig") remotes
fig can be used in two different ways: 1. On a global level using
fig_*
functions 1. On a class instance level
Check out the following sections to find the way that suits your needs.
fig_*
FunctionsThis approach works with no additional prep. It is especially useful
if you want to access stored values without the hassle to pass an
argument through entire codebase. Values stored with fig_*
live inside fig package making them accessible from any place in the
code.
fig_store("foo", 123)
fig_get("foo") # == 123
For more examples see package documentation.
Fig
Class
InstanceUsing Fig
class allows storing values separately in
several distinct class instances. If you need a config separation in
your code, then Fig
class is for you. Note that, unlike
with fig_*
functions, you have to pass the instance around
to access values stored in it.
<- Fig$new()
fig $store("foo", 123)
fig$get("foo") # == 123
fig
<- Fig$new()$store("foo", 456)
fig2 $get("foo") # == 456 fig2
For more examples see package documentation.
:information_source: This feature is useful if you want to override a stored value without introducing a code change (e.g. log level, API URL, …).
fig supports a two level precedence. Every fig_get()
function and get()
method call performs a lookup in a
following order: 1. System environment variables 1. Stored values
fig_store_many(foo = 123, bar = 456)
fig_get_many("foo", "bar") # == list(123, 456)
# Environment variable value gets picked over a stored value
::with_envvar(list(foo = "xyz"), {
withrfig_get_many("foo", "bar")) # == list("xyz", 456)
})
fig_delete("foo")
# Environment variable value gets picked over a missing stored value
::with_envvar(list(foo = "xyz"), {
withrfig_get("foo")) # == "xyz"
})
fig_get("foo") # == NULL
.
) in keys are replaced with underscores
(_
) during system environment lookup.This feature goes in pair with precedence. fig can be configured with
env_prefix
argument (default: ""
). It can be
provided via fig_configure()
(or configure()
method) or during Fig
instance creation.
env_prefix
determines value prepended to the key before
performing a system environment lookup.
<- Fig$new(env_prefix = "RCONNECT_")
fig ::with_envvar(list(RCONNECT_SERVER = "example.com", {
withr$get("SERVER") # == "example.com"
fig })
:information_source: This feature is useful if you want interact (dynamically) with a nested config without a hassle.
fig can be configured with split_on
argument (default:
"."
). It can be provided via fig_configure()
(or configure()
method) or during Fig
instance
creation.
split_on
determines a level delimiter for keys,
i.e. with split_on
set "foo.bar"
is treated as
bar
nested under foo
.
fig_store("foo", list(bar = 1))
fig_get("foo.bar") # == 1
# Storage
# └── foo
# └── bar
# └── 1
fig_configure(split_on = "") # Disable this functionality
fig_store("foo.bar", 2)
fig_get("foo.bar") # == 2
# Storage
# ├── foo
# │ └── bar
# │ └── 1
# └── foo.bar
# └── 2
Note: this behavior currently is not supported by delete functions and methods.
If you are using config package and would
like to enjoy fig’s features, then the suggested approach is to wrap
your main config::get()
call in
fig_store_list()
(or store_list()
method).
# default:
# foo: 123
fig_store_list(config::get())
fig_get("foo") # == 123
::with_envvar(list(foo = "xyz"), {
withrfig_get("foo")) # == "xyz"
})
This way you can use fig functions to have precedence and key splitting working for retrieving values from your config.
Licensed under MIT. Inspired by viper. Written in Neovim. Tested with testthat. Used in radian.