continuent-tools-core 0.1.6 → 0.5.0

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