fig 1.1.0 → 1.2.0
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 +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)
|