dotcfg 0.0.1.1 → 0.0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/dotcfg.rb +48 -55
  2. data/rakefile.rb +1 -0
  3. metadata +2 -2
data/lib/dotcfg.rb CHANGED
@@ -4,38 +4,35 @@ require 'yaml'
4
4
  # uses JSON or YAML for serialization
5
5
  # top-level structure is object/hash/dict
6
6
  #
7
- # provide and prefer method-based access to str/sym/etc keys
8
7
  # e.g.
9
8
  # d = DotCfg.new('~/.dotcfg')
10
- # d.hello = 'world'
11
- # d.hello
9
+ # d['hello'] = 'world'
10
+ # d['hello']
12
11
  # => "world"
13
12
  # d.save
14
- # d.get = "bent"
13
+ # d['get'] = "bent"
15
14
  # d.load
16
- # d.get
15
+ # d['get']
17
16
  # => nil
18
17
  #
19
18
  class DotCfg
20
19
  def self.normalize key
21
20
  case key
22
21
  when Numeric, Symbol
23
- key
22
+ key # pass thru
24
23
  when String
25
24
  # leading numerics are invalid
26
25
  raise "invalid key: #{key}" if key[0,1] == '0' or key[0,1].to_i != 0
27
- key.downcase.gsub(/\W/, '_').to_sym
26
+ key.downcase.gsub(/[\W_]+/, '_').gsub(/_\z/, '').to_sym
28
27
  else
29
28
  raise "invalid key: #{key} (#{key.class})"
30
29
  end
31
30
  end
32
31
 
33
- DEFAULT = {}
34
-
35
32
  PROCS = {
36
33
  json: {
37
34
  to: proc { |data| data.to_json },
38
- from: proc { |json| YAML.load json },
35
+ from: proc { |json| JSON.parse json }, # YAML.load json },
39
36
  pretty: proc { |data| JSON.pretty_generate data },
40
37
  },
41
38
  yaml: {
@@ -45,94 +42,90 @@ class DotCfg
45
42
  },
46
43
  }
47
44
 
48
- attr_reader :filename, :format, :storage
45
+ attr_reader :filename, :format
49
46
 
50
47
  def initialize filename, format = :json
51
48
  @filename = File.expand_path filename
52
49
  @format = format
53
- File.exists?(@filename) ? self.load : self.reset
50
+ @cfg = Hash.new
51
+ File.exists?(@filename) ? self.try_load : self.reset
54
52
  end
55
53
 
56
-
57
- # manipulate @storage
58
54
  #
55
+ # @cfg manipulation
56
+ #
57
+
59
58
  def [] key
60
59
  key = self.class.normalize key
61
- @storage[key] or @storage[key.to_s]
60
+ @cfg[key] or @cfg[key.to_s]
62
61
  end
63
- #
62
+
64
63
  def []= key, value
65
- @storage[self.class.normalize(key)] = value
64
+ @cfg[self.class.normalize key] = value
66
65
  end
67
- #
66
+
68
67
  def delete key
69
- @storage.delete(self.class.normalize(key))
68
+ @cfg.delete self.class.normalize key
70
69
  end
71
- #
72
- def method_missing key, *args
73
- if key[-1,1] == '='
74
- self[key[0, key.length - 1]] = args.first
75
- else
76
- self[key]
77
- end
70
+
71
+ # if you need to call this, you might be Doing It Wrong (tm)
72
+ def to_h
73
+ @cfg
78
74
  end
75
+
79
76
  #
80
- def respond_to? key, *args
81
- true
82
- end
77
+ # serialization, using PROCS
83
78
  #
84
- # end simple @storage manipulation
85
-
86
79
 
87
- # serialization, based on PROCS
88
- #
89
80
  def serialize
90
- raise "invalid storage" unless @storage.is_a? Hash
91
- self.class::PROCS.fetch(@format)[:to].call @storage
81
+ raise "invalid storage" unless @cfg.is_a? Hash
82
+ self.class::PROCS.fetch(@format)[:to].call @cfg
92
83
  end
93
- #
84
+
94
85
  def deserialize junk
95
86
  data = self.class::PROCS.fetch(@format)[:from].call junk
96
- raise "invalid junk: #{junk} (#{junk.class})" unless data.is_a? Hash
87
+ unless data.is_a? Hash
88
+ raise ArgumentError, "invalid junk: #{junk} (#{junk.class})"
89
+ end
97
90
  data.each { |k, v| self[k] = v }
98
- @storage
99
- end
100
- #
101
- def dump
102
- self.class::PROCS.fetch(@format)[:pretty].call @storage
91
+ @cfg
103
92
  end
104
- #
105
- # end serialization
106
93
 
94
+ def pretty
95
+ self.class::PROCS.fetch(@format)[:pretty].call @cfg
96
+ end
107
97
 
98
+ #
108
99
  # file operations
109
100
  #
101
+
110
102
  def save
111
103
  File.open(@filename, 'w') { |f| f.write self.serialize }
112
104
  end
113
- #
105
+
114
106
  def load
107
+ File.open(@filename, 'r') { |f| self.deserialize f.read }
108
+ end
109
+
110
+ def try_load
115
111
  rescues = 0
116
112
  begin
117
- File.open(@filename, 'r') { |f| @storage = self.deserialize f.read }
118
- rescue Exception => e
113
+ self.load
114
+ rescue SystemCallError, ArgumentError, JSON::ParserError => e
119
115
  rescues += 1
120
116
  puts "#{e} (#{e.class})"
121
117
  if rescues < 2
122
118
  puts "Resetting #{@filename}"
123
- reset
119
+ self.reset
124
120
  retry
125
121
  end
126
- puts "load failed!"
122
+ puts "try_load failed!"
127
123
  raise e
128
124
  end
129
125
  end
130
- #
126
+
131
127
  def reset
132
- @storage = DEFAULT.dup
133
- save
128
+ @cfg = Hash.new
129
+ self.save
134
130
  end
135
- #
136
- # end file operations
137
-
138
131
  end
data/rakefile.rb CHANGED
@@ -6,6 +6,7 @@ Buildar.new do |b|
6
6
  b.version_file = 'VERSION'
7
7
  b.gemspec.name = 'dotcfg'
8
8
  b.gemspec.summary = 'simple filesystem de/serialization for app configs'
9
+ b.gemspec.homepage = 'https://github.com/rickhull/dotcfg'
9
10
  b.gemspec.author = 'Rick Hull'
10
11
  b.gemspec.license = 'MIT'
11
12
  b.gemspec.description = 'JSON and YAML config serialization and synch'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotcfg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.1
4
+ version: 0.0.1.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -19,7 +19,7 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - rakefile.rb
21
21
  - lib/dotcfg.rb
22
- homepage:
22
+ homepage: https://github.com/rickhull/dotcfg
23
23
  licenses:
24
24
  - MIT
25
25
  post_install_message: