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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc877f6c4fc1d24cf76c6b6a0eb8cea7bffe14a0
4
- data.tar.gz: 1b0cf2c4aeabc5d44475b7959bb5d21dc53af90f
3
+ metadata.gz: 256816c02fae6a3705e6ebccdff65da094570a94
4
+ data.tar.gz: 9ce21782909d9e01f599191e51fceb9dd9c942e5
5
5
  SHA512:
6
- metadata.gz: 34001efb0e766f5258ee514a3e8db5817af9bfe3d39c14817b754718c135fd8450c62a310e25b712a13543573eec7bb9340876cabc62c2717290929bcf29a034
7
- data.tar.gz: 1f85017ebab7a298b35e285750eafd04b19a4a81d67560e61cf86f5a22d0d917ce14f7acc5d3d90b2b5bcb461ff0bb79dc6fd037d6e6d996f940d540b3eeec36
6
+ metadata.gz: fbf0c48597aedd4672accc6b5ed353604a488978b27500902a928df6d7c3e2bd859c682daf16a74345524ff08501dfbb3692b2a6573586c8ef025ef38e116241
7
+ data.tar.gz: 05cd1d15c8ba0bd16d46ac0aaf0564fe5187c1031e418befed059d3ac1329b7413d86487ea049bb914cf368dedfa7fbd72c2c176329d6dad79a51626587fad95
@@ -140,17 +140,6 @@ module TungstenScript
140
140
 
141
141
  def validate
142
142
  orig_validate()
143
-
144
- @option_definitions.each{
145
- |option_key,definition|
146
-
147
- if definition[:required] == true
148
- if opt(option_key).to_s() == ""
149
- arg = definition[:on][0].split(" ")[0]
150
- TU.error("Missing value for the #{arg} option")
151
- end
152
- end
153
- }
154
143
  end
155
144
  end
156
145
 
