dotenvx 4.0.6-x86_64-linux → 5.0.0-x86_64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a211e3510b8c548dd2c35e2fc818d5550ae8df731766918345d372963bcee382
4
- data.tar.gz: 472897b244350b8a95fa3b39be0283a53e14f16e6e3263abd7ae80b010029cae
3
+ metadata.gz: f13f1e7d066d8bff987f1b8a6cda67c3cefe84fea9d3dcf83c868c5cd2aca397
4
+ data.tar.gz: 486303a2d59e37aaec691bb9d4d6f8a2e9def99dda1e7c9ae93c92ab057ccd0c
5
5
  SHA512:
6
- metadata.gz: 63a8bab5e3ba7655be5ef699ef52567df63966b70c3511f8ddd8f895f96f7200c13fa6d8fc62a017e012b672edbbb1415843af2139ab37febbaf6f99570ae9a0
7
- data.tar.gz: 266cf24f3e2b10fe7d1800308bf929047bf41f7e69ed1cb61dd12dde4dd551d0435346d060e25ac7b8b8946fc926468b44ffeec8123715c11decc91fa5200adc
6
+ metadata.gz: 1dd5c0720195aab1072bbb16811b270c7eb3a19c563b3be3ec2b52e9944f71f7f8c32968bd8a8738d465d6e93a5c8461cee30c2d11d592f41723c0efc4fe1e1f
7
+ data.tar.gz: ad92ea842a5c7485962a4a91eeda2443d84a4d74b7d05ee3b5947617f0b388ce35e9fb46d657b12d0096456dfabe4648be1bbad91d12be908a88af7a2324d063
data/CHANGELOG.md CHANGED
@@ -2,18 +2,18 @@
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...main)
5
+ ## Unreleased
6
6
 
7
- ## [4.0.5](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.4...v4.0.5)
7
+ ## 4.0.5
8
8
 
9
9
  - Continue after parse and decryption errors by default, with strict and
10
10
  error-code ignore options for callers that need them.
11
11
 
12
- ## [4.0.4](https://github.com/dotenvx/dotenvx-ruby/compare/v4.0.3...v4.0.4)
12
+ ## 4.0.4
13
13
 
14
14
  - Report the unique variables injected from readable dotenv files.
15
15
 
16
- ## [4.0.0](https://github.com/dotenvx/dotenvx-ruby/compare/v0.0.2...v4.0.0)
16
+ ## 4.0.0
17
17
 
18
18
  - Load plaintext and encrypted dotenv files through `dotenvx-primitives`.
19
19
  - Bundle the Rust implementation as a Magnus native extension.
data/README.md CHANGED
@@ -2,10 +2,9 @@
2
2
 
