fig 0.1.69 → 0.1.71

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,32 +1,11 @@
1
1
  # Treetop (http://treetop.rubyforge.org/) grammar for package definitions.
2
2
 
3
- require 'fig/package'
4
- require 'fig/package_descriptor'
5
- require 'fig/parser'
6
- require 'fig/statement/archive'
7
- require 'fig/statement/command'
8
- require 'fig/statement/configuration'
9
- require 'fig/statement/include'
10
- require 'fig/statement/override'
11
- require 'fig/statement/path'
12
- require 'fig/statement/resource'
13
- require 'fig/statement/retrieve'
14
- require 'fig/statement/set'
15
-
16
3
  module Fig
17
4
  grammar Fig
18
5
  rule package
19
6
  optional_ws statements:(package_statement*) optional_ws {
20
7
  def to_package(directory, build_state)
21
- Package.new(
22
- build_state.descriptor.name,
23
- build_state.descriptor.version,
24
- directory,
25
- statements.elements.map do
26
- |statement|
27
- statement.to_package_statement(build_state)
28
- end
29
- )
8
+ return build_state.new_package_statement(directory, statements)
30
9
  end
31
10
  }
32
11
  end
@@ -35,13 +14,13 @@ module Fig
35
14
  archive / resource / retrieve / config
36
15
  end
37
16
 
17
+ # Note that these are being parsed like they allow globbing despite
18
+ # globbing not being performed.
38
19
  rule archive
