Skip to content
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

support custom config folder #1081

Merged
merged 4 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs-site/content/docs/the-app/your-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ The scaffold generator will build several files in your application:
| `assets/views/posts/show.html` | Show post template. only for HTML and HTMX templates. |

## Your app configuration
Configuration in `loco` lives in `config/` and by default sets up 3 different environments:
By default, loco stores its configuration files in the config/ directory. It provides predefined configurations for three environments:

```
config/
Expand All @@ -211,6 +211,9 @@ When nothing is given, the default value is `development`.

The `Loco` framework allows support for custom environments in addition to the default environment. To add a custom environment, create a configuration file with a name matching the environment identifier used in the preceding example.

### Overriding the Default Configuration Path
To use a custom configuration directory, set the `LOCO_CONFIG_FOLDER` environment variable to the desired folder path. This will instruct `loco` to load configuration files from the specified directory instead of the default `config/` folder.

### Placeholders / variables in config

It is possible to inject values into a configuration file. In this example, we get a port value from the `NODE_PORT` environment variable:
Expand Down
10 changes: 6 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,12 @@ impl Config {
path.join(format!("{env}.yaml")),
];

let selected_path = files
.iter()
.find(|p| p.exists())
.ok_or_else(|| Error::Message("no configuration file found".to_string()))?;
let selected_path = files.iter().find(|p| p.exists()).ok_or_else(|| {
Error::Message(format!(
"no configuration file found in folder: {}",
path.display()
))
})?;

info!(selected_path =? selected_path, "loading environment from");

Expand Down
5 changes: 2 additions & 3 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use tracing::info;
use super::Result as AppResult;
use crate::{
app::{AppContext, Hooks},
config, doctor,
config, doctor, env_vars,
errors::Error,
};

Expand Down Expand Up @@ -470,8 +470,7 @@ async fn create_postgres_database(
db_name: &str,
db: &DatabaseConnection,
) -> Result<(), sea_orm::DbErr> {
let with_options =
std::env::var("LOCO_POSTGRES_DB_OPTIONS").unwrap_or_else(|_| "ENCODING='UTF8'".to_string());
let with_options = env_vars::get_or_default(env_vars::POSTGRES_DB_OPTIONS, "ENCODING='UTF8'");

let query = format!("CREATE DATABASE {db_name} WITH {with_options}");
tracing::info!(query, "creating postgres database");
Expand Down
25 changes: 25 additions & 0 deletions src/env_vars.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! This module contains utility functions and constants for working with
//! environment variables in the application. It centralizes the logic for
//! fetching environment variables, ensuring that keys are easily accessible
//! from a single location in the codebase.

/// The key for `PostgreSQL` database options environment variable.
pub const POSTGRES_DB_OPTIONS: &str = "LOCO_POSTGRES_DB_OPTIONS";
/// The key for the application's environment (e.g., development, production).
pub const LOCO_ENV: &str = "LOCO_ENV";
/// The key for the application's environment (e.g., development, production).
pub const RAILS_ENV: &str = "RAILS_ENV";
/// The key for the application's environment (e.g., development, production).
pub const NODE_ENV: &str = "NODE_ENV";
// The key for the application environment configuration
pub const CONFIG_FOLDER: &str = "LOCO_CONFIG_FOLDER";

/// Fetches the value of the given environment variable.
pub fn get(key: &str) -> Result<String, std::env::VarError> {
std::env::var(key)
}

/// Retrieves the value of the given environment variable, or returns a default value if the variable is not set.
pub fn get_or_default(key: &str, default: &str) -> String {
get(key).unwrap_or_else(|_| default.to_string())
}
19 changes: 10 additions & 9 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
//! let config = environment.load().expect("failed to load environment");
//! }
//! ```
use std::{path::Path, str::FromStr};

use super::config::Config;
use crate::{env_vars, Result};
use serde::{Deserialize, Serialize};
use serde_variant::to_variant_name;

use super::config::Config;
use crate::Result;
use std::{path::Path, str::FromStr};

pub const DEFAULT_ENVIRONMENT: &str = "development";
pub const LOCO_ENV: &str = "LOCO_ENV";
Expand All @@ -33,9 +31,9 @@ impl From<String> for Environment {

#[must_use]
pub fn resolve_from_env() -> String {
std::env::var("LOCO_ENV")
.or_else(|_| std::env::var("RAILS_ENV"))
.or_else(|_| std::env::var("NODE_ENV"))
env_vars::get(env_vars::LOCO_ENV)
.or_else(|_| env_vars::get(env_vars::RAILS_ENV))
.or_else(|_| env_vars::get(env_vars::NODE_ENV))
.unwrap_or_else(|_| DEFAULT_ENVIRONMENT.to_string())
}

Expand All @@ -59,7 +57,10 @@ impl Environment {
/// Returns error if an error occurs during loading
/// configuration file an parse into [`Config`] struct.
pub fn load(&self) -> Result<Config> {
Config::new(self)
env_vars::get(env_vars::CONFIG_FOLDER).map_or_else(
|_| Config::new(self),
|config_folder| self.load_from_folder(Path::new(&config_folder)),
)
}

/// Load environment variables from the given config path
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ pub mod schema;
mod tera;

pub mod app;
#[cfg(feature = "cli")]
pub mod cli;

pub mod auth;
pub mod boot;
pub mod cache;
#[cfg(feature = "cli")]
pub mod cli;
pub mod config;
pub mod controller;
mod env_vars;
pub mod environment;
pub mod errors;
pub mod hash;
Expand Down
Loading