- Published on
Scripting = Configuration
4 min read - 644 words- Authors
- Name
- Florian Bellmann
Overview
- Common ways of configuring software
- Scripting as configuration
- Lua
- Utilizing the power
- Extensibility of software
Common ways of configuring software
Over the years we have seen many ways of configuring software products. Most of the time, these products can either be run with environment variables or through loading a configuration file. These files have formats like .xml
, .yml
, .json
, .toml
and so on.
One advantage that .yml
files have, is that they can use placeholders and allow for substitution of default values. More complex scenarios oftentimes require to have the logic inside of the software product itself though. The configuration files hold flags and values to that behavior.
Scripting as configuration
A modern approach when building software for developers, is to configure them by using a scripting language. This is a powerful approach, as it allows to use the full capabilities of a programming language. In practise one builds a configuration object inside the scripting language and returns it to the software at hand.
Lua
Neovim and WezTerm chose to use Lua for that and Lua is continuing to gain market share. Lua is a small and fast scripting language. It is very easy to learn and has a small footprint. Additionally, Lua has the concept of a Lua table which is basically a key value object.
local config = {
name = "John Doe",
age = 42,
address = {
street = "Main Street",
city = "New York",
country = "USA"
}
}
return config
The config
object is such a table. This small file returns it to whoever consumes the output. It could already be a configuration that a software program could read.
Utilizing the power
To give an example on where the scripting is useful, let's take a look at the following configuration file.
local config = {
name = "Great software product",
theme = "Github light",
update_interval = 1000
}
return config
Say we want to deploy our software on both MacOS and Windows which require a different update_interval
. With a small scripting function we can automate this.
-- Function to execute a shell command and capture its output
local function execute(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
return result
end
local is_macos = execute("uname -s") == "Darwin"
local config = {
name = "Great software product",
theme = "Github light",
update_interval = is_macos and 1000 or 5000 -- Ternary if in lua
}
return config
What if we want to provide our users the option to choose between light and dark themes in the application. Traditionally, one would implement a theme switcher inside the app itself. With the same helper function execute()
we can achieve an automatic switcher in the config file. This example is build for MacOS, it can be done in a similar way for Windows.
local function is_macos_dark_theme()
-- Check MacOS system theme
local command = "defaults read -g AppleInterfaceStyle"
local theme = execute(command)
-- Remove leading/trailing white space and line breaks from the theme
theme = theme:gsub("^%s*(.-)%s*$", "%1")
-- Determine and return the theme
if theme == "Dark" then
return true
else
return false
end
end
local config = {
name = "Great software product",
theme = is_macos_dark_theme() and "Github dark" or "Github light",
update_interval = is_macos and 1000 or 5000
}
return config
Extensibility of software
By providing the possibility to script, it encourages users of the software to do so. This allows for a high degree of extensibility. The users can write their own plugins and share them with the community. It fosters experimenting and a new level of engagement with the software.
To be fair, this is mainly possible with software that is targeting software developers or people that have some knowledge of scripting.
I anyhow think it's a great approach that supports a fun way to interact with the software at hand.
Cheers
Flo