From 7c4f37f1009960b3497627db29d327e2e7d1013c Mon Sep 17 00:00:00 2001 From: Juri Pakaste Date: Sat, 18 May 2024 15:49:24 +0300 Subject: [PATCH 1/3] Add a make method for source string --- Sources/DotEnvy/Load.swift | 15 +++++++++++++++ Tests/DotEnvyTests/LoadTests.swift | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Sources/DotEnvy/Load.swift b/Sources/DotEnvy/Load.swift index 9915843..1a38230 100644 --- a/Sources/DotEnvy/Load.swift +++ b/Sources/DotEnvy/Load.swift @@ -77,6 +77,21 @@ extension DotEnvironment { } } + /// Create a `DotEnvironment` from `source` and `overrides`. + /// + /// - Parameter source: A string in dotenv format. + public static func make( + source: String, + overrides: DotEnvironment.Override = .process + ) throws -> DotEnvironment { + do { + let values = try self.parse(string: source) + return DotEnvironment(environment: values, overrides: overrides) + } catch let error as ParseErrorWithLocation { + throw LoadError.parseError(error, source) + } + } + /// Create a `DotEnvironment` from `url` and `overrides`. /// /// Defaults to loading `.env` from the current working directory and using the process environment diff --git a/Tests/DotEnvyTests/LoadTests.swift b/Tests/DotEnvyTests/LoadTests.swift index cab060e..4eb0b84 100644 --- a/Tests/DotEnvyTests/LoadTests.swift +++ b/Tests/DotEnvyTests/LoadTests.swift @@ -59,6 +59,25 @@ final class LoadTests: XCTestCase { } } + func testLoadErrorFromMakeSource() throws { + let source = """ + KEY1=VALUE1 + KEY2-VALUE2 + KEY3=VALUE3 + """ + XCTAssertThrowsError(try DotEnvironment.make(source: source)) { error in + guard let error = error as? LoadError else { + XCTFail("Unexpected error: \(error)") + return + } + guard case let .parseError(p, _) = error else { + XCTFail("Unexpected LoadError: \(error)") + return + } + XCTAssertEqual(p.error, .missingEquals) + } + } + func testMakeDotEnvironmentWithDefaultFile() throws { try inTemporaryDirectory { tempDir in try Data(""" From 84ef1de1caf073d89e079c819e56c0d52cfbb31a Mon Sep 17 00:00:00 2001 From: Juri Pakaste Date: Sat, 18 May 2024 15:49:43 +0300 Subject: [PATCH 2/3] Add export for exporting to environment --- Sources/DotEnvy/Load.swift | 10 +++++++++ Tests/DotEnvyTests/ExportTests.swift | 32 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 Tests/DotEnvyTests/ExportTests.swift diff --git a/Sources/DotEnvy/Load.swift b/Sources/DotEnvy/Load.swift index 1a38230..e73df33 100644 --- a/Sources/DotEnvy/Load.swift +++ b/Sources/DotEnvy/Load.swift @@ -46,6 +46,16 @@ extension DotEnvironment.Override { } extension DotEnvironment { + /// Export the `DotEnvironment` values into the process environment. + /// + /// - Parameter overwrite: Indicates if the calculated value should overwrite any existing value + /// in the process environment. + public func export(overwrite: Bool = true) { + for value in self.merge() { + setenv(value.key, value.value, overwrite ? 1 : 0) + } + } + /// Load the contents of a dotenv file into a dictionary. /// /// Defaults to loading `.env` from the current working directory. If the file does not exist, an diff --git a/Tests/DotEnvyTests/ExportTests.swift b/Tests/DotEnvyTests/ExportTests.swift new file mode 100644 index 0000000..3d1d126 --- /dev/null +++ b/Tests/DotEnvyTests/ExportTests.swift @@ -0,0 +1,32 @@ +@testable import DotEnvy +import XCTest + +final class ExportTests: XCTestCase { + func testOverwrite() throws { + setenv("KEY1", "ENVVALUE1", 1) + let dotenv = try DotEnvironment.make( + source: """ + KEY1=DOTENVVALUE1 + KEY2=DOTENVVALUE2 + """, + overrides: .none + ) + dotenv.export(overwrite: true) + XCTAssertEqual(ProcessInfo.processInfo.environment["KEY1"], "DOTENVVALUE1") + XCTAssertEqual(ProcessInfo.processInfo.environment["KEY2"], "DOTENVVALUE2") + } + + func testNoOverwrite() throws { + setenv("KEY1", "ENVVALUE1", 1) + let dotenv = try DotEnvironment.make( + source: """ + KEY1=DOTENVVALUE1 + KEY2=DOTENVVALUE2 + """, + overrides: .none + ) + dotenv.export(overwrite: false) + XCTAssertEqual(ProcessInfo.processInfo.environment["KEY1"], "ENVVALUE1") + XCTAssertEqual(ProcessInfo.processInfo.environment["KEY2"], "DOTENVVALUE2") + } +} From bce71edae58ea5dd8d2de3ad3b018c3afdea22d8 Mon Sep 17 00:00:00 2001 From: Juri Pakaste Date: Sat, 18 May 2024 15:52:51 +0300 Subject: [PATCH 3/3] Amend docs with export --- Sources/DotEnvy/Documentation.docc/Documentation.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Sources/DotEnvy/Documentation.docc/Documentation.md b/Sources/DotEnvy/Documentation.docc/Documentation.md index fc04839..e70278d 100644 --- a/Sources/DotEnvy/Documentation.docc/Documentation.md +++ b/Sources/DotEnvy/Documentation.docc/Documentation.md @@ -80,6 +80,17 @@ func env() -> [String: String] { } ``` +If you want to override the process environment, you can use ``DotEnvironment/export(overwrite:)``: + +```swift +import DotEnvy + +func overrideEnv() throws { + let environment = try DotEnvironment.make() + environment.export() +} +``` + ## Topics ### Group