keyp 0.0.3 → 0.0.4

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
  SHA1:
3
- metadata.gz: f6fe1096a2986fb5e0c7294dde7465399487f46f
4
- data.tar.gz: aa53557b7a5ef2a0ddaf83c5005f653f08e1de25
3
+ metadata.gz: d98a2fa1da818cd0aec0b3a51abe7d1dd4b8afa4
4
+ data.tar.gz: 4033012aa8d82fe633552d53520e4e2e1edd0732
5
5
  SHA512:
6
- metadata.gz: 9728123d215cafbf15881a10b8b43b3fad95e5b6a473fea52ac42f0d28d429b20a4295a1d0fd700f8c71224182fb59c58e122ac1ca308dfab803af7f77170114
7
- data.tar.gz: 320ce0f3a9c587b577b5d7b6dd466aac857ecf99fec6208874232324b2d79b23867b1a188d4f22e76a3eb20613156a1e8d49ef1fe33a9f7ad87dc279536acab3
6
+ metadata.gz: 1cbb72344649affc084601ee562eb99a08f40b05763c0947b4bb955b4165a2a5f5e78ccc974ecb51ebac98e15c930b29eaa8dba05718565f9176bcff40511dc5
7
+ data.tar.gz: 69b475bbb836067eb02bb45332dcd0ba83baa219f2e9ac435daacc4f3c9a04249271b9ac251e8145457a4aed8b67467773746080e72d8fd331d3b5097d8980c9
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/keyp.png)](http://badge.fury.io/rb/keyp)
2
+
1
3
  # Keyp
2
4
 
3
5
  Keyp is an executable Ruby gem that manages user/machine specific key/value pairs for your Ruby application.
@@ -16,7 +18,7 @@ for any kind of production code at this point in this gem's lifecycle.
16
18
 
17
19
  ## Quick Tour
18
20
 
19
- Keyp manages key value pairs in collections. As of version 0.0.1, Keyp refers to collections as *bags*. There is a
21
+ Keyp manages key value pairs in collections. As of version 0.0.4, Keyp refers to collections as *bags*. There is a
20
22
  default bag called *default*. Unless you specify a bag name, *default* will be used.
21
23
 
22
24
  Here are some command line examples showing some basic Keyp functionality using the default bag. Here we set a couple
@@ -90,6 +92,10 @@ TODO: Write detailed usage instructions here
90
92
  TODO: Write more detailed documentation, For now, see the quick start above and run the following to see CLI options
91
93
  $ keyp --help
92
94
 
95
+ ## Release Notes
96
+
97
+ * v 0.0.4 - Fixed missing file error
98
+
93
99
  ## Development plan/Features to implement
94
100
 
95
101
  * Get basic functionality working soundly backed with effective tests
data/lib/keyp.rb CHANGED
@@ -115,7 +115,7 @@ module Keyp
115
115
  # * +options+ - options are passed through to Bag.new
116
116
  #
117
117
  def self.bag(name='default', options = {})
118
- bag = Keyper.new(name, options)
118
+ bag = Bag.new(name, options)
119
119
  bag
120
120
  end
121
121
 
@@ -221,223 +221,6 @@ module Keyp
221
221
 
222
222
  end
223
223
 
224
- # ----------------------------------------------
225
-
226
- # Some inspiration:
227
- # http://stackoverflow.com/questions/2680523/dry-ruby-initialization-with-hash-argument
228
- #
229
- # TODO: add handling so that keys (hierarchical keys too) are accessed as members instead of
230
- # hash access
231
- #
232
- # TODO: move to own file, rename to "Bag"
233
- # TODO: i18n error messages
234
- #
235
- class Keyper
236
-
237
- attr_reader :keypdir, :dirty
238
- attr_accessor :name, :data, :file_hash
239
-
240
- def keypfile
241
- File.join(@keypdir, @name+@ext)
242
- end
243
-
244
- # We expect
245
- # I'm not happy with how creating instance variables works. There must be a cleaner way
246
- def initialize(name, options = {})
247
- @name = name
248
- options.each do |k,v|
249
- puts "processing options #{k} = #{v}"
250
- instance_variable_set("@#{k}", v) unless v.nil?
251
- end
252
- # set attributes not set by params
253
-
254
- @keypdir ||= Keyp::home
255
- @read_only ||= false
256
- @ext ||= Keyp::DEFAULT_EXT
257
- #@keypfile = config_path
258
- # load our resource
259
-
260
- # load config file into hashes
261
- # not the most efficient thing, but simpler and safe enough for now
262
-
263
- unless File.exist? keypfile
264
- puts "Keyper.initialize, create_bag #{keypfile}"
265
- Keyp::create_bag(name)
266
- end
267
- file_data = load(keypfile)
268
-
269
- @meta = file_data[:meta]
270
- @data = file_data[:data]|| {}
271
- @file_hash = file_data[:file_hash]
272
- @dirty = false
273
- end
274
-
275
- def [](key)
276
- @data[key]
277
- end
278
-
279
- def []=(key, value)
280
- set_prop(key, value)
281
- end
282
-
283
- def set_prop(key, value)
284
- unless @read_only
285
- # TODO: check if data has been modified
286
- # maybe there is a way hash tells us its been modified. If not then
287
- # just check if key,val is already in hash and matches
288
- @data[key] = value
289
- @dirty = true
290
- else
291
- raise "Bag #{@name} is read only"
292
- end
293
- end
294
-
295
- def delete(key)
296
- unless @read_only
297
- if @data.key? key
298
- @dirty = true
299
- end
300
- val = @data.delete(key)
301
- else
302
- raise "Bag #{@name} is read only"
303
- end
304
- val
305
- end
306
-
307
- def empty?
308
- @data.empty?
309
- end
310
-
311
-
312
- ##
313
- # Adds key/value pairs from this bag to the Ruby ENV
314
- # NOTE: Currently in development.
315
- # If no options are provided, then all of the bag's key/value pairs will be assigned.
316
- #
317
- # ==== Options
318
- # TBD:
319
- # +:sysvar+ Only use valid system environment vars
320
- # +:selection+ Provide a list of keys to match
321
- # +:overwrite+
322
- # +:no_overwrite+ - This is enabled by default
323
- # +:to_upper
324
-
325
- # Returns a hash of the key/value pairs which have been set
326
- # ==== Examples
327
- # +add_to_env upper:+
328
- # To assign keys matching a pattern:
329
- # +add_to_env regex: '\A(_|[A-Z])[a-zA-Z\d]*'
330
-
331
- def add_to_env(options = {})
332
- # TODO: Add checking, upcase
333
-
334
- # pattern matching valid env var
335
- sys_env_reg = /\A(_|[a-zA-Z])\w*/
336
- assigned = {}
337
- overwrite = options[:overwrite] || false
338
- pattern = options[:sysvar] if options.key?(:sysvar)
339
-
340
- pattern ||= '(...)'
341
-
342
- bag.data.each do |key,value|
343
- if pattern.match(key)
344
- # TODO: add overwrite checking
345
- ENV[key] = value
346
- assigned[key] = value
347
- end
348
- end
349
- assigned
350
- end
351
-
352
-
353
- # TODO add from hash
354
-
355
-
356
- def import(filename)
357
- raise "import not yet supported"
358
- end
359
-
360
- def export(filename)
361
- raise "export not yet supported"
362
- end
363
-
364
-
365
- # TODO: def to_yaml
366
- # TODO: def to_json
367
- # TODO: def to_s
368
-
369
- ##
370
- # Give full path, attempt to load
371
- # sticking with YAML format for now
372
- # May add new file format later in which case we'll
373
- # TODO: consider changing to class method
374
- def load (config_path)
375
- #config_data = {}
376
- # Get extension
377
- file_ext = File.extname(config_path)
378
-
379
- # check
380
- # only YAML supported for initial version. Will consider adapters to
381
- # abstract the persistence layer
382
-
383
-
384
- # TODO: make this hardcoded case a hash of helpers
385
- # TODO: Add two sections: Meta and data, then return as hash
386
-
387
- if file_ext.downcase == Keyp::DEFAULT_EXT
388
-
389
- # Either we are arbitrarily creating directories when
390
- # given a path for a file that doesn't exist
391
- # or we have special behavior for the default dir
392
- # or we just fault and let the caller deal with it
393
- unless File.exist? config_path
394
- raise "Keyp config file not found: #{config_path}"
395
- end
396
-
397
- file_data = YAML.load_file(config_path)
398
-
399
- else
400
- raise "Keyp version x only supports YAML for config files. You tried a #{file_ext}"
401
- end
402
- { meta: file_data['meta'], data: file_data['data']||{}, file_hash: file_data.hash }
403
- end
404
-
405
- ##
406
- # Saves the Bag to file
407
- #
408
- # NOT thread safe
409
- # TODO: make thread safe
410
- def save
411
- if @read_only
412
- raise "This bag instance is read only"
413
- end
414
- if @dirty
415
- # lock file
416
- # read checksum
417
- # if checksum matches our saved checksum then update file and release lock
418
- # otherwise, raise
419
- # TODO: implement merge from updated file and raise only if conflict
420
- begin
421
- file_data = { 'meta' => @meta, 'data' => @data }
422
-
423
- if File.exist? keypfile
424
- read_file_data = load(keypfile)
425
- unless @file_hash == read_file_data[:file_hash]
426
- raise "Will not write to #{keypfile}\nHashes differ. Expected hash =#{@file_hash}\n" +
427
- "found hash #{read_file_data[:file_hash]}"
428
- end
429
- end
430
- File.open(keypfile, 'w') do |f|
431
- f.write file_data.to_yaml
432
- end
433
- @dirty = false
434
- rescue
435
- # TODO: log error
436
-
437
- end
438
- end
439
- end
440
- end
441
224
 
442
225
 
443
226
  # Hmm, do we really need this or can we suffice with the meta hash in the bag
data/lib/keyp/bag.rb ADDED
@@ -0,0 +1,219 @@
1
+ module Keyp
2
+ # ----------------------------------------------
3
+
4
+ # Some inspiration:
5
+ # http://stackoverflow.com/questions/2680523/dry-ruby-initialization-with-hash-argument
6
+ #
7
+ # TODO: add handling so that keys (hierarchical keys too) are accessed as members instead of
8
+ # hash access
9
+ #
10
+ # TODO: move to own file, rename to "Bag"
11
+ # TODO: i18n error messages
12
+ #
13
+ class Bag
14
+
15
+ attr_reader :keypdir, :dirty
16
+ attr_accessor :name, :data, :file_hash
17
+
18
+ def keypfile
19
+ File.join(@keypdir, @name+@ext)
20
+ end
21
+
22
+ # We expect
23
+ # I'm not happy with how creating instance variables works. There must be a cleaner way
24
+ def initialize(name, options = {})
25
+ @name = name
26
+ options.each do |k,v|
27
+ puts "processing options #{k} = #{v}"
28
+ instance_variable_set("@#{k}", v) unless v.nil?
29
+ end
30
+ # set attributes not set by params
31
+
32
+ @keypdir ||= Keyp::home
33
+ @read_only ||= false
34
+ @ext ||= Keyp::DEFAULT_EXT
35
+ #@keypfile = config_path
36
+ # load our resource
37
+
38
+ # load config file into hashes
39
+ # not the most efficient thing, but simpler and safe enough for now
40
+
41
+ unless File.exist? keypfile
42
+ puts "Keyper.initialize, create_bag #{keypfile}"
43
+ Keyp::create_bag(name)
44
+ end
45
+ file_data = load(keypfile)
46
+
47
+ @meta = file_data[:meta]
48
+ @data = file_data[:data]|| {}
49
+ @file_hash = file_data[:file_hash]
50
+ @dirty = false
51
+ end
52
+
53
+ def [](key)
54
+ @data[key]
55
+ end
56
+
57
+ def []=(key, value)
58
+ set_prop(key, value)
59
+ end
60
+
61
+ def set_prop(key, value)
62
+ unless @read_only
63
+ # TODO: check if data has been modified
64
+ # maybe there is a way hash tells us its been modified. If not then
65
+ # just check if key,val is already in hash and matches
66
+ @data[key] = value
67
+ @dirty = true
68
+ else
69
+ raise "Bag #{@name} is read only"
70
+ end
71
+ end
72
+
73
+ def delete(key)
74
+ unless @read_only
75
+ if @data.key? key
76
+ @dirty = true
77
+ end
78
+ val = @data.delete(key)
79
+ else
80
+ raise "Bag #{@name} is read only"
81
+ end
82
+ val
83
+ end
84
+
85
+ def empty?
86
+ @data.empty?
87
+ end
88
+
89
+
90
+ ##
91
+ # Adds key/value pairs from this bag to the Ruby ENV
92
+ # NOTE: Currently in development.
93
+ # If no options are provided, then all of the bag's key/value pairs will be assigned.
94
+ #
95
+ # ==== Options
96
+ # TBD:
97
+ # +:sysvar+ Only use valid system environment vars
98
+ # +:selection+ Provide a list of keys to match
99
+ # +:overwrite+
100
+ # +:no_overwrite+ - This is enabled by default
101
+ # +:to_upper
102
+
103
+ # Returns a hash of the key/value pairs which have been set
104
+ # ==== Examples
105
+ # +add_to_env upper:+
106
+ # To assign keys matching a pattern:
107
+ # +add_to_env regex: '\A(_|[A-Z])[a-zA-Z\d]*'
108
+
109
+ def add_to_env(options = {})
110
+ # TODO: Add checking, upcase
111
+
112
+ # pattern matching valid env var
113
+ sys_env_reg = /\A(_|[a-zA-Z])\w*/
114
+ assigned = {}
115
+ overwrite = options[:overwrite] || false
116
+ pattern = options[:sysvar] if options.key?(:sysvar)
117
+
118
+ pattern ||= '(...)'
119
+
120
+ bag.data.each do |key,value|
121
+ if pattern.match(key)
122
+ # TODO: add overwrite checking
123
+ ENV[key] = value
124
+ assigned[key] = value
125
+ end
126
+ end
127
+ assigned
128
+ end
129
+
130
+
131
+ # TODO add from hash
132
+
133
+
134
+ def import(filename)
135
+ raise "import not yet supported"
136
+ end
137
+
138
+ def export(filename)
139
+ raise "export not yet supported"
140
+ end
141
+
142
+
143
+ # TODO: def to_yaml
144
+ # TODO: def to_json
145
+ # TODO: def to_s
146
+
147
+ ##
148
+ # Give full path, attempt to load
149
+ # sticking with YAML format for now
150
+ # May add new file format later in which case we'll
151
+ # TODO: consider changing to class method
152
+ def load (config_path)
153
+ #config_data = {}
154
+ # Get extension
155
+ file_ext = File.extname(config_path)
156
+
157
+ # check
158
+ # only YAML supported for initial version. Will consider adapters to
159
+ # abstract the persistence layer
160
+
161
+
162
+ # TODO: make this hardcoded case a hash of helpers
163
+ # TODO: Add two sections: Meta and data, then return as hash
164
+
165
+ if file_ext.downcase == Keyp::DEFAULT_EXT
166
+
167
+ # Either we are arbitrarily creating directories when
168
+ # given a path for a file that doesn't exist
169
+ # or we have special behavior for the default dir
170
+ # or we just fault and let the caller deal with it
171
+ unless File.exist? config_path
172
+ raise "Keyp config file not found: #{config_path}"
173
+ end
174
+
175
+ file_data = YAML.load_file(config_path)
176
+
177
+ else
178
+ raise "Keyp version x only supports YAML for config files. You tried a #{file_ext}"
179
+ end
180
+ { meta: file_data['meta'], data: file_data['data']||{}, file_hash: file_data.hash }
181
+ end
182
+
183
+ ##
184
+ # Saves the Bag to file
185
+ #
186
+ # NOT thread safe
187
+ # TODO: make thread safe
188
+ def save
189
+ if @read_only
190
+ raise "This bag instance is read only"
191
+ end
192
+ if @dirty
193
+ # lock file
194
+ # read checksum
195
+ # if checksum matches our saved checksum then update file and release lock
196
+ # otherwise, raise
197
+ # TODO: implement merge from updated file and raise only if conflict
198
+ begin
199
+ file_data = { 'meta' => @meta, 'data' => @data }
200
+
201
+ if File.exist? keypfile
202
+ read_file_data = load(keypfile)
203
+ unless @file_hash == read_file_data[:file_hash]
204
+ raise "Will not write to #{keypfile}\nHashes differ. Expected hash =#{@file_hash}\n" +
205
+ "found hash #{read_file_data[:file_hash]}"
206
+ end
207
+ end
208
+ File.open(keypfile, 'w') do |f|
209
+ f.write file_data.to_yaml
210
+ end
211
+ @dirty = false
212
+ rescue
213
+ # TODO: log error
214
+
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
data/lib/keyp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Keyp
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/spec/keyp_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe Keyp do
5
5
  context "CONSTANTS" do
6
6
  it 'should return correct version string' do
7
7
  #Keyp.version_string.should == "Keyp version #{Keyp::VERSION}"
8
- Keyp::VERSION.should == '0.0.3'
8
+ Keyp::VERSION.should == '0.0.4'
9
9
  end
10
10
 
11
11
  it 'should specify default store' do
data/spec/keyper_spec.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Keyp::Keyper do
3
+ describe Keyp::Bag do
4
4
 
5
5
  context "is empty" do
6
6
  before (:each) do
7
7
  puts "before : is empty"
8
- @bag = Keyp::Keyper.new 'testing123'
8
+ @bag = Keyp::Bag.new 'testing123'
9
9
  end
10
10
 
11
11
  it "should return an empty hash" do
@@ -20,7 +20,7 @@ describe Keyp::Keyper do
20
20
  context "is not empty" do
21
21
  before (:each) do
22
22
  puts "before : is not empty"
23
- @bag = Keyp::Keyper.new 'grue_eats_you'
23
+ @bag = Keyp::Bag.new 'grue_eats_you'
24
24
  @bag['LIGHTS'] = 'out'
25
25
  end
26
26
  it "should return a non-empty hash" do
@@ -32,7 +32,7 @@ describe Keyp::Keyper do
32
32
  before (:each) do
33
33
  # TODO: pseudo random bag name generation to a helper
34
34
  bag_name = "grue_eats_you_when_it_is_dark_#{Time.now.strftime("%Y%m%d%H%M")}"
35
- @bag = Keyp::Keyper.new bag_name
35
+ @bag = Keyp::Bag.new bag_name
36
36
  end
37
37
  it "should copy all vars"
38
38
  =begin
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keyp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Baldwin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-30 00:00:00.000000000 Z
11
+ date: 2014-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -83,6 +83,7 @@ files:
83
83
  - bin/keyp
84
84
  - keyp.gemspec
85
85
  - lib/keyp.rb
86
+ - lib/keyp/bag.rb
86
87
  - lib/keyp/cli.rb
87
88
  - lib/keyp/version.rb
88
89
  - spec/keyp_spec.rb