diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..bb10507 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +GH_GPT_GITHUB_TOKEN="..." +GH_GPT_OPENAI_API_KEY="..." \ No newline at end of file diff --git a/.gitignore b/.gitignore index 196e176..4634afb 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,6 @@ Cargo.lock # Added by cargo - /target + +.env diff --git a/Cargo.toml b/Cargo.toml index ea47ec1..aab7714 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,14 @@ edition = "2021" [dependencies] clap = {version = "4.2.7", features = ["derive"]} +color-eyre = "0.6.2" +config = "0.13.3" +dotenv = "0.15.0" env_logger = "0.10.0" +lazy_static = "1.4.0" log = "0.4.17" +serde = "1.0.163" +serde_derive = "1.0.163" + +[profile.dev.package.backtrace] +opt-level = 3 diff --git a/src/config.rs b/src/config.rs index 2da9ff6..a2fceb3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,14 +1,27 @@ //! General configuration -/// Configuration for the application. -#[derive(Debug, Default)] -pub struct Config { - pub api_keys: ApiKeys, -} +use color_eyre::eyre::Result; +use config::Config; +use serde_derive::Deserialize; -/// Configuration for the API keys. -#[derive(Debug, Default)] -pub struct ApiKeys { +/// Configuration for the application. +#[derive(Debug, Default, Deserialize)] +pub struct GhGptConfig { pub github_token: String, pub openai_api_key: String, } + +impl GhGptConfig { + /// Create a new configuration from environment variables. + pub fn new() -> Result { + CONFIG.clone().try_deserialize().map_err(|e| e.into()) + } +} + +lazy_static::lazy_static! { + #[derive(Debug)] + pub static ref CONFIG: Config = Config::builder() + .add_source(config::Environment::with_prefix("gh_gpt")) + .build() + .unwrap(); +} diff --git a/src/labels.rs b/src/labels.rs index 645a892..b7cf921 100644 --- a/src/labels.rs +++ b/src/labels.rs @@ -1,13 +1,15 @@ //! Module related to Github labels. +use color_eyre::eyre::Result; use log::debug; -use crate::config::Config; +use crate::config::GhGptConfig; /// Labelize a Github issue. /// # Arguments /// * `cfg` - The application configuration. /// * `gh_issue_number` - The Github issue number. -pub fn labelize(_cfg: &Config, gh_issue_number: u64) { +pub fn labelize(_cfg: &GhGptConfig, gh_issue_number: u64) -> Result<()> { debug!("labelize: {}", gh_issue_number); + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 37e1202..16e8bf9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,32 +1,39 @@ #[macro_use] extern crate log; use clap::Parser; +use color_eyre::eyre::Result; +use dotenv::dotenv; use gh_gpt::cli::commands::{Cli, Commands}; -use gh_gpt::config::Config; +use gh_gpt::config::GhGptConfig; use gh_gpt::labels::labelize; -fn main() { +fn main() -> Result<()> { // Initialize the logger. env_logger::init(); + + // Initialize the error handler. + color_eyre::install()?; + + // Load the environment variables from the .env file. + dotenv()?; + + // Say hello. info!("hello from gh-gpt 🤖 !"); // Parse the command line arguments. let cli = Cli::parse(); // Retrieve the application configuration. - let cfg = config(); + let cfg = GhGptConfig::new()?; - if let Some(command) = cli.command { - match command { - Commands::Labelize { gh_issue_number } => { - labelize(&cfg, gh_issue_number); - } + // Execute the command. + match cli.command { + Some(command) => match command { + Commands::Labelize { gh_issue_number } => labelize(&cfg, gh_issue_number), + }, + None => { + info!("nothing to do there, bye 👋"); + Ok(()) } } } - -/// Parse and return the application configuration. -fn config() -> Config { - // TODO: Parse the configuration from the environment variables. - Config::default() -}