-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add some extra detail to docs #45
Conversation
This crate aims to help with reading configuration of application from files, environment variables and command line arguments, merging it together and validating. It auto-generates most of the code for you based on configuration (heh) file. It creates a struct for you, which contains all the parsed and validated fields, so you can access the information quickly easily and idiomatically. This is currently only a facade for the dependencies, the core of the crate is in `configure_me_codegen` crate. **Important:** In order to use this crate, you need to create a build script using `configure_me_codegen` to generate the code that will use this crate! See the example. Wait a second, why this crate doesn't use derive? ------------------------------------------------- I'd love to use derive. Unfortunately it doesn't compose well with man page generation and other tooling. For a longer version, see [docs/why\_not\_derive.md](docs/why_not_derive.md) Example ------- Let's say, your application needs these parametrs to run: * Port - this is mandatory * IP address to bind to - defaults to 0.0.0.0 * Path to TLS certificate - optional, the server will be unsecure if not given * RunFast - switch, if present the server will run in fast mode First create `config_spec.toml` configuration file specifying all the parameters: ```toml [[param]] # short param, e.g -p abbr = "p" # long arg, e.g --port name = "port" type = "u16" optional = false # This text will be used in the documentation (help etc) # It's not mandatory, but your progam will be ugly without it. doc = "Port to listen on." [[param]] name = "bind_addr" # merge from env var. e.g BIND_ADDR env_var = true # Yes, this works and you can use your own T: Deserialize + ParseArg as well! type = "::std::net::Ipv4Addr" default = "::std::net::Ipv4Addr::new(0, 0, 0, 0)" # Rust expression that creates the value doc = "IP address to bind to." [[param]] name = "tls_cert" type = "::std::path::PathBuf" doc = "Path to the TLS certificate. The connections will be unsecure if it isn't provided." # optional = true is the default, no need to add it here # If the type is optional, it will be represented as Option<T> # e.g. Option<::std::path::PathBuf> in this case. [[switch]] # switches are parsed as bools, true if present false otherwise name = "run_fast" doc = "Will make the server run in fast mode" ``` Then, create a simple build script: ```rust extern crate configure_me; fn main() { configure_me::build_script_auto().unwrap_or_exit(); } ``` Add dependencies to `Cargo.toml`: ```toml [package] # ... build = "build.rs" # This tells auto build script and other tools where to look for your specificcation [package.metadata.configure_me] spec = "config_spec.toml" [dependencies] configure_me = "0.3.3" [build-dependencies] configure_me_codegen = "0.3.3" ``` And finally add appropriate incantations into `src/main.rs`: ```rust #[macro_use] extern crate configure_me; include_config!(); fn main() { // This will read configuration from "/etc/my_awesome_server/server.conf" file, environment variables and // the command-line arguments. let (server_config, _remaining_args) = Config::including_optional_config_files(&["/etc/my_awesome_server/server.conf]").unwrap_or_exit(); // Your code here // E.g.: let listener = std::net::TcpListener::bind((server_config.bind_addr, server_config.port)).expect("Failed to bind socket"); } ``` Configuration ------------- Configuration of the code generation is set in the same toml file as the specification ```toml [general] # Prefix for all env vars - enables all env vars by default if present build = "build.rs" # The name of the parameter which, if specified causes parameter parsing to # immediately load a config file, parse it, and override all configuration # provided so far with that file. conf_file_param = "/path/to/conf/file.toml" ``` If you need to generate different files for multiple binaries, create a separate file for each binary and then define them separately in `Cargo.toml`: ```toml [package.metadata.configure_me.bin] # config for binary foo foo = "foo_config_spec.toml" # config for binary bar bar = "bar_config_spec.toml" ``` And include the file in `foo` like this: ```rust include_config!("foo"); ``` This needs to be specific because there's no way to detect binary name. License: MITNFA
Is the main README.md just a copy of the one in configure_me |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for contribution! I wanted to review it sooner but was unable to do so. I found some issues, even a few serious ones - those definitely need to be addressed.
Question, if I use the
conf_file_param
I find that options set in that config file overwrite options set in environment variables. Is that intentional?
Yes, it's intentional.
|
||
```rust | ||
extern crate configure_me_codegen; | ||
extern crate configure_me; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incorrect, it must be configure_me_codegen
in build script as mentioned above.
This particular case could be removed entirely thanks to edition 2018.
fn main() -> Result<(), configure_me_codegen::Error> { | ||
configure_me_codegen::build_script_auto() | ||
fn main() { | ||
configure_me::build_script_auto().unwrap_or_exit(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to stay configure_me_codegen
} | ||
``` | ||
|
||
*Tip: use [`cfg_me`](https://github.com/Kixunil/cfg_me) to generate a man page for your program.* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this removed? There's no way for people to generate man page without knowing about cfg_me
.
|
||
[build-dependencies] | ||
configure_me_codegen = "0.3.11" | ||
configure_me_codegen = "0.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, just realized I forgot to push the new version - 0.4
to git - it was in crates.io for a while. Pushed it now. Sorry about that.
@@ -92,24 +107,36 @@ extern crate configure_me; | |||
include_config!(); | |||
|
|||
fn main() { | |||
// Don't worry, unwrap_or_exit() prints a nice message instead of ugly panic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should still be mentioned, maybe using different wording?
```toml | ||
[general] | ||
# Prefix for all env vars - enables all env vars by default if present | ||
build = "build.rs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did git screw up the diff somehow? env var prefix is configured using env_prefix
, not build
//! ```toml | ||
//! [general] | ||
//! # Prefix for all env vars - enables all env vars by default if present | ||
//! build = "build.rs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same mistake as above
thanks for catching all of that, I think most of them are due to subtle differences between the documentation in the .rs and the documentation in the readme. I'll go back over it and clean things up and get them properly in sync. |
Ping, do you intend to continue working on this? |
Closing due to inactivity. Feel free to open a new one when you're ready. |
closes #44
This doesn't cover all functionality, but it covers a bunch of common use cases I had to figure out to use this crate for another project.
Question, if I use the
conf_file_param
I find that options set in that config file overwrite options set in environment variables. Is that intentional?