summaryrefslogtreecommitdiff
path: root/src/_posts/2020-07-15-config-3.0.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/_posts/2020-07-15-config-3.0.md')
-rw-r--r--src/_posts/2020-07-15-config-3.0.md181
1 files changed, 0 insertions, 181 deletions
diff --git a/src/_posts/2020-07-15-config-3.0.md b/src/_posts/2020-07-15-config-3.0.md
deleted file mode 100644
index 9fb33c0..0000000
--- a/src/_posts/2020-07-15-config-3.0.md
+++ /dev/null
@@ -1,181 +0,0 @@
----
-title: Config 3.0
-layout: post
-tags: Raku Programming
-social:
- email: mailto:~tyil/public-inbox@lists.sr.ht&subject=Config 3.0
- mastodon: https://soc.fglt.nl/notice/9x8QT2TxD2dSlEYse8
-description: >
- I've made a reasonably sized change to Raku's Config module, resulting in a
- major version bump. This article details my reasoning behind it, and shows
- some examples on how I think I solved the issues at hand.
----
-
-For those who don't know, the
-[`Config`](https://modules.raku.org/dist/Config:cpan:TYIL) module for the Raku
-programming language is a generic class to hold... well... configuration data.
-It supports
-[`Config::Parser`](https://modules.raku.org/search/?q=Config%3A%3AParser)
-modules to handle different configuration file formats, such as `JSON`, `YAML`
-and `TOML`.
-
-Up until now, the module didn't do much for you other than provide an interface
-that's generally the same, so you won't need to learn differing methods to
-handle differing configuration file formats. It was my first Raku module, and
-as such, the code wasn't the cleanest. I've written many new modules since
-then, and learned about a good number of (hopefully better) practices.
-
-For version 3.0, I specifically wanted to remove effort from using the `Config`
-module on the developer's end. It should check default locations for
-configuration files, so I don't have to rewrite that code in every other module
-all the time. Additionally, configuration using environment variables is quite
-popular in the current day and age, especially for Dockerized applications. So,
-I set out to make an automated way to read those too.
-
-## The Old Way
-
-First, let's take a look at how it used to work. Generally, I'd create the
-default configuration structure and values first.
-
-{% highlight perl6 %}
-use Config;
-
-my $config = Config.new.read({
- foo => "bar",
- alpha => {
- beta => "gamma",
- },
- version => 3,
-});
-{% endhighlight %}
-
-And after that, check for potential configuration file locations, and read any
-that exist.
-
-{% highlight perl6 %}
-$config.read($*HOME.add('config/project.toml').absolute);
-{% endhighlight %}
-
-The `.absolute` call was necessary because I wrote the initial `Config` version
-with the `.read` method not supporting `IO::Path` objects. A fix for this has
-existed for a while, but wasn't released, so couldn't be relied on outside of
-my general development machines.
-
-If you wanted to add additional environment variable lookups, you'd have to
-check for those as well, and perhaps also cast them as well, since environment
-variables are all strings by default.
-
-## Version 3.0
-
-So, how does the new version improve this? For starters, the `.new` method of
-`Config` now takes a `Hash` as positional argument, in order to create the
-structure, and optionally types *or* default values of your configuration
-object.
-
-{% highlight perl6 %}
-use Config;
-
-my $config = Config.new({
- foo => Str,
- alpha => {
- beta => "gamma",
- },
- version => 3,
-}, :name<project>);
-{% endhighlight %}
-
-{% admonition_md note %}
-`foo` has been made into the `Str` *type object*, rather than a `Str` *value*.
-This was technically allowed in previous `Config` versions, but it comes with
-actual significance in 3.0.
-{% endadmonition_md %}
-
-Using `.new` instead of `.read` is a minor syntactic change, which saves 1 word
-per program. This isn't quite that big of a deal. However, the optional `name`
-argument will enable the new automagic features. The name you give to `.new` is
-arbitrary, but will be used to deduce which directories to check, and which
-environment variables to read.
-
-### Automatic Configuration File Handling
-
-By setting `name` to the value `project`, `Config` will consult the
-configuration directories from the [XDG Base Directory
-Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
-It uses one of my other modules,
-[`IO::Path::XDG`](https://modules.raku.org/dist/IO::Path::XDG:cpan:TYIL), for
-this, together with
-[`IO::Glob`](https://modules.raku.org/dist/IO::Glob:cpan:HANENKAMP).
-Specifically, it will check my `$XDG_CONFIG_DIRS` and `$XDG_CONFIG_HOME` (in
-that order) for any files that match the globs `project.*` or
-`project/config.*`.
-
-If any files are found to match, they will be read as well, and the
-configuration values contained therein, merged into `$config`. It will load the
-appropriate `Config::Parser` implementation based on the file's extension. I
-intend to add a number of these to future Rakudo Star releases, to ensure most
-default configuration file formats are supported out of the box.
-
-### Automatic Environment Variable Handling
-
-After this step, it will try out some environment variables for configuration
-values. Which variables are checked depends on the structure (and `name`) of
-the `Config` object. The entire structure is squashed into a 1-dimensional list
-of fields. Each level is replaced by an `_`. Additionally, each variable name
-is prefixed with the `name`. Lastly, all the variable names are uppercased.
-
-For the example `Config` given above, this would result in the following
-environment variables being checked.
-
-{% highlight sh %}
-$PROJECT_FOO
-$PROJECT_ALPHA_BETA
-$PROJECT_VERSION
-{% endhighlight %}
-
-If any are found, they're also cast to the appropriate type. Thus,
-`$PROJECT_FOO` would be cast to a `Str`, and so would `$PROJECT_ALPHA_BETA`. In
-this case that doesn't do much, since they're already strings. But
-`$PROJECT_VERSION` would be cast to an `Int`, since it's default value is also
-of the `Int` type. This should ensure that your variables are always in the
-type you expected them to be originally, no matter the user's configuration
-choices.
-
-## Debugging
-
-In addition to these new features, `Config` now also makes use of my
-[`Log`](https://modules.raku.org/dist/Log:cpan:TYIL) module. This module is
-made around the idea that logging should be simple if module developers are to
-use it, and the way logs are represented is up to the end-user. When running an
-application in your local terminal, you may want more human-friendly logs,
-whereas in production you may want `JSON` formatted logs to make it fit better
-into other tools.
-
-You can tune the amount of logging performed using the `$RAKU_LOG_LEVEL`
-environment variable, as per the `Log` module's interface. When set to `7` (for
-"debug"), it will print the configuration files that are being merged into your
-`Config` and which environment veriables are being used as well.
-
-{% admonition_md note %}
-A downside is that the application using `Config` for its configuration must
-also support `Log` to actually make the new logging work. Luckily, this is
-quite easy to set up, and there's example code for this in `Log`'s README.
-{% endadmonition_md %}
-
-## Too Fancy For Me
-
-It could very well be that you don't want these features, and you want to stick
-to the old ways as much as possible. No tricks, just plain and simple
-configuration handling. This can be done by simply ommitting the `name`
-argument to `.new`. The new features depend on this name to be set, and won't
-do anything without it.
-
-Alternatively, both the automatic configuration file handling and the
-environment variable handling can be turned off individually using `:!from-xdg`
-and `:!from-env` arguments respectively.
-
-## In Conclusion
-
-The new `Config` module should result in cleaner code in modules using it, and
-more convenience for the developer. If you find any bugs or have other ideas
-for improving the module, feel free to send an email to
-`https://lists.sr.ht/~tyil/raku-devel`.