From 9d204d45aaed9e1997fbba5863bf9a9a8ca085ff Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Sun, 7 Jul 2024 02:06:53 -0700 Subject: [PATCH 1/2] feat: simplified macro usage and added dotenv_override! macro --- dotenv/README.md | 11 ++++ dotenv_codegen/src/lib.rs | 62 +++++----------------- dotenv_codegen/tests/basic_dotenv_macro.rs | 15 +----- 3 files changed, 26 insertions(+), 62 deletions(-) diff --git a/dotenv/README.md b/dotenv/README.md index 2b875a84..43bdb150 100644 --- a/dotenv/README.md +++ b/dotenv/README.md @@ -40,6 +40,17 @@ fn main() { The `dotenv!` macro provided by `dotenvy_macro` crate can be used. +```rs +use dotenvy_macro::dotenv; + +fn main() { + // load environment variables from .env file + dotenvy_macro::dotenv!(); + + env!("PATH"); +} +``` + ## Minimum supported Rust version Currently: **1.68.0** diff --git a/dotenv_codegen/src/lib.rs b/dotenv_codegen/src/lib.rs index 418c2dfe..a162d25c 100644 --- a/dotenv_codegen/src/lib.rs +++ b/dotenv_codegen/src/lib.rs @@ -1,65 +1,29 @@ #![forbid(unsafe_code)] use quote::quote; -use std::env::{self, VarError}; -use syn::{parse::Parser, punctuated::Punctuated, spanned::Spanned, Token}; #[proc_macro] -pub fn dotenv(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - dotenv_inner(input.into()).into() -} - -fn dotenv_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { +pub fn dotenv(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { if let Err(err) = dotenvy::dotenv() { let msg = format!("Error loading .env file: {}", err); return quote! { compile_error!(#msg); - }; + } + .into(); } - match expand_env(input) { - Ok(stream) => stream, - Err(e) => e.to_compile_error(), - } + quote! {}.into() } -fn expand_env(input_raw: proc_macro2::TokenStream) -> syn::Result { - let args = >::parse_terminated - .parse(input_raw.into()) - .expect("expected macro to be called with a comma-separated list of string literals"); - - let mut iter = args.iter(); - - let var_name = iter - .next() - .ok_or_else(|| syn::Error::new(args.span(), "dotenv! takes 1 or 2 arguments"))? - .value(); - let err_msg = iter.next(); - - if iter.next().is_some() { - return Err(syn::Error::new( - args.span(), - "dotenv! takes 1 or 2 arguments", - )); +#[proc_macro] +pub fn dotenv_override(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { + if let Err(err) = dotenvy::dotenv_override() { + let msg = format!("Error loading .env file: {}", err); + return quote! { + compile_error!(#msg); + } + .into(); } - match env::var(&var_name) { - Ok(val) => Ok(quote!(#val)), - Err(e) => Err(syn::Error::new( - var_name.span(), - err_msg.map_or_else( - || match e { - VarError::NotPresent => { - format!("environment variable `{}` not defined", var_name) - } - - VarError::NotUnicode(s) => format!( - "environment variable `{}` was not valid unicode: {:?}", - var_name, s - ), - }, - |lit| lit.value(), - ), - )), - } + quote! {}.into() } diff --git a/dotenv_codegen/tests/basic_dotenv_macro.rs b/dotenv_codegen/tests/basic_dotenv_macro.rs index f48c4a74..af819199 100644 --- a/dotenv_codegen/tests/basic_dotenv_macro.rs +++ b/dotenv_codegen/tests/basic_dotenv_macro.rs @@ -1,16 +1,5 @@ #[test] fn dotenv_works() { - assert_eq!(dotenvy_macro::dotenv!("CODEGEN_TEST_VAR1"), "hello!"); -} - -#[test] -fn two_argument_form_works() { - assert_eq!( - dotenvy_macro::dotenv!( - "CODEGEN_TEST_VAR2", - "err, you should be running this in the 'dotenv_codegen' \ - directory to pick up the right .env file." - ), - "'quotes within quotes'" - ); + dotenvy_macro::dotenv!(); + assert_eq!(env!("CODEGEN_TEST_VAR1"), "hello!"); } From b571a03c9a43c8eb1721801b01e653d270dd707b Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Sun, 7 Jul 2024 03:33:02 -0700 Subject: [PATCH 2/2] added test for `dotenv_override!` macro --- .env | 5 +++-- dotenv_codegen/tests/basic_dotenv_macro.rs | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 7e052ef4..a575373d 100644 --- a/.env +++ b/.env @@ -1,8 +1,9 @@ # Start of .env file # Comment line with single ' quote # Comment line with double " quote - # Comment line, starts with space with double " quote +# Comment line, starts with space with double " quote +USER=dotenv! CODEGEN_TEST_VAR1="hello!" CODEGEN_TEST_VAR2="'quotes within quotes'" CODEGEN_TEST_VAR3="double quoted with # hash in value" @@ -11,7 +12,7 @@ CODEGEN_TEST_VAR5=not_quoted_with_#_hash_in_value CODEGEN_TEST_VAR6=not_quoted_with_comment_beheind # var6 comment CODEGEN_TEST_VAR7=not\ quoted\ with\ escaped\ space CODEGEN_TEST_VAR8="double quoted with comment beheind" # var7 comment - CODEGEN_TEST_VAR9="Variable starts with a whitespace" +CODEGEN_TEST_VAR9="Variable starts with a whitespace" CODEGEN_TEST_VAR10= "Value starts with a whitespace after =" CODEGEN_TEST_VAR11 ="Variable ends with a whitespace before =" CODEGEN_TEST_MULTILINE1="First Line diff --git a/dotenv_codegen/tests/basic_dotenv_macro.rs b/dotenv_codegen/tests/basic_dotenv_macro.rs index af819199..4486780e 100644 --- a/dotenv_codegen/tests/basic_dotenv_macro.rs +++ b/dotenv_codegen/tests/basic_dotenv_macro.rs @@ -3,3 +3,9 @@ fn dotenv_works() { dotenvy_macro::dotenv!(); assert_eq!(env!("CODEGEN_TEST_VAR1"), "hello!"); } + +#[test] +fn dotenv_override_works() { + dotenvy_macro::dotenv_override!(); + assert_eq!(env!("USER"), "dotenv!"); +}