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