continuent-tools-core 0.1.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,327 @@
1
+ module IniParse
2
+ module Lines
3
+ # A base class from which other line types should inherit.
4
+ module Line
5
+ # ==== Parameters
6
+ # opts<Hash>:: Extra options for the line.
7
+ #
8
+ def initialize(opts = {})
9
+ @comment = opts.fetch(:comment, nil)
10
+ @comment_sep = opts.fetch(:comment_sep, ';')
11
+ @comment_prefix = opts.fetch(:comment_prefix, ' ')
12
+ @comment_offset = opts.fetch(:comment_offset, 0)
13
+ @indent = opts.fetch(:indent, '')
14
+ end
15
+
16
+ # Returns if this line has an inline comment.
17
+ def has_comment?
18
+ not @comment.nil?
19
+ end
20
+
21
+ # Returns this line as a string as it would be represented in an INI
22
+ # document.
23
+ def to_ini
24
+ ini = line_contents
25
+ ini = @indent + ini if @indent
26
+
27
+ if has_comment?
28
+ ini += ' ' if ini =~ /\S/ # not blank
29
+ ini = ini.ljust(@comment_offset)
30
+ ini += comment
31
+ end
32
+
33
+ ini
34
+ end
35
+
36
+ # Returns the contents for this line.
37
+ def line_contents
38
+ ''
39
+ end
40
+
41
+ # Returns the inline comment for this line. Includes the comment
42
+ # separator at the beginning of the string.
43
+ def comment
44
+ "#{ @comment_sep }#{ @comment_prefix }#{ @comment }"
45
+ end
46
+
47
+ # Returns whether this is a line which has no data.
48
+ def blank?
49
+ false
50
+ end
51
+ end
52
+
53
+ # Represents a section header in an INI document. Section headers consist
54
+ # of a string of characters wrapped in square brackets.
55
+ #
56
+ # [section]
57
+ # key=value
58
+ # etc
59
+ # ...
60
+ #
61
+ class Section
62
+ include Line
63
+
64
+ @regex = /^\[ # Opening bracket
65
+ ([^\]]+) # Section name
66
+ \]$ # Closing bracket
67
+ /x
68
+
69
+ attr_accessor :key
70
+ attr_reader :lines
71
+
72
+ include Enumerable
73
+
74
+ # ==== Parameters
75
+ # key<String>:: The section name.
76
+ # opts<Hash>:: Extra options for the line.
77
+ #
78
+ def initialize(key, opts = {})
79
+ super(opts)
80
+ @key = key.to_s
81
+ @lines = IniParse::OptionCollection.new
82
+ end
83
+
84
+ def self.parse(line, opts)
85
+ if m = @regex.match(line)
86
+ [:section, m[1], opts]
87
+ end
88
+ end
89
+
90
+ # Returns this line as a string as it would be represented in an INI
91
+ # document. Includes options, comments and blanks.
92
+ def to_ini
93
+ coll = lines.to_a
94
+
95
+ if coll.any?
96
+ super + $/ + coll.to_a.map do |line|
97
+ if line.kind_of?(Array)
98
+ line.map { |dup_line| dup_line.to_ini }.join($/)
99
+ else
100
+ line.to_ini
101
+ end
102
+ end.join($/)
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ # Enumerates through each Option in this section.
109
+ #
110
+ # Does not yield blank and comment lines by default; if you want _all_
111
+ # lines to be yielded, pass true.
112
+ #
113
+ # ==== Parameters
114
+ # include_blank<Boolean>:: Include blank/comment lines?
115
+ #
116
+ def each(*args, &blk)
117
+ @lines.each(*args, &blk)
118
+ end
119
+
120
+ # Adds a new option to this section, or updates an existing one.
121
+ #
122
+ # Note that +[]=+ has no knowledge of duplicate options and will happily
123
+ # overwrite duplicate options with your new value.
124
+ #
125
+ # section['an_option']
126
+ # # => ['duplicate one', 'duplicate two', ...]
127
+ # section['an_option'] = 'new value'
128
+ # section['an_option]
129
+ # # => 'new value'
130
+ #
131
+ # If you do not wish to overwrite duplicates, but wish instead for your
132
+ # new option to be considered a duplicate, use +add_option+ instead.
133
+ #
134
+ def []=(key, value)
135
+ @lines[key.to_s] = IniParse::Lines::Option.new(key.to_s, value)
136
+ end
137
+
138
+ # Returns the value of an option identified by +key+.
139
+ #
140
+ # Returns nil if there is no corresponding option. If the key provided
141
+ # matches a set of duplicate options, an array will be returned containing
142
+ # the value of each option.
143
+ #
144
+ def [](key)
145
+ key = key.to_s
146
+
147
+ if @lines.has_key?(key)
148
+ if (match = @lines[key]).kind_of?(Array)
149
+ match.map { |line| line.value }
150
+ else
151
+ match.value
152
+ end
153
+ end
154
+ end
155
+
156
+ # Deletes the option identified by +key+.
157
+ #
158
+ # Returns the section.
159
+ #
160
+ def delete(*args)
161
+ @lines.delete(*args)
162
+ self
163
+ end
164
+
165
+ # Like [], except instead of returning just the option value, it returns
166
+ # the matching line instance.
167
+ #
168
+ # Will return an array of lines if the key matches a set of duplicates.
169
+ #
170
+ def option(key)
171
+ @lines[key.to_s]
172
+ end
173
+
174
+ # Returns true if an option with the given +key+ exists in this section.
175
+ def has_option?(key)
176
+ @lines.has_key?(key.to_s)
177
+ end
178
+
179
+ # Merges section +other+ into this one. If the section being merged into
180
+ # this one contains options with the same key, they will be handled as
181
+ # duplicates.
182
+ #
183
+ # ==== Parameters
184
+ # other<IniParse::Section>:: The section to merge into this one.
185
+ #
186
+ def merge!(other)
187
+ other.lines.each(true) do |line|
188
+ if line.kind_of?(Array)
189
+ line.each { |duplicate| @lines << duplicate }
190
+ else
191
+ @lines << line
192
+ end
193
+ end
194
+ end
195
+
196
+ #######
197
+ private
198
+ #######
199
+
200
+ def line_contents
201
+ '[%s]' % key
202
+ end
203
+ end
204
+
205
+ # Stores options which appear at the beginning of a file, without a
206
+ # preceding section.
207
+ class AnonymousSection < Section
208
+ def initialize
209
+ super('__anonymous__')
210
+ end
211
+
212
+ def to_ini
213
+ # Remove the leading space which is added by joining the blank line
214
+ # content with the options.
215
+ super.gsub(/\A\n/, '')
216
+ end
217
+
218
+ #######
219
+ private
220
+ #######
221
+
222
+ def line_contents
223
+ ''
224
+ end
225
+ end
226
+
227
+ # Represents probably the most common type of line in an INI document:
228
+ # an option. Consists of a key and value, usually separated with an =.
229
+ #
230
+ # key = value
231
+ #
232
+ class Option
233
+ include Line
234
+
235
+ @regex = /^\s*([^=]+) # Option
236
+ =
237
+ (.*?)$ # Value
238
+ /x
239
+
240
+ attr_accessor :key, :value
241
+
242
+ # ==== Parameters
243
+ # key<String>:: The option key.
244
+ # value<String>:: The value for this option.
245
+ # opts<Hash>:: Extra options for the line.
246
+ #
247
+ def initialize(key, value, opts = {})
248
+ super(opts)
249
+ @key, @value = key.to_s, value
250
+ end
251
+
252
+ def self.parse(line, opts)
253
+ if m = @regex.match(line)
254
+ [:option, m[1].strip, typecast(m[2].strip), opts]
255
+ end
256
+ end
257
+
258
+ # Attempts to typecast values.
259
+ def self.typecast(value)
260
+ case value
261
+ when /^\s*$/ then nil
262
+ when /^-?(?:\d|[1-9]\d+)$/ then Integer(value)
263
+ when /^-?(?:\d|[1-9]\d+)(?:\.\d+)?(?:e[+-]?\d+)?$/i then Float(value)
264
+ when /true/i then true
265
+ when /false/i then false
266
+ else value
267
+ end
268
+ end
269
+
270
+ #######
271
+ private
272
+ #######
273
+
274
+ def line_contents
275
+ '%s = %s' % [key, value]
276
+ end
277
+ end
278
+
279
+ # Represents a blank line. Used so that we can preserve blank lines when
280
+ # writing back to the file.
281
+ class Blank
282
+ include Line
283
+
284
+ def blank?
285
+ true
286
+ end
287
+
288
+ def self.parse(line, opts)
289
+ if line !~ /\S/ # blank
290
+ if opts[:comment].nil?
291
+ [:blank]
292
+ else
293
+ [:comment, opts[:comment], opts]
294
+ end
295
+ end
296
+ end
297
+ end
298
+
299
+ # Represents a comment. Comment lines begin with a semi-colon or hash.
300
+ #
301
+ # ; this is a comment
302
+ # # also a comment
303
+ #
304
+ class Comment < Blank
305
+ # Returns if this line has an inline comment.
306
+ #
307
+ # Being a Comment this will always return true, even if the comment
308
+ # is nil. This would be the case if the line starts with a comment
309
+ # seperator, but has no comment text. See spec/fixtures/smb.ini for a
310
+ # real-world example.
311
+ #
312
+ def has_comment?
313
+ true
314
+ end
315
+
316
+ # Returns the inline comment for this line. Includes the comment
317
+ # separator at the beginning of the string.
318
+ #
319
+ # In rare cases where a comment seperator appeared in the original file,
320
+ # but without a comment, just the seperator will be returned.
321
+ #
322
+ def comment
323
+ @comment !~ /\S/ ? @comment_sep : super
324
+ end
325
+ end
326
+ end # Lines
327
+ end # IniParse
@@ -0,0 +1,110 @@
1
+ module IniParse
2
+ class Parser
3
+
4
+ # Returns the line types.
5
+ #
6
+ # ==== Returns
7
+ # Array
8
+ #
9
+ def self.parse_types
10
+ @@parse_types ||= []
11
+ end
12
+
13
+ # Sets the line types. Handy if you want to add your own custom Line
14
+ # classes.
15
+ #
16
+ # ==== Parameters
17
+ # types<Array[IniParse::Lines::Line]>:: An array containing Line classes.
18
+ #
19
+ def self.parse_types=(types)
20
+ parse_types.replace(types)
21
+ end
22
+
23
+ self.parse_types = [ IniParse::Lines::Section,
24
+ IniParse::Lines::Option, IniParse::Lines::Blank ]
25
+
26
+ # Creates a new Parser instance for parsing string +source+.
27
+ #
28
+ # ==== Parameters
29
+ # source<String>:: The source string.
30
+ #
31
+ def initialize(source)
32
+ @source = source.dup
33
+ end
34
+
35
+ # Parses the source string and returns the resulting data structure.
36
+ #
37
+ # ==== Returns
38
+ # IniParse::Document
39
+ #
40
+ def parse
41
+ IniParse::Generator.gen do |generator|
42
+ @source.split("\n", -1).each do |line|
43
+ generator.send(*Parser.parse_line(line))
44
+ end
45
+ end
46
+ end
47
+
48
+ class << self
49
+ # Takes a raw line from an INI document, striping out any inline
50
+ # comment, and indent, then returns the appropriate tuple so that the
51
+ # Generator instance can add the line to the Document.
52
+ #
53
+ # ==== Raises
54
+ # IniParse::ParseError: If the line could not be parsed.
55
+ #
56
+ def parse_line(line)
57
+ sanitized, opts = strip_indent(*strip_comment(line, {}))
58
+
59
+ parsed = nil
60
+ @@parse_types.each do |type|
61
+ break if (parsed = type.parse(sanitized, opts))
62
+ end
63
+
64
+ if parsed.nil?
65
+ raise IniParse::ParseError,
66
+ "A line of your INI document could not be parsed to a " \
67
+ "LineType: '#{line}'."
68
+ end
69
+
70
+ parsed
71
+ end
72
+
73
+ #######
74
+ private
75
+ #######
76
+
77
+ # Strips in inline comment from a line (or value), removes trailing
78
+ # whitespace and sets the comment options as applicable.
79
+ def strip_comment(line, opts)
80
+ if m = /^(^)(?:(;|\#)(\s*)(.*))$$/.match(line) ||
81
+ m = /^(.*?)(?:\s+(;|\#)(\s*)(.*))$/.match(line) # Comment lines.
82
+ opts[:comment] = m[4].rstrip
83
+ opts[:comment_prefix] = m[3]
84
+ opts[:comment_sep] = m[2]
85
+ # Remove the line content (since an option value may contain a
86
+ # semi-colon) _then_ get the index of the comment separator.
87
+ opts[:comment_offset] =
88
+ line[(m[1].length..-1)].index(m[2]) + m[1].length
89
+
90
+ line = m[1]
91
+ else
92
+ line.rstrip!
93
+ end
94
+
95
+ [line, opts]
96
+ end
97
+
98
+ # Removes any leading whitespace from a line, and adds it to the options
99
+ # hash.
100
+ def strip_indent(line, opts)
101
+ if m = /^(\s+).*$/.match(line)
102
+ line.lstrip!
103
+ opts[:indent] = m[1]
104
+ end
105
+
106
+ [line, opts]
107
+ end
108
+ end
109
+ end # Parser
110
+ end # IniParse
data/lib/tungsten/api.rb CHANGED
@@ -7,7 +7,7 @@ require 'net/http'
7
7
 
8
8
  # SAMPLE USAGE:
9
9
  # api_server='localhost:8090'
10
- # service=chicago
10
+ # service="chicago"
11
11
  #
12
12
  # cctrl = TungstenDataserviceManager.new(api_server)
13
13
  # cctrl.list(:text)
@@ -21,10 +21,10 @@ require 'net/http'
21
21
  #
22
22
  # begin
23
23
  # APICall.set_return_on_call_fail(:raise)
24
- # json_obj = cctrl.post(service}/host1', 'promote')
24
+ # json_obj = cctrl.post("#{service}/host1", 'promote')
25
25
  # pp json_obj["message"]
26
26
  # rescue Exception => e
27
- # puts e # failure message will coem here
27
+ # puts e # failure message will come here
28
28
  # end
29
29
 
30
30