fig 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes +94 -0
- data/lib/fig.rb +1 -1
- data/lib/fig/command.rb +18 -7
- data/lib/fig/command/action/dump_package_definition_for_command_line.rb +2 -2
- data/lib/fig/command/action/dump_package_definition_parsed.rb +2 -2
- data/lib/fig/command/action/dump_package_definition_text.rb +2 -2
- data/lib/fig/command/action/source_package.rb +65 -0
- data/lib/fig/command/options.rb +64 -15
- data/lib/fig/command/options/parser.rb +24 -14
- data/lib/fig/command/package_applier.rb +32 -7
- data/lib/fig/command/package_loader.rb +16 -7
- data/lib/fig/external_program.rb +72 -0
- data/lib/fig/figrc.rb +1 -1
- data/lib/fig/grammar/v0.rb +2 -2
- data/lib/fig/grammar/v0.treetop +2 -2
- data/lib/fig/grammar/v1.rb +17 -1737
- data/lib/fig/grammar/v1.treetop +6 -217
- data/lib/fig/grammar/v1_base.rb +1750 -0
- data/lib/fig/grammar/v1_base.treetop +229 -0
- data/lib/fig/grammar/v2.rb +508 -0
- data/lib/fig/grammar/v2.treetop +65 -0
- data/lib/fig/grammar_monkey_patches.rb +7 -0
- data/lib/fig/no_such_package_config_error.rb +3 -1
- data/lib/fig/not_yet_parsed_package.rb +27 -0
- data/lib/fig/operating_system.rb +5 -5
- data/lib/fig/package.rb +20 -2
- data/lib/fig/package_definition_text_assembler.rb +2 -1
- data/lib/fig/package_descriptor.rb +11 -4
- data/lib/fig/parser.rb +44 -58
- data/lib/fig/parser_package_build_state.rb +39 -4
- data/lib/fig/protocol/file.rb +2 -2
- data/lib/fig/protocol/ftp.rb +15 -10
- data/lib/fig/protocol/http.rb +1 -1
- data/lib/fig/protocol/netrc_enabled.rb +29 -16
- data/lib/fig/protocol/sftp.rb +19 -12
- data/lib/fig/repository.rb +33 -21
- data/lib/fig/repository_package_publisher.rb +129 -8
- data/lib/fig/runtime_environment.rb +114 -28
- data/lib/fig/statement/include.rb +21 -4
- data/lib/fig/statement/include_file.rb +94 -0
- data/lib/fig/unparser.rb +15 -7
- data/lib/fig/unparser/v1.rb +2 -80
- data/lib/fig/unparser/v1_base.rb +85 -0
- data/lib/fig/unparser/v2.rb +55 -0
- data/lib/fig/working_directory_maintainer.rb +12 -0
- metadata +61 -51
@@ -2,15 +2,17 @@ require 'stringio'
|
|
2
2
|
|
3
3
|
require 'fig/include_backtrace'
|
4
4
|
require 'fig/logging'
|
5
|
+
require 'fig/not_yet_parsed_package'
|
5
6
|
require 'fig/package'
|
6
7
|
require 'fig/package_descriptor'
|
7
8
|
require 'fig/repository_error'
|
8
9
|
require 'fig/statement/include'
|
10
|
+
require 'fig/statement/include_file'
|
9
11
|
require 'fig/statement/override'
|
10
12
|
require 'fig/statement/path'
|
11
13
|
require 'fig/statement/set'
|
12
|
-
require 'fig/user_input_error'
|
13
14
|
require 'fig/unparser'
|
15
|
+
require 'fig/user_input_error'
|
14
16
|
|
15
17
|
module Fig; end
|
16
18
|
|
@@ -24,16 +26,19 @@ class Fig::RuntimeEnvironment
|
|
24
26
|
|
25
27
|
def initialize(
|
26
28
|
repository,
|
29
|
+
parser,
|
27
30
|
suppress_includes,
|
28
31
|
variables_override,
|
29
32
|
working_directory_maintainer
|
30
33
|
)
|
31
34
|
@repository = repository
|
35
|
+
@parser = parser
|
32
36
|
@suppress_includes = suppress_includes
|
33
37
|
@variables =
|
34
38
|
variables_override || Fig::OperatingSystem.get_environment_variables()
|
35
39
|
@retrieves = {}
|
36
|
-
@
|
40
|
+
@named_packages = {}
|
41
|
+
@packages_from_files = {}
|
37
42
|
@working_directory_maintainer = working_directory_maintainer
|
38
43
|
end
|
39
44
|
|
@@ -74,13 +79,13 @@ class Fig::RuntimeEnvironment
|
|
74
79
|
)
|
75
80
|
end
|
76
81
|
|
77
|
-
@
|
82
|
+
@named_packages[name] = package
|
78
83
|
|
79
84
|
return
|
80
85
|
end
|
81
86
|
|
82
87
|
def get_package(name)
|
83
|
-
return @
|
88
|
+
return @named_packages[name]
|
84
89
|
end
|
85
90
|
|
86
91
|
def apply_config(package, config_name, backtrace)
|
@@ -88,6 +93,10 @@ class Fig::RuntimeEnvironment
|
|
88
93
|
return
|
89
94
|
end
|
90
95
|
|
96
|
+
Fig::Logging.debug(
|
97
|
+
"Applying #{package.to_descriptive_string_with_config config_name}."
|
98
|
+
)
|
99
|
+
|
91
100
|
new_backtrace = backtrace ||
|
92
101
|
Fig::IncludeBacktrace.new(
|
93
102
|
nil,
|
@@ -99,11 +108,13 @@ class Fig::RuntimeEnvironment
|
|
99
108
|
)
|
100
109
|
)
|
101
110
|
|
102
|
-
config =
|
111
|
+
config = nil
|
112
|
+
begin
|
113
|
+
config = package[config_name]
|
114
|
+
rescue Fig::NoSuchPackageConfigError => error
|
115
|
+
raise_repository_error(error.message, new_backtrace, error.package)
|
116
|
+
end
|
103
117
|
|
104
|
-
Fig::Logging.debug(
|
105
|
-
"Applying #{package.to_descriptive_string_with_config config_name}."
|
106
|
-
)
|
107
118
|
package.add_applied_config_name(config_name)
|
108
119
|
config.statements.each do
|
109
120
|
|statement|
|
@@ -155,7 +166,11 @@ class Fig::RuntimeEnvironment
|
|
155
166
|
when Fig::Statement::Set
|
156
167
|
set_variable(package, statement, backtrace)
|
157
168
|
when Fig::Statement::Include
|
158
|
-
include_config(package, statement
|
169
|
+
include_config(package, statement, backtrace)
|
170
|
+
when Fig::Statement::IncludeFile
|
171
|
+
include_file_config(
|
172
|
+
package, statement.path, statement.config_name, backtrace
|
173
|
+
)
|
159
174
|
when Fig::Statement::Override
|
160
175
|
backtrace.add_override(statement)
|
161
176
|
end
|
@@ -180,20 +195,46 @@ class Fig::RuntimeEnvironment
|
|
180
195
|
|
181
196
|
private
|
182
197
|
|
183
|
-
def include_config(starting_package,
|
198
|
+
def include_config(starting_package, include_statement, backtrace)
|
184
199
|
# Because package application starts with the synthetic package for the
|
185
200
|
# command-line, we can't really disable includes, full stop. Instead, we
|
186
201
|
# use the flag on the base package to break the chain of includes.
|
187
|
-
#
|
188
|
-
# Alternative approach: We could put a flag on synthetic include statements
|
189
|
-
# that says to always apply them.
|
190
202
|
return if starting_package.base? && @suppress_includes == :all
|
191
203
|
|
204
|
+
package, resolved_descriptor, new_backtrace =
|
205
|
+
determine_included_package starting_package, include_statement, backtrace
|
206
|
+
|
207
|
+
return if \
|
208
|
+
starting_package.base? \
|
209
|
+
&& @suppress_includes == :cross_package \
|
210
|
+
&& package != starting_package
|
211
|
+
|
212
|
+
apply_config(
|
213
|
+
package,
|
214
|
+
resolved_descriptor.config || Fig::Package::DEFAULT_CONFIG,
|
215
|
+
new_backtrace
|
216
|
+
)
|
217
|
+
|
218
|
+
return
|
219
|
+
end
|
220
|
+
|
221
|
+
def determine_included_package(starting_package, include_statement, backtrace)
|
222
|
+
descriptor = include_statement.descriptor
|
223
|
+
|
224
|
+
if ! include_statement.included_package.nil?
|
225
|
+
return \
|
226
|
+
include_statement.included_package,
|
227
|
+
descriptor,
|
228
|
+
Fig::IncludeBacktrace.new(backtrace, descriptor)
|
229
|
+
end
|
230
|
+
|
192
231
|
resolved_descriptor = nil
|
193
232
|
|
194
233
|
# Check to see if this include has been overridden.
|
195
|
-
if
|
234
|
+
if (
|
235
|
+
backtrace and
|
196
236
|
override_package_name = descriptor.name || starting_package.name
|
237
|
+
)
|
197
238
|
override = backtrace.get_override(override_package_name)
|
198
239
|
if override
|
199
240
|
resolved_descriptor =
|
@@ -205,21 +246,33 @@ class Fig::RuntimeEnvironment
|
|
205
246
|
resolved_descriptor ||= descriptor
|
206
247
|
|
207
248
|
new_backtrace = Fig::IncludeBacktrace.new(backtrace, resolved_descriptor)
|
208
|
-
package =
|
209
|
-
resolved_descriptor.name || starting_package.name,
|
210
|
-
resolved_descriptor.version,
|
211
|
-
new_backtrace
|
212
|
-
)
|
249
|
+
package = nil
|
213
250
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
251
|
+
if included_name = resolved_descriptor.name || starting_package.name
|
252
|
+
package = lookup_package(
|
253
|
+
included_name, resolved_descriptor.version, new_backtrace
|
254
|
+
)
|
255
|
+
else
|
256
|
+
package = starting_package
|
257
|
+
end
|
258
|
+
|
259
|
+
return package, resolved_descriptor, new_backtrace
|
260
|
+
end
|
261
|
+
|
262
|
+
def include_file_config(including_package, path, config_name, backtrace)
|
263
|
+
return if @suppress_includes
|
264
|
+
|
265
|
+
full_path = File.absolute_path(path, including_package.base_directory)
|
266
|
+
|
267
|
+
descriptor =
|
268
|
+
Fig::PackageDescriptor.new(nil, nil, nil, :description => full_path)
|
269
|
+
|
270
|
+
new_backtrace = Fig::IncludeBacktrace.new(backtrace, descriptor)
|
271
|
+
package =
|
272
|
+
package_for_file(including_package, full_path, descriptor, backtrace)
|
218
273
|
|
219
274
|
apply_config(
|
220
|
-
package,
|
221
|
-
resolved_descriptor.config || Fig::Package::DEFAULT_CONFIG,
|
222
|
-
new_backtrace
|
275
|
+
package, config_name || Fig::Package::DEFAULT_CONFIG, new_backtrace
|
223
276
|
)
|
224
277
|
|
225
278
|
return
|
@@ -284,7 +337,7 @@ class Fig::RuntimeEnvironment
|
|
284
337
|
Fig::PackageDescriptor.new(name, version, nil)
|
285
338
|
)
|
286
339
|
package.backtrace = backtrace
|
287
|
-
@
|
340
|
+
@named_packages[name] = package
|
288
341
|
elsif version && version != package.version
|
289
342
|
raise_repository_error(
|
290
343
|
"Version mismatch for package #{name} (#{version} vs #{package.version}).",
|
@@ -296,6 +349,32 @@ class Fig::RuntimeEnvironment
|
|
296
349
|
return package
|
297
350
|
end
|
298
351
|
|
352
|
+
def package_for_file(including_package, full_path, descriptor, backtrace)
|
353
|
+
package = @packages_from_files[full_path]
|
354
|
+
return package if package
|
355
|
+
|
356
|
+
if ! File.exist? full_path
|
357
|
+
raise_repository_error(
|
358
|
+
%Q<"#{full_path}" does not exist.>, backtrace, including_package
|
359
|
+
)
|
360
|
+
end
|
361
|
+
|
362
|
+
content = File.read full_path
|
363
|
+
|
364
|
+
unparsed_package = Fig::NotYetParsedPackage.new
|
365
|
+
unparsed_package.descriptor = descriptor
|
366
|
+
unparsed_package.working_directory = unparsed_package.base_directory =
|
367
|
+
File.dirname(full_path)
|
368
|
+
unparsed_package.source_description = full_path
|
369
|
+
unparsed_package.unparsed_text = content
|
370
|
+
|
371
|
+
package = @parser.parse_package unparsed_package
|
372
|
+
|
373
|
+
@packages_from_files[full_path] = package
|
374
|
+
|
375
|
+
return package
|
376
|
+
end
|
377
|
+
|
299
378
|
def determine_package_for_execution(base_package, base_config, descriptor)
|
300
379
|
config_name =
|
301
380
|
determine_config_to_executed(base_package, base_config, descriptor)
|
@@ -367,13 +446,20 @@ class Fig::RuntimeEnvironment
|
|
367
446
|
)
|
368
447
|
tokenized_value = statement.tokenized_value
|
369
448
|
return tokenized_value.to_expanded_string { '@' } \
|
370
|
-
unless package && package.name
|
449
|
+
unless package && (package.name || ! (package.synthetic? || package.base?))
|
371
450
|
|
372
451
|
variable_value =
|
373
452
|
tokenized_value.to_expanded_string { package.runtime_directory }
|
374
453
|
|
375
454
|
return variable_value if not @retrieves.member?(statement.name)
|
376
455
|
|
456
|
+
if ! package.name
|
457
|
+
Fig::Logging.warn \
|
458
|
+
"Retrieve of #{statement.name}=#{variable_value} ignored because the statement#{statement.position_string} is in an unnamed package."
|
459
|
+
|
460
|
+
return variable_value
|
461
|
+
end
|
462
|
+
|
377
463
|
return retrieve_files(
|
378
464
|
statement.name, variable_value, package, backtrace
|
379
465
|
)
|
@@ -8,7 +8,9 @@ module Fig; end
|
|
8
8
|
# incorporation of the "default" configuration from that other package if no
|
9
9
|
# ":configname" is specified.
|
10
10
|
class Fig::Statement::Include < Fig::Statement
|
11
|
-
attr_reader :descriptor
|
11
|
+
attr_reader :descriptor
|
12
|
+
attr_reader :included_package
|
13
|
+
attr_reader :containing_package_descriptor
|
12
14
|
|
13
15
|
# Centralized definition of requirements for descriptors for include
|
14
16
|
# statements.
|
@@ -16,10 +18,17 @@ class Fig::Statement::Include < Fig::Statement
|
|
16
18
|
return Fig::PackageDescriptor.parse(raw_string, options)
|
17
19
|
end
|
18
20
|
|
19
|
-
def initialize(
|
21
|
+
def initialize(
|
22
|
+
line_column,
|
23
|
+
source_description,
|
24
|
+
descriptor,
|
25
|
+
included_package, # For synthetic Package for command-line options.
|
26
|
+
containing_package_descriptor
|
27
|
+
)
|
20
28
|
super(line_column, source_description)
|
21
29
|
|
22
30
|
@descriptor = descriptor
|
31
|
+
@included_package = included_package
|
23
32
|
@containing_package_descriptor = containing_package_descriptor
|
24
33
|
end
|
25
34
|
|
@@ -71,11 +80,11 @@ class Fig::Statement::Include < Fig::Statement
|
|
71
80
|
end
|
72
81
|
|
73
82
|
def minimum_grammar_for_emitting_input()
|
74
|
-
return
|
83
|
+
return minimum_grammar
|
75
84
|
end
|
76
85
|
|
77
86
|
def minimum_grammar_for_publishing()
|
78
|
-
return
|
87
|
+
return minimum_grammar
|
79
88
|
end
|
80
89
|
|
81
90
|
private
|
@@ -101,4 +110,12 @@ class Fig::Statement::Include < Fig::Statement
|
|
101
110
|
def referenced_config_name()
|
102
111
|
config_name() || Fig::Package::DEFAULT_CONFIG
|
103
112
|
end
|
113
|
+
|
114
|
+
def minimum_grammar()
|
115
|
+
if included_package
|
116
|
+
raise 'Cannot unparse synthetic include statement with directly referenced package.'
|
117
|
+
end
|
118
|
+
|
119
|
+
return [0]
|
120
|
+
end
|
104
121
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'fig/package_descriptor'
|
2
|
+
require 'fig/statement'
|
3
|
+
require 'fig/user_input_error'
|
4
|
+
|
5
|
+
module Fig; end
|
6
|
+
|
7
|
+
# Like an include, but of an unpublished file.
|
8
|
+
class Fig::Statement::IncludeFile < Fig::Statement
|
9
|
+
def self.parse_path_with_config(path_with_config, &block)
|
10
|
+
if match = PATH_WITH_CONFIG_PATTERN.match(path_with_config)
|
11
|
+
return validate_and_process_raw_path_and_config_name(
|
12
|
+
match[:path], match[:config], &block
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
yield 'could not be understood as a path followed by a config name.'
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.validate_and_process_raw_path_and_config_name(
|
21
|
+
raw_path, config_name, &block
|
22
|
+
)
|
23
|
+
if raw_path !~ /['"]/ && raw_path =~ /:/
|
24
|
+
yield 'has an unquoted colon (:) in the path portion.'
|
25
|
+
return
|
26
|
+
end
|
27
|
+
if (
|
28
|
+
! config_name.nil? &&
|
29
|
+
config_name !~ Fig::PackageDescriptor::COMPONENT_PATTERN
|
30
|
+
)
|
31
|
+
yield "contains an invalid config name (#{config_name})."
|
32
|
+
return
|
33
|
+
end
|
34
|
+
tokenized_path = validate_and_process_escapes_in_path(raw_path, &block)
|
35
|
+
return if tokenized_path.nil?
|
36
|
+
|
37
|
+
return tokenized_path.to_expanded_string, config_name
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def self.validate_and_process_escapes_in_path(path, &block)
|
43
|
+
return Fig::StringTokenizer.new.tokenize(path, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
public
|
48
|
+
|
49
|
+
attr_reader :path
|
50
|
+
attr_reader :config_name
|
51
|
+
attr_reader :containing_package_descriptor
|
52
|
+
|
53
|
+
def initialize(
|
54
|
+
line_column,
|
55
|
+
source_description,
|
56
|
+
path,
|
57
|
+
config_name,
|
58
|
+
containing_package_descriptor
|
59
|
+
)
|
60
|
+
super(line_column, source_description)
|
61
|
+
|
62
|
+
@path = path
|
63
|
+
@config_name = config_name
|
64
|
+
@containing_package_descriptor = containing_package_descriptor
|
65
|
+
end
|
66
|
+
|
67
|
+
def statement_type()
|
68
|
+
return 'include-file'
|
69
|
+
end
|
70
|
+
|
71
|
+
def unparse_as_version(unparser)
|
72
|
+
return unparser.include_file(self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def minimum_grammar_for_emitting_input()
|
76
|
+
return [2, %q<didn't exist prior to v2>]
|
77
|
+
end
|
78
|
+
|
79
|
+
def minimum_grammar_for_publishing()
|
80
|
+
raise Fig::UserInputError.new 'Cannot publish an include-file statement.'
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
PATH_WITH_CONFIG_PATTERN = /
|
86
|
+
\A
|
87
|
+
(?<path> .+?)
|
88
|
+
(?:
|
89
|
+
[:]
|
90
|
+
(?<config> #{Fig::PackageDescriptor::UNBRACKETED_COMPONENT_PATTERN})
|
91
|
+
)?
|
92
|
+
\z
|
93
|
+
/x
|
94
|
+
end
|
data/lib/fig/unparser.rb
CHANGED
@@ -20,9 +20,13 @@ module Fig::Unparser
|
|
20
20
|
case version
|
21
21
|
when 0
|
22
22
|
return Fig::Unparser::V0, explanations
|
23
|
+
when 1
|
24
|
+
return Fig::Unparser::V1, explanations
|
25
|
+
when 2
|
26
|
+
return Fig::Unparser::V2, explanations
|
23
27
|
end
|
24
28
|
|
25
|
-
|
29
|
+
raise "Unexpected version #{version}."
|
26
30
|
end
|
27
31
|
|
28
32
|
def self.determine_version_and_unparse(
|
@@ -113,7 +117,7 @@ module Fig::Unparser
|
|
113
117
|
end
|
114
118
|
|
115
119
|
def command(statement)
|
116
|
-
raise NotImplementedError
|
120
|
+
raise NotImplementedError.new self
|
117
121
|
end
|
118
122
|
|
119
123
|
def configuration(configuration_statement)
|
@@ -144,7 +148,7 @@ module Fig::Unparser
|
|
144
148
|
end
|
145
149
|
|
146
150
|
def grammar_version(statement)
|
147
|
-
raise NotImplementedError
|
151
|
+
raise NotImplementedError.new self
|
148
152
|
end
|
149
153
|
|
150
154
|
def include(statement)
|
@@ -159,6 +163,10 @@ module Fig::Unparser
|
|
159
163
|
return
|
160
164
|
end
|
161
165
|
|
166
|
+
def include_file(statement)
|
167
|
+
raise NotImplementedError.new self
|
168
|
+
end
|
169
|
+
|
162
170
|
def override(statement)
|
163
171
|
add_indent
|
164
172
|
|
@@ -186,7 +194,7 @@ module Fig::Unparser
|
|
186
194
|
end
|
187
195
|
|
188
196
|
def retrieve(statement)
|
189
|
-
raise NotImplementedError
|
197
|
+
raise NotImplementedError.new self
|
190
198
|
end
|
191
199
|
|
192
200
|
def set(statement)
|
@@ -202,13 +210,13 @@ module Fig::Unparser
|
|
202
210
|
end
|
203
211
|
|
204
212
|
def grammar_description
|
205
|
-
raise NotImplementedError
|
213
|
+
raise NotImplementedError.new self
|
206
214
|
end
|
207
215
|
|
208
216
|
private
|
209
217
|
|
210
218
|
def asset(keyword, statement)
|
211
|
-
raise NotImplementedError
|
219
|
+
raise NotImplementedError.new self
|
212
220
|
end
|
213
221
|
|
214
222
|
def asset_path(statement)
|
@@ -220,7 +228,7 @@ module Fig::Unparser
|
|
220
228
|
end
|
221
229
|
|
222
230
|
def environment_variable(statement, keyword)
|
223
|
-
raise NotImplementedError
|
231
|
+
raise NotImplementedError.new self
|
224
232
|
end
|
225
233
|
|
226
234
|
def add_indent(indent_level = @indent_level)
|