fig 0.1.77 → 0.1.79
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 +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)
|