Skip to content

Commit

Permalink
Merge pull request #24 from aosasona/v1
Browse files Browse the repository at this point in the history
Version 1
  • Loading branch information
aosasona authored Jun 2, 2024
2 parents 1f7b960 + 363ff87 commit 19e0f69
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.0.0"
gleam-version: "1.2.1"
rebar3-version: "3"
- run: gleam publish --yes
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.0.0"
gleam-version: "1.2.1"
rebar3-version: "3"
- run: gleam format --check src test
- run: gleam deps download
Expand Down
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

<!--toc:start-->

- [dot_env](#dotenv)
- [Quick start](#quick-start)
- [Installation](#installation)
<!--toc:end-->
- [Quick start](#quick-start)
- [Installation](#installation)
<!--toc:end-->

[![Package Version](https://img.shields.io/hexpm/v/dot_env)](https://hex.pm/packages/dotenv)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/dot_env/)
Expand All @@ -14,24 +13,37 @@ dot_env is a port of the popular JavaScript [dotenv](https://github.com/motdotla

> This package may support other formats in the future but for now, supports the popular .env format
>
> You can find the Javascript test [here](https://github.com/aosasona/dot_js_test)
> You can find the Javascript "tests" [here](https://github.com/aosasona/dot_js_test)
## Quick start

```gleam
import dot_env
import dot_env as dot
import dot_env/env
import gleam/io
pub fn main() {
dot_env.load_with_opts(dot_env.Opts(path: "path/to/.env", debug: False, capitalize: False))
// or `dot_env.load()` to load the `.env` file in the root path
dot.new()
|> dot.set_path("path/to/.env")
|> dot.set_debug(False)
|> dot.load
// or dot_env.load_with_opts(dot_env.Opts(path: "path/to/.env", debug: False, capitalize: False))
// or `dot_env.load_default()` to load the `.env` file in the root path
case env.get("MY_ENV_VAR") {
Ok(value) -> io.println(value)
Error(_) -> io.println("something went wrong")
}
let app_name = env.get_or("APP_NAME", "my app name")
let port = env.get_int_or("PORT", 3000)
let enable_signup = env.get_bool_or("ENABLE_SIGNUP", True)
io.debug(app_name)
io.debug(port)
io.debug(enable_signup)
Nil
}
```
Expand Down
10 changes: 5 additions & 5 deletions gleam.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name = "dot_env"
version = "0.5.1"
version = "1.0.0"

description = "Load and use environment variables from files"
licences = ["Apache-2.0"]
repository = { type = "github", user = "aosasona", repo = "dotenv" }

internal_modules = ["dot_env/internal/*"]

gleam = ">= 0.34.0"
gleam = ">= 1.0.0"

[dependencies]
simplifile = "~> 1.5"
gleam_stdlib = "~> 0.34 or ~> 1.0"
simplifile = ">= 2.0.0 and < 3.0.0"
gleam_stdlib = ">= 0.38.0 and < 1.0.0"

[dev-dependencies]
gleeunit = "~> 1.0"
gleeunit = ">= 1.1.2 and < 2.0.0"
13 changes: 7 additions & 6 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
# You typically do not need to edit this file

packages = [
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
{ name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
{ name = "gleam_stdlib", version = "0.38.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "663CF11861179AF415A625307447775C09404E752FF99A24E2057C835319F1BE" },
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
{ name = "simplifile", version = "2.0.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "95219227A43FCFE62C6E494F413A1D56FF953B68FE420698612E3D89A1EFE029" },
]

[requirements]
gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
gleeunit = { version = "~> 1.0"}
simplifile = { version = "~> 1.5" }
gleam_stdlib = { version = ">= 0.38.0 and < 1.0.0"}
gleeunit = { version = ">= 1.1.2 and < 2.0.0" }
simplifile = { version = ">= 2.0.0 and < 3.0.0" }
103 changes: 77 additions & 26 deletions src/dot_env.gleam
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import dot_env/env
import dot_env/internal/parser
import gleam/bool
import gleam/io
import gleam/string
import gleam/result.{try}
import dot_env/internal/parser
import dot_env/env
import gleam/string
import simplifile

pub type Opts {
Expand Down Expand Up @@ -34,7 +34,66 @@ pub const default = DotEnv(
ignore_missing_file: True,
)

/// Create a default DotEnv instance. This is designed to use used as the starting point for using any of the builder methods
pub fn new() -> DotEnv {
default
}

/// Create a new DotEnv instance with the specified path
pub fn new_with_path(path: String) -> DotEnv {
DotEnv(..default, path: path)
}

/// Set whether to print debug information in the current DotEnv instance
pub fn set_debug(instance: DotEnv, debug: Bool) -> DotEnv {
DotEnv(..instance, debug: debug)
}

/// Set whether to capitalize all keys in the current DotEnv instance
pub fn set_capitalize(instance: DotEnv, capitalize: Bool) -> DotEnv {
DotEnv(..instance, capitalize: capitalize)
}

/// Set whether to ignore missing file errors in the current DotEnv instance
pub fn set_ignore_missing_file(
instance: DotEnv,
ignore_missing_file: Bool,
) -> DotEnv {
DotEnv(..instance, ignore_missing_file: ignore_missing_file)
}

/// Set the path to the .env file in the current DotEnv instance
pub fn set_path(instance: DotEnv, path: String) -> DotEnv {
DotEnv(..instance, path: path)
}

/// Get the path to the .env file in the current DotEnv instance
pub fn path(instance: DotEnv) -> String {
instance.path
}

/// Load the .env file using the current DotEnv instance and set the environment variables
///
/// # Example
///
/// ```gleam
/// import dot_env as dot
///
/// pub fn main() {
/// dot.new()
/// |> dot.set_path("src/.env")
/// |> dot.set_debug(False)
/// |> dot.load
/// }
pub fn load(dotenv: DotEnv) -> Nil {
load_with_opts(Opts(
path: dotenv.path,
debug: dotenv.debug,
capitalize: dotenv.capitalize,
ignore_missing_file: dotenv.ignore_missing_file,
))
}

/// Load the .env file at the default path (.env) and set the environment variables
///
/// Debug information will be printed to the console if something goes wrong and all keys will be capitalized
Expand All @@ -45,14 +104,13 @@ pub const default = DotEnv(
/// import dot_env
///
/// pub fn main() {
/// dot_env.load()
/// dot_env.load_default()
/// }
/// ```
pub fn load() {
pub fn load_default() -> Nil {
load_with_opts(Default)
}

///
/// Load the .env file at the specified path and set the environment variables
///
/// Debug information and key capitalization can be customized
Expand All @@ -73,9 +131,7 @@ pub fn load_with_opts(opts: Opts) {
Default -> default
}

let state =
dotenv
|> load_and_return_error
let state = dotenv |> load_and_return_error

case state {
Ok(_) -> Nil
Expand All @@ -96,8 +152,6 @@ fn load_and_return_error(dotenv: DotEnv) -> Result(Nil, String) {

dotenv
|> recursively_set_environment_variables(kv_pairs)

Ok(Nil)
}

fn handle_file_result(
Expand All @@ -108,34 +162,33 @@ fn handle_file_result(
res
}

fn set_env(config: DotEnv, pair: #(String, String)) {
let #(key, value) = pair

fn set_env(config: DotEnv, pair: #(String, String)) -> Result(Nil, String) {
let key = {
use <- bool.guard(when: !config.capitalize, return: key)
string.uppercase(key)
use <- bool.guard(when: !config.capitalize, return: pair.0)
string.uppercase(pair.0)
}

env.set(key, value)
key
|> env.set(pair.1)
}

fn recursively_set_environment_variables(
config: DotEnv,
kv_pairs: parser.KVPairs,
) {
) -> Result(Nil, String) {
case kv_pairs {
[] -> Nil
[] -> Ok(Nil)
[pair] -> set_env(config, pair)
[pair, ..rest] -> {
set_env(config, pair)
use _ <- result.try(set_env(config, pair))
recursively_set_environment_variables(config, rest)
}
}
}

fn read_file(dotenv: DotEnv) -> Result(String, String) {
use is_file <- result.try(
simplifile.verify_is_file(dotenv.path)
simplifile.is_file(dotenv.path)
|> result.map_error(with: fn(_) {
"Failed to access file, ensure the file exists and is a readable file"
}),
Expand All @@ -149,11 +202,9 @@ fn read_file(dotenv: DotEnv) -> Result(String, String) {
use contents <- result.try(
simplifile.read(dotenv.path)
|> result.map_error(with: fn(_) {
let msg =
"Unable to read file at `"
<> dotenv.path
<> "`, ensure the file exists and is readable"
msg
"Unable to read file at `"
<> dotenv.path
<> "`, ensure the file exists and is readable"
}),
)

Expand Down
Loading

0 comments on commit 19e0f69

Please sign in to comment.