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/TODO ADDED
@@ -0,0 +1,4 @@
1
+ Cleanup tasks:
2
+
3
+ - Clean up method names in Fig::Command, probably by breaking out package loading into a separate class.
4
+ - Make everything use PackageDescriptors rather than passing name/version/config around.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.51
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
- include Fig
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
@@ -1,6 +1,8 @@
1
+ module Fig; end
2
+
1
3
  # Contains traces of file inclusions so that the user can track down which file
2
4
  # an error occurred in.
3
- class Backtrace
5
+ class Fig::Backtrace
4
6
  attr_reader :overrides
5
7
 
6
8
  def initialize(parent, package_name, version_name, config_name)
@@ -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