fig 0.1.51 → 0.1.52

Sign up to get free protection for your applications and to get access to all the features.
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