fig 0.1.69 → 0.1.71

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