dotenvx 4.0.4 → 4.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/Cargo.lock +3 -3
- data/ext/dotenvx/Cargo.toml +2 -2
- data/ext/dotenvx/src/lib.rs +17 -34
- data/lib/dotenvx/version.rb +1 -1
- data/lib/dotenvx.rb +40 -9
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a226fa6cca5ffa31823ef4d670b2860f174260de75654902121e49438fe0ec50
|
|
4
|
+
data.tar.gz: 592d8ddbaf65cd2074078cb4cc4e09d885b7cb4c503dbd1ff42ec6ee0ce33dcd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9851c708289150555f197a20dd4a9a76805968f80138d8861db16d9132e85c6128755bbaa0b4e2adbe55b81b25a159430f6f152a21ab45e7c7c89ba7976cba44
|
|
7
|
+
data.tar.gz: 1a899dfc7ef979033f616a2958b1ee3d8a22d98b65bcd6ce2070951b2b1f14868996a7fa458149b4d547ef75f309c6b0479531867cd00c9e4e38ce2259473efb
|
data/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
## [Unreleased](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.
|
|
5
|
+
## [Unreleased](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.5...main)
|
|
6
|
+
|
|
7
|
+
## [4.0.5](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.4...v4.0.5)
|
|
8
|
+
|
|
9
|
+
- Continue after parse and decryption errors by default, with strict and
|
|
10
|
+
error-code ignore options for callers that need them.
|
|
6
11
|
|
|
7
12
|
## [4.0.4](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.3...v4.0.4)
|
|
8
13
|
|
data/Cargo.lock
CHANGED
|
@@ -208,9 +208,9 @@ dependencies = [
|
|
|
208
208
|
|
|
209
209
|
[[package]]
|
|
210
210
|
name = "dotenvx-primitives"
|
|
211
|
-
version = "
|
|
211
|
+
version = "3.0.0"
|
|
212
212
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
213
|
-
checksum = "
|
|
213
|
+
checksum = "3437345180bc51f1355f184583a394ce06ca94ddf4f37859f6e6a42cfa29db2c"
|
|
214
214
|
dependencies = [
|
|
215
215
|
"base64",
|
|
216
216
|
"ecies",
|
|
@@ -222,7 +222,7 @@ dependencies = [
|
|
|
222
222
|
|
|
223
223
|
[[package]]
|
|
224
224
|
name = "dotenvx_native"
|
|
225
|
-
version = "4.0.
|
|
225
|
+
version = "4.0.6"
|
|
226
226
|
dependencies = [
|
|
227
227
|
"dotenvx-primitives",
|
|
228
228
|
"magnus",
|
data/ext/dotenvx/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "dotenvx_native"
|
|
3
|
-
version = "4.0.
|
|
3
|
+
version = "4.0.6"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
rust-version = "1.83"
|
|
6
6
|
publish = false
|
|
@@ -10,7 +10,7 @@ name = "dotenvx_native"
|
|
|
10
10
|
crate-type = ["cdylib"]
|
|
11
11
|
|
|
12
12
|
[dependencies]
|
|
13
|
-
dotenvx-primitives = "=
|
|
13
|
+
dotenvx-primitives = "=3.0.0"
|
|
14
14
|
magnus = "0.8"
|
|
15
15
|
rb-sys = { version = "0.9.128", default-features = false, features = ["stable-api-compiled-force"] }
|
|
16
16
|
serde = { version = "1", features = ["derive"] }
|
data/ext/dotenvx/src/lib.rs
CHANGED
|
@@ -1,38 +1,28 @@
|
|
|
1
|
-
use dotenvx_primitives::{
|
|
1
|
+
use dotenvx_primitives::{parse, ParseOptions, ParseResult};
|
|
2
2
|
use magnus::{function, prelude::*, Error, Ruby};
|
|
3
3
|
use serde::Deserialize;
|
|
4
4
|
use std::collections::HashMap;
|
|
5
5
|
use std::path::PathBuf;
|
|
6
6
|
|
|
7
7
|
type StringPairs = Vec<(String, String)>;
|
|
8
|
+
type ErrorPairs = Vec<(String, String)>;
|
|
8
9
|
|
|
9
10
|
fn runtime_error(message: impl Into<String>) -> Error {
|
|
10
11
|
let ruby = Ruby::get().expect("Ruby VM is not available");
|
|
11
12
|
Error::new(ruby.exception_runtime_error(), message.into())
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
fn
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.collect()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if !result.errors.is_empty() {
|
|
26
|
-
let message = result
|
|
27
|
-
.errors
|
|
28
|
-
.iter()
|
|
29
|
-
.map(ToString::to_string)
|
|
30
|
-
.collect::<Vec<_>>()
|
|
31
|
-
.join("\n");
|
|
32
|
-
return Err(runtime_error(message));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
Ok((scalar_values(result.parsed), scalar_values(result.injected)))
|
|
15
|
+
fn parse_result(result: ParseResult) -> (StringPairs, StringPairs, ErrorPairs) {
|
|
16
|
+
let errors = result
|
|
17
|
+
.errors
|
|
18
|
+
.iter()
|
|
19
|
+
.map(|error| (error.code().to_owned(), error.to_string()))
|
|
20
|
+
.collect();
|
|
21
|
+
(
|
|
22
|
+
result.parsed.into_iter().collect(),
|
|
23
|
+
result.injected.into_iter().collect(),
|
|
24
|
+
errors,
|
|
25
|
+
)
|
|
36
26
|
}
|
|
37
27
|
|
|
38
28
|
#[derive(Deserialize)]
|
|
@@ -43,26 +33,19 @@ struct ParseInput {
|
|
|
43
33
|
key_files: Vec<String>,
|
|
44
34
|
}
|
|
45
35
|
|
|
46
|
-
fn parse_dotenv(input_json: String) -> Result<(StringPairs, StringPairs), Error> {
|
|
36
|
+
fn parse_dotenv(input_json: String) -> Result<(StringPairs, StringPairs, ErrorPairs), Error> {
|
|
47
37
|
let input = serde_json::from_str::<ParseInput>(&input_json)
|
|
48
38
|
.map_err(|error| runtime_error(error.to_string()))?;
|
|
49
39
|
let process_env = input.process_env;
|
|
50
|
-
|
|
51
|
-
process_env: process_env.clone(),
|
|
52
|
-
key_files: input.key_files.into_iter().map(PathBuf::from).collect(),
|
|
53
|
-
..Default::default()
|
|
54
|
-
})
|
|
55
|
-
.map_err(|error| runtime_error(error.to_string()))?;
|
|
56
|
-
|
|
57
|
-
parse_result(parse(
|
|
40
|
+
Ok(parse_result(parse(
|
|
58
41
|
&input.source,
|
|
59
42
|
&ParseOptions {
|
|
60
43
|
process_env,
|
|
61
44
|
overload: input.overwrite,
|
|
62
|
-
|
|
45
|
+
key_files: input.key_files.into_iter().map(PathBuf::from).collect(),
|
|
63
46
|
..Default::default()
|
|
64
47
|
},
|
|
65
|
-
))
|
|
48
|
+
)))
|
|
66
49
|
}
|
|
67
50
|
|
|
68
51
|
#[magnus::init]
|
data/lib/dotenvx/version.rb
CHANGED
data/lib/dotenvx.rb
CHANGED
|
@@ -13,14 +13,24 @@ module Dotenvx
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
class ParseError < RuntimeError
|
|
17
|
+
attr_reader :code
|
|
18
|
+
|
|
19
|
+
def initialize(code, message)
|
|
20
|
+
@code = code
|
|
21
|
+
super(message)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
16
25
|
class << self
|
|
17
26
|
attr_accessor :instrumenter
|
|
18
27
|
|
|
19
|
-
def load(*filenames, overwrite: false, ignore: true)
|
|
28
|
+
def load(*filenames, overwrite: false, ignore: true, strict: false)
|
|
20
29
|
env, injected_keys, loaded_paths = parse_files(
|
|
21
30
|
*filenames,
|
|
22
31
|
overwrite: overwrite,
|
|
23
|
-
ignore: ignore
|
|
32
|
+
ignore: ignore,
|
|
33
|
+
strict: strict
|
|
24
34
|
)
|
|
25
35
|
changed = update(env, overwrite: overwrite)
|
|
26
36
|
log_injected(injected_keys, loaded_paths)
|
|
@@ -28,7 +38,7 @@ module Dotenvx
|
|
|
28
38
|
end
|
|
29
39
|
|
|
30
40
|
def load!(*filenames)
|
|
31
|
-
load(*filenames, ignore: false)
|
|
41
|
+
load(*filenames, ignore: false, strict: true)
|
|
32
42
|
end
|
|
33
43
|
|
|
34
44
|
def overwrite(*filenames)
|
|
@@ -37,12 +47,17 @@ module Dotenvx
|
|
|
37
47
|
alias overload overwrite
|
|
38
48
|
|
|
39
49
|
def overwrite!(*filenames)
|
|
40
|
-
load(*filenames, overwrite: true, ignore: false)
|
|
50
|
+
load(*filenames, overwrite: true, ignore: false, strict: true)
|
|
41
51
|
end
|
|
42
52
|
alias overload! overwrite!
|
|
43
53
|
|
|
44
|
-
def parse(*filenames, overwrite: false, ignore: true)
|
|
45
|
-
parse_files(
|
|
54
|
+
def parse(*filenames, overwrite: false, ignore: true, strict: false)
|
|
55
|
+
parse_files(
|
|
56
|
+
*filenames,
|
|
57
|
+
overwrite: overwrite,
|
|
58
|
+
ignore: ignore,
|
|
59
|
+
strict: strict
|
|
60
|
+
).first
|
|
46
61
|
end
|
|
47
62
|
|
|
48
63
|
def update(env = {}, overwrite: false)
|
|
@@ -72,7 +87,7 @@ module Dotenvx
|
|
|
72
87
|
|
|
73
88
|
private
|
|
74
89
|
|
|
75
|
-
def parse_files(*filenames, overwrite: false, ignore: true)
|
|
90
|
+
def parse_files(*filenames, overwrite: false, ignore: true, strict: false)
|
|
76
91
|
filenames = [".env"] if filenames.empty?
|
|
77
92
|
filenames = filenames.flatten.reverse if overwrite
|
|
78
93
|
|
|
@@ -84,16 +99,17 @@ module Dotenvx
|
|
|
84
99
|
begin
|
|
85
100
|
source = File.binread(path).sub(/\A\xEF\xBB\xBF/, "").force_encoding(Encoding::UTF_8)
|
|
86
101
|
rescue Errno::ENOENT, Errno::EISDIR
|
|
87
|
-
raise unless ignore
|
|
102
|
+
raise unless ignore_missing?(ignore)
|
|
88
103
|
next accumulator
|
|
89
104
|
end
|
|
90
105
|
|
|
91
|
-
parsed, injected = Native.parse_dotenv(JSON.generate(
|
|
106
|
+
parsed, injected, errors = Native.parse_dotenv(JSON.generate(
|
|
92
107
|
source: source,
|
|
93
108
|
process_env: process_env,
|
|
94
109
|
overwrite: overwrite == true,
|
|
95
110
|
key_files: key_files(path)
|
|
96
111
|
))
|
|
112
|
+
handle_errors(errors, ignore: ignore, strict: strict)
|
|
97
113
|
parsed = parsed.to_h
|
|
98
114
|
injected.each { |key, _value| injected_keys[key] = true }
|
|
99
115
|
loaded_paths << path
|
|
@@ -105,6 +121,21 @@ module Dotenvx
|
|
|
105
121
|
[values, injected_keys.keys, loaded_paths]
|
|
106
122
|
end
|
|
107
123
|
|
|
124
|
+
def handle_errors(errors, ignore:, strict:)
|
|
125
|
+
ignored_codes = Array(ignore).grep(String)
|
|
126
|
+
errors.each do |code, message|
|
|
127
|
+
next if ignored_codes.include?(code)
|
|
128
|
+
|
|
129
|
+
raise ParseError.new(code, message) if strict
|
|
130
|
+
|
|
131
|
+
warn "☠ #{message}"
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def ignore_missing?(ignore)
|
|
136
|
+
ignore == true || Array(ignore).map(&:to_s).include?("MISSING_ENV_FILE")
|
|
137
|
+
end
|
|
138
|
+
|
|
108
139
|
def log_injected(injected_keys, loaded_paths)
|
|
109
140
|
message = "⟐ injected env (#{injected_keys.length})"
|
|
110
141
|
unless loaded_paths.empty?
|