fig 0.1.73 → 0.1.75
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.
- data/Changes +75 -0
- data/lib/fig.rb +1 -1
- data/lib/fig/command.rb +36 -12
- data/lib/fig/command/action.rb +1 -1
- data/lib/fig/command/action/dump_package_definition_parsed.rb +4 -6
- data/lib/fig/command/action/run_command_statement.rb +3 -2
- data/lib/fig/command/options.rb +12 -3
- data/lib/fig/command/options/parser.rb +2 -0
- data/lib/fig/command/package_loader.rb +1 -0
- data/lib/fig/config_file_error.rb +1 -1
- data/lib/fig/grammar/base.rb +214 -0
- data/lib/fig/grammar/base.treetop +29 -0
- data/lib/fig/grammar/v0.rb +1493 -0
- data/lib/fig/grammar/v0.treetop +167 -0
- data/lib/fig/grammar/v1.rb +1478 -0
- data/lib/fig/grammar/v1.treetop +174 -0
- data/lib/fig/grammar/version.rb +144 -0
- data/lib/fig/grammar/version.treetop +22 -0
- data/lib/fig/grammar/version_identification.rb +113 -0
- data/lib/fig/grammar/version_identification.treetop +27 -0
- data/lib/fig/log4r_config_error.rb +1 -1
- data/lib/fig/no_such_package_config_error.rb +1 -1
- data/lib/fig/not_found_error.rb +7 -0
- data/lib/fig/operating_system.rb +31 -20
- data/lib/fig/package.rb +8 -3
- data/lib/fig/package_definition_text_assembler.rb +88 -0
- data/lib/fig/package_descriptor_parse_error.rb +1 -1
- data/lib/fig/parser.rb +115 -29
- data/lib/fig/parser_package_build_state.rb +38 -11
- data/lib/fig/repository.rb +5 -8
- data/lib/fig/repository_package_publisher.rb +114 -96
- data/lib/fig/runtime_environment.rb +42 -14
- data/lib/fig/statement.rb +133 -0
- data/lib/fig/statement/archive.rb +6 -4
- data/lib/fig/statement/asset.rb +28 -34
- data/lib/fig/statement/command.rb +6 -2
- data/lib/fig/statement/configuration.rb +4 -12
- data/lib/fig/statement/grammar_version.rb +22 -0
- data/lib/fig/statement/include.rb +5 -6
- data/lib/fig/statement/override.rb +6 -3
- data/lib/fig/statement/path.rb +12 -2
- data/lib/fig/statement/resource.rb +8 -8
- data/lib/fig/statement/retrieve.rb +11 -3
- data/lib/fig/statement/set.rb +12 -2
- data/lib/fig/unparser.rb +127 -0
- data/lib/fig/unparser/v0.rb +84 -0
- data/lib/fig/unparser/v1.rb +77 -0
- data/lib/fig/url.rb +7 -0
- metadata +139 -25
- data/lib/fig/grammar.treetop +0 -147
@@ -9,6 +9,7 @@ require 'fig/statement/include'
|
|
9
9
|
require 'fig/statement/path'
|
10
10
|
require 'fig/statement/set'
|
11
11
|
require 'fig/user_input_error'
|
12
|
+
require 'fig/unparser/v0'
|
12
13
|
|
13
14
|
module Fig; end
|
14
15
|
|
@@ -106,19 +107,25 @@ class Fig::RuntimeEnvironment
|
|
106
107
|
return
|
107
108
|
end
|
108
109
|
|
109
|
-
def execute_config(base_package, descriptor, args, &block)
|
110
|
+
def execute_config(base_package, base_config, descriptor, args, &block)
|
110
111
|
config_name =
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
descriptor.
|
117
|
-
|
118
|
-
|
119
|
-
|
112
|
+
determine_config_to_executed(base_package, base_config, descriptor)
|
113
|
+
|
114
|
+
package = nil
|
115
|
+
|
116
|
+
if descriptor
|
117
|
+
name = descriptor.name || base_package.name
|
118
|
+
package = lookup_package(
|
119
|
+
name,
|
120
|
+
descriptor.version,
|
121
|
+
Fig::IncludeBacktrace.new(
|
122
|
+
nil,
|
123
|
+
Fig::PackageDescriptor.new(name, descriptor.version, config_name)
|
124
|
+
)
|
120
125
|
)
|
121
|
-
|
126
|
+
else
|
127
|
+
package = base_package
|
128
|
+
end
|
122
129
|
|
123
130
|
command_statement = package[config_name].command_statement
|
124
131
|
if command_statement
|
@@ -148,7 +155,9 @@ class Fig::RuntimeEnvironment
|
|
148
155
|
when Fig::Statement::Command
|
149
156
|
# Skip - has no effect on environment.
|
150
157
|
else
|
151
|
-
|
158
|
+
unparser = Fig::Unparser::V0.new :emit_as_to_be_published
|
159
|
+
text = unparser.unparse([statement]).strip
|
160
|
+
raise "Unexpected statement in a config block: #{text}"
|
152
161
|
end
|
153
162
|
|
154
163
|
return
|
@@ -191,8 +200,10 @@ class Fig::RuntimeEnvironment
|
|
191
200
|
|
192
201
|
statement = @retrieves[name]
|
193
202
|
if statement.loaded_but_not_referenced?
|
203
|
+
unparser = Fig::Unparser::V0.new :emit_as_to_be_published
|
204
|
+
text = unparser.unparse([statement]).strip
|
194
205
|
Fig::Logging.warn \
|
195
|
-
%Q<The #{name} variable was never referenced or didn't need expansion, so "#{
|
206
|
+
%Q<The #{name} variable was never referenced or didn't need expansion, so "#{text}"#{statement.position_string} was ignored.>
|
196
207
|
end
|
197
208
|
end
|
198
209
|
end
|
@@ -264,12 +275,29 @@ class Fig::RuntimeEnvironment
|
|
264
275
|
return package
|
265
276
|
end
|
266
277
|
|
267
|
-
def
|
278
|
+
def determine_config_to_executed(base_package, base_config, descriptor)
|
279
|
+
return base_config if base_config
|
280
|
+
|
281
|
+
if descriptor
|
282
|
+
return descriptor.config if descriptor.config
|
283
|
+
|
284
|
+
config_name = find_config_name_in_package_named(descriptor.name)
|
285
|
+
return config_name if config_name
|
286
|
+
end
|
287
|
+
|
288
|
+
return find_config_name_in_package(base_package)
|
289
|
+
end
|
290
|
+
|
291
|
+
def find_config_name_in_package_named(name)
|
268
292
|
package = get_package(name)
|
269
293
|
if not package
|
270
294
|
return Fig::Package::DEFAULT_CONFIG
|
271
295
|
end
|
272
296
|
|
297
|
+
return find_config_name_in_package(package)
|
298
|
+
end
|
299
|
+
|
300
|
+
def find_config_name_in_package(package)
|
273
301
|
return package.primary_config_name || Fig::Package::DEFAULT_CONFIG
|
274
302
|
end
|
275
303
|
|
data/lib/fig/statement.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
1
5
|
module Fig; end
|
2
6
|
|
3
7
|
# A statement within a package definition file (package.fig).
|
@@ -22,6 +26,121 @@ class Fig::Statement
|
|
22
26
|
return description
|
23
27
|
end
|
24
28
|
|
29
|
+
# Parameter will be modified.
|
30
|
+
#
|
31
|
+
# Takes a block that is invoked when there is an error. Block receives a
|
32
|
+
# single parameter of an error message that is the end of a statement
|
33
|
+
# describing the problem, with no leading space character. For example,
|
34
|
+
# given «'foo», the block will receive a message like 'has unbalanced single
|
35
|
+
# quotes.'.
|
36
|
+
#
|
37
|
+
# Returns whether parameter was single-quoted; if there was a parse error,
|
38
|
+
# then the return value will be nil (and the block will have been invoked).
|
39
|
+
def self.strip_quotes_and_process_escapes!(string, &error_block)
|
40
|
+
return false if string.length == 0
|
41
|
+
|
42
|
+
replaced_quotes = strip_single_quotes!(string, &error_block)
|
43
|
+
return true if replaced_quotes
|
44
|
+
return if replaced_quotes.nil?
|
45
|
+
|
46
|
+
return process_escapes_and_strip_double_quotes!(string, &error_block)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def self.strip_single_quotes!(string)
|
52
|
+
return false if string[0..0] != %q<'> && string[-1..-1] != %q<'>
|
53
|
+
|
54
|
+
if string.length == 1 || string[0..0] != %q<'> || string[-1..-1] != %q<'>
|
55
|
+
yield 'has unbalanced single quotes.'
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
if string =~ %r< \A ' [^']* ' .* ' \z >xs
|
60
|
+
yield %q<isn't permitted because it has a single quote inside single quotes.>
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
string.sub!(%r< \A ' (.*) ' \z >xs, '\1')
|
65
|
+
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
|
69
|
+
ALLOWED_ESCAPED_CHARACTERS = Set.new
|
70
|
+
ALLOWED_ESCAPED_CHARACTERS << '\\'
|
71
|
+
ALLOWED_ESCAPED_CHARACTERS << %q<'>
|
72
|
+
ALLOWED_ESCAPED_CHARACTERS << %q<">
|
73
|
+
ALLOWED_ESCAPED_CHARACTERS << '@' # Environment variable package replacement
|
74
|
+
|
75
|
+
def self.process_escapes_and_strip_double_quotes!(string)
|
76
|
+
if string[0..0] == %q<"> && (string.length == 1 || string[-1..-1] != %q<">)
|
77
|
+
yield 'has unbalanced double quotes.'
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
new_string = ''
|
82
|
+
|
83
|
+
characters = string.each_char
|
84
|
+
initial_character = characters.next
|
85
|
+
last_character = nil
|
86
|
+
had_starting_quote = initial_character == %q<">
|
87
|
+
in_escape = initial_character == '\\'
|
88
|
+
if ! had_starting_quote && ! in_escape
|
89
|
+
new_string << initial_character
|
90
|
+
end
|
91
|
+
|
92
|
+
last_was_escaped = nil
|
93
|
+
loop do
|
94
|
+
last_character = character = characters.next
|
95
|
+
if in_escape
|
96
|
+
if ! ALLOWED_ESCAPED_CHARACTERS.include? character
|
97
|
+
yield "contains a bad escape sequence (\\#{character})."
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
new_string << character
|
102
|
+
in_escape = false
|
103
|
+
last_was_escaped = true
|
104
|
+
elsif character == %q<">
|
105
|
+
# If we're at the end of the string, we'll get bounced out of the loop
|
106
|
+
# by a StopIteration exception.
|
107
|
+
characters.next
|
108
|
+
yield 'has an unescaped double quote in the middle.'
|
109
|
+
return
|
110
|
+
elsif character == %q<'>
|
111
|
+
yield 'has an unescaped single quote in the middle.'
|
112
|
+
return
|
113
|
+
elsif character == '\\'
|
114
|
+
in_escape = true
|
115
|
+
# TODO: need an
|
116
|
+
# «elsif character == '@'»
|
117
|
+
# here to deal with package substitution in variable statements
|
118
|
+
else
|
119
|
+
new_string << character
|
120
|
+
last_was_escaped = false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
if in_escape
|
125
|
+
yield 'ends in an incomplete escape sequence.'
|
126
|
+
return
|
127
|
+
elsif had_starting_quote
|
128
|
+
if last_was_escaped
|
129
|
+
yield 'has unbalanced double quotes (last quote was escaped).'
|
130
|
+
return
|
131
|
+
end
|
132
|
+
elsif ! last_was_escaped && ! had_starting_quote && last_character == %q<">
|
133
|
+
yield 'has unbalanced double quotes.'
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
string.replace(new_string)
|
138
|
+
|
139
|
+
return false
|
140
|
+
end
|
141
|
+
|
142
|
+
public
|
143
|
+
|
25
144
|
# This mess of getting these as a single array necessary is due to
|
26
145
|
# limitations of the "*" array splat operator in ruby v1.8.
|
27
146
|
def initialize(line_column, source_description)
|
@@ -37,6 +156,14 @@ class Fig::Statement
|
|
37
156
|
return
|
38
157
|
end
|
39
158
|
|
159
|
+
def unparse_as_version(unparser)
|
160
|
+
raise NotImplementedError
|
161
|
+
end
|
162
|
+
|
163
|
+
def minimum_grammar_version_required()
|
164
|
+
raise NotImplementedError
|
165
|
+
end
|
166
|
+
|
40
167
|
def urls()
|
41
168
|
return []
|
42
169
|
end
|
@@ -45,6 +172,10 @@ class Fig::Statement
|
|
45
172
|
return false
|
46
173
|
end
|
47
174
|
|
175
|
+
def is_environment_variable?()
|
176
|
+
return false
|
177
|
+
end
|
178
|
+
|
48
179
|
# Returns a representation of the position of this statement, if the position
|
49
180
|
# is known, empty string otherwise. This is written with the idea that you
|
50
181
|
# can do something like "puts %Q<Found a
|
@@ -56,3 +187,5 @@ class Fig::Statement
|
|
56
187
|
)
|
57
188
|
end
|
58
189
|
end
|
190
|
+
|
191
|
+
# vim: set fileencoding=utf8 :
|
@@ -2,6 +2,7 @@ require 'fig/statement'
|
|
2
2
|
require 'fig/statement/asset'
|
3
3
|
|
4
4
|
module Fig; end
|
5
|
+
class Fig::Statement; end
|
5
6
|
|
6
7
|
# Specifies an archive file (possibly via a URL) that is part of a package.
|
7
8
|
#
|
@@ -11,17 +12,18 @@ class Fig::Statement::Archive < Fig::Statement
|
|
11
12
|
|
12
13
|
attr_reader :url
|
13
14
|
|
14
|
-
def initialize(line_column, source_description, url)
|
15
|
+
def initialize(line_column, source_description, url, glob_if_not_url)
|
15
16
|
super(line_column, source_description)
|
16
17
|
|
17
|
-
|
18
|
+
@url = url
|
19
|
+
@glob_if_not_url = glob_if_not_url
|
18
20
|
end
|
19
21
|
|
20
22
|
def asset_name()
|
21
23
|
return standard_asset_name()
|
22
24
|
end
|
23
25
|
|
24
|
-
def
|
25
|
-
|
26
|
+
def unparse_as_version(unparser)
|
27
|
+
return unparser.archive(self)
|
26
28
|
end
|
27
29
|
end
|
data/lib/fig/statement/asset.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
require 'fig/parser'
|
2
|
+
require 'fig/statement'
|
3
|
+
require 'fig/url'
|
2
4
|
|
3
5
|
module Fig; end
|
4
6
|
class Fig::Statement; end
|
5
7
|
|
6
8
|
# Some sort of file to be included in a package.
|
7
9
|
module Fig::Statement::Asset
|
10
|
+
attr_reader :url
|
11
|
+
|
8
12
|
def self.included(class_included_into)
|
9
13
|
class_included_into.extend(ClassMethods)
|
10
14
|
|
11
15
|
return
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
15
|
-
return @
|
18
|
+
def glob_if_not_url?()
|
19
|
+
return @glob_if_not_url
|
16
20
|
end
|
17
21
|
|
18
22
|
def urls()
|
@@ -23,44 +27,36 @@ module Fig::Statement::Asset
|
|
23
27
|
return true
|
24
28
|
end
|
25
29
|
|
30
|
+
def requires_globbing?()
|
31
|
+
return glob_if_not_url? && ! Fig::URL.is_url?(url())
|
32
|
+
end
|
33
|
+
|
26
34
|
def standard_asset_name()
|
27
35
|
# Not so hot of an idea if the URL has query parameters in it, but not
|
28
36
|
# going to fix this now.
|
29
37
|
return url().split('/').last()
|
30
38
|
end
|
31
39
|
|
32
|
-
|
40
|
+
def minimum_grammar_version_required()
|
41
|
+
return 1 if url =~ /\s/
|
33
42
|
|
34
|
-
|
35
|
-
|
36
|
-
if url[0..0] == '"'
|
37
|
-
@url = url[1..-2]
|
38
|
-
@glob = true
|
39
|
-
else
|
40
|
-
@url = url
|
41
|
-
@glob = false
|
42
|
-
end
|
43
|
+
# Can't have octothorpes anywhere in v0 due to comment stripping via regex.
|
44
|
+
return 1 if url =~ /#/
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
# If we shouldn't glob, but we've got glob characters...
|
47
|
+
return 1 if ! glob_if_not_url? && url =~ /[*?\[\]{}]/
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
# Damn you Ruby 1.8!!!!
|
50
|
-
if url[0..0] == '"' && url[-1..-1] != '"' ||
|
51
|
-
url[0..0] != '"' && url[-1..-1] == '"'
|
52
|
-
yield 'has unbalanced quotes.'
|
53
|
-
return
|
54
|
-
end
|
49
|
+
return 0
|
50
|
+
end
|
55
51
|
|
56
|
-
|
57
|
-
if url.length < 3
|
58
|
-
yield 'is empty'
|
59
|
-
return
|
60
|
-
end
|
52
|
+
private
|
61
53
|
|
62
|
-
|
63
|
-
|
54
|
+
module ClassMethods
|
55
|
+
# Modifies the parameter to deal with quoting, escaping.
|
56
|
+
def validate_and_process_escapes_in_url!(url, &block)
|
57
|
+
was_in_single_quotes =
|
58
|
+
Fig::Statement.strip_quotes_and_process_escapes!(url, &block)
|
59
|
+
return if was_in_single_quotes.nil?
|
64
60
|
|
65
61
|
if url.include? '@'
|
66
62
|
yield %q<contains an "@", which isn't permitted in order to allow for package substitution.>
|
@@ -72,10 +68,8 @@ module Fig::Statement::Asset
|
|
72
68
|
return
|
73
69
|
end
|
74
70
|
|
75
|
-
if url =~ /
|
76
|
-
#
|
77
|
-
# require a change to the grammar.
|
78
|
-
yield %q<contains whitespace.>
|
71
|
+
if url =~ / ( ' ) /x
|
72
|
+
yield %Q<contains a "#{$1}", which isn't permitted to allow for future grammar expansion.>
|
79
73
|
return
|
80
74
|
end
|
81
75
|
|
@@ -84,7 +78,7 @@ module Fig::Statement::Asset
|
|
84
78
|
yield 'is a keyword.'
|
85
79
|
end
|
86
80
|
|
87
|
-
return
|
81
|
+
return ! was_in_single_quotes
|
88
82
|
end
|
89
83
|
end
|
90
84
|
end
|
@@ -13,7 +13,11 @@ class Fig::Statement::Command < Fig::Statement
|
|
13
13
|
@command = command
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def unparse_as_version(unparser)
|
17
|
+
return unparser.command(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def minimum_grammar_version_required()
|
21
|
+
return 0
|
18
22
|
end
|
19
23
|
end
|
@@ -35,19 +35,11 @@ class Fig::Statement::Configuration < Fig::Statement
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
38
|
+
def unparse_as_version(unparser)
|
39
|
+
return unparser.configuration(self)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
def unparse_statements(indent, prefix, statements, suffix)
|
45
|
-
body =
|
46
|
-
@statements.map {|statement| statement.unparse(indent + ' ') }.join("\n")
|
47
|
-
if body.length > 0
|
48
|
-
body << "\n"
|
49
|
-
end
|
50
|
-
|
51
|
-
return "\n#{indent}#{prefix}\n#{body}#{indent}#{suffix}"
|
42
|
+
def minimum_grammar_version_required()
|
43
|
+
return 0
|
52
44
|
end
|
53
45
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'fig/statement'
|
2
|
+
|
3
|
+
module Fig; end
|
4
|
+
|
5
|
+
# A statement that declares the syntax that a package is to be serialized in.
|
6
|
+
class Fig::Statement::GrammarVersion < Fig::Statement
|
7
|
+
attr_reader :version
|
8
|
+
|
9
|
+
def initialize(line_column, source_description, version)
|
10
|
+
super(line_column, source_description)
|
11
|
+
|
12
|
+
@version = version
|
13
|
+
end
|
14
|
+
|
15
|
+
def unparse_as_version(unparser)
|
16
|
+
return unparser.grammar_version(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def minimum_grammar_version_required()
|
20
|
+
return version
|
21
|
+
end
|
22
|
+
end
|