Settings refactor#481
Conversation
WalkthroughThe changes reorganize the application's configuration management by moving all settings-related logic from Changes
Sequence Diagram(s)sequenceDiagram
participant Main
participant ConfigUtil
participant ConfigSettings
participant GlobalConfig
Main->>ConfigUtil: init_configuration_file(config_path)
ConfigUtil->>ConfigUtil: Create config dir if missing
ConfigUtil-->>Main: Return or create config path and settings file
Main->>ConfigSettings: Settings::new(config_path)
ConfigSettings->>ConfigSettings: Load and merge config file & env vars
ConfigSettings->>GlobalConfig: init_mostro_settings(settings)
GlobalConfig-->>ConfigSettings: Store settings globally
ConfigSettings-->>Main: Return Settings instance
Main->>GlobalConfig: Access config via getters (e.g., get_ln, get_db)
GlobalConfig-->>Main: Return requested config section
Suggested reviewers
Poem
Tip ⚡️ Faster reviews with caching
Enjoy the performance boost—your workflow just got faster. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (5)
src/config/settings.rs (1)
52-67: Consider safer accessor methods to avoid potential panicsThe getter methods use
unwrap()which could panic if the global config hasn't been initialized. Consider usingResultorOptionreturn types or documenting that these should only be called after initialization.impl Settings { // ... - pub fn get_ln() -> Lightning { - MOSTRO_CONFIG.get().unwrap().lightning.clone() + pub fn get_ln() -> Option<Lightning> { + MOSTRO_CONFIG.get().map(|config| config.lightning.clone()) } - pub fn get_mostro() -> Mostro { - MOSTRO_CONFIG.get().unwrap().mostro.clone() + pub fn get_mostro() -> Option<Mostro> { + MOSTRO_CONFIG.get().map(|config| config.mostro.clone()) } - pub fn get_db() -> Database { - MOSTRO_CONFIG.get().unwrap().database.clone() + pub fn get_db() -> Option<Database> { + MOSTRO_CONFIG.get().map(|config| config.database.clone()) } - pub fn get_nostr() -> Nostr { - MOSTRO_CONFIG.get().unwrap().nostr.clone() + pub fn get_nostr() -> Option<Nostr> { + MOSTRO_CONFIG.get().map(|config| config.nostr.clone()) } }Alternatively, you could keep the current implementation but add a documentation comment explaining that these methods should only be called after
init_global_settingshas been called.src/config/types.rs (4)
1-3: Fix redundant comments.The file starts with two nearly identical comments. Consider consolidating them into a single comprehensive documentation comment to better describe the purpose and content of this file.
-// File with the types for the configuration settings -// Initialize the types for the configuration settings +/// This file defines the configuration data structures used throughout the application +/// and implements conversions between them and the main Settings type.
6-7: Fix incorrect doc comment syntax.The current format
// /is not valid Rust documentation syntax. Use///for documentation comments.-// / Implement the TryFrom trait for each of the structs in Settings -// / This allows you to convert from Settings to each of the structs directly. +/// Implement the TryFrom trait for each of the structs in Settings +/// This allows you to convert from Settings to each of the structs directly.
4-5: Consider adding more specific imports.The code only imports
Deserializefromserde, but in the future you might need other traits likeSerialize. Consider using more explicit imports or a wildcard import if more serde traits might be needed.-use serde::Deserialize; +use serde::{Deserialize, Serialize};Or alternatively:
-use serde::Deserialize; +use serde::*;
45-58: Consider grouping related configuration fields.The
Mostrostruct contains many fields with different purposes. Consider grouping related fields into nested structs for better organization and readability.Example:
#[derive(Debug, Deserialize, Default, Clone)] pub struct Fees { pub fee: f64, pub max_routing_fee: f64, } #[derive(Debug, Deserialize, Default, Clone)] pub struct Limits { pub max_order_amount: u32, pub min_payment_amount: u32, } #[derive(Debug, Deserialize, Default, Clone)] pub struct Mostro { pub fees: Fees, pub limits: Limits, pub expiration_hours: u32, // other fields... }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (16)
src/app.rs(1 hunks)src/app/order.rs(1 hunks)src/app/release.rs(1 hunks)src/cli.rs(1 hunks)src/cli/settings.rs(0 hunks)src/config/mod.rs(1 hunks)src/config/settings.rs(1 hunks)src/config/types.rs(1 hunks)src/config/util.rs(1 hunks)src/db.rs(1 hunks)src/lightning/invoice.rs(1 hunks)src/lightning/mod.rs(1 hunks)src/main.rs(2 hunks)src/nip33.rs(1 hunks)src/scheduler.rs(1 hunks)src/util.rs(1 hunks)
💤 Files with no reviewable changes (1)
- src/cli/settings.rs
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/cli.rs (1)
src/config/util.rs (1)
init_default_dir(51-76)
src/main.rs (1)
src/config/settings.rs (1)
init_global_settings(18-20)
src/config/util.rs (3)
src/config/settings.rs (1)
new(23-50)src/lightning/mod.rs (1)
new(41-55)src/app.rs (1)
e(355-355)
src/config/mod.rs (2)
src/config/settings.rs (1)
init_global_settings(18-20)src/config/util.rs (1)
init_default_dir(51-76)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: tests
🔇 Additional comments (22)
src/app/order.rs (1)
1-1: Import path updated to the newconfigmodule
TheSettingsstruct is now correctly imported fromcrate::config::settings::Settings, matching the refactored configuration layout.src/app/release.rs (1)
1-1: Import path updated to the newconfigmodule
TheSettingsstruct import has been updated fromcli::settingstoconfig::settings, aligning with the modularized configuration system.src/scheduler.rs (1)
3-3: Import path updated to the newconfigmodule
The importuse crate::config::settings::Settings;correctly reflects the relocation of configuration logic intosrc/config.src/lightning/invoice.rs (1)
1-1: Import path updated to the newconfigmodule
Switching theSettingsimport tocrate::config::settings::Settingsmaintains consistency with the refactored settings organization.src/db.rs (1)
21-21: Import path updated to the newconfigmodule
TheSettingsstruct is now being imported fromcrate::config::settings::Settings, which matches the updated config module structure.src/lightning/mod.rs (1)
3-3: Update import path for Settings
The import path for theSettingsstruct was correctly updated to point to the newconfig::settingsmodule, aligning with the refactor of the Settings module intosrc/config.src/main.rs (2)
4-4: Expose newconfigmodule at crate root
Addingpub mod config;makes the reorganized configuration submodules (settings,types,util) available at the crate root, which is the intended entry point for configuration management.
17-17: Update import path forinit_global_settingsandSettings
The imports have been updated to reflect the move ofSettingsand its initializer intoconfig::settings. This maintains correct linkage and ensures configuration is initialized from the new module.src/util.rs (1)
2-2: Update import path for Settings
TheSettingsstruct import now referencescrate::config::settings::Settings, matching the new module hierarchy after refactoring.src/app.rs (1)
36-36: Update import path for Settings
The import ofSettingshas been updated tocrate::config::settings::Settings, aligning with the relocated configuration code.src/nip33.rs (1)
1-1: Update import path for Settings
Correctly updated to importSettingsfrom the newconfig::settingsmodule, keeping configuration access consistent.src/cli.rs (2)
1-5: Good refactoring of import pathsThe import path has been correctly updated to use the new
config::utilmodule instead of the oldcli::settingsmodule, which aligns with the refactoring goal. The header comments are also useful for documenting the CLI's purpose.
34-42: Implementation looks correct after refactoringThe
settings_init()function correctly uses the refactoredinit_default_dirfunction from the new location. The function's implementation remains unchanged which is good for maintaining compatibility.src/config/mod.rs (2)
1-7: Well-structured module organizationThe new module structure is clean and follows good separation of concerns by dividing configuration into logical components: settings, types, and utilities. The doc comments clearly explain the module's purpose.
8-11: Good use of re-exports for API simplicityRe-exporting the key types and functions from submodules creates a clean public API. This approach makes the module easier to use while maintaining internal organization.
src/config/util.rs (3)
1-17: Well-documented utility module with clear importsThe module documentation clearly explains its purpose, and the imports are well-organized with appropriate platform-specific conditional compilation.
18-26: Platform-specific implementations for path handlingGood use of conditional compilation to handle platform differences in path separators. The code correctly handles Windows and Unix path conventions.
28-46: Path manipulation logic is well-implementedThe implementation correctly appends platform-specific trailing slashes to paths, with proper capacity allocation for the new string and fallback handling when the path has no filename component.
src/config/settings.rs (3)
1-15: Well-structured Settings implementationThe Settings struct is well-organized with clear domain separation into database, nostr, mostro, and lightning components. The imports correctly reference the types from the new module structure.
17-20: Simple global settings initializationThe global settings initialization function is concise and appropriately unwraps the result since this is a critical operation that should fail if unsuccessful.
22-50: Config loading implementation looks goodThe
newmethod correctly handles different run modes and properly uses the utility functionshas_trailing_slashandadd_trailing_slash. The configuration loading leverages the config crate with appropriate environment variable overrides.src/config/types.rs (1)
60-66: LGTM: Clear macro usage.The macro invocation is clear and correctly implements the
TryFromtrait for all configuration structs.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
src/config/util.rs (3)
1-5: Prefer Rust-doc comments over free-form// /commentsThe file-header comments start with a peculiar
// /prefix, which is not picked up byrustdoc.
Switching to idiomatic//!(module-level) or///(item-level) comments will allow the documentation to be rendered bycargo docand IDEs.-// / Utility functions for the config module -// / This module provides utility functions for the config module. -// / It includes functions to initialize the default settings directory and create a settings file from the template if it doesn't exist. -// / It also includes functions to add a trailing slash to a path if it doesn't already have one. +//! Utility helpers for the `config` module. +//! +//! * `init_default_dir` – creates `~/.mostro` (or a user-supplied path) on first run. +//! * `has_trailing_slash` / `add_trailing_slash` – path helpers that behave +//! consistently on Unix and Windows.
18-26: Avoid hard-coding separators; lean onMAIN_SEPARATOR
b'\\'andb'/'work, but the intent is clearer (and one branch can be removed) if we compare against the platform’s canonical separator supplied by std lib.-#[cfg(windows)] -pub fn has_trailing_slash(p: &Path) -> bool { - let last = p.as_os_str().encode_wide().last(); - last == Some(b'\\' as u16) || last == Some(b'/' as u16) -} +#[cfg(windows)] +pub fn has_trailing_slash(p: &Path) -> bool { + use std::path::MAIN_SEPARATOR; + let last = p.as_os_str().encode_wide().last(); + last == Some(MAIN_SEPARATOR as u16) +}If you still want to treat
/as valid on Windows, add a comment explaining why.
This keeps the function short, removes the magic numbers and improves readability.
68-72: Use structured logging instead ofprintln!Elsewhere in the codebase you already employ
tracing::info!.
Uniform logging makes it easier to redirect output and to keep stdout clean for TUI/CLI interactions.- println!( + tracing::info!( "Created settings file from template at {} for mostro - Edit it to configure your Mostro instance", config_path.display() - ); + );src/config/settings.rs (1)
64-82: Getter methods clone the entire sub-config each timeCloning small structs is cheap, but if these grow (e.g., include TLS certs or big strings) it becomes wasteful.
Two options:
- Return
&'staticreferences (&'static Lightning) usingMOSTRO_CONFIG.get().unwrap().- Expose the entire
Settingsonce and let callers borrow what they need.Not urgent, but worth considering for larger deployments.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/config/settings.rs(1 hunks)src/config/util.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/config/util.rs (1)
Learnt from: arkanoider
PR: MostroP2P/mostro#481
File: src/config/util.rs:48-76
Timestamp: 2025-05-02T14:21:39.391Z
Learning: The `init_default_dir` function in Mostro intentionally exits the process (std::process::exit(0)) after creating a new configuration file so users can edit the configuration before restarting the application.
🧬 Code Graph Analysis (1)
src/config/util.rs (1)
src/config/settings.rs (1)
new(23-62)
🔇 Additional comments (3)
src/config/util.rs (1)
55-58:HOMEis Unix-specific – fall back to a cross-platform solutionWindows often lacks the
HOMEenv var; the canonical variables areUSERPROFILEorHOMEDRIVE+HOMEPATH. Consider thedirs/homecrate or manual fallback:- let home = std::env::var("HOME") - .map_err(|e| MostroInternalErr(ServiceError::EnvVarError(e.to_string())))?; + let home = std::env::var("HOME") + .or_else(|_| std::env::var("USERPROFILE")) + .map_err(|e| MostroInternalErr(ServiceError::EnvVarError(e.to_string())))?;Failing to locate a home directory on Windows will currently crash the application even when a custom path is later supplied.
[ suggest_essential_refactor ]src/config/settings.rs (2)
17-20:init_global_settingswill panic if called twice
OnceCell::set(behindMOSTRO_CONFIG) panics on the second call.
If multiple integration tests (or a reload command) callinit_global_settings, the process will abort. Consider returning aResult<(), ()>or simply ignoring subsequent calls:-pub fn init_global_settings(s: Settings) { - MOSTRO_CONFIG.set(s).unwrap() +pub fn init_global_settings(s: Settings) -> Result<(), Settings> { + MOSTRO_CONFIG.set(s) }
49-58: Database URL points to a directory, not a file
sqlite://{path}/is not a valid Diesel/sqlx URL – it expects a file, e.g.sqlite://{path}/mostro.db.
Either append the DB filename here or document that downstream code appends it later.- .set_override( - "database.url", - format!("sqlite://{}", config_path.display()), - )? + .set_override( + "database.url", + format!("sqlite://{}/mostro.db", config_path.display()), + )?
- removed config dep and added more basic serde toml deserializer - removing cloning of Mostro Settings params - improve readability
- added some unit testing to config module to verify different parts of mostro settings struct - improved readability and removed cloning in getter functions of Mostro settings.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (3)
src/config/util.rs (3)
19-27: Use consistent logging approachThe
create_template_filefunction usesprintln!for logging, whileinit_default_diruses a mix ofprintln!and structured logging (as suggested by the previous review comments). Consider using the same logging approach throughout the codebase for consistency.- println!("Settings file not found - creating default settings file"); + tracing::info!("Settings file not found - creating default settings file"); std::fs::write(file_name, include_bytes!("../../settings.tpl.toml")) .expect("Failed to write template file"); // Print a message to the user - println!( + tracing::info!( "Created settings file from template at {} for Mostro", config_path.display() ); - println!("Please edit the settings file with your settings and run Mostro again"); + tracing::info!("Please edit the settings file with your settings and run Mostro again");
27-27: Fix typo in messageThere's an extra space in "with your settings".
- println!("Please edit the settings file with your settings and run Mostro again"); + println!("Please edit the settings file with your settings and run Mostro again");
68-71: Inconsistent use of "mostro" vs "Mostro" in log messagesThe message uses both lowercase "mostro" and uppercase "Mostro". Consider standardizing on one capitalization style for consistency.
- "Created settings file from template at {} for mostro - Edit it to configure your Mostro instance", + "Created settings file from template at {} for Mostro - Edit it to configure your Mostro instance",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/config/mod.rs(1 hunks)src/config/settings.rs(1 hunks)src/config/util.rs(1 hunks)src/lightning/invoice.rs(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lightning/invoice.rs
- src/config/mod.rs
- src/config/settings.rs
🔇 Additional comments (1)
src/config/util.rs (1)
72-72: Process exit in library function is intentionalIn accordance with the previous discussion in PR comments, the process exit is intentional as part of the application's configuration workflow. This is a valid pattern for CLI applications where users need to edit the config and restart.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- removed some parts of init functions: now just a single init is called from main. - added dirs crate to manage multiOs home folder
|
@coderabbitai please review |
|
Tip For best results, initiate chat on the files or code changes. @arkanoider I've reviewed your "Settings refactor" PR and I'm impressed with the improvements you've made to the codebase organization. Here's my assessment: What I like
Suggestions
Overall, this is a solid refactoring that improves code maintainability without changing core functionality. The code is now more modular, easier to navigate, and follows better Rust practices by separating different concerns into appropriate modules. |
Let me know if you see something to improve! |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/config/util.rs (3)
34-38: Consider using tracing instead of println for consistencyYou're using
tracing::info!for the success message at the end of the function, butprintln!for the configuration template creation message. For consistency, consider using the tracing framework throughout.- println!( - "Created settings file from template at {} for Mostro - Edit it to configure your Mostro instance", - config_file_path.display() - ); + tracing::info!( + "Created settings file from template at {} for Mostro - Edit it to configure your Mostro instance", + config_file_path.display() + );
45-46: Consider using a more specific error type for TOML parsingThe current implementation wraps the TOML parsing error as an
IOError, which isn't technically accurate. Consider using a more specific error type for parsing errors to provide better diagnostics.- let mut settings: Settings = toml::from_str(&contents) - .map_err(|e| MostroInternalErr(ServiceError::IOError(e.to_string())))?; + let mut settings: Settings = toml::from_str(&contents) + .map_err(|e| MostroInternalErr(ServiceError::ParseError(e.to_string())))?;This assumes you have a
ParseErrorvariant in yourServiceErrorenum. If not, you might want to consider adding one.
49-49: Consider making the database filename configurableThe database filename "mostro.db" is hardcoded. Consider either:
- Making it configurable through the settings file
- Using a constant at the module level for better maintainability
+const DB_FILENAME: &str = "mostro.db"; + // Later in the code: - settings.database.url = format!("sqlite://{}", settings_dir.join("mostro.db").display()); + settings.database.url = format!("sqlite://{}", settings_dir.join(DB_FILENAME).display());
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/config/util.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/config/util.rs (1)
Learnt from: arkanoider
PR: MostroP2P/mostro#481
File: src/config/util.rs:48-76
Timestamp: 2025-05-02T14:21:39.391Z
Learning: The `init_default_dir` function in Mostro intentionally exits the process (std::process::exit(0)) after creating a new configuration file so users can edit the configuration before restarting the application.
🧬 Code Graph Analysis (1)
src/config/util.rs (1)
src/config/settings.rs (1)
init_mostro_settings(15-19)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: tests
🔇 Additional comments (2)
src/config/util.rs (2)
38-38: Process exit is correctly implemented as intendedThe intentional process exit after creating the configuration template is a deliberate design decision to allow users to edit the configuration before restarting the application, as noted in the retrieved learnings.
1-57: Good overall implementation of configuration managementThis utility function correctly implements the configuration initialization workflow with proper error handling, cross-platform compatibility through the
dirscrate, and appropriate process management. The code is well-documented and follows the intended design patterns for the application.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
@grunch if you like this and we could merge i 'd like to do another improvement having the |
grunch
left a comment
There was a problem hiding this comment.
tACK
great job @arkanoider and @coderabbitai 🐰 😃
@grunch ,
refactored Settings module in a more readable way (imo) . I called the module
ConfigThis goes in the sense of having Mostrod always more readable and without long files.
Let me know your opinion.
Summary by CodeRabbit