39
20
  statement_start:"archive" ws resource_url {
40
21
  def to_package_statement(build_state)
41
- Statement::Archive.new(
42
- build_state.node_location(statement_start),
43
- build_state.source_description,
44
- resource_url.value.text_value
22
+ return build_state.new_asset_statement(
23
+ Statement::Archive, statement_start, resource_url
45
24
  )
46
25
  end
47
26
  }
@@ -50,10 +29,8 @@ module Fig
50
29
  rule resource
51
30
  statement_start:"resource" ws resource_url {
52
31
  def to_package_statement(build_state)
53
- Statement::Resource.new(
54
- build_state.node_location(statement_start),
55
- build_state.source_description,
56
- resource_url.value.text_value
32
+ return build_state.new_asset_statement(
33
+ Statement::Resource, statement_start, resource_url
57
34
  )
58
35
  end
59
36
  }
@@ -62,12 +39,7 @@ module Fig
62
39
  rule retrieve
63
40
  statement_start:"retrieve" ws var:environment_variable_name "->" path:retrieve_path ws {
64
41
  def to_package_statement(build_state)
65
- Statement::Retrieve.new(
66
- build_state.node_location(statement_start),
67
- build_state.source_description,
68
- var.text_value,
69
- path.text_value
70
- )
42
+ return build_state.new_retrieve_statement(statement_start, var, path)
71
43
  end
72
44
  }
73
45
  end
@@ -79,14 +51,8 @@ module Fig
79
51
  rule config
80
52
  statement_start:"config" ws config_name ws statements:config_statement* "end" ws {
81
53
  def to_package_statement(build_state)
82
- Statement::Configuration.new(
83
- build_state.node_location(statement_start),
84
- build_state.source_description,
85
- config_name.text_value,
86
- statements.elements.map do
87
- |statement|
88
- statement.to_config_statement(build_state)
89
- end
54
+ return build_state.new_configuration_statement(
55
+ statement_start, config_name, statements
90
56
  )
91
57
  end
92
58
  }
@@ -103,19 +69,8 @@ module Fig
103
69
  rule include
104
70
  statement_start:"include" ws descriptor_string ws {
105
71
  def to_config_statement(build_state)
106
- include_descriptor =
107
- Statement::Include.parse_descriptor(
108
- descriptor_string.text_value.strip,
109
- :source_description =>
110
- build_state.node_location_description(descriptor_string),
111
- :validation_context => ' for an include statement'
112
- )
113
-
114
- Statement::Include.new(
115
- build_state.node_location(statement_start),
116
- build_state.source_description,
117
- include_descriptor,
118
- build_state.descriptor
72
+ return build_state.new_include_statement(
73
+ statement_start, descriptor_string
119
74
  )
120
75
  end
121
76
  }
@@ -124,19 +79,8 @@ module Fig
124
79
  rule override
125
80
  statement_start:"override" ws descriptor_string ws {
126
81
  def to_config_statement(build_state)
127
- descriptor =
128
- Statement::Override.parse_descriptor(
129
- descriptor_string.text_value.strip,
130
- :source_description =>
131
- build_state.node_location_description(descriptor_string),
132
- :validation_context => ' for an override statement'
133
- )
134
-
135
- return Statement::Override.new(
136
- build_state.node_location(statement_start),
137
- build_state.source_description,
138
- descriptor.name,
139
- descriptor.version
82
+ return build_state.new_override_statement(
83
+ statement_start, descriptor_string
140
84
  )
141
85
  end
142
86
  }
@@ -169,11 +113,7 @@ module Fig
169
113
  rule command
170
114
  statement_start:"command" ws string {
171
115
  def to_config_statement(build_state)
172
- Statement::Command.new(
173
- build_state.node_location(statement_start),
174
- build_state.source_description,
175
- string.value.text_value
176
- )
116
+ return build_state.new_command_statement(statement_start, string)
177
117
  end
178
118
  }
179
119
  end
@@ -186,14 +126,6 @@ module Fig
186
126
  [\S]+
187
127
  end
188
128
 
189
- rule package_name
190
- [a-zA-Z0-9_.-]+
191
- end
192
-
193
- rule version_name
194
- [a-zA-Z0-9_.-]+
195
- end
196
-
197
129
  rule resource_url
198
130
  # Unquoted allows globbing for files, quoted does not.
199
131
  #
@@ -201,14 +133,14 @@ module Fig
201
133
  # @ - To allow for package substitution
202
134
  # "<>| - Characters not allowed in filenames on Windows
203
135
  # \s - Necessary for the "ws" token to work
204
- (value:[^@"<>|\s]+ ws)
136
+ (url:[^@"<>|\s]+ ws)
205
137
 
206
138
  # Quoted, anything but:
207
139
  # @ - To allow for package substitution
208
140
  # "<>| - Characters not allowed in filenames on Windows
209
141
  # *?\[\]{} - Characters significant to Dir.glob()
210
142
  # \s - We just don't want these. :] (May need to allow space.)
211
- / ('"' value:[^@"<>|*?\[\]{}\s]+ '"' ws)
143
+ / ('"' url:[^@"<>|*?\[\]{}\s]+ '"' ws)
212
144
  end
213
145
 
214
146
  rule ws
@@ -64,6 +64,7 @@ class Fig::PackageDescriptor
64
64
  validate_component name, 'name', :name, options
65
65
  validate_component version, 'version', :version, options
66
66
  validate_component config, 'config', :config, options
67
+ validate_name options
67
68
  validate_across_components options
68
69
  end
69
70
 
@@ -112,6 +113,17 @@ class Fig::PackageDescriptor
112
113
  )
113
114
  end
114
115
 
116
+ def validate_name(options)
117
+ return if @name.nil?
118
+
119
+ return if ! Fig::Parser.strict_keyword? @name
120
+
121
+ raise Fig::PackageDescriptorParseError.new(
122
+ %Q<Invalid package name; "#{@name}" is a keyword#{standard_exception_suffix(options)}>,
123
+ @original_string
124
+ )
125
+ end
126
+
115
127
  def throw_presence_exception(name, presence_requirement_symbol, options)
116
128
  presence = options[presence_requirement_symbol]
117
129
  raise Fig::PackageDescriptorParseError.new(
data/lib/fig/parser.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'set'
1
2
  require 'treetop'
2
3
 
3
4
  require 'fig/grammar' # this is grammar.treetop, not grammar.rb.
@@ -14,6 +15,19 @@ module Fig; end
14
15
  # Parses .fig files (wrapping the Treetop-generated parser object) and deals
15
16
  # with a few restrictions on them.
16
17
  class Fig::Parser
18
+ # Keywords that we really want to lock down.
19
+ def self.strict_keyword?(string)
20
+ # "config" is considered too useful for users, so we allow that where we
21
+ # restrict other keywords.
22
+ return false if string == 'config'
23
+
24
+ return keyword? string
25
+ end
26
+
27
+ def self.keyword?(string)
28
+ return KEYWORDS.include? string
29
+ end
30
+
17
31
  def initialize(application_config, check_include_versions)
18
32
  # Fig::FigParser class is synthesized by Treetop.
19
33
  @treetop_parser = Fig::FigParser.new
@@ -51,6 +65,21 @@ class Fig::Parser
51
65
 
52
66
  private
53
67
 
68
+ KEYWORDS = Set.new
69
+ KEYWORDS << 'add'
70
+ KEYWORDS << 'append'
71
+ KEYWORDS << 'archive'
72
+ KEYWORDS << 'command'
73
+ KEYWORDS << 'config'
74
+ KEYWORDS << 'end'
75
+ KEYWORDS << 'include'
76
+ KEYWORDS << 'override'
77
+ KEYWORDS << 'path'
78
+ KEYWORDS << 'resource'
79
+ KEYWORDS << 'retrieve'
80
+ KEYWORDS << 'set'
81
+
82
+
54
83
  def extend_source_description(directory, original_description)
55
84
  if original_description
56
85
  extended = original_description
@@ -1,5 +1,15 @@
1
+ require 'fig/package'
1
2
  require 'fig/package_parse_error'
2
3
  require 'fig/statement'
4
+ require 'fig/statement/archive'
5
+ require 'fig/statement/command'
6
+ require 'fig/statement/configuration'
7
+ require 'fig/statement/include'
8
+ require 'fig/statement/override'
9
+ require 'fig/statement/path'
10
+ require 'fig/statement/resource'
11
+ require 'fig/statement/retrieve'
12
+ require 'fig/statement/set'
3
13
 
4
14
  module Fig; end
5
15
 
@@ -33,6 +43,93 @@ class Fig::ParserPackageBuildState
33
43
  )
34
44
  end
35
45
 
46
+ def new_package_statement(directory, statements)
47
+ return Fig::Package.new(
48
+ descriptor.name,
49
+ descriptor.version,
50
+ directory,
51
+ statements.elements.map do
52
+ |statement|
53
+ statement.to_package_statement(self)
54
+ end
55
+ )
56
+ end
57
+
58
+ def new_asset_statement(statement_class, keyword_node, url_node)
59
+ url = url_node.url.text_value
60
+
61
+ statement_class.validate_url(url) {
62
+ |error_description|
63
+
64
+ raise_invalid_value_parse_error(
65
+ keyword_node, url_node.url, 'URL/path', error_description
66
+ )
67
+ }
68
+
69
+ return statement_class.new(
70
+ node_location(keyword_node), source_description, url
71
+ )
72
+ end
73
+
74
+ def new_retrieve_statement(keyword_node, variable_name_node, path_node)
75
+ return Fig::Statement::Retrieve.new(
76
+ node_location(keyword_node),
77
+ source_description,
78
+ variable_name_node.text_value,
79
+ path_node.text_value
80
+ )
81
+ end
82
+
83
+ def new_configuration_statement(keyword_node, name_node, statements)
84
+ if Fig::Parser.strict_keyword? name_node.text_value
85
+ raise_invalid_value_parse_error(
86
+ keyword_node, name_node, 'name', 'is a keyword.'
87
+ )
88
+ end
89
+
90
+ return Fig::Statement::Configuration.new(
91
+ node_location(keyword_node),
92
+ source_description,
93
+ name_node.text_value,
94
+ statements.elements.map do
95
+ |statement|
96
+ statement.to_config_statement(self)
97
+ end
98
+ )
99
+ end
100
+
101
+ def new_include_statement(keyword_node, descriptor_node)
102
+ include_descriptor =
103
+ Fig::Statement::Include.parse_descriptor(
104
+ descriptor_node.text_value.strip,
105
+ :source_description => node_location_description(descriptor_node),
106
+ :validation_context => ' for an include statement'
107
+ )
108
+
109
+ return Fig::Statement::Include.new(
110
+ node_location(keyword_node),
111
+ source_description,
112
+ include_descriptor,
113
+ descriptor
114
+ )
115
+ end
116
+
117
+ def new_override_statement(keyword_node, descriptor_node)
118
+ override_descriptor =
119
+ Fig::Statement::Override.parse_descriptor(
120
+ descriptor_node.text_value.strip,
121
+ :source_description => node_location_description(descriptor_node),
122
+ :validation_context => ' for an override statement'
123
+ )
124
+
125
+ return Fig::Statement::Override.new(
126
+ node_location(keyword_node),
127
+ source_description,
128
+ override_descriptor.name,
129
+ override_descriptor.version
130
+ )
131
+ end
132
+
36
133
  def new_environment_variable_statement(
37
134
  statement_class, keyword_node, value_node
38
135
  )
@@ -40,6 +137,7 @@ class Fig::ParserPackageBuildState
40
137
  raise_invalid_value_parse_error(
41
138
  keyword_node,
42
139
  value_node,
140
+ 'value',
43
141
  statement_class.const_get(:ARGUMENT_DESCRIPTION)
44
142
  )
45
143
  }
@@ -48,9 +146,19 @@ class Fig::ParserPackageBuildState
48
146
  )
49
147
  end
50
148
 
51
- def raise_invalid_value_parse_error(keyword_node, value_node, description)
149
+ def new_command_statement(keyword_node, command_node)
150
+ return Fig::Statement::Command.new(
151
+ node_location(keyword_node),
152
+ source_description,
153
+ command_node.value.text_value
154
+ )
155
+ end
156
+
157
+ def raise_invalid_value_parse_error(
158
+ keyword_node, value_node, value_name, description
159
+ )
52
160
  raise Fig::PackageParseError.new(
53
- %Q<Invalid value for #{keyword_node.text_value} statement: "#{value_node.text_value}" #{description}#{node_location_description(value_node)}>
161
+ %Q<Invalid #{value_name} for #{keyword_node.text_value} statement: "#{value_node.text_value}" #{description}#{node_location_description(value_node)}>
54
162
  )
55
163
  end
56
164
  end
@@ -159,13 +159,12 @@ class Fig::RuntimeEnvironment
159
159
 
160
160
  # Check to see if this include has been overridden.
161
161
  if backtrace
162
- override = backtrace.get_override(
163
- descriptor.name || base_package.name
164
- )
162
+ override_package_name = descriptor.name || base_package.name
163
+ override = backtrace.get_override(override_package_name)
165
164
  if override
166
165
  resolved_descriptor =
167
166
  Fig::PackageDescriptor.new(
168
- descriptor.name, override, descriptor.config
167
+ override_package_name, override, descriptor.config
169
168
  )
170
169
  end
171
170
  end
@@ -433,7 +432,11 @@ class Fig::RuntimeEnvironment
433
432
  def raise_repository_error(message, backtrace, package)
434
433
  string_handle = StringIO.new
435
434
  backtrace.dump(string_handle) if backtrace
436
- package.backtrace.dump(string_handle) if package && package.backtrace
435
+
436
+ if package && package.backtrace && package.backtrace != backtrace
437
+ package.backtrace.dump(string_handle)
438
+ end
439
+
437
440
  stacktrace = string_handle.string
438
441
 
439
442
  raise Fig::RepositoryError.new(
@@ -1,8 +1,16 @@
1
+ require 'fig/parser'
2
+
1
3
  module Fig; end
2
4
  class Fig::Statement; end
3
5
 
4
6
  # Some sort of file to be included in a package.
5
7
  module Fig::Statement::Asset
8
+ def self.included(class_included_into)
9
+ class_included_into.extend(ClassMethods)
10
+
11
+ return
12
+ end
13
+
6
14
  def urls()
7
15
  return [ url() ]
8
16
  end
@@ -16,4 +24,15 @@ module Fig::Statement::Asset
16
24
  # going to fix this now.
17
25
  return url().split('/').last()
18
26
  end
27
+
28
+ module ClassMethods
29
+ def validate_url(url)
30
+ # "config" is a reasonable asset name, so we let that pass.
31
+ if Fig::Parser.strict_keyword?(url)
32
+ yield 'is a keyword.'
33
+ end
34
+
35
+ return
36
+ end
37
+ end
19
38
  end