├── .gitignore ├── .github ├── .gitignore └── workflows │ ├── test-coverage-pak.yaml │ └── check-pak.yaml ├── LICENSE ├── NAMESPACE ├── .Rbuildignore ├── NEWS.md ├── DESCRIPTION ├── man ├── dotenv-package.Rd └── load_dot_env.Rd ├── README.md ├── README.Rmd └── R └── dotenv-package.r /.gitignore: -------------------------------------------------------------------------------- 1 | /tags 2 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2014-2017 2 | COPYRIGHT HOLDER: Gabor Csardi 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(load_dot_env) 4 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^tags$ 2 | ^.travis.yml$ 3 | ^appveyor.yml$ 4 | ^Makefile$ 5 | ^README.Rmd$ 6 | ^\.github$ 7 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2 | # dotenv development version 3 | 4 | # dotenv 1.0.3 5 | 6 | * dotenv now does not error if the env file is empty (#5, @cimentadaj). 7 | 8 | # dotenv 1.0.2 9 | 10 | No user visible changes. 11 | 12 | # dotenv 1.0.1 13 | 14 | No user visible changes. 15 | 16 | # dotenv 1.0.0 17 | 18 | First release on CRAN. 19 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: dotenv 2 | Title: Load Environment Variables from '.env' 3 | Version: 1.0.3.9000 4 | Authors@R: c(person("Gábor", "Csárdi", role = c("aut", "cre", "cph"), email = 5 | "csardi.gabor@gmail.com")) 6 | Description: Load configuration from a '.env' file, that is 7 | in the current working directory, into environment variables. 8 | License: MIT + file LICENSE 9 | URL: https://github.com/gaborcsardi/dotenv 10 | BugReports: https://github.com/gaborcsardi/dotenv/issues 11 | RoxygenNote: 7.1.2 12 | Encoding: UTF-8 13 | -------------------------------------------------------------------------------- /man/dotenv-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dotenv-package.r 3 | \docType{package} 4 | \name{dotenv-package} 5 | \alias{dotenv-package} 6 | \title{Load configuration parameters from .env into environment variables} 7 | \description{ 8 | It has become a practice to store configuration parameters related 9 | to a project, in a hidden file called \code{.env}, in the working 10 | directory of a project, and then set them as environment variables. 11 | } 12 | \details{ 13 | This package loads the variables defined in the \code{.env} file 14 | in the current working directory (as reported by \code{getwd}), 15 | and sets them as environment variables. 16 | 17 | This happens automatically when the \code{dotenv} package is loaded, 18 | so the typical use-case is to just put a `library(dotenv)` code at the 19 | beginning of your R script. 20 | 21 | Alternatively a \code{dotenv::load_dot_env()} call can be used 22 | to load variables from arbitrary files. 23 | 24 | The format of the \code{.env} file is also a valid unix shell 25 | file format, so e.g. in \code{bash} the environment variables 26 | can also be set by running \code{source .env}. 27 | 28 | See \code{\link{load_dot_env}} for the exact file format. 29 | } 30 | \seealso{ 31 | load_dot_env 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage-pak.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | - master 6 | - x 7 | pull_request: 8 | branches: 9 | - main 10 | - master 11 | - x 12 | 13 | name: test-coverage 14 | 15 | jobs: 16 | test-coverage: 17 | runs-on: ubuntu-18.04 18 | env: 19 | RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest 20 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - uses: r-lib/actions/setup-r@v1 26 | id: install-r 27 | 28 | - name: Install pak and query dependencies 29 | run: | 30 | install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") 31 | saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") 32 | shell: Rscript {0} 33 | 34 | - name: Restore R package cache 35 | uses: actions/cache@v2 36 | with: 37 | path: | 38 | ${{ env.R_LIBS_USER }}/* 39 | !${{ env.R_LIBS_USER }}/pak 40 | key: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }} 41 | restore-keys: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1- 42 | 43 | - name: Install system dependencies 44 | if: runner.os == 'Linux' 45 | run: | 46 | pak::local_system_requirements(execute = TRUE) 47 | pak::pkg_system_requirements("covr", execute = TRUE) 48 | shell: Rscript {0} 49 | 50 | - name: Install dependencies 51 | run: | 52 | pak::local_install_dev_deps(upgrade = TRUE) 53 | pak::pkg_install("covr") 54 | shell: Rscript {0} 55 | 56 | - name: Test coverage 57 | run: covr::codecov() 58 | shell: Rscript {0} 59 | -------------------------------------------------------------------------------- /man/load_dot_env.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dotenv-package.r 3 | \name{load_dot_env} 4 | \alias{load_dot_env} 5 | \title{Load environment variables from the specified file} 6 | \usage{ 7 | load_dot_env(file = ".env") 8 | } 9 | \arguments{ 10 | \item{file}{The name of the file to use.} 11 | } 12 | \description{ 13 | Load variables defined in the given file, as environment 14 | variables. 15 | } 16 | \details{ 17 | The file is parsed line by line, and line is expected 18 | to have one of the following formats: 19 | \preformatted{VARIABLE=value 20 | VARIABLE2="quoted value" 21 | VARIABLE3='another quoted variable' 22 | # Comment line 23 | export EXPORTED="exported variable" 24 | export EXPORTED2=another} 25 | 26 | In more details: 27 | \itemize{ 28 | \item A leading \code{export} is ignored, to keep the file 29 | compatible with Unix shells. 30 | \item No whitespace is allowed right before or after the 31 | equal sign, again, to promote compatilibity with Unix shells. 32 | \item No multi-line variables are supported currently. The 33 | file is strictly parsed line by line. 34 | \item Unlike for Unix shells, unquoted values are \emph{not} 35 | terminated by whitespace. 36 | \item Comments start with \code{#}, without any leading 37 | whitespace. You cannot mix variable definitions and 38 | comments in the same line. 39 | \item Empty lines (containing whitespace only) are ignored. 40 | } 41 | 42 | It is suggested to keep the file in a form that is parsed the 43 | same way with \code{dotenv} and \code{bash} (or other shells). 44 | } 45 | \examples{ 46 | # Remove, if it exists 47 | Sys.unsetenv("dotenvexamplefoo") 48 | Sys.getenv("dotenvexamplefoo") 49 | 50 | # Load from a file 51 | tmp <- tempfile() 52 | cat("dotenvexamplefoo=bar\n", file = tmp) 53 | load_dot_env(tmp) 54 | Sys.getenv("dotenvexamplefoo") 55 | 56 | # Clean up 57 | unlink(tmp) 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [![Project Status: Active - The project has reached a stable, usable 5 | state and is being actively 6 | developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 7 | [![R build 8 | status](https://github.com/gaborcsardi/dotenv/workflows/R-CMD-check/badge.svg)](https://github.com/gaborcsardi/dotenv/actions) 9 | [![CRAN RStudio mirror 10 | downloads](https://cranlogs.r-pkg.org/badges/dotenv)](https://www.r-pkg.org/pkg/dotenv) 11 | [![Coverage 12 | Status](https://img.shields.io/codecov/c/github/gaborcsardi/dotenv/master.svg)](https://codecov.io/github/gaborcsardi/dotenv?branch=master) 13 | 14 | 15 | # dotenv — Load environment variables from .env 16 | 17 | This package loads the variables defined in the `.env` file in the 18 | current working directory (as reported by `getwd()`), and sets them as 19 | environment variables. 20 | 21 | This happens automatically when the `dotenv` package is loaded, so the 22 | typical use-case is to just put a `library(dotenv)` call at the 23 | beginning of your R script. 24 | 25 | Alternatively a `dotenv::load_dot_env()` call can be used to load 26 | variables from arbitrary files. 27 | 28 | ## Installation 29 | 30 | ``` r 31 | install.packages("dotenv") 32 | ``` 33 | 34 | ## Usage 35 | 36 | You can simply put 37 | 38 | ``` r 39 | library(dotenv) 40 | ``` 41 | 42 | at the beginning of your script, to load the environment variables 43 | defined in `.env` in the current working directory. 44 | 45 | ## File format 46 | 47 | The `.env` file is parsed line by line, and line is expected to have one 48 | of the following formats: 49 | 50 | VARIABLE=value 51 | VARIABLE2="quoted value" 52 | VARIABLE3='another quoted variable' 53 | # Comment line 54 | export EXPORTED="exported variable" 55 | export EXPORTED2=another 56 | 57 | In more details: 58 | 59 | - A leading `export` is ignored, to keep the file compatible with Unix 60 | shells. 61 | - No whitespace is allowed right before or after the equal sign, 62 | again, to promote compatilibity with Unix shells. 63 | - No multi-line variables are supported currently. The file is 64 | strictly parsed line by line. 65 | - Unlike for Unix shells, unquoted values are *not* terminated by 66 | whitespace. 67 | - Comments start with `#`, without any leading whitespace. You cannot 68 | mix variable definitions and comments in the same line. 69 | - Empty lines (containing whitespace only) are ignored. 70 | 71 | It is suggested to keep the file in a form that is parsed the same way 72 | with `dotenv` and `bash` (or other shells). 73 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | ```{r, setup, echo = FALSE, message = FALSE} 6 | knitr::opts_chunk$set( 7 | comment = "##", 8 | error = TRUE, 9 | tidy = FALSE, 10 | fig.width = 8, 11 | fig.height = 8) 12 | ``` 13 | 14 | 15 | [![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 16 | [![R build status](https://github.com/gaborcsardi/dotenv/workflows/R-CMD-check/badge.svg)](https://github.com/gaborcsardi/dotenv/actions) 17 | [![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/dotenv)](https://www.r-pkg.org/pkg/dotenv) 18 | [![Coverage Status](https://img.shields.io/codecov/c/github/gaborcsardi/dotenv/master.svg)](https://codecov.io/github/gaborcsardi/dotenv?branch=master) 19 | 20 | 21 | # dotenv — Load environment variables from .env 22 | 23 | This package loads the variables defined in the `.env` file 24 | in the current working directory (as reported by `getwd()`), 25 | and sets them as environment variables. 26 | 27 | This happens automatically when the `dotenv` package is loaded, 28 | so the typical use-case is to just put a `library(dotenv)` call at the 29 | beginning of your R script. 30 | 31 | Alternatively a `dotenv::load_dot_env()` call can be used 32 | to load variables from arbitrary files. 33 | 34 | ## Installation 35 | 36 | ```{r eval = FALSE} 37 | install.packages("dotenv") 38 | ``` 39 | 40 | ## Usage 41 | 42 | You can simply put 43 | 44 | ```{r eval = FALSE} 45 | library(dotenv) 46 | ``` 47 | 48 | at the beginning of your script, to load the environment variables defined 49 | in `.env` in the current working directory. 50 | 51 | ## File format 52 | 53 | The `.env` file is parsed line by line, and line is expected 54 | to have one of the following formats: 55 | 56 | ``` 57 | VARIABLE=value 58 | VARIABLE2="quoted value" 59 | VARIABLE3='another quoted variable' 60 | # Comment line 61 | export EXPORTED="exported variable" 62 | export EXPORTED2=another 63 | ``` 64 | 65 | In more details: 66 | 67 | * A leading `export` is ignored, to keep the file 68 | compatible with Unix shells. 69 | * No whitespace is allowed right before or after the 70 | equal sign, again, to promote compatilibity with Unix shells. 71 | * No multi-line variables are supported currently. The 72 | file is strictly parsed line by line. 73 | * Unlike for Unix shells, unquoted values are _not_ 74 | terminated by whitespace. 75 | * Comments start with `#`, without any leading 76 | whitespace. You cannot mix variable definitions and 77 | comments in the same line. 78 | * Empty lines (containing whitespace only) are ignored. 79 | 80 | It is suggested to keep the file in a form that is parsed the 81 | same way with `dotenv` and `bash` (or other shells). 82 | -------------------------------------------------------------------------------- /.github/workflows/check-pak.yaml: -------------------------------------------------------------------------------- 1 | # NOTE: This workflow is overkill for most R packages 2 | # check-standard.yaml is likely a better choice 3 | # usethis::use_github_action("check-standard") will install it. 4 | # 5 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 6 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 7 | on: 8 | push: 9 | branches: 10 | - main 11 | - master 12 | - x 13 | pull_request: 14 | branches: 15 | - main 16 | - master 17 | - x 18 | 19 | name: R-CMD-check 20 | 21 | jobs: 22 | R-CMD-check: 23 | runs-on: ${{ matrix.config.os }} 24 | 25 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 26 | 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | config: 31 | - {os: macOS-latest, r: 'release'} 32 | - {os: windows-latest, r: 'release'} 33 | - {os: windows-latest, r: '3.6'} 34 | - {os: ubuntu-18.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest", http-user-agent: "R/4.0.0 (ubuntu-18.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions" } 35 | - {os: ubuntu-18.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 36 | - {os: ubuntu-18.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 37 | - {os: ubuntu-18.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 38 | - {os: ubuntu-18.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 39 | - {os: ubuntu-18.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 40 | 41 | env: 42 | RSPM: ${{ matrix.config.rspm }} 43 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 44 | 45 | steps: 46 | - uses: actions/checkout@v2 47 | 48 | - uses: r-lib/actions/setup-r@v1 49 | id: install-r 50 | with: 51 | r-version: ${{ matrix.config.r }} 52 | http-user-agent: ${{ matrix.config.http-user-agent }} 53 | 54 | - uses: r-lib/actions/setup-pandoc@v1 55 | 56 | - name: Install pak and query dependencies 57 | run: | 58 | install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") 59 | saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") 60 | shell: Rscript {0} 61 | 62 | - name: Restore R package cache 63 | uses: actions/cache@v2 64 | with: 65 | path: | 66 | ${{ env.R_LIBS_USER }}/* 67 | !${{ env.R_LIBS_USER }}/pak 68 | key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }} 69 | restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1- 70 | 71 | - name: Install system dependencies 72 | if: runner.os == 'Linux' 73 | run: | 74 | pak::local_system_requirements(execute = TRUE) 75 | pak::pkg_system_requirements("rcmdcheck", execute = TRUE) 76 | shell: Rscript {0} 77 | 78 | - name: Install dependencies 79 | run: | 80 | pak::local_install_dev_deps(upgrade = TRUE) 81 | pak::pkg_install("rcmdcheck") 82 | shell: Rscript {0} 83 | 84 | - name: Session info 85 | run: | 86 | options(width = 100) 87 | pkgs <- installed.packages()[, "Package"] 88 | sessioninfo::session_info(pkgs, include_base = TRUE) 89 | shell: Rscript {0} 90 | 91 | - name: Check 92 | env: 93 | _R_CHECK_CRAN_INCOMING_: false 94 | run: | 95 | options(crayon.enabled = TRUE) 96 | rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 97 | shell: Rscript {0} 98 | 99 | - name: Show testthat output 100 | if: always() 101 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 102 | shell: bash 103 | 104 | - name: Upload check results 105 | if: failure() 106 | uses: actions/upload-artifact@main 107 | with: 108 | name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results 109 | path: check 110 | -------------------------------------------------------------------------------- /R/dotenv-package.r: -------------------------------------------------------------------------------- 1 | 2 | ## -------------------------------------------------------------------- 3 | #' Load configuration parameters from .env into environment variables 4 | #' 5 | #' It has become a practice to store configuration parameters related 6 | #' to a project, in a hidden file called \code{.env}, in the working 7 | #' directory of a project, and then set them as environment variables. 8 | #' 9 | #' This package loads the variables defined in the \code{.env} file 10 | #' in the current working directory (as reported by \code{getwd}), 11 | #' and sets them as environment variables. 12 | #' 13 | #' This happens automatically when the \code{dotenv} package is loaded, 14 | #' so the typical use-case is to just put a `library(dotenv)` code at the 15 | #' beginning of your R script. 16 | #' 17 | #' Alternatively a \code{dotenv::load_dot_env()} call can be used 18 | #' to load variables from arbitrary files. 19 | #' 20 | #' The format of the \code{.env} file is also a valid unix shell 21 | #' file format, so e.g. in \code{bash} the environment variables 22 | #' can also be set by running \code{source .env}. 23 | #' 24 | #' See \code{\link{load_dot_env}} for the exact file format. 25 | #' 26 | #' @seealso load_dot_env 27 | #' @docType package 28 | #' @name dotenv-package 29 | NULL 30 | 31 | .onLoad <- function(libname, pkgname) { 32 | if (file.exists(".env")) load_dot_env() 33 | } 34 | 35 | #' Load environment variables from the specified file 36 | #' 37 | #' Load variables defined in the given file, as environment 38 | #' variables. 39 | #' 40 | #' @details 41 | #' The file is parsed line by line, and line is expected 42 | #' to have one of the following formats: 43 | #' \preformatted{VARIABLE=value 44 | #' VARIABLE2="quoted value" 45 | #' VARIABLE3='another quoted variable' 46 | #' # Comment line 47 | #' export EXPORTED="exported variable" 48 | #' export EXPORTED2=another} 49 | #' 50 | #' In more details: 51 | #' \itemize{ 52 | #' \item A leading \code{export} is ignored, to keep the file 53 | #' compatible with Unix shells. 54 | #' \item No whitespace is allowed right before or after the 55 | #' equal sign, again, to promote compatilibity with Unix shells. 56 | #' \item No multi-line variables are supported currently. The 57 | #' file is strictly parsed line by line. 58 | #' \item Unlike for Unix shells, unquoted values are \emph{not} 59 | #' terminated by whitespace. 60 | #' \item Comments start with \code{#}, without any leading 61 | #' whitespace. You cannot mix variable definitions and 62 | #' comments in the same line. 63 | #' \item Empty lines (containing whitespace only) are ignored. 64 | #' } 65 | #' 66 | #' It is suggested to keep the file in a form that is parsed the 67 | #' same way with \code{dotenv} and \code{bash} (or other shells). 68 | #' 69 | #' @param file The name of the file to use. 70 | #' @export 71 | #' 72 | #' @examples 73 | #' # Remove, if it exists 74 | #' Sys.unsetenv("dotenvexamplefoo") 75 | #' Sys.getenv("dotenvexamplefoo") 76 | #' 77 | #' # Load from a file 78 | #' tmp <- tempfile() 79 | #' cat("dotenvexamplefoo=bar\n", file = tmp) 80 | #' load_dot_env(tmp) 81 | #' Sys.getenv("dotenvexamplefoo") 82 | #' 83 | #' # Clean up 84 | #' unlink(tmp) 85 | 86 | load_dot_env <- function(file = ".env") { 87 | 88 | if (!file.exists(file)) stop("dot-env file does not exist", call. = TRUE) 89 | 90 | tmp <- readLines(file) 91 | tmp <- ignore_comments(tmp) 92 | tmp <- ignore_empty_lines(tmp) 93 | 94 | # If there's no env vars, return nothing 95 | if (length(tmp) == 0) return(invisible()) 96 | 97 | tmp <- lapply(tmp, parse_dot_line) 98 | set_env(tmp) 99 | } 100 | 101 | ignore_comments <- function(lines) { 102 | grep("^#", lines, invert = TRUE, value = TRUE) 103 | } 104 | 105 | ignore_empty_lines <- function(lines) { 106 | grep("^\\s*$", lines, invert = TRUE, value = TRUE) 107 | } 108 | 109 | line_regex <- paste0("^\\s*", # leading whitespace 110 | "(?export\\s+)?", # export, if given 111 | "(?[^=]+)", # variable name 112 | "=", # equals sign 113 | "(?['\"]?)", # quote if present 114 | "(?.*)", # value 115 | "\\g{q}", # the same quote again 116 | "\\s*", # trailing whitespace 117 | "$") # end of line 118 | 119 | parse_dot_line <- function(line) { 120 | match <- regexpr(line_regex, line, perl = TRUE) 121 | if (match == -1) stop("Cannot parse dot-env line: ", substr(line, 1, 40), 122 | call. = FALSE) 123 | as.list(extract_match(line, match)[c("key", "value")]) 124 | } 125 | 126 | extract_match <- function(line, match) { 127 | tmp <- mapply( 128 | attr(match, "capture.start"), 129 | attr(match, "capture.length"), 130 | FUN = function(start, length) { 131 | tmp <- substr(line, start, start + length - 1) 132 | } 133 | ) 134 | names(tmp) <- attr(match, "capture.names") 135 | tmp 136 | } 137 | 138 | set_env <- function(pairs) { 139 | tmp <- structure( 140 | .Data = lapply(pairs, "[[", "value"), 141 | .Names = sapply(pairs, "[[", "key") 142 | ) 143 | do.call(Sys.setenv, tmp) 144 | } 145 | --------------------------------------------------------------------------------