kvcsv 0.1.0

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: c196d089eae70c2cb577159c522bb1be9c6a8fb4e3f58a99665b4ebae483c379
4
+ data.tar.gz: f3f178417a8cddfb3fd40afb6080a454f45acb2ff5fae6dec6927c76db82ead0
5
+ SHA512:
6
+ metadata.gz: 791e43d7cb1308d7fd629eb531ac8cf918077cde255c30da8ba0efa65ab7050f9621a797b40ac18df0adaf8a8c33832c8c6fa71fec0c67576cf73472184c5fe0
7
+ data.tar.gz: 48dde60b19009ed1d7e1b83cdf5caa6f695e5545085d505495bc5d636264e818b72d225c0a19defddfca3b632f0670b26cfb19c262a8989b09dd64adb9b814ca
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rspec_status ADDED
@@ -0,0 +1,34 @@
1
+ example_id | status | run_time |
2
+ -------------------------------------- | ------ | --------------- |
3
+ ./spec/kvcsv/settings_spec.rb[1:1:1] | passed | 0.00059 seconds |
4
+ ./spec/kvcsv/settings_spec.rb[1:1:2] | passed | 0.00214 seconds |
5
+ ./spec/kvcsv/settings_spec.rb[1:1:3] | passed | 0.0006 seconds |
6
+ ./spec/kvcsv/settings_spec.rb[1:1:4] | passed | 0.00056 seconds |
7
+ ./spec/kvcsv/settings_spec.rb[1:1:5] | passed | 0.00057 seconds |
8
+ ./spec/kvcsv/settings_spec.rb[1:2:1] | passed | 0.00066 seconds |
9
+ ./spec/kvcsv/settings_spec.rb[1:2:2] | passed | 0.00058 seconds |
10
+ ./spec/kvcsv/settings_spec.rb[1:3:1] | passed | 0.00091 seconds |
11
+ ./spec/kvcsv/settings_spec.rb[1:3:2] | passed | 0.00056 seconds |
12
+ ./spec/kvcsv/settings_spec.rb[1:3:3] | passed | 0.00233 seconds |
13
+ ./spec/kvcsv/settings_spec.rb[1:4:1] | passed | 0.00191 seconds |
14
+ ./spec/kvcsv/settings_spec.rb[1:5:1] | passed | 0.00068 seconds |
15
+ ./spec/kvcsv/settings_spec.rb[1:6:1:1] | passed | 0.00053 seconds |
16
+ ./spec/kvcsv/settings_spec.rb[1:6:1:2] | passed | 0.00098 seconds |
17
+ ./spec/kvcsv/settings_spec.rb[1:6:1:3] | passed | 0.00055 seconds |
18
+ ./spec/kvcsv/settings_spec.rb[1:6:1:4] | passed | 0.00058 seconds |
19
+ ./spec/kvcsv/settings_spec.rb[1:6:1:5] | passed | 0.00054 seconds |
20
+ ./spec/kvcsv/settings_spec.rb[1:6:1:6] | passed | 0.00056 seconds |
21
+ ./spec/kvcsv/settings_spec.rb[1:6:2:1] | passed | 0.00091 seconds |
22
+ ./spec/kvcsv/settings_spec.rb[1:6:2:2] | passed | 0.00055 seconds |
23
+ ./spec/kvcsv/settings_spec.rb[1:6:2:3] | passed | 0.00056 seconds |
24
+ ./spec/kvcsv/settings_spec.rb[1:6:2:4] | passed | 0.00055 seconds |
25
+ ./spec/kvcsv/settings_spec.rb[1:6:2:5] | passed | 0.00054 seconds |
26
+ ./spec/kvcsv/settings_spec.rb[1:6:2:6] | passed | 0.00054 seconds |
27
+ ./spec/kvcsv/settings_spec.rb[1:6:3:1] | passed | 0.00055 seconds |
28
+ ./spec/kvcsv/settings_spec.rb[1:6:3:2] | passed | 0.00145 seconds |
29
+ ./spec/kvcsv/settings_spec.rb[1:6:3:3] | passed | 0.00056 seconds |
30
+ ./spec/kvcsv/settings_spec.rb[1:6:3:4] | passed | 0.00057 seconds |
31
+ ./spec/kvcsv/settings_spec.rb[1:6:3:5] | passed | 0.00058 seconds |
32
+ ./spec/kvcsv/settings_spec.rb[1:6:3:6] | passed | 0.00061 seconds |
33
+ ./spec/kvcsv/settings_spec.rb[1:6:4] | passed | 0.00063 seconds |
34
+ ./spec/kvcsv/settings_spec.rb[1:7:1] | passed | 0.00105 seconds |
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-09-24
4
+
5
+ ### Added
6
+
7
+ - Initial release of KVCSV gem
8
+ - Load settings from one or more CSV files
9
+ - Automatic type conversion for boolean values (true/false)
10
+ - Automatic type conversion for nil values
11
+ - Symbol-based key access
12
+ - Support for merging multiple configuration files
13
+ - Enumerable interface with map, select, and fetch methods
14
+ - YARD documentation for all public methods
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ryan Duryea
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,124 @@
1
+ # Kvcsv
2
+
3
+ A lightweight Ruby gem for managing application settings from CSV files. Kvcsv provides a simple, read-only interface for loading configuration from one or more CSV files with automatic type conversion for boolean and nil values.
4
+
5
+ ## Features
6
+
7
+ - Load settings from one or more CSV files
8
+ - Automatic type conversion (true/false/nil)
9
+ - Simple key-based access with symbol keys
10
+ - Support for default values via `fetch`
11
+ - Enumerable interface (map, select, etc.)
12
+ - Later files override earlier ones for easy environment-specific configuration
13
+
14
+ ## Installation
15
+
16
+ Install the gem and add to the application's Gemfile by executing:
17
+
18
+ ```bash
19
+ bundle add kvcsv
20
+ ```
21
+
22
+ If bundler is not being used to manage dependencies, install the gem by executing:
23
+
24
+ ```bash
25
+ gem install kvcsv
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### CSV File Format
31
+
32
+ Create CSV files with two columns: `key` and `value`:
33
+
34
+ ```csv
35
+ key,value
36
+ database_host,localhost
37
+ database_port,5432
38
+ debug,true
39
+ cache_enabled,false
40
+ api_key,sk-1234567890
41
+ timeout,30
42
+ environment,production
43
+ ```
44
+
45
+ ### Basic Usage
46
+
47
+ ```ruby
48
+ require 'kvcsv'
49
+
50
+ # Load from a single file
51
+ settings = KVCSV::Settings.new("config/app.csv")
52
+
53
+ # Access settings
54
+ database_host = settings[:database_host] # => "localhost"
55
+ debug_mode = settings[:debug] # => true (automatically converted)
56
+ missing_key = settings[:missing_key] # => nil
57
+
58
+ # Use fetch with defaults
59
+ port = settings.fetch(:port, 3000) # => 3000 (default value)
60
+ ```
61
+
62
+ ### Loading Multiple Files
63
+
64
+ Later files override values from earlier files:
65
+
66
+ ```ruby
67
+ # config/defaults.csv has debug=false
68
+ # config/production.csv has debug=true
69
+ settings = KVCSV::Settings.new(
70
+ "config/defaults.csv",
71
+ "config/production.csv"
72
+ )
73
+
74
+ settings[:debug] # => true (from production.csv)
75
+ ```
76
+
77
+ ### Type Conversion
78
+
79
+ The following values are automatically converted:
80
+
81
+ - **True values:** `t`, `1`, `true`, `yes`, `y` (case-insensitive)
82
+ - **False values:** `f`, `0`, `false`, `no`, `n` (case-insensitive)
83
+ - **Nil values:** `nil`, `null`, `na`, `n/a` (case-insensitive), or empty values
84
+
85
+ ```csv
86
+ key,value
87
+ feature_enabled,true
88
+ verbose,yes
89
+ disabled,0
90
+ optional_field,nil
91
+ ```
92
+
93
+ ```ruby
94
+ settings = KVCSV::Settings.new("config.csv")
95
+ settings[:feature_enabled] # => true
96
+ settings[:verbose] # => true
97
+ settings[:disabled] # => false
98
+ settings[:optional_field] # => nil
99
+ ```
100
+
101
+ ### Enumerable Interface
102
+
103
+ Settings objects support enumerable methods:
104
+
105
+ ```ruby
106
+ # Map over settings
107
+ urls = settings.map { |key, value| value if key.to_s.end_with?("_url") }.compact
108
+
109
+ # Select specific settings
110
+ database_settings = settings.select { |key, _| key.to_s.start_with?("database_") }
111
+
112
+ # Check for existence
113
+ settings.fetch(:required_key) # Raises KeyError if not found
114
+ ```
115
+
116
+ ## Development
117
+
118
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
119
+
120
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
121
+
122
+ ## Contributing
123
+
124
+ Bug reports and pull requests are welcome on GitHub at https://github.com/aguynamedryan/kvcsv.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: %i[spec rubocop]
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+ require "forwardable"
5
+
6
+ module KVCSV
7
+ # Settings class for managing application settings from CSV files
8
+ #
9
+ # This class loads settings from one or more CSV files and provides
10
+ # read-only access to the merged configuration. CSV files should have
11
+ # two columns: "key" and "value".
12
+ #
13
+ # @example Basic usage
14
+ # settings = KVCSV::Settings.new("config/app.csv", "config/local.csv")
15
+ # database_host = settings[:database_host]
16
+ # debug_mode = settings[:debug]
17
+ #
18
+ # @example Using fetch with default value
19
+ # port = settings.fetch(:port, 3000)
20
+ #
21
+ # @example CSV file format
22
+ # key,value
23
+ # database_host,localhost
24
+ # database_port,5432
25
+ # debug,true
26
+ # cache_enabled,false
27
+ #
28
+ class Settings
29
+ extend Forwardable
30
+
31
+ # @!method [](key)
32
+ # Access a setting value by key
33
+ # @param key [String, Symbol] The setting key to retrieve
34
+ # @return [String, TrueClass, FalseClass, nil] The setting value
35
+ #
36
+ # @!method fetch(key, default = nil)
37
+ # Access a setting value with optional default
38
+ # @param key [String, Symbol] The setting key to retrieve
39
+ # @param default [Object] Default value if key not found
40
+ # @return [Object] The setting value or default
41
+ #
42
+ # @!method map(&block)
43
+ # Iterate over settings with map
44
+ # @yield [key, value] Each key-value pair
45
+ # @return [Array] Results of the block
46
+ #
47
+ # @!method select(&block)
48
+ # Select settings matching criteria
49
+ # @yield [key, value] Each key-value pair
50
+ # @return [Hash] Filtered settings
51
+ def_delegators :@settings, :[], :fetch, :map, :select
52
+
53
+ # Values that are converted to true
54
+ TRUE_VALUES = %w[t 1 true yes y].freeze
55
+
56
+ # Values that are converted to false
57
+ FALSE_VALUES = %w[f 0 false no n].freeze
58
+
59
+ # Values that are converted to nil
60
+ NIL_VALUES = %w[nil null na n/a].freeze
61
+
62
+ # Initialize a new Settings object with one or more CSV files
63
+ #
64
+ # @param file_paths [Array<String>] Variable number of paths to CSV files
65
+ # @note Non-existent files are silently ignored
66
+ # @note Later files override values from earlier files
67
+ #
68
+ # @example Load from multiple files
69
+ # settings = KVCSV::Settings.new(
70
+ # "config/defaults.csv",
71
+ # "config/environment.csv",
72
+ # "config/local.csv"
73
+ # )
74
+ def initialize(*file_paths)
75
+ @settings = {}
76
+ file_paths.compact.each do |file_path|
77
+ next unless File.exist?(file_path)
78
+
79
+ load_file(file_path)
80
+ end
81
+ symbolize_keys!
82
+ end
83
+
84
+ private
85
+
86
+ def symbolize_keys!
87
+ @settings = @settings.transform_keys(&:to_sym)
88
+ end
89
+
90
+ def load_file(file_path)
91
+ CSV.foreach(file_path, headers: true) do |row|
92
+ key = row["key"]
93
+ value = convert_value(row["value"])
94
+ @settings[key] = value
95
+ end
96
+ end
97
+
98
+ def convert_value(value)
99
+ return nil if value.nil? || NIL_VALUES.include?(value.downcase)
100
+ return true if TRUE_VALUES.include?(value.downcase)
101
+ return false if FALSE_VALUES.include?(value.downcase)
102
+
103
+ value
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KVCSV
4
+ VERSION = "0.1.0"
5
+ end
data/lib/kvcsv.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "kvcsv/version"
4
+ require_relative "kvcsv/settings"
5
+
6
+ module KVCSV
7
+ class Error < StandardError; end
8
+ end
data/sig/kvcsv.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module KVCSV
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
@@ -0,0 +1,283 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe KVCSV::Settings do
6
+ let(:temp_dir) { Dir.mktmpdir }
7
+
8
+ after do
9
+ FileUtils.rm_rf(temp_dir)
10
+ end
11
+
12
+ def create_csv_file(filename, content)
13
+ path = File.join(temp_dir, filename)
14
+ File.write(path, content)
15
+ path
16
+ end
17
+
18
+ describe "#initialize" do
19
+ it "loads settings from a single CSV file" do
20
+ file = create_csv_file("settings.csv", <<~CSV)
21
+ key,value
22
+ database_host,localhost
23
+ database_port,5432
24
+ CSV
25
+
26
+ settings = described_class.new(file)
27
+ expect(settings[:database_host]).to eq("localhost")
28
+ expect(settings[:database_port]).to eq("5432")
29
+ end
30
+
31
+ it "loads settings from multiple CSV files" do
32
+ file1 = create_csv_file("defaults.csv", <<~CSV)
33
+ key,value
34
+ host,default.com
35
+ port,3000
36
+ debug,false
37
+ CSV
38
+
39
+ file2 = create_csv_file("overrides.csv", <<~CSV)
40
+ key,value
41
+ host,override.com
42
+ timeout,30
43
+ CSV
44
+
45
+ settings = described_class.new(file1, file2)
46
+ expect(settings[:host]).to eq("override.com")
47
+ expect(settings[:port]).to eq("3000")
48
+ expect(settings[:debug]).to be false
49
+ expect(settings[:timeout]).to eq("30")
50
+ end
51
+
52
+ it "ignores non-existent files" do
53
+ valid_file = create_csv_file("valid.csv", <<~CSV)
54
+ key,value
55
+ setting,value
56
+ CSV
57
+
58
+ settings = described_class.new("/nonexistent/file.csv", valid_file, "/another/missing.csv")
59
+ expect(settings[:setting]).to eq("value")
60
+ end
61
+
62
+ it "ignores nil file paths" do
63
+ file = create_csv_file("settings.csv", <<~CSV)
64
+ key,value
65
+ foo,bar
66
+ CSV
67
+
68
+ settings = described_class.new(nil, file, nil)
69
+ expect(settings[:foo]).to eq("bar")
70
+ end
71
+
72
+ it "symbolizes keys" do
73
+ file = create_csv_file("settings.csv", <<~CSV)
74
+ key,value
75
+ string_key,value
76
+ CSV
77
+
78
+ settings = described_class.new(file)
79
+ expect(settings[:string_key]).to eq("value")
80
+ expect(settings["string_key"]).to be_nil
81
+ end
82
+ end
83
+
84
+ describe "#[]" do
85
+ let(:file) do
86
+ create_csv_file("settings.csv", <<~CSV)
87
+ key,value
88
+ existing_key,value
89
+ CSV
90
+ end
91
+ let(:settings) { described_class.new(file) }
92
+
93
+ it "returns value for existing key" do
94
+ expect(settings[:existing_key]).to eq("value")
95
+ end
96
+
97
+ it "returns nil for non-existing key" do
98
+ expect(settings[:missing_key]).to be_nil
99
+ end
100
+ end
101
+
102
+ describe "#fetch" do
103
+ let(:file) do
104
+ create_csv_file("settings.csv", <<~CSV)
105
+ key,value
106
+ existing_key,value
107
+ CSV
108
+ end
109
+ let(:settings) { described_class.new(file) }
110
+
111
+ it "returns value for existing key" do
112
+ expect(settings.fetch(:existing_key)).to eq("value")
113
+ end
114
+
115
+ it "returns default value for non-existing key" do
116
+ expect(settings.fetch(:missing_key, "default")).to eq("default")
117
+ end
118
+
119
+ it "raises error for non-existing key without default" do
120
+ expect { settings.fetch(:missing_key) }.to raise_error(KeyError)
121
+ end
122
+ end
123
+
124
+ describe "#map" do
125
+ let(:file) do
126
+ create_csv_file("settings.csv", <<~CSV)
127
+ key,value
128
+ key1,value1
129
+ key2,value2
130
+ CSV
131
+ end
132
+ let(:settings) { described_class.new(file) }
133
+
134
+ it "maps over key-value pairs" do
135
+ result = settings.map { |k, v| "#{k}=#{v}" }
136
+ expect(result).to contain_exactly("key1=value1", "key2=value2")
137
+ end
138
+ end
139
+
140
+ describe "#select" do
141
+ let(:file) do
142
+ create_csv_file("settings.csv", <<~CSV)
143
+ key,value
144
+ enabled,true
145
+ disabled,false
146
+ name,test
147
+ CSV
148
+ end
149
+ let(:settings) { described_class.new(file) }
150
+
151
+ it "selects matching key-value pairs" do
152
+ result = settings.select { |_k, v| v == true }
153
+ expect(result).to eq({ enabled: true })
154
+ end
155
+ end
156
+
157
+ describe "value conversion" do
158
+ context "true values" do
159
+ %w[t 1 true yes y].each do |true_value|
160
+ it "converts '#{true_value}' to true" do
161
+ file = create_csv_file("settings.csv", <<~CSV)
162
+ key,value
163
+ bool_setting,#{true_value}
164
+ CSV
165
+
166
+ settings = described_class.new(file)
167
+ expect(settings[:bool_setting]).to be true
168
+ end
169
+ end
170
+
171
+ it "converts uppercase TRUE values" do
172
+ file = create_csv_file("settings.csv", <<~CSV)
173
+ key,value
174
+ upper,TRUE
175
+ mixed,True
176
+ CSV
177
+
178
+ settings = described_class.new(file)
179
+ expect(settings[:upper]).to be true
180
+ expect(settings[:mixed]).to be true
181
+ end
182
+ end
183
+
184
+ context "false values" do
185
+ %w[f 0 false no n].each do |false_value|
186
+ it "converts '#{false_value}' to false" do
187
+ file = create_csv_file("settings.csv", <<~CSV)
188
+ key,value
189
+ bool_setting,#{false_value}
190
+ CSV
191
+
192
+ settings = described_class.new(file)
193
+ expect(settings[:bool_setting]).to be false
194
+ end
195
+ end
196
+
197
+ it "converts uppercase FALSE values" do
198
+ file = create_csv_file("settings.csv", <<~CSV)
199
+ key,value
200
+ upper,FALSE
201
+ mixed,False
202
+ CSV
203
+
204
+ settings = described_class.new(file)
205
+ expect(settings[:upper]).to be false
206
+ expect(settings[:mixed]).to be false
207
+ end
208
+ end
209
+
210
+ context "nil values" do
211
+ %w[nil null na n/a].each do |nil_value|
212
+ it "converts '#{nil_value}' to nil" do
213
+ file = create_csv_file("settings.csv", <<~CSV)
214
+ key,value
215
+ nil_setting,#{nil_value}
216
+ CSV
217
+
218
+ settings = described_class.new(file)
219
+ expect(settings[:nil_setting]).to be_nil
220
+ end
221
+ end
222
+
223
+ it "converts uppercase NIL values" do
224
+ file = create_csv_file("settings.csv", <<~CSV)
225
+ key,value
226
+ upper,NULL
227
+ mixed,Nil
228
+ CSV
229
+
230
+ settings = described_class.new(file)
231
+ expect(settings[:upper]).to be_nil
232
+ expect(settings[:mixed]).to be_nil
233
+ end
234
+
235
+ it "converts empty values to nil" do
236
+ file = create_csv_file("settings.csv", <<~CSV)
237
+ key,value
238
+ empty,
239
+ CSV
240
+
241
+ settings = described_class.new(file)
242
+ expect(settings[:empty]).to be_nil
243
+ end
244
+ end
245
+
246
+ it "preserves string values that don't match special values" do
247
+ file = create_csv_file("settings.csv", <<~CSV)
248
+ key,value
249
+ string,regular string
250
+ number,42
251
+ truthy,truth
252
+ falsy,failure
253
+ CSV
254
+
255
+ settings = described_class.new(file)
256
+ expect(settings[:string]).to eq("regular string")
257
+ expect(settings[:number]).to eq("42")
258
+ expect(settings[:truthy]).to eq("truth")
259
+ expect(settings[:falsy]).to eq("failure")
260
+ end
261
+ end
262
+
263
+ describe "file merging" do
264
+ it "later files override earlier files" do
265
+ file1 = create_csv_file("first.csv", <<~CSV)
266
+ key,value
267
+ setting1,first
268
+ setting2,original
269
+ CSV
270
+
271
+ file2 = create_csv_file("second.csv", <<~CSV)
272
+ key,value
273
+ setting2,overridden
274
+ setting3,new
275
+ CSV
276
+
277
+ settings = described_class.new(file1, file2)
278
+ expect(settings[:setting1]).to eq("first")
279
+ expect(settings[:setting2]).to eq("overridden")
280
+ expect(settings[:setting3]).to eq("new")
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require "kvcsv"
5
+ require "tempfile"
6
+ require "fileutils"
7
+
8
+ RSpec.configure do |config|
9
+ # Enable flags like --only-failures and --next-failure
10
+ config.example_status_persistence_file_path = ".rspec_status"
11
+
12
+ # Disable RSpec exposing methods globally on `Module` and `main`
13
+ config.disable_monkey_patching!
14
+
15
+ config.expect_with :rspec do |c|
16
+ c.syntax = :expect
17
+ end
18
+
19
+ # Run specs in random order to surface order dependencies
20
+ config.order = :random
21
+
22
+ # Seed global randomization in this process using the `--seed` CLI option
23
+ Kernel.srand config.seed
24
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kvcsv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Duryea
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: csv
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '3.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '3.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ description: A lightweight Ruby gem for managing application settings from CSV files
55
+ with automatic type conversion and multi-file support.
56
+ email:
57
+ - aguynamedryan@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".rspec"
63
+ - ".rspec_status"
64
+ - CHANGELOG.md
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - lib/kvcsv.rb
69
+ - lib/kvcsv/settings.rb
70
+ - lib/kvcsv/version.rb
71
+ - sig/kvcsv.rbs
72
+ - spec/kvcsv/settings_spec.rb
73
+ - spec/spec_helper.rb
74
+ homepage: https://github.com/aguynamedryan/kvcsv
75
+ licenses:
76
+ - MIT
77
+ metadata:
78
+ allowed_push_host: https://rubygems.org
79
+ homepage_uri: https://github.com/aguynamedryan/kvcsv
80
+ source_code_uri: https://github.com/aguynamedryan/kvcsv
81
+ changelog_uri: https://github.com/aguynamedryan/kvcsv/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: 3.2.0
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.6.7
97
+ specification_version: 4
98
+ summary: Key-value pairs from stackable CSV files
99
+ test_files: []