✨ Habilita a módulos inicializar su conf. predet.
This commit is contained in:
parent
466ea97186
commit
81852a66c8
5 changed files with 86 additions and 42 deletions
|
|
@ -38,6 +38,9 @@ impl Application {
|
||||||
// Registra acciones de los módulos.
|
// Registra acciones de los módulos.
|
||||||
module::all::register_actions();
|
module::all::register_actions();
|
||||||
|
|
||||||
|
// Inicializa valores predefinidos de configuración.
|
||||||
|
module::all::init_settings();
|
||||||
|
|
||||||
// Inicializa los módulos.
|
// Inicializa los módulos.
|
||||||
module::all::init_modules();
|
module::all::init_modules();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,32 @@
|
||||||
//! Gestión de la configuración.
|
//! Gestión de la configuración.
|
||||||
//!
|
//!
|
||||||
//! Carga la configuración de la aplicación en forma de pares `clave = valor` incluidos en archivos
|
//! Carga durante el arranque la configuración de la aplicación en forma de pares `clave = valor`
|
||||||
//! [TOML](https://toml.io).
|
//! recogidos en archivos [TOML](https://toml.io).
|
||||||
//!
|
//!
|
||||||
//! La metodología [The Twelve-Factor App](https://12factor.net/es/) define **la configuración de
|
//! La metodología [The Twelve-Factor App](https://12factor.net/es/) define **la configuración de
|
||||||
//! una aplicación como todo lo que puede variar entre despliegues**, distinguiendo entornos de
|
//! una aplicación como todo lo que puede variar entre despliegues**, diferenciando entre entornos
|
||||||
//! desarrollo, pre-producción, producción, etc.
|
//! de desarrollo, pre-producción, producción, etc.
|
||||||
//!
|
//!
|
||||||
//! A veces las aplicaciones guardan configuraciones como constantes en el código, lo que supone una
|
//! A veces las aplicaciones guardan configuraciones como constantes en el código, lo que supone una
|
||||||
//! violación de esta metodología. Es necesaria una **estricta separación de configuración y
|
//! violación de esta metodología. Debe existir una **estricta separación entre la configuración y
|
||||||
//! código**. La configuración varía sustancialmente en cada despliegue, el código no.
|
//! el código**. La configuración variará sustancialmente en cada despliegue, el código no.
|
||||||
//!
|
//!
|
||||||
//! PageTop aplica estos principios cargando la configuración asociada al modo de ejecución activo.
|
//! # Cómo usar archivos de configuración
|
||||||
//!
|
//!
|
||||||
//! # ¿Cómo usar los archivos de configuración?
|
//! Si tu aplicación requiere archivos de configuración debes crear un directorio llamado *config* al
|
||||||
//!
|
|
||||||
//! Si tu aplicación requiere ajustes de configuración debes crear un directorio llamado *config* al
|
|
||||||
//! mismo nivel del archivo *Cargo.toml* de tu proyecto (o del ejecutable binario de la aplicación).
|
//! mismo nivel del archivo *Cargo.toml* de tu proyecto (o del ejecutable binario de la aplicación).
|
||||||
//!
|
//!
|
||||||
//! Guarda la configuración usando archivos TOML asumiendo el siguiente orden de lectura secuencial
|
//! Guarda la configuración usando archivos TOML asumiendo el siguiente orden de lectura secuencial
|
||||||
//! (todos los archivos son opcionales):
|
//! (todos los archivos son opcionales):
|
||||||
//!
|
//!
|
||||||
//! 1. *config/common.toml*, útil para asignar los valores comunes a cualquier entorno. Estos
|
//! 1. *config/common.toml*, útil para los ajustes comunes para cualquier entorno. Estos valores
|
||||||
//! valores pueden ser modificados al fusionar los archivos de configuración siguientes.
|
//! podrán ser sobrescritos al fusionar los archivos de configuración siguientes.
|
||||||
//!
|
//!
|
||||||
//! 2. *config/{archivo}.toml*, donde *{archivo}* puede definirse mediante la variable de entorno
|
//! 2. *config/{archivo}.toml*, donde *{archivo}* puede definirse mediante la variable de entorno
|
||||||
//! PAGETOP_RUN_MODE:
|
//! PAGETOP_RUN_MODE:
|
||||||
//!
|
//!
|
||||||
//! * Si no está definida, se asumirá *default* como nombre predeterminado y PageTop cargará el
|
//! * Si no está definida, se asumirá *default* por defecto, y PageTop cargará el archivo de
|
||||||
//! archivo de configuración *config/default.toml* si existe.
|
//! configuración *config/default.toml* si existe.
|
||||||
//!
|
//!
|
||||||
//! * De esta manera, se pueden tener diferentes ajustes de configuración para diferentes
|
//! * De esta manera, se pueden tener diferentes ajustes de configuración para diferentes
|
||||||
//! entornos de ejecución. Por ejemplo, para *devel.toml*, *staging.toml* o *production.toml*.
|
//! entornos de ejecución. Por ejemplo, para *devel.toml*, *staging.toml* o *production.toml*.
|
||||||
|
|
@ -40,30 +38,53 @@
|
||||||
//!
|
//!
|
||||||
//! 3. *config/local.toml*, para añadir o sobrescribir ajustes.
|
//! 3. *config/local.toml*, para añadir o sobrescribir ajustes.
|
||||||
//!
|
//!
|
||||||
//! # ¿Cómo añadir valores de configuración predeterminados?
|
//! # Cómo añadir valores predefinidos de configuración
|
||||||
|
//!
|
||||||
|
//! Si nuestra **aplicación** o **módulo** requiere sus propios ajustes de configuración, es
|
||||||
|
//! recomendable (aunque no imprescindible) inicializarlos antes de su uso.
|
||||||
|
//!
|
||||||
|
//! Sólo tienes que añadir el método [`settings()`](crate::core::module::ModuleTrait::settings) al
|
||||||
|
//! implementar [`ModuleTrait`](crate::core::module::ModuleTrait) para tu módulo, devolviendo los
|
||||||
|
//! nuevos valores predefinidos con la macro [`predefined_settings!`].
|
||||||
|
//!
|
||||||
|
//! Cuando se carga la configuración de la aplicación, estos valores podrán ser sobrescritos con los
|
||||||
|
//! ajustes personalizados del entorno. Y sólo será realmente necesario incluir en los archivos de
|
||||||
|
//! configuración los ajustes que difieran de los predefinidos.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use pagetop::{config, default_settings};
|
//! use pagetop::prelude::*;
|
||||||
//!
|
//!
|
||||||
//! // Una aplicación o un módulo podrá añadir nuevos valores de configuración predeterminados.
|
//! pub_const_handler!(MY_MODULE_HANDLER);
|
||||||
//! config::add_defaults(default_settings![
|
//!
|
||||||
//! // [my_app]
|
//! pub struct MyModule;
|
||||||
//! "my_app.test_1" => "Test 1",
|
//!
|
||||||
//! "my_app.test_2" => "Test 2",
|
//! impl ModuleTrait for MyModule {
|
||||||
//! "my_app.passwd" => "Pass_1234",
|
//! fn handler(&self) -> Handler {
|
||||||
//! ]);
|
//! MY_MODULE_HANDLER
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn settings(&self) -> PredefinedSettings {
|
||||||
|
//! predefined_settings![
|
||||||
|
//! // Valores predefinidos para "my_module".
|
||||||
|
//! "my_module.name" => "Name",
|
||||||
|
//! "my_module.desc" => "Description",
|
||||||
|
//! // Valores predefinidos para "my_module.database".
|
||||||
|
//! "my_module.database.db_port" => "3306"
|
||||||
|
//! ]
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! # ¿Cómo leer los valores de configuración?
|
//! # Cómo obtener los valores de configuración
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use pagetop::config;
|
//! use pagetop::config;
|
||||||
//!
|
//!
|
||||||
//! // Obtiene el valor (String) de una clave.
|
//! // Obtiene el valor (String) de una clave.
|
||||||
//! let app_name: String = config::get("app.name");
|
//! let name: String = config::get("my_module.name");
|
||||||
//!
|
//!
|
||||||
//! // Obtiene el valor (del tipo especificado) de una clave.
|
//! // Obtiene el valor (del tipo especificado) de una clave.
|
||||||
//! let db_port: u16 = config::get_value::<u16>("database.db_port");
|
//! let db_port: u16 = config::get_value::<u16>("my_module.database.db_port");
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::{trace, LazyStatic};
|
use crate::{trace, LazyStatic};
|
||||||
|
|
@ -77,9 +98,12 @@ use std::fmt::Debug;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
pub type PredefinedSettings = HashMap<&'static str, &'static str>;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! default_settings {
|
macro_rules! predefined_settings {
|
||||||
( $($key:literal => $value:literal),* ) => {{
|
( $($key:literal => $value:literal),* ) => {{
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut a = std::collections::HashMap::new();
|
let mut a = std::collections::HashMap::new();
|
||||||
$(
|
$(
|
||||||
a.insert($key, $value);
|
a.insert($key, $value);
|
||||||
|
|
@ -120,8 +144,8 @@ static CONFIG: LazyStatic<Config> = LazyStatic::new(|| {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static DEFAULTS: LazyStatic<RwLock<HashMap<&str, &str>>> = LazyStatic::new(||
|
static DEFAULTS: LazyStatic<RwLock<PredefinedSettings>> = LazyStatic::new(||
|
||||||
RwLock::new(default_settings![
|
RwLock::new(predefined_settings![
|
||||||
// [app]
|
// [app]
|
||||||
"app.name" => "PageTop Application",
|
"app.name" => "PageTop Application",
|
||||||
"app.description" => "Developed with the amazing PageTop framework.",
|
"app.description" => "Developed with the amazing PageTop framework.",
|
||||||
|
|
@ -155,8 +179,8 @@ static DEFAULTS: LazyStatic<RwLock<HashMap<&str, &str>>> = LazyStatic::new(||
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Una aplicación o un módulo podrá añadir nuevos valores de configuración predeterminados.
|
/// Una aplicación o módulo podrá añadir nuevos valores predefinidos de configuración.
|
||||||
pub fn add_defaults(defaults: HashMap<&'static str, &'static str>) {
|
pub(crate) fn add_predefined_settings(defaults: PredefinedSettings) {
|
||||||
DEFAULTS.write().unwrap().extend(defaults);
|
DEFAULTS.write().unwrap().extend(defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use super::ModuleStaticRef;
|
use super::ModuleStaticRef;
|
||||||
|
use crate::config;
|
||||||
use crate::core::hook::add_action;
|
use crate::core::hook::add_action;
|
||||||
use crate::core::theme;
|
use crate::core::theme;
|
||||||
use crate::{app, trace, LazyStatic};
|
use crate::{app, trace, LazyStatic};
|
||||||
|
|
@ -85,6 +86,24 @@ pub fn register_actions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// INIT SETTINGS ***********************************************************************************
|
||||||
|
|
||||||
|
pub fn init_settings() {
|
||||||
|
trace::info!("initializing custom predefined settings");
|
||||||
|
for m in ENABLED_MODULES.read().unwrap().iter() {
|
||||||
|
config::add_predefined_settings(m.settings());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// INIT MODULES ************************************************************************************
|
||||||
|
|
||||||
|
pub fn init_modules() {
|
||||||
|
trace::info!("Calling application bootstrap");
|
||||||
|
for m in ENABLED_MODULES.read().unwrap().iter() {
|
||||||
|
m.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RUN MIGRATIONS **********************************************************************************
|
// RUN MIGRATIONS **********************************************************************************
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
|
|
@ -120,15 +139,6 @@ pub fn run_migrations() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// INIT MODULES ************************************************************************************
|
|
||||||
|
|
||||||
pub fn init_modules() {
|
|
||||||
trace::info!("Calling application bootstrap");
|
|
||||||
for m in ENABLED_MODULES.read().unwrap().iter() {
|
|
||||||
m.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CONFIGURE SERVICES ******************************************************************************
|
// CONFIGURE SERVICES ******************************************************************************
|
||||||
|
|
||||||
pub fn configure_services(cfg: &mut app::web::ServiceConfig) {
|
pub fn configure_services(cfg: &mut app::web::ServiceConfig) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::app;
|
use crate::app;
|
||||||
|
use crate::predefined_settings;
|
||||||
|
use crate::config::PredefinedSettings;
|
||||||
use crate::core::hook::HookAction;
|
use crate::core::hook::HookAction;
|
||||||
use crate::core::theme::ThemeStaticRef;
|
use crate::core::theme::ThemeStaticRef;
|
||||||
use crate::util::{single_type_name, Handler};
|
use crate::util::{single_type_name, Handler};
|
||||||
|
|
@ -40,14 +42,18 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn settings(&self) -> PredefinedSettings {
|
||||||
|
predefined_settings![]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(&self) {}
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn migrations(&self) -> Vec<MigrationItem> {
|
fn migrations(&self) -> Vec<MigrationItem> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self) {}
|
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn configure_service(&self, cfg: &mut app::web::ServiceConfig) {}
|
fn configure_service(&self, cfg: &mut app::web::ServiceConfig) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ pub use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::config;
|
pub use crate::config;
|
||||||
|
pub use crate::config::PredefinedSettings;
|
||||||
|
|
||||||
pub use crate::trace;
|
pub use crate::trace;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue