Merge pull request 'Rendre le système de fichier de configuration runtime fonctionnel en dev et en release' (#56) from fix/55_move_env_config_into_consistent_dirs into main
Reviewed-on: #56 Reviewed-by: kosssi <simon@p4pillon.org> # Détails - Rajoute une librairie d'utilitaires crates/utils - Rajoute des fonctions de gestion des fichiers et dossiers de configuration dans la lib utils, dont une fonction de chargement du fichier de config approprié - Remplace le chargement d'un .env relatif au CARGO_MANIFEST_DIR de la librairie sesam-vitale par la fonction de chargement de config La fonction de chargement de config génère une hiérarchie d'emplacements de fichiers de config (.env dans : dossier courant, dossier manifest, dossier système) et charge le "plus proche", afin de permettre d'avoir une configuration stable au niveau système, mais de pouvoir la surcharger facilement en local, en particulier lors de phases de développement). Pourquoi ? L'usage de CARGO_MANIFEST_DIR pour trouver le fichier de configuration n'était pas viable, car cette variable d'environnement n'existe que lors d'un lancement via cargo run, mais pas lors d'un appel direct à l'executable buildé. La nouvelle implémentation est maintenant totalement compatible, autant avec des approches de surcharge en développement que pour de installations pérennes sur un système. # Documentation Le chemin standard des fichiers de config, spécifique à chaque OS, est obtenu à l'aide de la librairie directories-rs Closes #55
This commit is contained in:
commit
ca2a0ace71
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,3 +21,5 @@ target/
|
|||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# Ignore .env files
|
||||||
|
.env
|
||||||
|
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -1097,6 +1097,15 @@ dependencies = [
|
|||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "directories"
|
||||||
|
version = "5.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys 0.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
@ -3951,6 +3960,7 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"libc",
|
"libc",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5068,6 +5078,15 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"directories",
|
||||||
|
"dotenv",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -3,5 +3,6 @@ resolver = "2"
|
|||||||
members = [
|
members = [
|
||||||
"crates/app",
|
"crates/app",
|
||||||
"crates/sesam-vitale",
|
"crates/sesam-vitale",
|
||||||
"crates/desktop"
|
"crates/desktop",
|
||||||
|
"crates/utils",
|
||||||
]
|
]
|
||||||
|
14
README.md
14
README.md
@ -7,6 +7,20 @@ Logiciel de Pharmacie libre et open-source.
|
|||||||
- `app`: Interface du logiciel, servie par un serveur web propulsé par Axum. Utilisable en mode endpoint ou encapsulé dans le client `desktop`
|
- `app`: Interface du logiciel, servie par un serveur web propulsé par Axum. Utilisable en mode endpoint ou encapsulé dans le client `desktop`
|
||||||
- `desktop`: Client desktop propulsé par Tauri, encapsulant le serveur web `app`
|
- `desktop`: Client desktop propulsé par Tauri, encapsulant le serveur web `app`
|
||||||
- `sesam-vitale`: Bibliothèque de gestion des services SESAM-Vitale (Lecture des cartes CPS et Vitale, téléservices ...)
|
- `sesam-vitale`: Bibliothèque de gestion des services SESAM-Vitale (Lecture des cartes CPS et Vitale, téléservices ...)
|
||||||
|
- `utils`: Bibliothèque de fonctions utilitaires
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Fichiers de configuration
|
||||||
|
|
||||||
|
Certaines librairies nécessitent de définir certaines paramètres de configuration pour fonctionner correctement, en particulier le moteur SESAM-Vitale.
|
||||||
|
|
||||||
|
Ces paramètres sont définis dans un fichier de configuration `.env` situé dans un des dossiers suivant (par ordre de priorité) :
|
||||||
|
- dans le dossier courant (`./.env`)
|
||||||
|
- dans le dossier du manifeste (par exemple `crates/sesam-vitale/.env`)
|
||||||
|
- dans le dossier de configuration standard de l'OS (par exemple, sur linux, `~/.config/krys4lide/.env` - [plus d'info](https://github.com/dirs-dev/directories-rs?tab=readme-ov-file#projectdirs))
|
||||||
|
|
||||||
|
Des exemples de fichiers de configuration sont disponibles à la racine du projet : `.env.linux.example` et `.env.win.example`.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0"
|
||||||
dotenv = "0.15"
|
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
thiserror = "1.0.63"
|
thiserror = "1.0"
|
||||||
|
utils = { path = "../utils" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
extern crate dotenv;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use dotenv::from_path;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Load the .env.build file for build-time environment variables
|
// Load the .env.build file for build-time environment variables
|
||||||
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR must be set");
|
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR must be set");
|
||||||
let manifest_path = PathBuf::from(manifest_dir);
|
let manifest_path = PathBuf::from(manifest_dir);
|
||||||
dotenv::from_path(manifest_path.join(".env.build")).ok();
|
from_path(manifest_path.join(".env.build")).ok();
|
||||||
|
|
||||||
println!("cargo::rerun-if-env-changed=SESAM_FSV_LIB_PATH");
|
println!("cargo::rerun-if-env-changed=SESAM_FSV_LIB_PATH");
|
||||||
println!("cargo::rerun-if-env-changed=SESAM_FSV_SSVLIB");
|
println!("cargo::rerun-if-env-changed=SESAM_FSV_SSVLIB");
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
/// High level API for the SSV library,
|
/// High level API for the SSV library,
|
||||||
/// based on the low level bindings in libssv.rs.
|
/// based on the low level bindings in libssv.rs.
|
||||||
extern crate dotenv;
|
|
||||||
use libc::{c_void, size_t};
|
use libc::{c_void, size_t};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::cps::lire_carte;
|
use crate::cps::lire_carte;
|
||||||
use crate::libssv::{SSV_InitLIB2, SSV_LireConfig};
|
use crate::libssv::{SSV_InitLIB2, SSV_LireConfig};
|
||||||
|
|
||||||
|
use ::utils::config::load_config;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum SSVDemoError {
|
pub enum SSVDemoError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
@ -66,12 +66,11 @@ fn ssv_lire_config() -> Result<(), SSVDemoError> {
|
|||||||
pub fn demo() -> Result<(), SSVDemoError> {
|
pub fn demo() -> Result<(), SSVDemoError> {
|
||||||
// TODO : this is probably not working on release, because I'm not sure it exists a CARGO_MANIFEST_DIR and so it can find the `.env`
|
// TODO : this is probably not working on release, because I'm not sure it exists a CARGO_MANIFEST_DIR and so it can find the `.env`
|
||||||
// Maybe we could use a system standard config path to store a config file
|
// Maybe we could use a system standard config path to store a config file
|
||||||
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR must be set");
|
|
||||||
let manifest_path = PathBuf::from(manifest_dir);
|
|
||||||
dotenv::from_path(manifest_path.join(".env")).ok();
|
|
||||||
|
|
||||||
println!("------- Demo for the SSV library --------");
|
println!("------- Demo for the SSV library --------");
|
||||||
|
|
||||||
|
load_config()?;
|
||||||
|
|
||||||
ssv_init_lib_2()?;
|
ssv_init_lib_2()?;
|
||||||
|
|
||||||
let code_pin = "1234";
|
let code_pin = "1234";
|
||||||
|
9
crates/utils/Cargo.toml
Normal file
9
crates/utils/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
|
directories = "5.0"
|
||||||
|
dotenv = "0.15"
|
48
crates/utils/src/config.rs
Normal file
48
crates/utils/src/config.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
use anyhow::{bail, Context, Result};
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
use dotenv::from_path;
|
||||||
|
|
||||||
|
const CONFIG_FILE_NAME: &str = ".env";
|
||||||
|
|
||||||
|
pub fn get_config_dirs() -> Vec<PathBuf> {
|
||||||
|
let mut config_dirs = vec![
|
||||||
|
PathBuf::from(""), // Current directory
|
||||||
|
];
|
||||||
|
if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
|
||||||
|
config_dirs.push(PathBuf::from(manifest_dir));
|
||||||
|
}
|
||||||
|
if let Some(proj_dirs) = ProjectDirs::from("org", "P4pillon", "Krys4lide") {
|
||||||
|
config_dirs.push(proj_dirs.config_dir().to_path_buf());
|
||||||
|
}
|
||||||
|
config_dirs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_config_files() -> Result<Vec<PathBuf>> {
|
||||||
|
let config_dirs = get_config_dirs();
|
||||||
|
let mut config_files = Vec::new();
|
||||||
|
for config_dir in config_dirs.iter() {
|
||||||
|
let config_file = config_dir.join(CONFIG_FILE_NAME);
|
||||||
|
if config_file.exists() {
|
||||||
|
config_files.push(config_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if config_files.is_empty() {
|
||||||
|
bail!(
|
||||||
|
"No config file {CONFIG_FILE_NAME} found in the following directories: {config_dirs:#?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(config_files)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_config() -> Result<()> {
|
||||||
|
let config_files = get_config_files()?;
|
||||||
|
// Load the first config file found
|
||||||
|
// TODO: add a verbose log to list all config files found
|
||||||
|
println!(
|
||||||
|
"DEBUG: Config files found (1st loaded): {:#?}",
|
||||||
|
config_files
|
||||||
|
);
|
||||||
|
from_path(config_files[0].as_path()).context("Failed to load config file")
|
||||||
|
}
|
1
crates/utils/src/lib.rs
Normal file
1
crates/utils/src/lib.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod config;
|
Loading…
Reference in New Issue
Block a user