Merge pull request #50 from vowstar/global-configuration

feat(config): add global configuration support
This commit is contained in:
Sahaj Jain 2025-03-20 16:08:25 +05:30 committed by GitHub
commit 6c0be23fe6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 120 additions and 12 deletions

94
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "addr2line"
@ -215,6 +215,27 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.59.0",
]
[[package]]
name = "encoding_rs"
version = "0.8.35"
@ -315,6 +336,17 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.31.1"
@ -494,6 +526,16 @@ version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@ -522,12 +564,13 @@ version = "1.8.0"
dependencies = [
"async-trait",
"clap",
"dirs",
"indoc",
"reqwest",
"serde",
"serde_json",
"spinoff",
"thiserror",
"thiserror 1.0.65",
"tokio",
]
@ -640,6 +683,12 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -695,9 +744,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "proc-macro2"
version = "1.0.89"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
@ -720,6 +769,17 @@ dependencies = [
"bitflags 2.6.0",
]
[[package]]
name = "redox_users"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
"getrandom",
"libredox",
"thiserror 2.0.12",
]
[[package]]
name = "reqwest"
version = "0.11.27"
@ -935,9 +995,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.85"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@ -990,7 +1050,16 @@ version = "1.0.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.65",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl 2.0.12",
]
[[package]]
@ -1004,6 +1073,17 @@ dependencies = [
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tinyvec"
version = "1.8.0"

View file

@ -18,6 +18,7 @@ async-trait = "0.1.83"
spinoff = { version = "0.8.0", features = ["dots"] }
thiserror = "1.0"
indoc = "2.0.5"
dirs = "6.0.0"
[profile.release]
lto = true

View file

@ -166,7 +166,20 @@ export LUMEN_AI_MODEL="gpt-4o"
## Advanced Configuration 🔅
### Configuration File
Create a `lumen.config.json` at your project root or specify a custom path with `--config`:
Lumen supports configuration through a JSON file. You can place the configuration file in one of the following locations:
1. Project Root: Create a lumen.config.json file in your project's root directory.
2. Custom Path: Specify a custom path using the --config CLI option.
3. Global Configuration (Optional): Place a lumen.config.json file in your system's default configuration directory:
- Linux/macOS: `~/.config/lumen/lumen.config.json`
- Windows: `%USERPROFILE%\.config\lumen\lumen.config.json`
Lumen will load configurations in the following order of priority:
1. CLI arguments (highest priority)
2. Configuration file specified by --config
3. Project root lumen.config.json
4. Global configuration file (lowest priority)
```json
{

View file

@ -1,5 +1,6 @@
use crate::config::cli::ProviderType;
use crate::error::LumenError;
use dirs::home_dir;
use indoc::indoc;
use serde::{Deserialize, Deserializer};
use serde_json::from_reader;
@ -92,12 +93,25 @@ fn default_draft_config() -> DraftConfig {
}
}
fn default_config_path() -> Option<String> {
home_dir().and_then(|mut path| {
path.push(".config/lumen/lumen.config.json");
path.exists()
.then(|| path)
.and_then(|p| p.to_str().map(|s| s.to_string()))
})
}
impl LumenConfig {
pub fn build(cli: &Cli) -> Result<Self, LumenError> {
let config = cli.config.as_ref().map_or_else(
|| Ok(LumenConfig::default()),
|path| LumenConfig::from_file(path),
)?;
let config = if let Some(config_path) = &cli.config {
LumenConfig::from_file(config_path)?
} else {
match default_config_path() {
Some(path) => LumenConfig::from_file(&path)?,
None => LumenConfig::default(),
}
};
let provider = cli.provider.as_ref().cloned().unwrap_or(config.provider);
let api_key = cli.api_key.clone().or(config.api_key);