3
3
  *a secure dotenv–from the creator of [`dotenv`](https://github.com/motdotla/dotenv).*
4
4
 
5
- `dotenvx` loads plaintext and encrypted dotenv files through the shared
6
- [`dotenvx-primitives`](https://crates.io/crates/dotenvx-primitives) Rust
7
- implementation. The native extension is bundled in the gem; users do not need
8
- Node.js, a dotenvx CLI, or a Rust toolchain.
5
+ `dotenvx` loads plaintext and encrypted dotenv files through the shared `dotenvx-sdk` Rust loader, backed by published
6
+ [`dotenvx-primitives`](https://crates.io/crates/dotenvx-primitives). The native extension is bundled in the gem; users do not need
7
+ Node.js or a Rust toolchain.
9
8
 
10
9
  ## Install
11
10
 
@@ -61,14 +60,10 @@ Raise when a file is missing:
61
60
  Dotenvx.load!(".env")
62
61
  ```
63
62
 
64
- Require configuration keys:
65
-
66
- ```ruby
67
- Dotenvx.require_keys("DATABASE_URL", "SECRET_KEY")
68
- ```
69
-
70
- Encrypted values are decrypted automatically when the matching private key is
71
- available through the process environment, `<filename>.keys`, or `.env.keys`.
63
+ Encrypted values are decrypted automatically with keys from the process
64
+ environment, `<filename>.keys`, or `.env.keys`. For keys in Armor, 1Password,
65
+ or another custody provider, install a dotenvx CLI with `command-sdk` and the
66
+ matching feature.
72
67
 
73
68
  ## Native platforms
74
69
 
@@ -81,3 +76,24 @@ Tagged releases publish variants of the same `dotenvx` gem for:
81
76
  - Windows x64
82
77
 
83
78
  RubyGems selects the correct variant during `gem install dotenvx`.
79
+
80
+ ## Loading errors and policy
81
+
82
+ Loading errors are reported and loading continues by default. `strict: true`,
83
+ `load!` stops loading and raises before updating `ENV`. Selected error codes
84
+ can be ignored with `ignore: ["CODE"]`.
85
+
86
+ The shared loader returns redaction metadata without changing real application
87
+ values. Application-output redaction hooks are not installed by this adapter.
88
+
89
+ ## Shared file selection
90
+
91
+ File discovery, directory expansion, conventions, and key-based filename
92
+ inference are resolved by `dotenvx-sdk`. The CLI's file-selection and error-ignore
93
+ environment variables apply here too. Rails supplies its root and environment;
94
+ the shared loader chooses the Rails files and their order.
95
+
96
+ ```ruby
97
+ Dotenvx.load(convention: "nextjs")
98
+ Dotenvx.load("app", key_files: "shared/.env.keys")
99
+ ```
Binary file
data/lib/dotenvx/rails.rb CHANGED
@@ -39,25 +39,12 @@ module Dotenvx
39
39
  def load
40
40
  return if @loaded
41
41
 
42
- Dotenvx.load(*dotenvx_files)
42
+ Dotenvx.load(root.to_s, convention: "rails", environment: Rails.env.to_s)
43
43
  @loaded = true
44
44
  end
45
45
 
46
46
  private
47
47
 
48
- def dotenvx_files
49
- environment = Rails.env
50
- files = [
51
- root.join(".env.#{environment}.local")
52
- ]
53
- files << root.join(".env.local") unless environment == "test"
54
- files.concat([
55
- root.join(".env.#{environment}"),
56
- root.join(".env")
57
- ])
58
- files
59
- end
60
-
61
48
  def root
62
49
  Pathname.new(Rails.root || ENV["RAILS_ROOT"] || Dir.pwd)
63
50
  end
@@ -1,3 +1,3 @@
1
1
  module Dotenvx
2
- VERSION = "4.0.6"
2
+ VERSION = "5.0.0"
3
3
  end
data/lib/dotenvx.rb CHANGED
@@ -1,18 +1,8 @@
1
1
  require "dotenvx/version"
2
2
  require "dotenvx/dotenvx_native"
3
3
  require "json"
4
- require "pathname"
5
4
 
6
5
  module Dotenvx
7
- class MissingKeys < RuntimeError
8
- attr_reader :keys
9
-
10
- def initialize(keys)
11
- @keys = keys
12
- super("Missing required configuration keys: #{keys.join(", ")}")
13
- end
14
- end
15
-
16
6
  class ParseError < RuntimeError
17
7
  attr_reader :code
18
8
 
@@ -25,15 +15,18 @@ module Dotenvx
25
15
  class << self
26
16
  attr_accessor :instrumenter
27
17
 
28
- def load(*filenames, overwrite: false, ignore: true, strict: false)
29
- env, injected_keys, loaded_paths = parse_files(
18
+ def load(*filenames, overwrite: false, ignore: [], strict: false, convention: nil, environment: nil, key_files: nil)
19
+ env, summary = parse_files(
30
20
  *filenames,
31
21
  overwrite: overwrite,
32
22
  ignore: ignore,
33
- strict: strict
23
+ strict: strict,
24
+ convention: convention,
25
+ environment: environment,
26
+ key_files: key_files
34
27
  )
35
28
  changed = update(env, overwrite: overwrite)
36
- log_injected(injected_keys, loaded_paths)
29
+ warn summary
37
30
  changed
38
31
  end
39
32
 
@@ -51,12 +44,15 @@ module Dotenvx
51
44
  end
52
45
  alias overload! overwrite!
53
46
 
54
- def parse(*filenames, overwrite: false, ignore: true, strict: false)
47
+ def parse(*filenames, overwrite: false, ignore: [], strict: false, convention: nil, environment: nil, key_files: nil)
55
48
  parse_files(
56
49
  *filenames,
57
50
  overwrite: overwrite,
58
51
  ignore: ignore,
59
- strict: strict
52
+ strict: strict,
53
+ convention: convention,
54
+ environment: environment,
55
+ key_files: key_files
60
56
  ).first
61
57
  end
62
58
 
@@ -80,83 +76,34 @@ module Dotenvx
80
76
  changed
81
77
  end
82
78
 
83
- def require_keys(*keys)
84
- missing = keys.flatten.map(&:to_s) - ENV.keys
85
- raise MissingKeys, missing unless missing.empty?
86
- end
87
-
88
79
  private
89
80
 
90
- def parse_files(*filenames, overwrite: false, ignore: true, strict: false)
91
- filenames = [".env"] if filenames.empty?
92
- filenames = filenames.flatten.reverse if overwrite
93
-
94
- process_env = ENV.to_h
95
- injected_keys = {}
96
- loaded_paths = []
97
- values = filenames.reduce({}) do |accumulator, filename|
98
- path = File.expand_path(filename)
99
- begin
100
- source = File.binread(path).sub(/\A\xEF\xBB\xBF/, "").force_encoding(Encoding::UTF_8)
101
- rescue Errno::ENOENT, Errno::EISDIR
102
- raise unless ignore_missing?(ignore)
103
- next accumulator
104
- end
105
-
106
- parsed, injected, errors = Native.parse_dotenv(JSON.generate(
107
- source: source,
108
- process_env: process_env,
109
- overwrite: overwrite == true,
110
- key_files: key_files(path)
111
- ))
112
- handle_errors(errors, ignore: ignore, strict: strict)
113
- parsed = parsed.to_h
114
- injected.each { |key, _value| injected_keys[key] = true }
115
- loaded_paths << path
116
- process_env.merge!(parsed)
117
- accumulator.merge!(parsed)
118
- yield Environment.new(path, parsed) if block_given?
119
- accumulator
120
- end
121
- [values, injected_keys.keys, loaded_paths]
122
- end
123
-
124
- def handle_errors(errors, ignore:, strict:)
81
+ def parse_files(*filenames, overwrite: false, ignore: [], strict: false, convention: nil, environment: nil, key_files: nil)
82
+ filenames = filenames.flatten
125
83
  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
-
139
- def log_injected(injected_keys, loaded_paths)
140
- message = "⟐ injected env (#{injected_keys.length})"
141
- unless loaded_paths.empty?
142
- paths = loaded_paths.map { |path| readable_path(path) }
143
- message = "#{message} from #{paths.join(", ")}"
84
+ ignored_codes << "MISSING_ENV_FILE" if ignore == true
85
+ result = JSON.parse(Native.load_env(JSON.generate(
86
+ sources: filenames.map { |filename| { type: "file", value: filename.to_s } },
87
+ cwd: Dir.pwd,
88
+ convention: convention,
89
+ environment_name: environment,
90
+ key_files: key_files.nil? ? nil : Array(key_files).map(&:to_s),
91
+ process_env: ENV.to_h,
92
+ overload: overwrite == true,
93
+ strict: strict,
94
+ ignore: ignored_codes,
95
+ adjacent_keys: true
96
+ )))
97
+ result.fetch("diagnostics").each do |error|
98
+ if error.fetch("strict")
99
+ if error["code"] == "MISSING_ENV_FILE" && ignore == false
100
+ raise Errno::ENOENT, error["path"]
101
+ end
102
+ raise ParseError.new(error.fetch("code"), error.fetch("message"))
103
+ end
104
+ warn "☠ #{error.fetch("message")}"
144
105
  end
145
- warn message
146
- end
147
-
148
- def readable_path(path)
149
- pathname = Pathname.new(path)
150
- relative = pathname.relative_path_from(Pathname.pwd).to_s
151
- relative.start_with?("../") ? pathname.to_s : relative
152
- rescue ArgumentError
153
- pathname.to_s
154
- end
155
-
156
- def key_files(path)
157
- candidates = ["#{path}.keys", File.join(File.dirname(path), ".env.keys")]
158
- candidates.select { |candidate| File.file?(candidate) }
159
- .uniq
106
+ [result.fetch("values"), result.fetch("inject_summary")]
160
107
  end
161
108
  end
162
109
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotenvx
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.6
4
+ version: 5.0.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - motdotla
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-11 00:00:00.000000000 Z
11
+ date: 2026-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -81,13 +81,13 @@ files:
81
81
  - lib/dotenvx/load.rb
82
82
  - lib/dotenvx/rails.rb
83
83
  - lib/dotenvx/version.rb
84
- homepage: https://github.com/dotenvx/dotenvx-ruby
84
+ homepage: https://github.com/dotenvx/dotenvx
85
85
  licenses:
86
86
  - BSD-3-Clause
87
87
  metadata:
88
- homepage_uri: https://github.com/dotenvx/dotenvx-ruby
89
- source_code_uri: https://github.com/dotenvx/dotenvx-ruby
90
- changelog_uri: https://github.com/dotenvx/dotenvx-ruby
88
+ homepage_uri: https://github.com/dotenvx/dotenvx
89
+ source_code_uri: https://github.com/dotenvx/dotenvx
90
+ changelog_uri: https://github.com/dotenvx/dotenvx
91
91
  post_install_message:
92
92
  rdoc_options: []
93
93
  require_paths: