Skip to content

Commit a1b6ccc

Browse files
Override configuration using environment variables (#541)
* Added the ability to update config settings from env vars * Added tests * Documented that you can override configuration with environment variables * Refactored the config get() methods to use toml-query * Made the `Updateable` trait more generic
1 parent e825357 commit a1b6ccc

File tree

5 files changed

+250
-73
lines changed

5 files changed

+250
-73
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ tempdir = "0.3.4"
3434
itertools = "0.7.4"
3535
tempfile = "2.2.0"
3636
shlex = "0.1.1"
37+
toml-query = "0.6"
3738

3839
# Watch feature
3940
notify = { version = "4.0", optional = true }

book-example/src/format/config.md

+40
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,43 @@ additional-js = ["custom.js"]
106106
editor = "./path/to/editor"
107107
editable = false
108108
```
109+
110+
111+
## Environment Variables
112+
113+
All configuration values van be overridden from the command line by setting the
114+
corresponding environment variable. Because many operating systems restrict
115+
environment variables to be alphanumeric characters or `_`, the configuration
116+
key needs to be formatted slightly differently to the normal `foo.bar.baz` form.
117+
118+
Variables starting with `MDBOOK_` are used for configuration. The key is
119+
created by removing the `MDBOOK_` prefix and turning the resulting
120+
string into `kebab-case`. Double underscores (`__`) separate nested
121+
keys, while a single underscore (`_`) is replaced with a dash (`-`).
122+
123+
For example:
124+
125+
- `MDBOOK_foo` -> `foo`
126+
- `MDBOOK_FOO` -> `foo`
127+
- `MDBOOK_FOO__BAR` -> `foo.bar`
128+
- `MDBOOK_FOO_BAR` -> `foo-bar`
129+
- `MDBOOK_FOO_bar__baz` -> `foo-bar.baz`
130+
131+
So by setting the `MDBOOK_BOOK__TITLE` environment variable you can
132+
override the book's title without needing to touch your `book.toml`.
133+
134+
> **Note:** To facilitate setting more complex config items, the value
135+
> of an environment variable is first parsed as JSON, falling back to a
136+
> string if the parse fails.
137+
>
138+
> This means, if you so desired, you could override all book metadata
139+
> when building the book with something like
140+
>
141+
> ```text
142+
> $ export MDBOOK_BOOK="{'title': 'My Awesome Book', authors: ['Michael-F-Bryan']}"
143+
> $ mdbook build
144+
> ```
145+
146+
The latter case may be useful in situations where `mdbook` is invoked
147+
from a script or CI, where it sometimes isn't possible to update the
148+
`book.toml` before building.

src/book/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@ impl MDBook {
5858
warn!("\thttps://rust-lang-nursery.github.io/mdBook/format/config.html");
5959
}
6060

61-
let config = if config_location.exists() {
61+
let mut config = if config_location.exists() {
6262
debug!("[*] Loading config from {}", config_location.display());
6363
Config::from_disk(&config_location)?
6464
} else {
6565
Config::default()
6666
};
6767

68+
config.update_from_env();
69+
6870
if log_enabled!(::log::Level::Trace) {
6971
for line in format!("Config: {:#?}", config).lines() {
7072
trace!("{}", line);

0 commit comments

Comments
 (0)