dotcfg 0.0.1.1

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 +138 -0
  2. data/rakefile.rb +13 -0
  3. metadata +47 -0
data/lib/dotcfg.rb ADDED
@@ -0,0 +1,138 @@
1
+ require 'json'
2
+ require 'yaml'
3
+
4
+ # uses JSON or YAML for serialization
5
+ # top-level structure is object/hash/dict
6
+ #
7
+ # provide and prefer method-based access to str/sym/etc keys
8
+ # e.g.
9
+ # d = DotCfg.new('~/.dotcfg')
10
+ # d.hello = 'world'
11
+ # d.hello
12
+ # => "world"
13
+ # d.save
14
+ # d.get = "bent"
15
+ # d.load
16
+ # d.get
17
+ # => nil
18
+ #
19
+ class DotCfg
20
+ def self.normalize key
21
+ case key
22
+ when Numeric, Symbol
23
+ key
24
+ when String
25
+ # leading numerics are invalid
26
+ raise "invalid key: #{key}" if key[0,1] == '0' or key[0,1].to_i != 0
27
+ key.downcase.gsub(/\W/, '_').to_sym
28
+ else
29
+ raise "invalid key: #{key} (#{key.class})"
30
+ end
31
+ end
32
+
33
+ DEFAULT = {}
34
+
35
+ PROCS = {
36
+ json: {
37
+ to: proc { |data| data.to_json },
38
+ from: proc { |json| YAML.load json },
39
+ pretty: proc { |data| JSON.pretty_generate data },
40
+ },
41
+ yaml: {
42
+ to: proc { |data| data.to_yaml },
43
+ from: proc { |yaml| YAML.load yaml },
44
+ pretty: proc { |data| data.to_yaml },
45
+ },
46
+ }
47
+
48
+ attr_reader :filename, :format, :storage
49
+
50
+ def initialize filename, format = :json
51
+ @filename = File.expand_path filename
52
+ @format = format
53
+ File.exists?(@filename) ? self.load : self.reset
54
+ end
55
+
56
+
57
+ # manipulate @storage
58
+ #
59
+ def [] key
60
+ key = self.class.normalize key
61
+ @storage[key] or @storage[key.to_s]
62
+ end
63
+ #
64
+ def []= key, value
65
+ @storage[self.class.normalize(key)] = value
66
+ end
67
+ #
68
+ def delete key
69
+ @storage.delete(self.class.normalize(key))
70
+ 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
78
+ end
79
+ #
80
+ def respond_to? key, *args
81
+ true
82
+ end
83
+ #
84
+ # end simple @storage manipulation
85
+
86
+
87
+ # serialization, based on PROCS
88
+ #
89
+ def serialize
90
+ raise "invalid storage" unless @storage.is_a? Hash
91
+ self.class::PROCS.fetch(@format)[:to].call @storage
92
+ end
93
+ #
94
+ def deserialize junk
95
+ data = self.class::PROCS.fetch(@format)[:from].call junk
96
+ raise "invalid junk: #{junk} (#{junk.class})" unless data.is_a? Hash
97
+ data.each { |k, v| self[k] = v }
98
+ @storage
99
+ end
100
+ #
101
+ def dump
102
+ self.class::PROCS.fetch(@format)[:pretty].call @storage
103
+ end
104
+ #
105
+ # end serialization
106
+
107
+
108
+ # file operations
109
+ #
110
+ def save
111
+ File.open(@filename, 'w') { |f| f.write self.serialize }
112
+ end
113
+ #
114
+ def load
115
+ rescues = 0
116
+ begin
117
+ File.open(@filename, 'r') { |f| @storage = self.deserialize f.read }
118
+ rescue Exception => e
119
+ rescues += 1
120
+ puts "#{e} (#{e.class})"
121
+ if rescues < 2
122
+ puts "Resetting #{@filename}"
123
+ reset
124
+ retry
125
+ end
126
+ puts "load failed!"
127
+ raise e
128
+ end
129
+ end
130
+ #
131
+ def reset
132
+ @storage = DEFAULT.dup
133
+ save
134
+ end
135
+ #
136
+ # end file operations
137
+
138
+ end
data/rakefile.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'buildar'
2
+ require 'rake/testtask'
3
+
4
+ Buildar.new do |b|
5
+ b.use_git = true
6
+ b.version_file = 'VERSION'
7
+ b.gemspec.name = 'dotcfg'
8
+ b.gemspec.summary = 'simple filesystem de/serialization for app configs'
9
+ b.gemspec.author = 'Rick Hull'
10
+ b.gemspec.license = 'MIT'
11
+ b.gemspec.description = 'JSON and YAML config serialization and synch'
12
+ b.gemspec.files = %w{rakefile.rb lib/dotcfg.rb}
13
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dotcfg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rick Hull
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-19 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: JSON and YAML config serialization and synch
15
+ email:
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - rakefile.rb
21
+ - lib/dotcfg.rb
22
+ homepage:
23
+ licenses:
24
+ - MIT
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 1.8.23
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: simple filesystem de/serialization for app configs
47
+ test_files: []