fig 0.1.77 → 0.1.79
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes +58 -1
- data/bin/fig +1 -1
- data/lib/fig.rb +1 -1
- data/lib/fig/command.rb +3 -3
- data/lib/fig/command/action/dump_package_definition_parsed.rb +5 -4
- data/lib/fig/command/action/list_variables/all_configs.rb +2 -5
- data/lib/fig/command/action/publish_local.rb +1 -1
- data/lib/fig/command/action/role/list_variables_in_a_tree.rb +2 -5
- data/lib/fig/command/action/run_command_line.rb +10 -3
- data/lib/fig/command/action/run_command_statement.rb +1 -1
- data/lib/fig/command/options.rb +8 -7
- data/lib/fig/command/options/parser.rb +1 -1
- data/lib/fig/environment_variables/case_insensitive.rb +1 -1
- data/lib/fig/environment_variables/case_sensitive.rb +1 -1
- data/lib/fig/figrc.rb +10 -10
- data/lib/fig/{not_found_error.rb → file_not_found_error.rb} +1 -1
- data/lib/fig/grammar/v0.rb +174 -173
- data/lib/fig/grammar/v0.treetop +27 -21
- data/lib/fig/grammar/v1.rb +477 -171
- data/lib/fig/grammar/v1.treetop +34 -22
- data/lib/fig/operating_system.rb +139 -60
- data/lib/fig/package.rb +8 -4
- data/lib/fig/package_definition_text_assembler.rb +31 -23
- data/lib/fig/parser.rb +3 -5
- data/lib/fig/parser_package_build_state.rb +15 -14
- data/lib/fig/repository.rb +41 -28
- data/lib/fig/repository_package_publisher.rb +20 -25
- data/lib/fig/runtime_environment.rb +136 -87
- data/lib/fig/statement.rb +15 -116
- data/lib/fig/statement/archive.rb +6 -4
- data/lib/fig/statement/asset.rb +50 -35
- data/lib/fig/statement/command.rb +6 -2
- data/lib/fig/statement/configuration.rb +10 -2
- data/lib/fig/statement/environment_variable.rb +35 -0
- data/lib/fig/statement/grammar_version.rb +6 -2
- data/lib/fig/statement/include.rb +6 -2
- data/lib/fig/statement/override.rb +6 -2
- data/lib/fig/statement/path.rb +7 -8
- data/lib/fig/statement/resource.rb +7 -3
- data/lib/fig/statement/retrieve.rb +10 -2
- data/lib/fig/statement/set.rb +7 -8
- data/lib/fig/string_tokenizer.rb +195 -0
- data/lib/fig/tokenized_string.rb +22 -0
- data/lib/fig/tokenized_string/plain_segment.rb +24 -0
- data/lib/fig/tokenized_string/token.rb +18 -0
- data/lib/fig/unparser.rb +84 -1
- data/lib/fig/unparser/v0.rb +4 -0
- data/lib/fig/unparser/v1.rb +7 -7
- data/lib/fig/url.rb +12 -1
- data/lib/fig/{url_access_error.rb → url_access_disallowed_error.rb} +2 -2
- metadata +129 -128
- data/lib/fig/grammar/v0_asset_location.rb +0 -162
- data/lib/fig/grammar/v0_ish.rb +0 -1356
- data/lib/fig/grammar/v1_asset_location.rb +0 -162
- data/lib/fig/grammar/v2.rb +0 -1478
data/lib/fig/package.rb
CHANGED
@@ -71,12 +71,16 @@ class Fig::Package
|
|
71
71
|
return @statements.select { |statement| statement.is_a?(Fig::Statement::Retrieve) }
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
return @statements.
|
74
|
+
def archive_locations
|
75
|
+
return @statements.
|
76
|
+
select{|s| s.is_a?(Fig::Statement::Archive)}.
|
77
|
+
map{|s| s.location}
|
76
78
|
end
|
77
79
|
|
78
|
-
def
|
79
|
-
return @statements.
|
80
|
+
def resource_locations
|
81
|
+
return @statements.
|
82
|
+
select{|s| s.is_a?(Fig::Statement::Resource)}.
|
83
|
+
map{|s| s.location}
|
80
84
|
end
|
81
85
|
|
82
86
|
def applied_config_names()
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fig/statement/grammar_version'
|
2
|
+
require 'fig/unparser'
|
1
3
|
require 'fig/unparser/v0'
|
2
4
|
require 'fig/unparser/v1'
|
3
5
|
|
@@ -8,7 +10,10 @@ class Fig::PackageDefinitionTextAssembler
|
|
8
10
|
attr_reader :input_statements
|
9
11
|
attr_reader :output_statements
|
10
12
|
|
11
|
-
def initialize()
|
13
|
+
def initialize(emit_as_input_or_to_be_published_values)
|
14
|
+
@emit_as_input_or_to_be_published_values =
|
15
|
+
emit_as_input_or_to_be_published_values
|
16
|
+
|
12
17
|
@input_statements = []
|
13
18
|
@output_statements = []
|
14
19
|
@header_text = []
|
@@ -30,6 +35,9 @@ class Fig::PackageDefinitionTextAssembler
|
|
30
35
|
@output_statements << statements
|
31
36
|
@output_statements.flatten!
|
32
37
|
|
38
|
+
# Version gets determined by other statements, not by existing grammar.
|
39
|
+
@output_statements.reject! { |s| s.is_a? Fig::Statement::GrammarVersion }
|
40
|
+
|
33
41
|
return
|
34
42
|
end
|
35
43
|
|
@@ -52,37 +60,37 @@ class Fig::PackageDefinitionTextAssembler
|
|
52
60
|
end
|
53
61
|
|
54
62
|
def assemble_package_definition()
|
63
|
+
unparsed_statements, explanations = unparse_statements()
|
55
64
|
definition =
|
56
|
-
[@header_text,
|
65
|
+
[@header_text, unparsed_statements, @footer_text].flatten.join("\n")
|
57
66
|
definition.gsub!(/\n{3,}/, "\n\n")
|
58
67
|
definition.strip!
|
59
68
|
definition << "\n"
|
60
69
|
|
61
|
-
return definition
|
70
|
+
return definition, explanations
|
62
71
|
end
|
63
72
|
|
64
73
|
private
|
65
74
|
|
66
75
|
def unparse_statements()
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
return text
|
76
|
+
unparser_class, explanations = Fig::Unparser.class_for_statements(
|
77
|
+
@output_statements, @emit_as_input_or_to_be_published_values
|
78
|
+
)
|
79
|
+
|
80
|
+
grammar_statement =
|
81
|
+
Fig::Statement::GrammarVersion.new(
|
82
|
+
nil,
|
83
|
+
%Q<[synthetic statement created in #{__FILE__} line #{__LINE__}]>,
|
84
|
+
%q<Fake grammar version that shouldn't be used because the Unparser should determine what gets emitted.>
|
85
|
+
)
|
86
|
+
|
87
|
+
unparser = unparser_class.new @emit_as_input_or_to_be_published_values
|
88
|
+
text = unparser.unparse( [grammar_statement] + @output_statements )
|
89
|
+
|
90
|
+
explanations.unshift(
|
91
|
+
"Publishing using the #{unparser.grammar_description} grammar."
|
92
|
+
)
|
93
|
+
|
94
|
+
return text, explanations
|
87
95
|
end
|
88
96
|
end
|
data/lib/fig/parser.rb
CHANGED
@@ -8,7 +8,7 @@ require 'fig/package_parse_error'
|
|
8
8
|
require 'fig/parser_package_build_state'
|
9
9
|
require 'fig/statement'
|
10
10
|
require 'fig/url'
|
11
|
-
require 'fig/
|
11
|
+
require 'fig/url_access_disallowed_error'
|
12
12
|
require 'fig/user_input_error'
|
13
13
|
|
14
14
|
module Fig; end
|
@@ -82,9 +82,7 @@ class Fig::Parser
|
|
82
82
|
return 0 if not statement
|
83
83
|
|
84
84
|
version = statement.version
|
85
|
-
|
86
|
-
# if version > 1
|
87
|
-
if version > 0
|
85
|
+
if version > 1
|
88
86
|
raise Fig::PackageParseError.new(
|
89
87
|
%Q<Don't know how to parse grammar version #{version}#{statement.position_string()}.>
|
90
88
|
)
|
@@ -198,7 +196,7 @@ class Fig::Parser
|
|
198
196
|
end
|
199
197
|
end
|
200
198
|
|
201
|
-
raise Fig::
|
199
|
+
raise Fig::URLAccessDisallowedError.new(bad_urls, descriptor) if not bad_urls.empty?
|
202
200
|
|
203
201
|
return
|
204
202
|
end
|
@@ -79,19 +79,22 @@ class Fig::ParserPackageBuildState
|
|
79
79
|
)
|
80
80
|
end
|
81
81
|
|
82
|
-
def new_asset_statement(statement_class, keyword_node,
|
83
|
-
|
82
|
+
def new_asset_statement(statement_class, keyword_node, location_node)
|
83
|
+
raw_location = location_node.text_value
|
84
84
|
|
85
|
-
|
86
|
-
|
85
|
+
tokenized_location =
|
86
|
+
statement_class.validate_and_process_escapes_in_location(raw_location) do
|
87
|
+
|error_description|
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
raise_invalid_value_parse_error(
|
90
|
+
keyword_node, location_node, 'URL/path', error_description
|
91
|
+
)
|
92
|
+
end
|
92
93
|
|
94
|
+
location = tokenized_location.to_expanded_string
|
95
|
+
need_to_glob = ! tokenized_location.single_quoted?
|
93
96
|
return statement_class.new(
|
94
|
-
node_location(keyword_node), source_description,
|
97
|
+
node_location(keyword_node), source_description, location, need_to_glob
|
95
98
|
)
|
96
99
|
end
|
97
100
|
|
@@ -161,11 +164,9 @@ class Fig::ParserPackageBuildState
|
|
161
164
|
statement_class, keyword_node, value_node
|
162
165
|
)
|
163
166
|
name, value = statement_class.parse_name_value(value_node.text_value) {
|
164
|
-
|
165
|
-
|
166
|
-
value_node
|
167
|
-
'value',
|
168
|
-
statement_class.const_get(:ARGUMENT_DESCRIPTION)
|
167
|
+
description = statement_class.const_get(:ARGUMENT_DESCRIPTION)
|
168
|
+
raise Fig::PackageParseError.new(
|
169
|
+
%Q<Invalid #{keyword_node.text_value} statement: "#{value_node.text_value}" #{description}#{node_location_description(value_node)}>
|
169
170
|
)
|
170
171
|
}
|
171
172
|
return statement_class.new(
|
data/lib/fig/repository.rb
CHANGED
@@ -6,8 +6,8 @@ require 'tmpdir'
|
|
6
6
|
|
7
7
|
require 'fig'
|
8
8
|
require 'fig/at_exit'
|
9
|
+
require 'fig/file_not_found_error'
|
9
10
|
require 'fig/logging'
|
10
|
-
require 'fig/not_found_error'
|
11
11
|
require 'fig/package_cache'
|
12
12
|
require 'fig/package_descriptor'
|
13
13
|
require 'fig/parser'
|
@@ -212,11 +212,13 @@ class Fig::Repository
|
|
212
212
|
if @remote_repository_version.nil?
|
213
213
|
temp_dir = base_temp_dir()
|
214
214
|
@operating_system.delete_and_recreate_directory(temp_dir)
|
215
|
-
remote_version_file =
|
215
|
+
remote_version_file = Fig::URL.append_path_components(
|
216
|
+
remote_repository_url(), [VERSION_FILE_NAME]
|
217
|
+
)
|
216
218
|
local_version_file = File.join(temp_dir, "remote-#{VERSION_FILE_NAME}")
|
217
219
|
begin
|
218
220
|
@operating_system.download(remote_version_file, local_version_file)
|
219
|
-
rescue Fig::
|
221
|
+
rescue Fig::FileNotFoundError
|
220
222
|
# The download may create an empty file, so get rid of it.
|
221
223
|
if File.exist?(local_version_file)
|
222
224
|
File.unlink(local_version_file)
|
@@ -265,17 +267,13 @@ class Fig::Repository
|
|
265
267
|
temp_dir = package_download_temp_dir(descriptor)
|
266
268
|
begin
|
267
269
|
install_package(descriptor, temp_dir)
|
268
|
-
rescue Fig::
|
270
|
+
rescue Fig::FileNotFoundError => error
|
269
271
|
Fig::Logging.fatal \
|
270
272
|
"Package #{descriptor.to_string()} not found in remote repository. (Was looking for #{error.path}.)"
|
271
273
|
|
272
|
-
delete_local_package(descriptor)
|
273
|
-
|
274
274
|
raise Fig::RepositoryError.new
|
275
275
|
rescue StandardError => exception
|
276
|
-
Fig::Logging.fatal %Q<Install failed
|
277
|
-
|
278
|
-
delete_local_package(descriptor)
|
276
|
+
Fig::Logging.fatal %Q<Install failed: #{exception}>
|
279
277
|
|
280
278
|
raise Fig::RepositoryError.new
|
281
279
|
ensure
|
@@ -289,28 +287,43 @@ class Fig::Repository
|
|
289
287
|
remote_fig_file = remote_fig_file_for_package(descriptor)
|
290
288
|
local_dir = local_dir_for_package(descriptor)
|
291
289
|
local_fig_file = fig_file_for_package_download(local_dir)
|
292
|
-
return if not @operating_system.download(remote_fig_file, local_fig_file)
|
293
290
|
|
294
|
-
@operating_system.
|
291
|
+
if @operating_system.path_up_to_date? remote_fig_file, local_fig_file
|
292
|
+
Fig::Logging.debug \
|
293
|
+
"Skipping update of #{descriptor.to_string} because it looks like #{local_fig_file} is up-to-date."
|
294
|
+
return
|
295
|
+
end
|
296
|
+
|
297
|
+
temp_fig_file = fig_file_for_package_download(temp_dir)
|
295
298
|
|
296
|
-
|
299
|
+
FileUtils.rm_rf temp_dir
|
300
|
+
if File.exist? local_dir
|
301
|
+
FileUtils.mkdir_p File.dirname(temp_dir)
|
302
|
+
FileUtils.cp_r local_dir, temp_dir, :preserve => true
|
303
|
+
else
|
304
|
+
FileUtils.mkdir_p temp_dir
|
305
|
+
end
|
297
306
|
|
298
|
-
@operating_system.download(remote_fig_file, temp_fig_file)
|
307
|
+
return if ! @operating_system.download(remote_fig_file, temp_fig_file)
|
299
308
|
|
300
309
|
package = read_package_from_directory(temp_dir, descriptor)
|
301
310
|
|
302
|
-
|
303
|
-
|
304
|
-
|
311
|
+
remote_package_directory = remote_dir_for_package(descriptor)
|
312
|
+
package.archive_locations.each do |archive_location|
|
313
|
+
if not Fig::URL.is_url?(archive_location)
|
314
|
+
archive_location = Fig::URL.append_path_components(
|
315
|
+
remote_package_directory, [archive_location]
|
316
|
+
)
|
305
317
|
end
|
306
|
-
@operating_system.download_and_unpack_archive(
|
318
|
+
@operating_system.download_and_unpack_archive(archive_location, temp_dir)
|
307
319
|
end
|
308
|
-
package.
|
309
|
-
if not Fig::URL.is_url?(
|
310
|
-
|
311
|
-
|
320
|
+
package.resource_locations.each do |resource_location|
|
321
|
+
if not Fig::URL.is_url?(resource_location)
|
322
|
+
resource_location = Fig::URL.append_path_components(
|
323
|
+
remote_package_directory, [resource_location]
|
324
|
+
)
|
312
325
|
end
|
313
|
-
@operating_system.download_resource(
|
326
|
+
@operating_system.download_resource(resource_location, temp_dir)
|
314
327
|
end
|
315
328
|
|
316
329
|
FileUtils.rm_rf(local_dir)
|
@@ -346,12 +359,10 @@ class Fig::Repository
|
|
346
359
|
return package
|
347
360
|
end
|
348
361
|
|
349
|
-
def delete_local_package(descriptor)
|
350
|
-
FileUtils.rm_rf(local_dir_for_package(descriptor))
|
351
|
-
end
|
352
|
-
|
353
362
|
def remote_fig_file_for_package(descriptor)
|
354
|
-
|
363
|
+
return Fig::URL.append_path_components(
|
364
|
+
remote_dir_for_package(descriptor), [PACKAGE_FILE_IN_REPO]
|
365
|
+
)
|
355
366
|
end
|
356
367
|
|
357
368
|
def local_fig_file_for_package(descriptor)
|
@@ -363,7 +374,9 @@ class Fig::Repository
|
|
363
374
|
end
|
364
375
|
|
365
376
|
def remote_dir_for_package(descriptor)
|
366
|
-
|
377
|
+
return Fig::URL.append_path_components(
|
378
|
+
remote_repository_url(), [descriptor.name, descriptor.version]
|
379
|
+
)
|
367
380
|
end
|
368
381
|
|
369
382
|
def local_dir_for_package(descriptor)
|
@@ -6,8 +6,8 @@ require 'tmpdir'
|
|
6
6
|
|
7
7
|
require 'fig'
|
8
8
|
require 'fig/at_exit'
|
9
|
+
require 'fig/file_not_found_error'
|
9
10
|
require 'fig/logging'
|
10
|
-
require 'fig/not_found_error'
|
11
11
|
require 'fig/package_cache'
|
12
12
|
require 'fig/package_definition_text_assembler'
|
13
13
|
require 'fig/package_descriptor'
|
@@ -37,7 +37,8 @@ class Fig::RepositoryPackagePublisher
|
|
37
37
|
attr_writer :local_only
|
38
38
|
|
39
39
|
def initialize()
|
40
|
-
@text_assembler =
|
40
|
+
@text_assembler =
|
41
|
+
Fig::PackageDefinitionTextAssembler.new :emit_as_to_be_published
|
41
42
|
|
42
43
|
return
|
43
44
|
end
|
@@ -111,7 +112,11 @@ class Fig::RepositoryPackagePublisher
|
|
111
112
|
add_output_statements_and_create_resource_archive()
|
112
113
|
add_unparsed_text()
|
113
114
|
|
114
|
-
file_content = @text_assembler.assemble_package_definition()
|
115
|
+
file_content, explanations = @text_assembler.assemble_package_definition()
|
116
|
+
if Fig::Logging.debug?
|
117
|
+
explanations.each {|explanation| Fig::Logging.debug explanation}
|
118
|
+
end
|
119
|
+
|
115
120
|
begin
|
116
121
|
Fig::Parser.new(nil, false).parse_package(
|
117
122
|
@descriptor,
|
@@ -161,17 +166,6 @@ class Fig::RepositoryPackagePublisher
|
|
161
166
|
def assemble_output_statements()
|
162
167
|
@resource_paths = []
|
163
168
|
|
164
|
-
if (
|
165
|
-
@text_assembler.input_statements.empty? \
|
166
|
-
|| ! @text_assembler.input_statements[0].is_a?(Fig::Statement::GrammarVersion)
|
167
|
-
)
|
168
|
-
@text_assembler.add_output Fig::Statement::GrammarVersion.new(
|
169
|
-
nil,
|
170
|
-
%Q<[synthetic statement created in #{__FILE__} line #{__LINE__}]>,
|
171
|
-
0 # Grammar version
|
172
|
-
)
|
173
|
-
end
|
174
|
-
|
175
169
|
@text_assembler.input_statements.each do
|
176
170
|
|statement|
|
177
171
|
|
@@ -186,11 +180,11 @@ class Fig::RepositoryPackagePublisher
|
|
186
180
|
end
|
187
181
|
|
188
182
|
def add_asset_to_output_statements(asset_statement)
|
189
|
-
if Fig::URL.is_url? asset_statement.
|
183
|
+
if Fig::URL.is_url? asset_statement.location
|
190
184
|
@text_assembler.add_output asset_statement
|
191
185
|
elsif asset_statement.is_a? Fig::Statement::Archive
|
192
186
|
if asset_statement.requires_globbing?
|
193
|
-
expand_globs_from( [asset_statement.
|
187
|
+
expand_globs_from( [asset_statement.location] ).each do
|
194
188
|
|file|
|
195
189
|
|
196
190
|
@text_assembler.add_output(
|
@@ -206,9 +200,9 @@ class Fig::RepositoryPackagePublisher
|
|
206
200
|
@text_assembler.add_output asset_statement
|
207
201
|
end
|
208
202
|
elsif asset_statement.requires_globbing?
|
209
|
-
@resource_paths.concat expand_globs_from( [asset_statement.
|
203
|
+
@resource_paths.concat expand_globs_from( [asset_statement.location] )
|
210
204
|
else
|
211
|
-
@resource_paths << asset_statement.
|
205
|
+
@resource_paths << asset_statement.location
|
212
206
|
end
|
213
207
|
|
214
208
|
return
|
@@ -220,7 +214,7 @@ class Fig::RepositoryPackagePublisher
|
|
220
214
|
|
221
215
|
file = Fig::Repository::RESOURCES_FILE
|
222
216
|
@operating_system.create_archive(file, @resource_paths)
|
223
|
-
Fig::AtExit.add {
|
217
|
+
Fig::AtExit.add { FileUtils.rm_f(file) }
|
224
218
|
|
225
219
|
@text_assembler.add_output(
|
226
220
|
Fig::Statement::Archive.new(
|
@@ -249,19 +243,20 @@ class Fig::RepositoryPackagePublisher
|
|
249
243
|
|
250
244
|
def publish_asset(asset_statement)
|
251
245
|
asset_name = asset_statement.asset_name()
|
252
|
-
asset_remote =
|
246
|
+
asset_remote =
|
247
|
+
Fig::URL.append_path_components @remote_dir_for_package, [asset_name]
|
253
248
|
|
254
|
-
if Fig::URL.is_url? asset_statement.
|
249
|
+
if Fig::URL.is_url? asset_statement.location
|
255
250
|
asset_local = File.join(publish_temp_dir(), asset_name)
|
256
251
|
|
257
252
|
begin
|
258
|
-
@operating_system.download(asset_statement.
|
259
|
-
rescue Fig::
|
260
|
-
Fig::Logging.fatal "Could not download #{asset_statement.
|
253
|
+
@operating_system.download(asset_statement.location, asset_local)
|
254
|
+
rescue Fig::FileNotFoundError
|
255
|
+
Fig::Logging.fatal "Could not download #{asset_statement.location}."
|
261
256
|
raise Fig::RepositoryError.new
|
262
257
|
end
|
263
258
|
else
|
264
|
-
asset_local = asset_statement.
|
259
|
+
asset_local = asset_statement.location
|
265
260
|
check_asset_path(asset_local)
|
266
261
|
end
|
267
262
|
|
@@ -9,7 +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
|
12
|
+
require 'fig/unparser'
|
13
13
|
|
14
14
|
module Fig; end
|
15
15
|
|
@@ -99,37 +99,31 @@ class Fig::RuntimeEnvironment
|
|
99
99
|
return
|
100
100
|
end
|
101
101
|
|
102
|
-
def
|
102
|
+
def execute_command_line(base_package, base_config, descriptor, command_line)
|
103
|
+
package, * =
|
104
|
+
determine_package_for_execution(base_package, base_config, descriptor)
|
105
|
+
|
106
|
+
expanded_command_line =
|
107
|
+
command_line.map {
|
108
|
+
|argument| expand_command_line_argument(argument, base_package)
|
109
|
+
}
|
110
|
+
|
103
111
|
@variables.with_environment do
|
104
|
-
yield
|
112
|
+
yield expanded_command_line
|
105
113
|
end
|
106
114
|
|
107
115
|
return
|
108
116
|
end
|
109
117
|
|
110
|
-
def execute_config(
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
)
|
125
|
-
)
|
126
|
-
else
|
127
|
-
package = base_package
|
128
|
-
end
|
118
|
+
def execute_config(
|
119
|
+
base_package, base_config, descriptor, extra_arguments, &block
|
120
|
+
)
|
121
|
+
package, config_name =
|
122
|
+
determine_package_for_execution(base_package, base_config, descriptor)
|
129
123
|
|
130
124
|
command_statement = package[config_name].command_statement
|
131
125
|
if command_statement
|
132
|
-
execute_command(command_statement,
|
126
|
+
execute_command(command_statement, extra_arguments, package, &block)
|
133
127
|
else
|
134
128
|
raise Fig::UserInputError.new(
|
135
129
|
%Q<The "#{package.to_s}" package with the "#{config_name}" configuration does not contain a command.>
|
@@ -140,35 +134,35 @@ class Fig::RuntimeEnvironment
|
|
140
134
|
end
|
141
135
|
|
142
136
|
# In order for this to work correctly, any Overrides need to be processed
|
143
|
-
# before any other kind of Statement. The Configuration class
|
144
|
-
# that those come first in its set of Statements.
|
145
|
-
def apply_config_statement(
|
137
|
+
# before any other kind of Statement. The Statement::Configuration class
|
138
|
+
# guarantees that those come first in its set of Statements.
|
139
|
+
def apply_config_statement(package, statement, backtrace)
|
146
140
|
case statement
|
147
141
|
when Fig::Statement::Path
|
148
|
-
prepend_variable(
|
142
|
+
prepend_variable(package, statement, backtrace)
|
149
143
|
when Fig::Statement::Set
|
150
|
-
set_variable(
|
144
|
+
set_variable(package, statement, backtrace)
|
151
145
|
when Fig::Statement::Include
|
152
|
-
include_config(
|
146
|
+
include_config(package, statement.descriptor, backtrace)
|
153
147
|
when Fig::Statement::Override
|
154
148
|
backtrace.add_override(statement)
|
155
149
|
when Fig::Statement::Command
|
156
150
|
# Skip - has no effect on environment.
|
157
151
|
else
|
158
|
-
|
159
|
-
|
160
|
-
raise "Unexpected statement in a config block: #{text}"
|
152
|
+
text, * =
|
153
|
+
Fig::Unparser.determine_version_and_unparse(statement, :emit_as_input)
|
154
|
+
raise "Unexpected statement in a config block: #{text.strip}"
|
161
155
|
end
|
162
156
|
|
163
157
|
return
|
164
158
|
end
|
165
159
|
|
166
|
-
def include_config(
|
160
|
+
def include_config(starting_package, descriptor, backtrace)
|
167
161
|
resolved_descriptor = nil
|
168
162
|
|
169
163
|
# Check to see if this include has been overridden.
|
170
164
|
if backtrace
|
171
|
-
override_package_name = descriptor.name ||
|
165
|
+
override_package_name = descriptor.name || starting_package.name
|
172
166
|
override = backtrace.get_override(override_package_name)
|
173
167
|
if override
|
174
168
|
resolved_descriptor =
|
@@ -181,7 +175,7 @@ class Fig::RuntimeEnvironment
|
|
181
175
|
|
182
176
|
new_backtrace = Fig::IncludeBacktrace.new(backtrace, resolved_descriptor)
|
183
177
|
package = lookup_package(
|
184
|
-
resolved_descriptor.name ||
|
178
|
+
resolved_descriptor.name || starting_package.name,
|
185
179
|
resolved_descriptor.version,
|
186
180
|
new_backtrace
|
187
181
|
)
|
@@ -200,24 +194,26 @@ class Fig::RuntimeEnvironment
|
|
200
194
|
|
201
195
|
statement = @retrieves[name]
|
202
196
|
if statement.loaded_but_not_referenced?
|
203
|
-
|
204
|
-
|
197
|
+
text, * = Fig::Unparser.determine_version_and_unparse(
|
198
|
+
[statement], :emit_as_input
|
199
|
+
)
|
205
200
|
Fig::Logging.warn \
|
206
|
-
%Q<The #{name} variable was never referenced or didn't need expansion, so "#{text}"#{statement.position_string} was ignored.>
|
201
|
+
%Q<The #{name} variable was never referenced or didn't need expansion, so "#{text.strip}"#{statement.position_string} was ignored.>
|
207
202
|
end
|
208
203
|
end
|
209
204
|
end
|
210
205
|
|
211
206
|
private
|
212
207
|
|
213
|
-
def set_variable(
|
214
|
-
expanded_value =
|
215
|
-
|
216
|
-
|
217
|
-
|
208
|
+
def set_variable(package, statement, backtrace)
|
209
|
+
expanded_value = expand_variable_as_path_and_process_retrieves(
|
210
|
+
statement, package, backtrace
|
211
|
+
)
|
212
|
+
name = statement.name
|
218
213
|
@variables[name] = expanded_value
|
219
214
|
|
220
215
|
if Fig::Logging.debug?
|
216
|
+
value = statement.value
|
221
217
|
expanded_message =
|
222
218
|
expanded_value == value ? '' \
|
223
219
|
: %Q< (expanded from "#{value}")>
|
@@ -230,14 +226,15 @@ class Fig::RuntimeEnvironment
|
|
230
226
|
return
|
231
227
|
end
|
232
228
|
|
233
|
-
def prepend_variable(
|
234
|
-
expanded_value =
|
235
|
-
|
236
|
-
|
237
|
-
|
229
|
+
def prepend_variable(package, statement, backtrace)
|
230
|
+
expanded_value = expand_variable_as_path_and_process_retrieves(
|
231
|
+
statement, package, backtrace
|
232
|
+
)
|
233
|
+
name = statement.name
|
238
234
|
@variables.prepend_variable(name, expanded_value)
|
239
235
|
|
240
236
|
if Fig::Logging.debug?
|
237
|
+
value = statement.value
|
241
238
|
expanded_message =
|
242
239
|
expanded_value == value ? '' \
|
243
240
|
: %Q< ("#{value}" expanded to "#{expanded_value}")>
|
@@ -275,6 +272,31 @@ class Fig::RuntimeEnvironment
|
|
275
272
|
return package
|
276
273
|
end
|
277
274
|
|
275
|
+
def determine_package_for_execution(base_package, base_config, descriptor)
|
276
|
+
config_name =
|
277
|
+
determine_config_to_executed(base_package, base_config, descriptor)
|
278
|
+
|
279
|
+
package = nil
|
280
|
+
|
281
|
+
if descriptor
|
282
|
+
package_name = descriptor.name || base_package.name
|
283
|
+
package = lookup_package(
|
284
|
+
package_name,
|
285
|
+
descriptor.version,
|
286
|
+
Fig::IncludeBacktrace.new(
|
287
|
+
nil,
|
288
|
+
Fig::PackageDescriptor.new(
|
289
|
+
package_name, descriptor.version, config_name
|
290
|
+
)
|
291
|
+
)
|
292
|
+
)
|
293
|
+
else
|
294
|
+
package = base_package
|
295
|
+
end
|
296
|
+
|
297
|
+
return [package, config_name]
|
298
|
+
end
|
299
|
+
|
278
300
|
def determine_config_to_executed(base_package, base_config, descriptor)
|
279
301
|
return base_config if base_config
|
280
302
|
|
@@ -301,44 +323,44 @@ class Fig::RuntimeEnvironment
|
|
301
323
|
return package.primary_config_name || Fig::Package::DEFAULT_CONFIG
|
302
324
|
end
|
303
325
|
|
304
|
-
def execute_command(command_statement,
|
326
|
+
def execute_command(command_statement, extra_arguments, package)
|
305
327
|
@variables.with_environment do
|
306
328
|
argument =
|
307
329
|
expand_command_line_argument(
|
308
|
-
"#{command_statement.command} #{
|
330
|
+
"#{command_statement.command} #{extra_arguments.join(' ')}", package
|
309
331
|
)
|
310
332
|
|
311
|
-
yield
|
333
|
+
yield argument.split(' ')
|
312
334
|
end
|
313
335
|
|
314
336
|
return
|
315
337
|
end
|
316
338
|
|
317
339
|
def expand_variable_as_path_and_process_retrieves(
|
318
|
-
|
340
|
+
statement, package, backtrace
|
319
341
|
)
|
320
|
-
return
|
342
|
+
return statement.value unless package && package.name
|
321
343
|
|
322
344
|
variable_value =
|
323
|
-
expand_at_signs_in_path(
|
345
|
+
expand_at_signs_in_path(statement.value, package, backtrace)
|
324
346
|
|
325
|
-
return variable_value if not @retrieves.member?(
|
347
|
+
return variable_value if not @retrieves.member?(statement.name)
|
326
348
|
|
327
349
|
return retrieve_files(
|
328
|
-
|
350
|
+
statement.name, variable_value, package, backtrace
|
329
351
|
)
|
330
352
|
end
|
331
353
|
|
332
|
-
def retrieve_files(variable_name, variable_value,
|
354
|
+
def retrieve_files(variable_name, variable_value, package, backtrace)
|
333
355
|
check_source_existence(
|
334
|
-
variable_name, variable_value,
|
356
|
+
variable_name, variable_value, package, backtrace
|
335
357
|
)
|
336
358
|
|
337
359
|
destination_path =
|
338
|
-
derive_retrieve_destination(variable_name, variable_value,
|
360
|
+
derive_retrieve_destination(variable_name, variable_value, package)
|
339
361
|
|
340
362
|
@working_directory_maintainer.switch_to_package_version(
|
341
|
-
|
363
|
+
package.name, package.version
|
342
364
|
)
|
343
365
|
@working_directory_maintainer.retrieve(variable_value, destination_path)
|
344
366
|
|
@@ -346,20 +368,20 @@ class Fig::RuntimeEnvironment
|
|
346
368
|
end
|
347
369
|
|
348
370
|
def check_source_existence(
|
349
|
-
variable_name, variable_value,
|
371
|
+
variable_name, variable_value, package, backtrace
|
350
372
|
)
|
351
373
|
return if File.exists?(variable_value) || File.symlink?(variable_value)
|
352
374
|
|
353
375
|
raise_repository_error(
|
354
|
-
%Q<In #{
|
376
|
+
%Q<In #{package}, the #{variable_name} variable points to a path that does not exist ("#{variable_value}", after expansion).>,
|
355
377
|
backtrace,
|
356
|
-
|
378
|
+
package
|
357
379
|
)
|
358
380
|
end
|
359
381
|
|
360
|
-
def derive_retrieve_destination(variable_name, variable_value,
|
382
|
+
def derive_retrieve_destination(variable_name, variable_value, package)
|
361
383
|
retrieve_path =
|
362
|
-
get_retrieve_path_with_substitution(variable_name,
|
384
|
+
get_retrieve_path_with_substitution(variable_name, package)
|
363
385
|
|
364
386
|
# A '//' in the variable value tells us to preserve path
|
365
387
|
# information after the '//' when doing a retrieve.
|
@@ -376,56 +398,83 @@ class Fig::RuntimeEnvironment
|
|
376
398
|
return File.join(retrieve_path, File.basename(variable_value))
|
377
399
|
end
|
378
400
|
|
379
|
-
def expand_at_signs_in_path(path,
|
401
|
+
def expand_at_signs_in_path(path, package, backtrace)
|
380
402
|
expanded_path =
|
381
|
-
replace_at_signs_with_package_references(path,
|
382
|
-
check_for_bad_escape(expanded_path, path,
|
403
|
+
replace_at_signs_with_package_references(path, package)
|
404
|
+
check_for_bad_escape(expanded_path, path, package, backtrace)
|
383
405
|
|
384
406
|
return collapse_backslashes_for_escaped_at_signs(expanded_path)
|
385
407
|
end
|
386
408
|
|
387
|
-
def replace_at_signs_with_package_references(
|
388
|
-
return
|
409
|
+
def replace_at_signs_with_package_references(argument, package)
|
410
|
+
return argument.gsub(
|
389
411
|
%r<
|
390
412
|
(?: ^ | \G) # Zero-width anchor.
|
391
|
-
( [^\\@]*
|
413
|
+
( [^\\@]* ) # A bunch of not-slashes-or-at-signs
|
414
|
+
( \\* ) # Any leading backslashes
|
392
415
|
\@ # The package indicator
|
393
416
|
>x
|
394
417
|
) do |match|
|
395
|
-
backslashes = $1
|
396
|
-
|
418
|
+
frontmatter, backslashes = $1, $2
|
419
|
+
|
420
|
+
replacement = backslashes.length % 2 == 1 ? '@' : package.directory
|
421
|
+
|
422
|
+
"#{frontmatter}#{backslashes}#{replacement}"
|
397
423
|
end
|
398
424
|
end
|
399
425
|
|
400
|
-
def expand_command_line_argument(
|
401
|
-
package_substituted =
|
402
|
-
check_for_bad_escape(package_substituted,
|
426
|
+
def expand_command_line_argument(argument, package)
|
427
|
+
package_substituted = expand_package_references(argument, package)
|
428
|
+
check_for_bad_escape(package_substituted, argument, package, nil)
|
403
429
|
|
404
430
|
return collapse_backslashes_for_escaped_at_signs(package_substituted)
|
405
431
|
end
|
406
432
|
|
407
|
-
def
|
408
|
-
return
|
433
|
+
def expand_package_references(argument, package)
|
434
|
+
return argument.gsub(
|
409
435
|
# TODO: Refactor package name regex into PackageDescriptor constant.
|
410
436
|
%r<
|
411
437
|
(?: ^ | \G) # Zero-width anchor.
|
412
|
-
( [^\\@]*
|
438
|
+
( [^\\@]* ) # A bunch of not-slashes-or-at-signs
|
439
|
+
( \\* ) # Any leading backslashes
|
413
440
|
\@ # The package indicator
|
414
|
-
( [a-zA-Z0-9_.-]
|
441
|
+
( [a-zA-Z0-9_.-]* ) # Package name
|
415
442
|
>x
|
416
443
|
) do |match|
|
417
|
-
backslashes = $1
|
418
|
-
|
444
|
+
frontmatter, backslashes, package_name = $1, $2, $3
|
445
|
+
|
446
|
+
expand_package_reference(
|
447
|
+
frontmatter, backslashes, package_name, package
|
448
|
+
)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
def expand_package_reference(
|
453
|
+
frontmatter, backslashes, package_name, starting_package
|
454
|
+
)
|
455
|
+
if backslashes.length % 2 == 1
|
456
|
+
return "#{frontmatter}#{backslashes}@#{package_name}"
|
457
|
+
end
|
458
|
+
|
459
|
+
package = nil
|
460
|
+
if ! package_name.empty?
|
419
461
|
package = get_package(package_name)
|
420
462
|
if package.nil?
|
421
463
|
raise_repository_error(
|
422
464
|
%Q<Command-line referenced the "#{package_name}" package, which has not been referenced by any other package, so there's nothing to substitute with.>,
|
423
|
-
|
465
|
+
nil,
|
424
466
|
nil
|
425
467
|
)
|
426
468
|
end
|
427
|
-
|
469
|
+
else
|
470
|
+
package = starting_package
|
428
471
|
end
|
472
|
+
|
473
|
+
if package && package.directory
|
474
|
+
return "#{frontmatter}#{backslashes}#{package.directory}"
|
475
|
+
end
|
476
|
+
|
477
|
+
return "#{frontmatter}#{backslashes}@"
|
429
478
|
end
|
430
479
|
|
431
480
|
# The value is expected to have had any @ substitution already done, but
|
@@ -450,11 +499,11 @@ class Fig::RuntimeEnvironment
|
|
450
499
|
return string.gsub(%r< \\ ([\\@]) >x, '\1')
|
451
500
|
end
|
452
501
|
|
453
|
-
def get_retrieve_path_with_substitution(
|
454
|
-
retrieve_statement = @retrieves[
|
502
|
+
def get_retrieve_path_with_substitution(variable_name, package)
|
503
|
+
retrieve_statement = @retrieves[variable_name]
|
455
504
|
retrieve_statement.referenced(true)
|
456
505
|
|
457
|
-
return retrieve_statement.path.gsub(/ \[package\] /x,
|
506
|
+
return retrieve_statement.path.gsub(/ \[package\] /x, package.name)
|
458
507
|
end
|
459
508
|
|
460
509
|
def raise_repository_error(message, backtrace, package)
|