varlock 1.23.0-x86_64-linux-gnu

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 71b6936c740e6ed3033399c8a2a2d9a808e96aa87f87502b4df27f9ee8d7d261
4
+ data.tar.gz: 768eba584b61322ebf6c0a615203f964c5935fa5d58d03a86905ec87c4de5aeb
5
+ SHA512:
6
+ metadata.gz: 4d766cf783665f36f235cf12952e70c90b9b3707b4f444fa6c4d03db9682b83930b5df86cab714253f95736f3f36d8c739cc750be0eb2d11acadf71f2fbd5f26
7
+ data.tar.gz: 19ec02ff677483e0ae7acb6eab8829bee021579e93ea77946c939410d1048fe0f3a941bc0fa8fdbd8f9c1e7a4daed2103ebadf526259f64806f5b9f999840bb6
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 1.23.0 (unreleased)
4
+
5
+ Initial Ruby gem release, bundling Varlock CLI 1.23.0.
6
+
7
+ - Ship platform gems for macOS ARM64 and Linux x86_64 with glibc, with verified upstream downloads and encryption helpers.
8
+ - Load typed configuration with `Varlock.load!`, apply values with `Varlock.load_and_set!`, and access the last successful load through `Varlock.config`.
9
+ - Provide an optional Rails boot integration and the `varlock:check` Rake task.
10
+ - Forward CLI arguments, streams, and exit status through `bundle exec varlock`.
11
+
12
+ Requires Ruby 2.7 or later. Rails is optional and has its own Ruby requirements.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 akodkod
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # Varlock for Ruby
2
+
3
+ A small, unofficial Ruby wrapper around the [Varlock CLI](https://varlock.dev).
4
+ Varlock resolves and validates your configuration; this gem returns typed Ruby values and can apply them to `ENV`.
5
+
6
+ ## Setup
7
+
8
+ Platform gems include Varlock 1.23.0 for macOS ARM64 (`arm64-darwin`) or Linux
9
+ x86_64 with glibc (`x86_64-linux-gnu`). No separate Varlock or Node.js installation
10
+ is needed. Alpine/musl, Intel macOS, Linux ARM64, and Windows are not packaged.
11
+ Configure your `.env.schema` and `.env` files using Varlock.
12
+
13
+ For a source checkout, run `ruby script/build.rb` before `bundle install` to
14
+ download and package the host binary. Published platform gems need no download
15
+ at installation or runtime.
16
+
17
+ Once the release is published to RubyGems, add:
18
+
19
+ ```ruby
20
+ # Gemfile
21
+ gem "varlock", "~> 1.23.0"
22
+ ```
23
+
24
+ Then run `bundle install`. Before publication, use `path: "/path/to/varlock"`
25
+ in your Gemfile or install the built platform gem from `pkg/`.
26
+
27
+ ```sh
28
+ bundle exec varlock --version
29
+ bundle exec varlock load
30
+ bundle exec varlock run -- ruby app.rb
31
+ ```
32
+
33
+ The Ruby launcher directly executes the bundled binary, forwarding arguments,
34
+ streams, and exit status. It never searches `PATH` for another `varlock`.
35
+
36
+ ## Ruby
37
+
38
+ ```ruby
39
+ require "varlock"
40
+
41
+ config = Varlock.load! # Typed values; leaves ENV unchanged
42
+ config.fetch("DATABASE_URL")
43
+
44
+ Varlock.load_and_set! # Stringifies values and updates ENV
45
+ ENV.fetch("DATABASE_URL")
46
+
47
+ # Optional settings:
48
+ Varlock.load_and_set!(path: "/path/to/app", env: "production", executable: "/usr/local/bin/varlock")
49
+ Varlock.load_and_set!(path: "/path/to/monorepo", env: nil, filter: "#api")
50
+ ```
51
+
52
+ Both methods accept the same options and invoke `varlock load --format json` without a shell. With no path,
53
+ Varlock uses its default search location. The environment defaults to
54
+ `ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"`, evaluated on each call.
55
+ Pass `env:` to override it, or `env: nil` to omit the CLI's `--env` option.
56
+ A schema's `@currentEnv` takes
57
+ precedence over `env:`. By default, the loader uses the bundled binary.
58
+ The executable option is a single program path, not a shell command.
59
+
60
+ `load!` returns a hash with the original JSON types, including nil values, without
61
+ changing `ENV`. `load_and_set!` returns a hash of the strings applied to `ENV`. Matching existing keys
62
+ are overwritten with Varlock's resolved values; unrelated keys are preserved.
63
+ Strings are kept verbatim, numbers and booleans become strings, and arrays/objects
64
+ are JSON encoded. Null values and omitted keys are skipped, preserving any existing
65
+ value. All output is parsed and checked before any environment variables are changed.
66
+ Call at startup, before starting application threads. Each call resolves again.
67
+
68
+ `Varlock.config` contains the original JSON values from the last successful load,
69
+ with unchanged string keys and native Ruby numbers, booleans, arrays, hashes, and
70
+ nil values. It is nil before the first successful load. Each successful load replaces
71
+ it; failed loads leave it unchanged. Both methods update `Varlock.config`.
72
+
73
+ Code that previously used `load!` to populate `ENV` should use `load_and_set!`.
74
+
75
+ For a Sorbet struct, transform keys in your application's `env.rb` and instantiate
76
+ the struct directly after loading. For example, given schema keys `APP_PORT` and
77
+ `APP_DEBUG`:
78
+
79
+ ```ruby
80
+ class EnvConfig < T::Struct
81
+ const :port, Integer
82
+ const :debug, T::Boolean
83
+ end
84
+
85
+ config = T.must(Varlock.config)
86
+ attributes = config.transform_keys { |key| key.delete_prefix("APP_").downcase.to_sym }
87
+ Env = T.let(EnvConfig.new(**attributes), EnvConfig)
88
+ ```
89
+
90
+ The config keys must match the struct's fields after transformation. Custom enum
91
+ values still need conversion to their Ruby enum instances. No `sorbet-schema`
92
+ deserialization or custom coercer is needed for native JSON types.
93
+
94
+ On CLI failure, missing executable, or invalid output, `Varlock::Error` is raised.
95
+ CLI failures include Varlock's stderr diagnostics, showing configuration errors
96
+ automatically without resolving a second time. Varlock handles redaction of its
97
+ diagnostics; custom executables should also avoid writing secrets to stderr.
98
+ Captured JSON stdout and JSON parse details are never included in errors.
99
+ If the CLI provides no diagnostics, the error suggests running `bundle exec varlock load`.
100
+
101
+ ## Rails
102
+
103
+ Use the optional Rails entry point instead of the default require:
104
+
105
+ ```ruby
106
+ # Gemfile
107
+ gem "varlock", "~> 1.23.0", require: "varlock/rails"
108
+ ```
109
+
110
+ The Railtie calls `Varlock.load_and_set!` in `before_configuration`, using the application
111
+ root and `Rails.env`. It runs in all environments, including tests, and a failure
112
+ stops application boot. Rails remains an optional dependency.
113
+
114
+ For variables needed earlier (for example, by another gem at require time), use
115
+ `require: false` in the Gemfile and load explicitly in `config/boot.rb`, immediately
116
+ after `require "bundler/setup"`:
117
+
118
+ ```ruby
119
+ require "varlock"
120
+ Varlock.load_and_set!(path: File.expand_path("..", __dir__))
121
+ ```
122
+
123
+ Choose either explicit boot loading or the Rails adapter to avoid resolving twice.
124
+ Avoid loading a second dotenv loader afterward, which could overwrite validated values.
125
+
126
+ If you already launch through `varlock run -- bundle exec rails server`, you can
127
+ use the injected `ENV` directly without this gem. The adapter does not detect or
128
+ skip a surrounding `varlock run`, and this gem does not add runtime log redaction.
129
+
130
+ ## Checking configuration
131
+
132
+ With the Rails adapter, the validation task is registered automatically:
133
+
134
+ ```sh
135
+ bin/rails varlock:check
136
+ RAILS_ENV=production bin/rails varlock:check
137
+ # Or: bundle exec rake varlock:check
138
+ ```
139
+
140
+ For a plain Ruby project, add this to your `Rakefile`:
141
+
142
+ ```ruby
143
+ require "varlock/tasks"
144
+ ```
145
+
146
+ Then run `bundle exec rake varlock:check`. The task runs `varlock load --format pretty`
147
+ with native stdout and stderr, including Varlock's validation summary and redaction.
148
+ It preserves the CLI's exit code on validation failure. It does not apply values
149
+ to `ENV` or update `Varlock.config`.
150
+
151
+ Configure the task using `VARLOCK_PATH`, `VARLOCK_FILTER`, and `VARLOCK_ENV`:
152
+
153
+ ```sh
154
+ VARLOCK_PATH=/path/to/app VARLOCK_FILTER='#api' bundle exec rake varlock:check
155
+ VARLOCK_PATH=/path/to/app VARLOCK_FILTER='#api' VARLOCK_ENV=production bin/rails varlock:check
156
+ VARLOCK_FILTER='APP_*,!APP_SECRET' bundle exec rake varlock:check
157
+ ```
158
+
159
+ The task accepts configuration only through environment variables. Without overrides,
160
+ plain Rake uses the loader's default path and environment; Rails uses the application
161
+ root and `Rails.env`. `VARLOCK_ENV` overrides the default environment in both cases.
162
+ The filter controls which items the CLI shows.
163
+
164
+ The task does not initialize the Rails application. When `varlock:check` is the
165
+ only requested task, the Rails adapter skips its auto-loading hook, so validation
166
+ runs once with the supplied overrides. If you request additional tasks in the same
167
+ command, the hook still runs to supply their environment configuration.
168
+
169
+ ## Development
170
+
171
+ ```sh
172
+ ruby script/build.rb
173
+ bundle install
174
+ bundle exec rake test
175
+ ruby script/smoke.rb
176
+ ```
177
+
178
+ Default tests use a fixture executable and do not need Varlock or real secrets. To include
179
+ the actual Rails boot test, install with `RAILS_VERSION='~> 7.2.0' bundle install`
180
+ and run `RAILS_VERSION='~> 7.2.0' bundle exec rake test` on Ruby 3.2+.
181
+ CI builds and tests Linux x86_64 and macOS ARM64 packages, including the installed
182
+ gem launcher and real CLI integration. Ruby 2.7+ is accepted by the gem;
183
+ Rails has its own newer Ruby requirements.
184
+
185
+ ### RuboCop
186
+
187
+ Use Ruby 3.2+ for development tooling, then run `bundle install` and
188
+ `bundle exec rubocop`. The configuration is adapted from 811spotter's API,
189
+ keeping core Ruby rules, `rubocop-performance`, and the pinned `rubocop-sane`
190
+ plugin. Rails, RSpec, GraphQL, Sorbet, and app-specific rules are omitted.
191
+ Test exclusions use `test/` rather than `spec/`.
192
+
193
+ The lint target is Ruby 2.7, the oldest target supported by this RuboCop version;
194
+ the gem's runtime requirement remains Ruby 2.7+. Existing files have not been
195
+ bulk-formatted as part of importing these rules.
196
+
197
+ ### Testing with the real Varlock CLI
198
+
199
+ Build the bundled CLI, then enable the optional integration tests:
200
+
201
+ ```sh
202
+ ruby script/build.rb
203
+ VARLOCK_INTEGRATION=1 bundle exec rake test
204
+ # Include the Rails test too, after installing its dependency as described above:
205
+ RAILS_VERSION='~> 7.2.0' VARLOCK_INTEGRATION=1 bundle exec rake test
206
+ ```
207
+
208
+ The real CLI tests copy `test/fixtures/schema/.env.schema` into a temporary
209
+ directory. They check defaults, numbers/booleans, interpolation, synthetic sensitive
210
+ values, empty/undefined values, `.env.test` overrides, and failures for an invalid
211
+ number or missing required value. No real credentials or external services are used.
212
+ These tests were verified locally with Varlock 1.23.0 and Ruby 3.3.5.
213
+
214
+ To try the fixture directly from this checkout:
215
+
216
+ ```sh
217
+ ruby -Ilib -rvarlock -e 'Varlock.load_and_set!(path: "test/fixtures/schema"); puts ENV.fetch("VARLOCK_REAL_URL")'
218
+ # http://localhost:3000
219
+ ```
220
+
221
+ The Ruby wrapper is available under the [MIT license](LICENSE). The bundled
222
+ Varlock CLI retains its [upstream MIT license](licenses/VARLOCK-MIT.txt).
223
+ See [RELEASING.md](RELEASING.md) for validation and publishing instructions.
224
+
225
+ ## Building platform gems
226
+
227
+ ```sh
228
+ ruby script/build.rb arm64-darwin
229
+ ruby script/build.rb x86_64-linux-gnu
230
+ ```
231
+
232
+ Both commands can run on either supported host; executing the result requires
233
+ the matching platform. Packages are written to `pkg/`. Each contains only its
234
+ platform's executable and upstream encryption helpers, plus the upstream MIT
235
+ license in `licenses/VARLOCK-MIT.txt`. Downloads are cached under `vendor/downloads`
236
+ by CLI version and checked against pinned SHA-256 hashes in `lib/varlock/release.json`.
237
+ Source maps are omitted. Binaries and built gems are ignored by Git.
238
+
239
+ ## Updating bundled Varlock
240
+
241
+ ```sh
242
+ ruby script/update_binaries.rb 1.23.0 # Replace with the desired release version
243
+ RAILS_VERSION='~> 7.2.0' VARLOCK_INTEGRATION=1 bundle exec rake test
244
+ ruby script/smoke.rb
245
+ ```
246
+
247
+ The updater downloads the release's `checksums.txt`, both platform archives, and
248
+ its license. It verifies both archives before updating the version/checksum pins
249
+ in `lib/varlock/release.json`, refreshes the license, and rebuilds both gems in
250
+ `pkg/`. A failed download or checksum check leaves the existing pins and binaries
251
+ unchanged. If a build fails after the pins are updated, rerun `script/build.rb`
252
+ for that platform. An explicit stable release version is required; the script
253
+ does not silently select the latest version or publish packages.
254
+
255
+ Review the manifest and license changes and run runtime tests on both hosts.
256
+ The gem version matches the embedded CLI version. The updater generates
257
+ `lib/varlock/version.rb` from the verified release version before building both
258
+ packages, so there is no separate manual version bump. Versioned download caches
259
+ prevent reuse of older archives.
data/RELEASING.md ADDED
@@ -0,0 +1,67 @@
1
+ # Releasing
2
+
3
+ The gem version follows the bundled CLI version. The first prepared release is
4
+ 1.23.0. Publishing is manual; building or updating binaries never uploads gems.
5
+
6
+ ## Prepare and validate
7
+
8
+ Use Ruby 3.2+ for development tooling. For a new CLI release, first run
9
+ `ruby script/update_binaries.rb VERSION` and review the manifest and upstream license.
10
+ For a wrapper-only follow-up, use a fourth version component (for example
11
+ 1.23.0.1) and update the version-equality checks and updater policy before releasing.
12
+ RubyGems versions cannot be replaced after publication.
13
+
14
+ 1. Update `CHANGELOG.md`, replacing `unreleased` with the release date.
15
+ 2. Build both platform gems:
16
+
17
+ ```sh
18
+ ruby script/build.rb arm64-darwin
19
+ ruby script/build.rb x86_64-linux-gnu
20
+ ```
21
+
22
+ 3. On each supported host, run the checks used by CI:
23
+
24
+ ```sh
25
+ RAILS_VERSION='~> 7.2.0' bundle install
26
+ bundle exec rubocop
27
+ RAILS_VERSION='~> 7.2.0' VARLOCK_INTEGRATION=1 bundle exec rake test
28
+ ruby script/smoke.rb
29
+ ```
30
+
31
+ The smoke test installs the host package into a temporary gem directory and
32
+ exercises its CLI, Ruby loader, and exit status. Cross-building does not test
33
+ the other platform's executable. Require passing Linux and macOS CI before publishing.
34
+
35
+ 4. Review and commit the release changes. Confirm both packages contain `LICENSE`,
36
+ `licenses/VARLOCK-MIT.txt`, the release manifest, and only the intended platform's
37
+ binaries. Keep the resulting artifacts for publication.
38
+
39
+ Use `script/build.rb`, not plain `gem build`: the build script verifies upstream
40
+ checksums and sets the platform explicitly. The source-checkout specification uses
41
+ the generic Ruby platform for Bundler; that generic package must not be published.
42
+ Avoid wildcard pushes because `pkg/` may contain artifacts from older versions.
43
+
44
+ ## Publish
45
+
46
+ Confirm the `varlock` name is available or owned by your RubyGems account. Enable
47
+ MFA on the account (required by the gem metadata), and authenticate using your
48
+ normal RubyGems credentials. Do not commit API keys.
49
+
50
+ For version 1.23.0, publish exactly these artifacts after validation:
51
+
52
+ ```sh
53
+ gem push pkg/varlock-1.23.0-arm64-darwin.gem
54
+ gem push pkg/varlock-1.23.0-x86_64-linux-gnu.gem
55
+ ```
56
+
57
+ Verify both platforms appear on RubyGems, then tag the committed release:
58
+
59
+ ```sh
60
+ git tag -a v1.23.0 -m 'Release 1.23.0'
61
+ git push origin v1.23.0
62
+ ```
63
+
64
+ If only one upload succeeds, retry only the missing platform. Verify a fresh
65
+ `gem install varlock -v 1.23.0` on each supported host and create a GitHub release
66
+ using the changelog notes. Update the README's prepublication wording when the
67
+ packages are live.
data/exe/varlock ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "varlock"
5
+
6
+ begin
7
+ exec(Varlock.executable_path, *ARGV)
8
+ rescue Varlock::Error, SystemCallError => e
9
+ warn "varlock: #{e.message}"
10
+ exit 1
11
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+ require "json"
5
+
6
+ module Varlock
7
+ class Error < StandardError; end
8
+
9
+ RELEASE = JSON.parse(File.read(File.join(__dir__, "release.json")))
10
+ CLI_VERSION = RELEASE.fetch("version").freeze
11
+ SUPPORTED_PLATFORMS = RELEASE.fetch("platforms").keys.freeze
12
+
13
+ def self.binary_platform
14
+ platform = Gem::Platform.local
15
+ return "arm64-darwin" if platform.os == "darwin" && platform.cpu == "arm64"
16
+
17
+ if platform.os == "linux" && platform.cpu == "x86_64" && platform.version != "musl"
18
+ return "x86_64-linux-gnu"
19
+ end
20
+
21
+ raise Error, "No bundled Varlock for #{platform}. Pass executable: to use your own CLI."
22
+ end
23
+
24
+ def self.executable_path
25
+ path = File.expand_path("../../vendor/#{binary_platform}/varlock", __dir__)
26
+
27
+ unless File.executable?(path)
28
+ raise Error, "Bundled Varlock is missing. Reinstall the platform gem or run ruby script/build.rb in a source checkout."
29
+ end
30
+
31
+ path
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "varlock"
4
+ require "rails/railtie"
5
+
6
+ module Varlock
7
+ class Railtie < Rails::Railtie
8
+ rake_tasks do
9
+ require "varlock/tasks"
10
+ end
11
+
12
+ config.before_configuration do |app|
13
+ next if defined?(Rake) && Rake.application.top_level_tasks == ["varlock:check"]
14
+
15
+ Varlock.load_and_set!(path: app.root.to_s, env: Rails.env.to_s)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "1.23.0",
3
+ "platforms": {
4
+ "arm64-darwin": {
5
+ "archive": "varlock-macos-arm64.tar.gz",
6
+ "sha256": "7d14daeb9d749b24355280954a9c1b7087533855296b3ac44df6c46ba7d582bc"
7
+ },
8
+ "x86_64-linux-gnu": {
9
+ "archive": "varlock-linux-x64.tar.gz",
10
+ "sha256": "a40d86ceddde2f032cd8bdc594feca74f60754d01615c1a11031c9f4ca97e8ed"
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+ require "varlock"
5
+
6
+ namespace :varlock do
7
+ desc "Validate configuration with native Varlock output (VARLOCK_PATH, VARLOCK_FILTER, VARLOCK_ENV)"
8
+ task :check do
9
+ rails_app = Rails.application if defined?(Rails) && Rails.respond_to?(:application)
10
+
11
+ path = ENV["VARLOCK_PATH"] || rails_app&.root&.to_s
12
+ filter = ENV["VARLOCK_FILTER"]
13
+ env = ENV["VARLOCK_ENV"] || (rails_app ? Rails.env.to_s : ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
14
+
15
+ command = [Varlock.executable_path.to_s, "load", "--format", "pretty"]
16
+ command.push("--path", path) if path
17
+ command.push("--filter", filter) if filter
18
+ command.push("--env", env)
19
+
20
+ success = system(*command)
21
+ raise Varlock::Error, "Could not start the Varlock executable. Check its path and permissions." if success.nil?
22
+
23
+ exit(Process.last_status.exitstatus || 1) unless success
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by script/update_binaries.rb from the pinned Varlock release
4
+ module Varlock
5
+ VERSION = "1.23.0"
6
+ end
data/lib/varlock.rb ADDED
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "open3"
5
+ require_relative "varlock/version"
6
+ require_relative "varlock/binary"
7
+
8
+ module Varlock
9
+ # Original JSON values from the last successful load, or nil before loading
10
+ def self.config
11
+ @config
12
+ end
13
+
14
+ # Resolve and validate configuration without changing ENV. Preserve JSON types.
15
+ def self.load!(**options)
16
+ config, = resolve_values(**options)
17
+ @config = config
18
+ end
19
+
20
+ # Resolve and validate everything before changing ENV. Returned values are strings.
21
+ def self.load_and_set!(**options)
22
+ config, values = resolve_values(**options)
23
+ ENV.update(values)
24
+ @config = config
25
+ values
26
+ end
27
+
28
+ def self.resolve_values(path: nil, env: ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development", filter: nil, executable: executable_path)
29
+ command = [executable.to_s, "load", "--format", "json"]
30
+ command.push("--path", path.to_s) if path
31
+ command.push("--env", env.to_s) if env
32
+ command.push("--filter", filter.to_s) if filter
33
+ stdout, stderr, status = Open3.capture3(*command)
34
+
35
+ unless status.success?
36
+ message = "Varlock failed (exit #{status.exitstatus || 'signal'})."
37
+ diagnostics = stderr.strip
38
+ message += diagnostics.empty? ? " Run bundle exec varlock load to inspect configuration." : "\n#{diagnostics}"
39
+ raise Error, message
40
+ end
41
+
42
+ parse_values(stdout)
43
+ rescue Errno::ENOENT
44
+ raise Error, "Varlock executable not found. Install the Varlock CLI or pass executable:.", cause: nil
45
+ rescue Errno::EACCES
46
+ raise Error, "Varlock executable is not executable. Check its permissions.", cause: nil
47
+ end
48
+ private_class_method :resolve_values
49
+
50
+ def self.parse_values(output)
51
+ data = JSON.parse(output)
52
+ raise Error, "Varlock output must be a JSON object." unless data.is_a?(Hash)
53
+
54
+ values = data.each_with_object({}) do |(key, value), result|
55
+ if key.empty? || key.include?("=") || key.include?("\0")
56
+ raise Error, "Varlock returned an invalid environment variable name."
57
+ end
58
+
59
+ next if value.nil?
60
+
61
+ string = value.is_a?(String) ? value : JSON.generate(value)
62
+ raise Error, "Varlock returned a value containing a null byte." if string.include?("\0")
63
+
64
+ result[key] = string
65
+ end
66
+
67
+ [data, values]
68
+ rescue JSON::ParserError, JSON::GeneratorError
69
+ # Parser exceptions can contain secrets from the input. Do not chain them.
70
+ raise Error, "Varlock returned invalid JSON.", cause: nil
71
+ end
72
+ private_class_method :parse_values
73
+ end
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DMNO Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ [diffend] Oversized file quarantined before diffing.
2
+ name: data/vendor/x86_64-linux-gnu/varlock
3
+ size: 88970720 bytes
4
+ sha256: 34726a0fef40d1d7458466bac22da9d6fa42b02f443490033cbc7adab4a0f190
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: varlock
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.23.0
5
+ platform: x86_64-linux-gnu
6
+ authors:
7
+ - akodkod
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.1'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '4'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '2.1'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '4'
32
+ - !ruby/object:Gem::Dependency
33
+ name: open3
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0.1'
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '1'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0.1'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '1'
52
+ description: A small wrapper around the Varlock CLI with an optional Rails boot integration.
53
+ executables:
54
+ - varlock
55
+ extensions: []
56
+ extra_rdoc_files: []
57
+ files:
58
+ - CHANGELOG.md
59
+ - LICENSE
60
+ - README.md
61
+ - RELEASING.md
62
+ - exe/varlock
63
+ - lib/varlock.rb
64
+ - lib/varlock/binary.rb
65
+ - lib/varlock/rails.rb
66
+ - lib/varlock/release.json
67
+ - lib/varlock/tasks.rb
68
+ - lib/varlock/version.rb
69
+ - licenses/VARLOCK-MIT.txt
70
+ - vendor/x86_64-linux-gnu/varlock
71
+ - vendor/x86_64-linux-gnu/varlock-local-encrypt
72
+ - vendor/x86_64-linux-gnu/varlock-local-encrypt.exe
73
+ homepage: https://github.com/akodkod/varlock
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ rubygems_mfa_required: 'true'
78
+ allowed_push_host: https://rubygems.org
79
+ source_code_uri: https://github.com/akodkod/varlock
80
+ bug_tracker_uri: https://github.com/akodkod/varlock/issues
81
+ changelog_uri: https://github.com/akodkod/varlock/blob/main/CHANGELOG.md
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '2.7'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 4.0.20
97
+ specification_version: 4
98
+ summary: Load validated environment variables into Ruby using Varlock.
99
+ test_files: []