fig 0.1.51 → 0.1.52
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 +93 -0
- data/LICENSE +1 -1
- data/README.md +330 -99
- data/TODO +4 -0
- data/VERSION +1 -1
- data/bin/fig +2 -4
- data/lib/fig/backtrace.rb +3 -1
- data/lib/fig/command.rb +477 -0
- data/lib/fig/environment.rb +76 -23
- data/lib/fig/figrc.rb +2 -2
- data/lib/fig/grammar.treetop +23 -31
- data/lib/fig/{os.rb → operatingsystem.rb} +11 -9
- data/lib/fig/options.rb +424 -202
- data/lib/fig/package.rb +134 -18
- data/lib/fig/packagecache.rb +36 -0
- data/lib/fig/packagedescriptor.rb +46 -0
- data/lib/fig/parser.rb +2 -2
- data/lib/fig/repository.rb +173 -124
- data/lib/fig/retriever.rb +3 -1
- data/lib/fig/statement.rb +18 -0
- data/lib/fig/{package → statement}/archive.rb +3 -4
- data/lib/fig/{package → statement}/command.rb +3 -4
- data/lib/fig/{package → statement}/configuration.rb +18 -6
- data/lib/fig/statement/include.rb +87 -0
- data/lib/fig/{package → statement}/override.rb +3 -4
- data/lib/fig/{package → statement}/path.rb +3 -4
- data/lib/fig/{package → statement}/publish.rb +3 -4
- data/lib/fig/{package → statement}/resource.rb +3 -4
- data/lib/fig/{package → statement}/retrieve.rb +3 -4
- data/lib/fig/{package → statement}/set.rb +3 -4
- metadata +118 -71
- data/lib/fig.rb +0 -288
- data/lib/fig/package/include.rb +0 -32
- data/lib/fig/package/install.rb +0 -22
- data/lib/fig/package/statement.rb +0 -13
data/TODO
ADDED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.52
|
data/bin/fig
CHANGED
@@ -4,9 +4,7 @@ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), %w< .. lib > ))
|
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
6
|
|
7
|
-
require 'fig'
|
7
|
+
require 'fig/command'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
return_code = run_with_exception_handling(ARGV)
|
9
|
+
return_code = Fig::Command.new.run_with_exception_handling(ARGV)
|
12
10
|
exit return_code
|
data/lib/fig/backtrace.rb
CHANGED
data/lib/fig/command.rb
ADDED
@@ -0,0 +1,477 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/ftp'
|
3
|
+
require 'log4r'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
require 'fig/environment'
|
7
|
+
require 'fig/figrc'
|
8
|
+
require 'fig/logging'
|
9
|
+
require 'fig/operatingsystem'
|
10
|
+
require 'fig/options'
|
11
|
+
require 'fig/package'
|
12
|
+
require 'fig/parser'
|
13
|
+
require 'fig/repository'
|
14
|
+
require 'fig/retriever'
|
15
|
+
require 'fig/statement/configuration'
|
16
|
+
require 'fig/statement/publish'
|
17
|
+
require 'fig/userinputerror'
|
18
|
+
require 'fig/windows'
|
19
|
+
|
20
|
+
module Fig; end
|
21
|
+
|
22
|
+
# Main program
|
23
|
+
class Fig::Command
|
24
|
+
DEFAULT_FIG_FILE = 'package.fig'
|
25
|
+
|
26
|
+
def run_fig(argv)
|
27
|
+
@options = Fig::Options.new(argv)
|
28
|
+
if not @options.exit_code.nil?
|
29
|
+
return @options.exit_code
|
30
|
+
end
|
31
|
+
@descriptor = @options.descriptor
|
32
|
+
|
33
|
+
configure
|
34
|
+
|
35
|
+
if @options.clean?
|
36
|
+
check_required_package_descriptor('to clean')
|
37
|
+
@repository.clean(@descriptor.name, @descriptor.version)
|
38
|
+
return 0
|
39
|
+
end
|
40
|
+
|
41
|
+
if handle_pre_parse_list_options()
|
42
|
+
return 0
|
43
|
+
end
|
44
|
+
|
45
|
+
if @options.publishing?
|
46
|
+
return publish()
|
47
|
+
end
|
48
|
+
|
49
|
+
get_package()
|
50
|
+
|
51
|
+
if @options.listing()
|
52
|
+
handle_post_parse_list_options()
|
53
|
+
elsif @options.get()
|
54
|
+
puts @environment[@options.get()]
|
55
|
+
elsif @options.shell_command
|
56
|
+
@environment.execute_shell(@options.shell_command) do
|
57
|
+
|command| @operating_system.shell_exec command
|
58
|
+
end
|
59
|
+
elsif @descriptor
|
60
|
+
@environment.include_config(
|
61
|
+
@package, @descriptor.name, @descriptor.config, @descriptor.version, {}, nil
|
62
|
+
)
|
63
|
+
@environment.execute_config(
|
64
|
+
@package, @descriptor.name, @descriptor.config, nil, []
|
65
|
+
) { |cmd| @operating_system.shell_exec cmd }
|
66
|
+
elsif not @repository.updating?
|
67
|
+
$stderr.puts "Nothing to do.\n"
|
68
|
+
$stderr.puts Fig::Options::USAGE
|
69
|
+
$stderr.puts %q<Run "fig --help" for a full list of commands.>
|
70
|
+
return 1
|
71
|
+
end
|
72
|
+
|
73
|
+
return 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def run_with_exception_handling(argv)
|
77
|
+
begin
|
78
|
+
return_code = run_fig(argv)
|
79
|
+
return return_code
|
80
|
+
rescue Fig::URLAccessError => error
|
81
|
+
urls = error.urls.join(', ')
|
82
|
+
$stderr.puts "Access to #{urls} in #{error.package}/#{error.version} not allowed."
|
83
|
+
return 1
|
84
|
+
rescue Fig::UserInputError => error
|
85
|
+
log_error_message(error)
|
86
|
+
return 1
|
87
|
+
rescue OptionParser::InvalidOption => error
|
88
|
+
$stderr.puts error.to_s
|
89
|
+
$stderr.puts Fig::Options::USAGE
|
90
|
+
return 1
|
91
|
+
rescue Fig::RepositoryError => error
|
92
|
+
log_error_message(error)
|
93
|
+
return 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def derive_remote_url()
|
100
|
+
if remote_operation_necessary?()
|
101
|
+
if ENV['FIG_REMOTE_URL'].nil?
|
102
|
+
raise Fig::UserInputError.new('Please define the FIG_REMOTE_URL environment variable.')
|
103
|
+
end
|
104
|
+
return ENV['FIG_REMOTE_URL']
|
105
|
+
end
|
106
|
+
|
107
|
+
return nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def configure()
|
111
|
+
Fig::Logging.initialize_pre_configuration(@options.log_level())
|
112
|
+
|
113
|
+
remote_url = derive_remote_url()
|
114
|
+
|
115
|
+
@configuration = Fig::FigRC.find(
|
116
|
+
@options.figrc(),
|
117
|
+
remote_url,
|
118
|
+
@options.login?,
|
119
|
+
@options.home(),
|
120
|
+
@options.no_figrc?
|
121
|
+
)
|
122
|
+
|
123
|
+
Fig::Logging.initialize_post_configuration(
|
124
|
+
@options.log_config() || @configuration['log configuration'],
|
125
|
+
@options.log_level()
|
126
|
+
)
|
127
|
+
|
128
|
+
@operating_system = Fig::OperatingSystem.new(@options.login?)
|
129
|
+
@repository = Fig::Repository.new(
|
130
|
+
@operating_system,
|
131
|
+
File.expand_path(File.join(@options.home(), 'repos')),
|
132
|
+
remote_url,
|
133
|
+
@configuration,
|
134
|
+
nil, # remote_user
|
135
|
+
@options.update?,
|
136
|
+
@options.update_if_missing?
|
137
|
+
)
|
138
|
+
|
139
|
+
@retriever = Fig::Retriever.new('.')
|
140
|
+
|
141
|
+
# Check to see if this is still happening with the new layers of abstraction.
|
142
|
+
at_exit { @retriever.save }
|
143
|
+
|
144
|
+
@environment = Fig::Environment.new(@repository, nil, @retriever)
|
145
|
+
|
146
|
+
@options.non_command_package_statements().each do |statement|
|
147
|
+
@environment.apply_config_statement(nil, statement, nil)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def check_required_package_descriptor(operation_description)
|
152
|
+
if not @descriptor
|
153
|
+
raise Fig::UserInputError.new(
|
154
|
+
"Need to specify a package #{operation_description}."
|
155
|
+
)
|
156
|
+
end
|
157
|
+
|
158
|
+
return
|
159
|
+
end
|
160
|
+
|
161
|
+
def check_disallowed_package_descriptor(operation_description)
|
162
|
+
if @descriptor
|
163
|
+
raise Fig::UserInputError.new(
|
164
|
+
"Cannot specify a package for #{operation_description}."
|
165
|
+
)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def read_in_package_config_file(config_file)
|
170
|
+
if File.exist?(config_file)
|
171
|
+
return File.read(config_file)
|
172
|
+
else
|
173
|
+
raise Fig::UserInputError.new(%Q<File not found: "#{config_file}".>)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def remote_operation_necessary?()
|
178
|
+
return @options.updating? ||
|
179
|
+
@options.publish? ||
|
180
|
+
@options.listing == :remote_packages
|
181
|
+
end
|
182
|
+
|
183
|
+
def load_package_config_file_contents()
|
184
|
+
package_config_file = @options.package_config_file()
|
185
|
+
|
186
|
+
if package_config_file == :none
|
187
|
+
return nil
|
188
|
+
elsif package_config_file == '-'
|
189
|
+
return $stdin.read
|
190
|
+
elsif package_config_file.nil?
|
191
|
+
if File.exist?(DEFAULT_FIG_FILE)
|
192
|
+
return File.read(DEFAULT_FIG_FILE)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
return read_in_package_config_file(package_config_file)
|
196
|
+
end
|
197
|
+
|
198
|
+
return
|
199
|
+
end
|
200
|
+
|
201
|
+
def display_local_package_list()
|
202
|
+
check_disallowed_package_descriptor('--list-local')
|
203
|
+
@repository.list_packages.sort.each do |item|
|
204
|
+
puts item
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def display_remote_package_list()
|
209
|
+
check_disallowed_package_descriptor('--list-remote')
|
210
|
+
@repository.list_remote_packages.sort.each do |item|
|
211
|
+
puts item
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def display_configs_in_local_packages_list()
|
216
|
+
@package.configs.each do |config|
|
217
|
+
puts config.name
|
218
|
+
end
|
219
|
+
|
220
|
+
return
|
221
|
+
end
|
222
|
+
|
223
|
+
def handle_pre_parse_list_options()
|
224
|
+
case @options.listing()
|
225
|
+
when :local_packages
|
226
|
+
display_local_package_list()
|
227
|
+
when :remote_packages
|
228
|
+
display_remote_package_list()
|
229
|
+
else
|
230
|
+
return false
|
231
|
+
end
|
232
|
+
|
233
|
+
return true
|
234
|
+
end
|
235
|
+
|
236
|
+
def display_dependencies()
|
237
|
+
if @options.list_tree?
|
238
|
+
display_dependencies_in_tree(@package, derive_base_display_config_names())
|
239
|
+
else
|
240
|
+
display_dependencies_flat()
|
241
|
+
end
|
242
|
+
|
243
|
+
return
|
244
|
+
end
|
245
|
+
|
246
|
+
def display_dependencies_in_tree(package, config_names, indent = 0)
|
247
|
+
config_names.each do
|
248
|
+
|config_name|
|
249
|
+
|
250
|
+
print ' ' * (indent * 4)
|
251
|
+
puts package.to_s_with_config(config_name)
|
252
|
+
|
253
|
+
package.package_dependencies(config_name).each do
|
254
|
+
|descriptor|
|
255
|
+
|
256
|
+
display_dependencies_in_tree(
|
257
|
+
@repository.get_package(descriptor.name, descriptor.version),
|
258
|
+
[descriptor.config],
|
259
|
+
indent + 1
|
260
|
+
)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
return
|
265
|
+
end
|
266
|
+
|
267
|
+
def display_dependencies_flat()
|
268
|
+
base_config_names = derive_base_display_config_names()
|
269
|
+
packages = gather_package_depencency_configurations(base_config_names)
|
270
|
+
|
271
|
+
if packages.empty? and $stdout.tty?
|
272
|
+
puts '<no dependencies>'
|
273
|
+
else
|
274
|
+
packages.keys.sort.each do
|
275
|
+
|package|
|
276
|
+
|
277
|
+
if @options.list_all_configs?
|
278
|
+
packages[package].sort.each do
|
279
|
+
|config_name|
|
280
|
+
|
281
|
+
puts package.to_s_with_config(config_name)
|
282
|
+
end
|
283
|
+
else
|
284
|
+
puts package
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
return
|
290
|
+
end
|
291
|
+
|
292
|
+
def derive_base_display_config_names()
|
293
|
+
if @options.list_all_configs?
|
294
|
+
return @package.config_names
|
295
|
+
end
|
296
|
+
|
297
|
+
return [
|
298
|
+
@descriptor && @descriptor.config || Fig::Package::DEFAULT_CONFIG
|
299
|
+
]
|
300
|
+
end
|
301
|
+
|
302
|
+
def gather_package_depencency_configurations(starting_config_names)
|
303
|
+
packages = {}
|
304
|
+
|
305
|
+
if ! @package.package_name.nil?
|
306
|
+
packages[@package] = starting_config_names.to_set
|
307
|
+
end
|
308
|
+
|
309
|
+
starting_config_names.each do
|
310
|
+
|config_name|
|
311
|
+
|
312
|
+
@package[config_name].walk_statements_following_package_dependencies(
|
313
|
+
@repository, @package
|
314
|
+
) do
|
315
|
+
|package, statement|
|
316
|
+
|
317
|
+
if (
|
318
|
+
! package.package_name.nil? \
|
319
|
+
&& statement.is_a?(Fig::Statement::Configuration)
|
320
|
+
)
|
321
|
+
packages[package] ||= Set.new
|
322
|
+
packages[package] << statement.name
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
if ! @options.list_all_configs? && @descriptor
|
328
|
+
packages.reject! do
|
329
|
+
|package, config_names|
|
330
|
+
package.package_name == @descriptor.name
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
return packages
|
335
|
+
end
|
336
|
+
|
337
|
+
def handle_post_parse_list_options()
|
338
|
+
case @options.listing()
|
339
|
+
when :configs
|
340
|
+
display_configs_in_local_packages_list()
|
341
|
+
when :dependencies
|
342
|
+
display_dependencies()
|
343
|
+
when :dependencies_all_configs
|
344
|
+
raise Fig::UserInputError.new('--list-dependencies-all-configs not yet implemented.')
|
345
|
+
when :variables
|
346
|
+
raise Fig::UserInputError.new('--list-variables not yet implemented.')
|
347
|
+
when :variables_all_configs
|
348
|
+
raise Fig::UserInputError.new('--list-variables-all-configs not yet implemented.')
|
349
|
+
else
|
350
|
+
raise %Q<Bug in code! Found unknown :listing option value "#{options.listing()}">
|
351
|
+
end
|
352
|
+
|
353
|
+
return
|
354
|
+
end
|
355
|
+
|
356
|
+
def register_package_with_environment_if_not_listing()
|
357
|
+
return if @options.listing
|
358
|
+
|
359
|
+
if @options.updating?
|
360
|
+
@package.retrieves.each do |var, path|
|
361
|
+
@environment.add_retrieve(var, path)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
@environment.register_package(@package)
|
366
|
+
@environment.apply_config(
|
367
|
+
@package,
|
368
|
+
@options.config() || @descriptor && @descriptor.config() || 'default',
|
369
|
+
nil
|
370
|
+
)
|
371
|
+
|
372
|
+
return
|
373
|
+
end
|
374
|
+
|
375
|
+
def parse_package_config_file(config_raw_text)
|
376
|
+
if config_raw_text.nil?
|
377
|
+
@package = Fig::Package.new(nil, nil, '.', [])
|
378
|
+
return
|
379
|
+
end
|
380
|
+
|
381
|
+
@package =
|
382
|
+
Fig::Parser.new(@configuration).parse_package(
|
383
|
+
nil, nil, '.', config_raw_text
|
384
|
+
)
|
385
|
+
|
386
|
+
register_package_with_environment_if_not_listing()
|
387
|
+
|
388
|
+
return
|
389
|
+
end
|
390
|
+
|
391
|
+
def load_package_file()
|
392
|
+
config_raw_text = load_package_config_file_contents()
|
393
|
+
|
394
|
+
parse_package_config_file(config_raw_text)
|
395
|
+
end
|
396
|
+
|
397
|
+
def get_package()
|
398
|
+
if @descriptor.nil?
|
399
|
+
load_package_file()
|
400
|
+
else
|
401
|
+
# TODO: complain if config file was specified on the command-line.
|
402
|
+
@package =
|
403
|
+
@repository.get_package(
|
404
|
+
@descriptor.name, @descriptor.version, :disable_updating
|
405
|
+
)
|
406
|
+
|
407
|
+
register_package_with_environment_if_not_listing()
|
408
|
+
end
|
409
|
+
|
410
|
+
return
|
411
|
+
end
|
412
|
+
|
413
|
+
def publish()
|
414
|
+
check_required_package_descriptor('to publish')
|
415
|
+
|
416
|
+
if @descriptor.name.nil? || @descriptor.version.nil?
|
417
|
+
raise Fig::UserInputError.new('Please specify a package name and a version name.')
|
418
|
+
end
|
419
|
+
|
420
|
+
if not @options.non_command_package_statements().empty?
|
421
|
+
publish_statements =
|
422
|
+
@options.resources() +
|
423
|
+
@options.archives() +
|
424
|
+
[
|
425
|
+
Fig::Statement::Configuration.new(
|
426
|
+
'default', @options.non_command_package_statements()
|
427
|
+
)
|
428
|
+
]
|
429
|
+
publish_statements << Fig::Statement::Publish.new('default','default')
|
430
|
+
else
|
431
|
+
load_package_file()
|
432
|
+
if not @package.statements.empty?
|
433
|
+
publish_statements = @package.statements
|
434
|
+
else
|
435
|
+
$stderr.puts 'Nothing to publish.'
|
436
|
+
return 1
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
if @options.publish?
|
441
|
+
Fig::Logging.info "Checking status of #{@descriptor.name}/#{@descriptor.version}..."
|
442
|
+
|
443
|
+
if @repository.list_remote_packages.include?("#{@descriptor.name}/#{@descriptor.version}")
|
444
|
+
Fig::Logging.info "#{@descriptor.name}/#{@descriptor.version} has already been published."
|
445
|
+
|
446
|
+
if not @options.force?
|
447
|
+
Fig::Logging.fatal 'Use the --force option if you really want to overwrite, or use --publish-local for testing.'
|
448
|
+
return 1
|
449
|
+
else
|
450
|
+
Fig::Logging.info 'Overwriting...'
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
Fig::Logging.info "Publishing #{@descriptor.name}/#{@descriptor.version}."
|
456
|
+
@repository.publish_package(
|
457
|
+
publish_statements,
|
458
|
+
@descriptor.name,
|
459
|
+
@descriptor.version,
|
460
|
+
@options.publish_local?
|
461
|
+
)
|
462
|
+
|
463
|
+
return 0
|
464
|
+
end
|
465
|
+
|
466
|
+
def log_error_message(error)
|
467
|
+
# If there's no message, we assume that the cause has already been logged.
|
468
|
+
if error_has_message?(error)
|
469
|
+
Fig::Logging.fatal error.to_s
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def error_has_message?(error)
|
474
|
+
class_name = error.class.name
|
475
|
+
return error.message != class_name
|
476
|
+
end
|
477
|
+
end
|