dotcfg 0.0.1.1 → 0.0.1.12

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.
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: