unifig-env 0.3.0 → 0.3.1

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: 6dd90ff75c3bdc6a91214a289e1075f3c99c55e77ab6c7cbecc6a972a1e6a933
4
- data.tar.gz: 1865d23646a0377f368880ec973404e2ddc50d467d343f4cb723062f585b363c
3
+ metadata.gz: 4f2d1338c397c1f5c2ceaa7819cb67e06ed6eea4c54e225c8ed398dcc82bc107
4
+ data.tar.gz: 6a8df43fd3c7cab42cea78a768749d5ab83fbc60cc0570397d77efbcf5d09802
5
5
  SHA512:
6
- metadata.gz: 2cd00b09159eb1311ac39de13c259109af5d6b349026f51786eb23b55649a1232cc575573bcb1f85517383e1cf605ad5d577f0786e05c2e3f5c6d539583ca0ef
7
- data.tar.gz: 6f55ca98475a3265c7bd8b88cd8f258960a1844a3b5854a02f10dfa2a277595c9e7032c31ec17a609d12d431bb33c81a74961fd4e5b0c21cacfa29a14390f530
6
+ metadata.gz: febd724191f72d90b8f26d075cb3f939803e0a8f975c3afb4e77836068fd41f5535d31401b697cdd18df986c4736f7c8757d84b6dacb8c70f1deca48cbd4e818
7
+ data.tar.gz: 75208b5aa9ffdac96cd7ab6f4bd91a7afacb7679720ef2fc9654d6331570e0f88f10297127c48ee304c6c892c54e82c6b3f53d14bbf0c7deac596b182ebd80d7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # [0.3.1][] (2022-10-18)
2
+
3
+ ## Added
4
+
5
+ - An `env-file` provider for dotenv (e.g. `.env`) files.
6
+
1
7
  # [0.3.0][] (2022-09-01)
2
8
 
3
9
  ## Changed
@@ -14,6 +20,7 @@
14
20
 
15
21
  Initial release.
16
22
 
23
+ [0.3.1]: https://github.com/AaronLasseigne/unifig-env/compare/v0.3.0...v0.3.1
17
24
  [0.3.0]: https://github.com/AaronLasseigne/unifig-env/compare/v0.2.0...v0.3.0
18
25
  [0.2.0]: https://github.com/AaronLasseigne/unifig-env/compare/v0.1.0...v0.2.0
19
26
  [0.1.0]: https://github.com/AaronLasseigne/unifig-env/compare/v0.0.0...v0.1.0
data/README.md CHANGED
@@ -10,13 +10,13 @@ Adds a provider to support loading environment variables to [Unifig][].
10
10
  Add it to your Gemfile:
11
11
 
12
12
  ``` rb
13
- gem 'unifig-env', '~> 0.3.0'
13
+ gem 'unifig-env', '~> 0.3.1'
14
14
  ```
15
15
 
16
16
  Or install it manually:
17
17
 
18
18
  ``` sh
19
- $ gem install unifig-env --version '~> 0.3.0'
19
+ $ gem install unifig-env --version '~> 0.3.1'
20
20
  ```
21
21
 
22
22
  This project uses [Semantic Versioning][].
@@ -24,6 +24,8 @@ Check out [GitHub releases][] for a detailed list of changes.
24
24
 
25
25
  ## Usage
26
26
 
27
+ ### Environment
28
+
27
29
  Use `env` as your provider or add it to your list of providers:
28
30
 
29
31
  ``` yml
@@ -35,6 +37,27 @@ HOST:
35
37
 
36
38
  This will pull `"HOST"` from `ENV` and add it to Unifig.
37
39
 
40
+ ### Environment File
41
+
42
+ Use `env-file` as your provider or add it to your list of providers:
43
+
44
+ ``` yml
45
+ unifig:
46
+ providers: env-file
47
+ ```
48
+
49
+ By default, it looks for `.env` in the local directory.
50
+ The file can be specified by passing `file` to the configuration.
51
+
52
+ ``` yml
53
+ unifig:
54
+ providers:
55
+ list: env-file
56
+ config:
57
+ env-file:
58
+ file: my.env
59
+ ```
60
+
38
61
  ## Contributing
39
62
 
40
63
  If you want to contribute to Unifig:Env, please read [our contribution guidelines][].
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'strscan'
4
+
5
+ module Unifig
6
+ module Env
7
+ # @private
8
+ module Parser
9
+ Error = Class.new(Unifig::Error)
10
+
11
+ WHITESPACE = /\s*/.freeze
12
+ COMMENT = /\#.*$/.freeze
13
+ EXPORT = /export\s+/.freeze
14
+ KEY = /[^=\s]+/.freeze
15
+ ASSIGNMENT = /\s*=\s*/.freeze
16
+ SINGLE_LINE_VALUE = /\S+/.freeze
17
+ QUOTE = /['"]/.freeze
18
+ TO_END_OF_LINE = /\s*(?:\#.*)?$/.freeze
19
+
20
+ class << self
21
+ def call(file_path)
22
+ content = File.read(file_path)
23
+
24
+ vars = {}
25
+ parser = StringScanner.new(content.strip)
26
+ until parser.eos?
27
+ parser.skip(WHITESPACE)
28
+
29
+ next if parser.skip(COMMENT)
30
+
31
+ parser.skip(EXPORT)
32
+ key = extract!(parser, KEY, 'Missing env key on line %i')
33
+ extract!(parser, ASSIGNMENT, 'Missing env var assignment on line %i')
34
+ quote = parser.scan(QUOTE)
35
+ value =
36
+ if quote
37
+ parser.scan(/.*?#{quote}/m).chop
38
+ else
39
+ parser.scan(SINGLE_LINE_VALUE)
40
+ end
41
+
42
+ extract!(parser, TO_END_OF_LINE, 'Invalid env var value on line %i')
43
+
44
+ vars[key] = value
45
+ end
46
+
47
+ vars
48
+ end
49
+
50
+ private
51
+
52
+ def line(parser)
53
+ parser.string[0...parser.pos].scan(/$/).count
54
+ end
55
+
56
+ def extract!(parser, pattern, error_msg)
57
+ parser.scan(pattern).tap do |match|
58
+ raise Error, error_msg % line(parser) if match.nil?
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Unifig
4
4
  module Env
5
- VERSION = '0.3.0'
5
+ VERSION = '0.3.1'
6
6
  end
7
7
  end
data/lib/unifig/env.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'unifig'
4
+
3
5
  require_relative 'env/version'
6
+ require_relative 'env/parser'
4
7
  require_relative 'providers/env'
8
+ require_relative 'providers/env-file'
5
9
 
6
10
  module Unifig
7
11
  # @private
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unifig
4
+ module Providers
5
+ # @private
6
+ module EnvFile
7
+ PATH = File.join(Dir.pwd, '.env')
8
+ private_constant :PATH
9
+
10
+ class << self
11
+ def name
12
+ :'env-file'
13
+ end
14
+
15
+ def retrieve(var_names, config)
16
+ env_vars = Unifig::Env::Parser.call(config.fetch(:file, PATH))
17
+
18
+ var_names.to_h do |name|
19
+ [name, env_vars[name.to_s]]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -8,7 +8,7 @@ module Unifig
8
8
  :env
9
9
  end
10
10
 
11
- def self.retrieve(var_names)
11
+ def self.retrieve(var_names, _config)
12
12
  var_names.to_h do |name|
13
13
  [name, ::ENV[name.to_s]]
14
14
  end
@@ -0,0 +1,89 @@
1
+ require 'tempfile'
2
+
3
+ RSpec.describe Unifig::Env::Parser do
4
+ describe '.call' do
5
+ let(:file_content) do
6
+ <<~ENV
7
+ # standalone comment
8
+ ONE=1
9
+ export TWO=2
10
+ THREE = 3 # in-line comment
11
+
12
+ MULTI_LINE="
13
+ first
14
+ second
15
+ "
16
+ ENV
17
+ end
18
+ let(:file) do
19
+ file = Tempfile.new('.env', Dir.pwd)
20
+ file.write(file_content)
21
+ file.close
22
+ file
23
+ end
24
+ let(:config) { { file: file.path } }
25
+
26
+ after do
27
+ file.unlink
28
+ end
29
+
30
+ it 'returns a hash representing the env vars loaded from the file' do
31
+ result = described_class.call(file.path)
32
+
33
+ expect(result).to be_an_instance_of(Hash)
34
+ expect(result.keys.size).to be 4
35
+ expect(result['ONE']).to eql '1'
36
+ expect(result['TWO']).to eql '2'
37
+ expect(result['THREE']).to eql '3'
38
+ expect(result['MULTI_LINE']).to eql "\nfirst\nsecond\n"
39
+ end
40
+
41
+ context 'with a missing key' do
42
+ let(:file_content) { '=1' }
43
+
44
+ it 'throws an error' do
45
+ expect do
46
+ described_class.call(file.path)
47
+ end.to raise_error Unifig::Env::Parser::Error, 'Missing env key on line 1'
48
+ end
49
+ end
50
+
51
+ context 'with no equal sign' do
52
+ let(:file_content) { 'ONE' }
53
+
54
+ it 'throws an error' do
55
+ expect do
56
+ described_class.call(file.path)
57
+ end.to raise_error Unifig::Env::Parser::Error, 'Missing env var assignment on line 1'
58
+ end
59
+ end
60
+
61
+ context 'with an invalid value' do
62
+ let(:file_content) { 'ONE=1 2' }
63
+
64
+ it 'throws an error' do
65
+ expect do
66
+ described_class.call(file.path)
67
+ end.to raise_error Unifig::Env::Parser::Error, 'Invalid env var value on line 1'
68
+ end
69
+ end
70
+
71
+ context 'an error later in the file' do
72
+ let(:file_content) do
73
+ <<~ENV
74
+ ONE=1
75
+ TWO=2
76
+
77
+ FOUR=4 invalid
78
+ FIVE=5
79
+ ENV
80
+ end
81
+
82
+ it 'puts the correct line' do
83
+ expect do
84
+ described_class.call(file.path)
85
+ end.to raise_error Unifig::Env::Parser::Error, 'Invalid env var value on line 4'
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,45 @@
1
+ require 'tempfile'
2
+
3
+ RSpec.describe Unifig::Providers::EnvFile do
4
+ describe '.name' do
5
+ it 'returns the provider name' do
6
+ expect(described_class.name).to be :'env-file'
7
+ end
8
+ end
9
+
10
+ describe '.retrieve' do
11
+ let(:file) do
12
+ file = Tempfile.new('.env', Dir.pwd)
13
+ file.write <<~ENV
14
+ # standalone comment
15
+ ONE=1
16
+ export TWO=2
17
+ THREE = 3 # in-line comment
18
+
19
+ MULTI_LINE="
20
+ first
21
+ second
22
+ "
23
+ ENV
24
+ file.close
25
+ file
26
+ end
27
+ let(:config) { { file: file.path } }
28
+
29
+ after do
30
+ file.unlink
31
+ end
32
+
33
+ it 'returns a hash of only the available vars' do
34
+ result = described_class.retrieve(%i[ONE TWO THREE MULTI_LINE INVALID], config)
35
+
36
+ expect(result).to be_an_instance_of(Hash)
37
+ expect(result.keys.size).to be 5
38
+ expect(result[:ONE]).to eql '1'
39
+ expect(result[:TWO]).to eql '2'
40
+ expect(result[:THREE]).to eql '3'
41
+ expect(result[:MULTI_LINE]).to eql "\nfirst\nsecond\n"
42
+ expect(result[:INVALID]).to be_nil
43
+ end
44
+ end
45
+ end
@@ -8,18 +8,18 @@ RSpec.describe Unifig::Providers::Env do
8
8
  describe '.retrieve' do
9
9
  before do
10
10
  allow(ENV).to receive(:[]).and_return(nil)
11
- allow(ENV).to receive(:[]).with('FOO').and_return('foo')
12
- allow(ENV).to receive(:[]).with('BAR').and_return('bar')
11
+ allow(ENV).to receive(:[]).with('ONE').and_return('1')
12
+ allow(ENV).to receive(:[]).with('TWO').and_return('2')
13
13
  end
14
14
 
15
15
  it 'returns a hash of only the available vars' do
16
- result = described_class.retrieve(%i[FOO BAR BAZ])
16
+ result = described_class.retrieve(%i[ONE TWO INVALID], {})
17
17
 
18
18
  expect(result).to be_an_instance_of(Hash)
19
19
  expect(result.keys.size).to be 3
20
- expect(result[:FOO]).to eql 'foo'
21
- expect(result[:BAR]).to eql 'bar'
22
- expect(result[:BAZ]).to be_nil
20
+ expect(result[:ONE]).to eql '1'
21
+ expect(result[:TWO]).to eql '2'
22
+ expect(result[:INVALID]).to be_nil
23
23
  end
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unifig-env
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Lasseigne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-01 00:00:00.000000000 Z
11
+ date: 2022-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: unifig
@@ -36,9 +36,13 @@ files:
36
36
  - LICENSE.txt
37
37
  - README.md
38
38
  - lib/unifig/env.rb
39
+ - lib/unifig/env/parser.rb
39
40
  - lib/unifig/env/version.rb
41
+ - lib/unifig/providers/env-file.rb
40
42
  - lib/unifig/providers/env.rb
41
43
  - spec/spec_helper.rb
44
+ - spec/unifig/env/parser_spec.rb
45
+ - spec/unifig/providers/env-file_spec.rb
42
46
  - spec/unifig/providers/env_spec.rb
43
47
  homepage: https://github.com/AaronLasseigne/unifig-env
44
48
  licenses:
@@ -69,4 +73,6 @@ specification_version: 4
69
73
  summary: Adds a provider to support loading environment variables to Unifig.
70
74
  test_files:
71
75
  - spec/spec_helper.rb
76
+ - spec/unifig/env/parser_spec.rb
77
+ - spec/unifig/providers/env-file_spec.rb
72
78
  - spec/unifig/providers/env_spec.rb