-
Notifications
You must be signed in to change notification settings - Fork 8
add recursive search to load_dot_env #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
R/dotenv-package.r
Outdated
| found_file <- NA # Used to store the path of the found .env file | ||
|
|
||
| # Loop until the file is found or we cannot go further up in the directory tree | ||
| while (is.na(found_file) && !identical(path, normalizePath(dirname(path)))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possibly to get into an infinite loop here with symbolic links? Should we have some limit (100?) for the number of directories to try?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, we can account for symbolic links by keeping track of the visited directories. Here is some updated logic. What are your thoughts?
load_dot_env <- function(file = ".env", recursive = FALSE) {
# Normalize the initial file path for consistent path handling
original_path <- normalizePath(file, mustWork = FALSE)
# Initialize the visited directories tracker and the found file path
visited <- character(0)
found_file <- character(0)
if (!file.exists(original_path)) {
if (recursive) {
# Start with the directory containing the original path
path <- dirname(original_path)
# Loop until we find the file or reach the root directory
while (!identical(path, normalizePath(dirname(path)))) {
# Normalize the current directory path for accurate detection
normalized_path <- normalizePath(path, mustWork = FALSE)
# Break the loop if a cycle is detected
if (normalized_path %in% visited) break
# Track the visited directory to prevent cycles
visited <- c(visited, normalized_path)
# Construct the expected .env file path for the current directory
test_path <- file.path(normalized_path, basename(original_path))
# If the .env file is found, update `found_file` and exit the loop
if (file.exists(test_path)) {
found_file <- test_path
break
}
# Move up one directory level
path <- dirname(normalized_path)
}
# If no file was found in the entire search, raise an error
if (length(found_file) == 0) {
stop(sprintf("No .env file found from '%s' up to the root directory", original_path), call. = TRUE)
} else {
file <- found_file
}
} else {
# Raise an error if recursive is FALSE and the .env file does not exist in the specified location
stop(sprintf(".env file does not exist in the specified path: '%s'", original_path), call. = TRUE)
}
}
# Read and process the .env file
tmp <- readLines(file)
tmp <- ignore_comments(tmp)
tmp <- ignore_empty_lines(tmp)
# If no environment variables are found, return invisibly
if (length(tmp) == 0) return(invisible())
# Parse and set environment variables from the .env file
tmp <- lapply(tmp, parse_dot_line)
set_env(tmp)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that looks good to me.
prevents circular logic due to symbolic links
|
Friendly ping @gaborcsardi |
|
Add my +1 to this merge |
|
+1 |
Added functionality to recursively search parent directories for an .env file. Users can opt-in to this by setting recursive = TRUE. If recursive = TRUE, then load_dot_env will search the directory, and if no .env file is found, parent directories are searched until one is found.