data/lib/iniparse.rb ADDED
@@ -0,0 +1,66 @@
1
+ dir = File.expand_path('iniparse', File.dirname(__FILE__))
2
+
3
+ require File.join(dir, 'document')
4
+ require File.join(dir, 'generator')
5
+ require File.join(dir, 'line_collection')
6
+ require File.join(dir, 'lines')
7
+ require File.join(dir, 'parser')
8
+
9
+ module IniParse
10
+ VERSION = '1.3.2'
11
+
12
+ # A base class for IniParse errors.
13
+ class IniParseError < StandardError; end
14
+
15
+ # Raised if an error occurs parsing an INI document.
16
+ class ParseError < IniParseError; end
17
+
18
+ # Raised when an option line is found during parsing before the first
19
+ # section.
20
+ class NoSectionError < ParseError; end
21
+
22
+ # Raised when a line is added to a collection which isn't allowed (e.g.
23
+ # adding a Section line into an OptionCollection).
24
+ class LineNotAllowed < IniParseError; end
25
+
26
+ module_function
27
+
28
+ # Parse given given INI document source +source+.
29
+ #
30
+ # See IniParse::Parser.parse
31
+ #
32
+ # ==== Parameters
33
+ # source<String>:: The source from the INI document.
34
+ #
35
+ # ==== Returns
36
+ # IniParse::Document
37
+ #
38
+ def parse(source)
39
+ IniParse::Parser.new(source).parse
40
+ end
41
+
42
+ # Opens the file at +path+, reads and parses it's contents.
43
+ #
44
+ # ==== Parameters
45
+ # path<String>:: The path to the INI document.
46
+ #
47
+ # ==== Returns
48
+ # IniParse::Document
49
+ #
50
+ def open(path)
51
+ document = IniParse::Parser.new(File.read(path)).parse
52
+ document.path = path
53
+ document
54
+ end
55
+
56
+ # Creates a new IniParse::Document using the specification you provide.
57
+ #
58
+ # See IniParse::Generator.
59
+ #
60
+ # ==== Returns
61
+ # IniParse::Document
62
+ #
63
+ def gen(&blk)
64
+ IniParse::Generator.new.gen(&blk)
65
+ end
66
+ end
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008-2010 Anthony Williams
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,84 @@
1
+ module IniParse
2
+ # Represents an INI document.
3
+ class Document
4
+ include Enumerable
5
+
6
+ attr_reader :lines
7
+ attr_accessor :path
8
+
9
+ # Creates a new Document instance.
10
+ def initialize(path = nil)
11
+ @path = path
12
+ @lines = IniParse::SectionCollection.new
13
+ end
14
+
15
+ # Enumerates through each Section in this document.
16
+ #
17
+ # Does not yield blank and comment lines by default; if you want _all_
18
+ # lines to be yielded, pass true.
19
+ #
20
+ # ==== Parameters
21
+ # include_blank<Boolean>:: Include blank/comment lines?
22
+ #
23
+ def each(*args, &blk)
24
+ @lines.each(*args, &blk)
25
+ end
26
+
27
+ # Returns the section identified by +key+.
28
+ #
29
+ # Returns nil if there is no Section with the given key.
30
+ #
31
+ def [](key)
32
+ @lines[key.to_s]
33
+ end
34
+
35
+ # Deletes the section whose name matches the given +key+.
36
+ #
37
+ # Returns the document.
38
+ #
39
+ def delete(*args)
40
+ @lines.delete(*args)
41
+ self
42
+ end
43
+
44
+ # Returns this document as a string suitable for saving to a file.
45
+ def to_ini
46
+ string = @lines.to_a.map { |line| line.to_ini }.join($/)
47
+ string = "#{ string }\n" unless string[-1] == "\n"
48
+
49
+ string
50
+ end
51
+
52
+ alias_method :to_s, :to_ini
53
+
54
+ # A human-readable version of the document, for debugging.
55
+ def inspect
56
+ sections = @lines.select { |l| l.is_a?(IniParse::Lines::Section) }
57
+ "#<IniParse::Document {#{ sections.map(&:key).join(', ') }}>"
58
+ end
59
+
60
+ # Returns true if a section with the given +key+ exists in this document.
61
+ def has_section?(key)
62
+ @lines.has_key?(key.to_s)
63
+ end
64
+
65
+ # Saves a copy of this Document to disk.
66
+ #
67
+ # If a path was supplied when the Document was initialized then nothing
68
+ # needs to be given to Document#save. If Document was not given a file
69
+ # path, or you wish to save the document elsewhere, supply a path when
70
+ # calling Document#save.
71
+ #
72
+ # ==== Parameters
73
+ # path<String>:: A path to which this document will be saved.
74
+ #
75
+ # ==== Raises
76
+ # IniParseError:: If your document couldn't be saved.
77
+ #
78
+ def save(path = nil)
79
+ @path = path if path
80
+ raise IniParseError, 'No path given to Document#save' if @path !~ /\S/
81
+ File.open(@path, 'w') { |f| f.write(self.to_ini) }
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,203 @@
1
+ module IniParse
2
+ # Generator provides a means for easily creating new INI documents.
3
+ #
4
+ # Rather than trying to hack together new INI documents by manually creating
5
+ # Document, Section and Option instances, it is preferable to use Generator
6
+ # which will handle it all for you.
7
+ #
8
+ # The Generator is exposed through IniParse.gen.
9
+ #
10
+ # IniParse.gen do |doc|
11
+ # doc.section("vehicle") do |vehicle|
12
+ # vehicle.option("road_side", "left")
13
+ # vehicle.option("realistic_acceleration", true)
14
+ # vehicle.option("max_trains", 500)
15
+ # end
16
+ #
17
+ # doc.section("construction") do |construction|
18
+ # construction.option("build_on_slopes", true)
19
+ # construction.option("autoslope", true)
20
+ # end
21
+ # end
22
+ #
23
+ # # => IniParse::Document
24
+ #
25
+ # This can be simplified further if you don't mind the small overhead
26
+ # which comes with +method_missing+:
27
+ #
28
+ # IniParse.gen do |doc|
29
+ # doc.vehicle do |vehicle|
30
+ # vehicle.road_side = "left"
31
+ # vehicle.realistic_acceleration = true
32
+ # vehicle.max_trains = 500
33
+ # end
34
+ #
35
+ # doc.construction do |construction|
36
+ # construction.build_on_slopes = true
37
+ # construction.autoslope = true
38
+ # end
39
+ # end
40
+ #
41
+ # # => IniParse::Document
42
+ #
43
+ # If you want to add slightly more complicated formatting to your document,
44
+ # each line type (except blanks) takes a number of optional parameters:
45
+ #
46
+ # :comment::
47
+ # Adds an inline comment at the end of the line.
48
+ # :comment_offset::
49
+ # Indent the comment. Measured in characters from _beginning_ of the line.
50
+ # See String#ljust.
51
+ # :indent::
52
+ # Adds the supplied text to the beginning of the line.
53
+ #
54
+ # If you supply +:indent+, +:comment_sep+, or +:comment_offset+ options when
55
+ # adding a section, the same options will be inherited by all of the options
56
+ # which belong to it.
57
+ #
58
+ # IniParse.gen do |doc|
59
+ # doc.section("vehicle",
60
+ # :comment => "Options for vehicles", :indent => " "
61
+ # ) do |vehicle|
62
+ # vehicle.option("road_side", "left")
63
+ # vehicle.option("realistic_acceleration", true)
64
+ # vehicle.option("max_trains", 500, :comment => "More = slower")
65
+ # end
66
+ # end.to_ini
67
+ #
68
+ # [vehicle] ; Options for vehicles
69
+ # road_side = left
70
+ # realistic_acceleration = true
71
+ # max_trains = 500 ; More = slower
72
+ #
73
+ class Generator
74
+ attr_reader :context
75
+ attr_reader :document
76
+
77
+ def initialize(opts = {}) # :nodoc:
78
+ @document = IniParse::Document.new
79
+ @context = @document
80
+
81
+ @in_section = false
82
+ @opt_stack = [opts]
83
+ end
84
+
85
+ def gen # :nodoc:
86
+ yield self
87
+ @document
88
+ end
89
+
90
+ # Creates a new IniParse::Document with the given sections and options.
91
+ #
92
+ # ==== Returns
93
+ # IniParse::Document
94
+ #
95
+ def self.gen(opts = {}, &blk)
96
+ new(opts).gen(&blk)
97
+ end
98
+
99
+ # Creates a new section with the given name and adds it to the document.
100
+ #
101
+ # You can optionally supply a block (as detailed in the documentation for
102
+ # Generator#gen) in order to add options to the section.
103
+ #
104
+ # ==== Parameters
105
+ # name<String>:: A name for the given section.
106
+ #
107
+ def section(name, opts = {})
108
+ if @in_section
109
+ # Nesting sections is bad, mmmkay?
110
+ raise LineNotAllowed, "You can't nest sections in INI files."
111
+ end
112
+
113
+ if @document.has_section?(name.to_s())
114
+ @context = @document[name.to_s()]
115
+ else
116
+ @context = Lines::Section.new(name, line_options(opts))
117
+ @document.lines << @context
118
+ end
119
+
120
+ if block_given?
121
+ begin
122
+ @in_section = true
123
+ with_options(opts) { yield self }
124
+ @context = @document
125
+ blank()
126
+ ensure
127
+ @in_section = false
128
+ end
129
+ end
130
+ end
131
+
132
+ # Adds a new option to the current section.
133
+ #
134
+ # Can only be called as part of a section block, or after at least one
135
+ # section has been added to the document.
136
+ #
137
+ # ==== Parameters
138
+ # key<String>:: The key (name) for this option.
139
+ # value:: The option's value.
140
+ # opts<Hash>:: Extra options for the line (formatting, etc).
141
+ #
142
+ # ==== Raises
143
+ # IniParse::NoSectionError::
144
+ # If no section has been added to the document yet.
145
+ #
146
+ def option(key, value, opts = {})
147
+ @context.lines << Lines::Option.new(
148
+ key, value, line_options(opts)
149
+ )
150
+ rescue LineNotAllowed
151
+ # Tried to add an Option to a Document.
152
+ raise NoSectionError,
153
+ 'Your INI document contains an option before the first section is ' \
154
+ 'declared which is not allowed.'
155
+ end
156
+
157
+ # Adds a new comment line to the document.
158
+ #
159
+ # ==== Parameters
160
+ # comment<String>:: The text for the comment line.
161
+ #
162
+ def comment(comment, opts = {})
163
+ @context.lines << Lines::Comment.new(
164
+ line_options(opts.merge(:comment => comment))
165
+ )
166
+ end
167
+
168
+ # Adds a new blank line to the document.
169
+ def blank
170
+ @context.lines << Lines::Blank.new
171
+ end
172
+
173
+ # Wraps lines, setting default options for each.
174
+ def with_options(opts = {}) # :nodoc:
175
+ opts = opts.dup
176
+ opts.delete(:comment)
177
+ @opt_stack.push( @opt_stack.last.merge(opts))
178
+ yield self
179
+ @opt_stack.pop
180
+ end
181
+
182
+ def method_missing(name, *args, &blk) # :nodoc:
183
+ if m = name.to_s.match(/(.*)=$/)
184
+ option(m[1], *args)
185
+ else
186
+ section(name.to_s, *args, &blk)
187
+ end
188
+ end
189
+
190
+ #######
191
+ private
192
+ #######
193
+
194
+ # Returns options for a line.
195
+ #
196
+ # If the context is a section, we use the section options as a base,
197
+ # rather than the global defaults.
198
+ #
199
+ def line_options(given_opts) # :nodoc:
200
+ @opt_stack.last.empty? ? given_opts : @opt_stack.last.merge(given_opts)
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,170 @@
1
+ module IniParse
2
+ # Represents a collection of lines in an INI document.
3
+ #
4
+ # LineCollection acts a bit like an Array/Hash hybrid, allowing arbitrary
5
+ # lines to be added to the collection, but also indexes the keys of Section
6
+ # and Option lines to enable O(1) lookup via LineCollection#[].
7
+ #
8
+ # The lines instances are stored in an array, +@lines+, while the index of
9
+ # each Section/Option is held in a Hash, +@indicies+, keyed with the
10
+ # Section/Option#key value (see LineCollection#[]=).
11
+ #
12
+ module LineCollection
13
+ include Enumerable
14
+
15
+ def initialize
16
+ @lines = []
17
+ @indicies = {}
18
+ end
19
+
20
+ # Retrive a value identified by +key+.
21
+ def [](key)
22
+ has_key?(key) ? @lines[ @indicies[key] ] : nil
23
+ end
24
+
25
+ # Set a +value+ identified by +key+.
26
+ #
27
+ # If a value with the given key already exists, the value will be replaced
28
+ # with the new one, with the new value taking the position of the old.
29
+ #
30
+ def []=(key, value)
31
+ key = key.to_s
32
+
33
+ if has_key?(key)
34
+ @lines[ @indicies[key] ] = value
35
+ else
36
+ @lines << value
37
+ @indicies[key] = @lines.length - 1
38
+ end
39
+ end
40
+
41
+ # Appends a line to the collection.
42
+ #
43
+ # Note that if you pass a line with a key already represented in the
44
+ # collection, the old item will be replaced.
45
+ #
46
+ def <<(line)
47
+ line.blank? ? (@lines << line) : (self[line.key] = line) ; self
48
+ end
49
+
50
+ alias_method :push, :<<
51
+
52
+ # Enumerates through the collection.
53
+ #
54
+ # By default #each does not yield blank and comment lines.
55
+ #
56
+ # ==== Parameters
57
+ # include_blank<Boolean>:: Include blank/comment lines?
58
+ #
59
+ def each(include_blank = false)
60
+ @lines.each do |line|
61
+ if include_blank || ! (line.is_a?(Array) ? line.empty? : line.blank?)
62
+ yield(line)
63
+ end
64
+ end
65
+ end
66
+
67
+ # Removes the value identified by +key+.
68
+ def delete(key)
69
+ key = key.key if key.respond_to?(:key)
70
+
71
+ unless (idx = @indicies[key]).nil?
72
+ @indicies.delete(key)
73
+ @indicies.each { |k,v| @indicies[k] = v -= 1 if v > idx }
74
+ @lines.delete_at(idx)
75
+ end
76
+ end
77
+
78
+ # Returns whether +key+ is in the collection.
79
+ def has_key?(*args)
80
+ @indicies.has_key?(*args)
81
+ end
82
+
83
+ # Return an array containing the keys for the lines added to this
84
+ # collection.
85
+ def keys
86
+ map { |line| line.key }
87
+ end
88
+
89
+ # Returns this collection as an array. Includes blank and comment lines.
90
+ def to_a
91
+ @lines.dup
92
+ end
93
+
94
+ # Returns this collection as a hash. Does not contain blank and comment
95
+ # lines.
96
+ def to_hash
97
+ Hash[ *(map { |line| [line.key, line] }).flatten ]
98
+ end
99
+
100
+ alias_method :to_h, :to_hash
101
+ end
102
+
103
+ # A implementation of LineCollection used for storing (mostly) Option
104
+ # instances contained within a Section.
105
+ #
106
+ # Since it is assumed that an INI document will only represent a section
107
+ # once, if SectionCollection encounters a Section key already held in the
108
+ # collection, the existing section is merged with the new one (see
109
+ # IniParse::Lines::Section#merge!).
110
+ class SectionCollection
111
+ include LineCollection
112
+
113
+ def <<(line)
114
+ if line.kind_of?(IniParse::Lines::Option)
115
+ option = line
116
+ line = IniParse::Lines::AnonymousSection.new
117
+
118
+ line.lines << option if option
119
+ end
120
+
121
+ if line.blank? || (! has_key?(line.key))
122
+ super # Adding a new section, comment or blank line.
123
+ else
124
+ self[line.key].merge!(line)
125
+ end
126
+
127
+ self
128
+ end
129
+ end
130
+
131
+ # A implementation of LineCollection used for storing (mostly) Option
132
+ # instances contained within a Section.
133
+ #
134
+ # Whenever OptionCollection encounters an Option key already held in the
135
+ # collection, it treats it as a duplicate. This means that instead of
136
+ # overwriting the existing value, the value is changed to an array
137
+ # containing the previous _and_ the new Option instances.
138
+ class OptionCollection
139
+ include LineCollection
140
+
141
+ # Appends a line to the collection.
142
+ #
143
+ # If you push an Option with a key already represented in the collection,
144
+ # the previous Option will not be overwritten, but treated as a duplicate.
145
+ #
146
+ # ==== Parameters
147
+ # line<IniParse::LineType::Line>:: The line to be added to this section.
148
+ #
149
+ def <<(line)
150
+ if line.kind_of?(IniParse::Lines::Section)
151
+ raise IniParse::LineNotAllowed,
152
+ "You can't add a Section to an OptionCollection."
153
+ end
154
+
155
+ if line.blank? || (! has_key?(line.key))
156
+ super # Adding a new option, comment or blank line.
157
+ else
158
+ self[line.key] = [self[line.key], line].flatten
159
+ end
160
+
161
+ self
162
+ end
163
+
164
+ # Return an array containing the keys for the lines added to this
165
+ # collection.
166
+ def keys
167
+ map { |line| line.kind_of?(Array) ? line.first.key : line.key }
168
+ end
169
+ end
170
+ end