keyp 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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