fig 0.1.57 → 0.1.59

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Changes +80 -0
  2. data/VERSION +1 -1
  3. data/bin/fig-debug +12 -0
  4. data/bin/fig.bat +1 -0
  5. data/lib/fig/applicationconfiguration.rb +41 -41
  6. data/lib/fig/backtrace.rb +28 -30
  7. data/lib/fig/command.rb +52 -112
  8. data/lib/fig/command/listing.rb +207 -41
  9. data/lib/fig/command/packageload.rb +137 -0
  10. data/lib/fig/environment.rb +59 -72
  11. data/lib/fig/environmentvariables.rb +44 -0
  12. data/lib/fig/environmentvariables/caseinsensitive.rb +49 -0
  13. data/lib/fig/environmentvariables/casesensitive.rb +30 -0
  14. data/lib/fig/grammar.treetop +60 -35
  15. data/lib/fig/log4r/outputter.rb +96 -0
  16. data/lib/fig/logging.rb +2 -1
  17. data/lib/fig/logging/colorizable.rb +14 -0
  18. data/lib/fig/nosuchpackageconfigerror.rb +15 -0
  19. data/lib/fig/operatingsystem.rb +24 -13
  20. data/lib/fig/options.rb +70 -20
  21. data/lib/fig/package.rb +25 -26
  22. data/lib/fig/packagecache.rb +3 -3
  23. data/lib/fig/packagedescriptor.rb +36 -19
  24. data/lib/fig/packageparseerror.rb +7 -0
  25. data/lib/fig/parser.rb +76 -39
  26. data/lib/fig/repository.rb +131 -93
  27. data/lib/fig/retriever.rb +61 -39
  28. data/lib/fig/statement.rb +24 -2
  29. data/lib/fig/statement/archive.rb +4 -6
  30. data/lib/fig/statement/command.rb +4 -6
  31. data/lib/fig/statement/configuration.rb +7 -9
  32. data/lib/fig/statement/include.rb +49 -32
  33. data/lib/fig/statement/override.rb +7 -8
  34. data/lib/fig/statement/path.rb +4 -6
  35. data/lib/fig/statement/publish.rb +4 -11
  36. data/lib/fig/statement/resource.rb +4 -6
  37. data/lib/fig/statement/retrieve.rb +4 -6
  38. data/lib/fig/statement/set.rb +4 -6
  39. data/lib/fig/urlaccesserror.rb +4 -5
  40. metadata +52 -215
  41. data/LICENSE +0 -27
  42. data/README.md +0 -526
  43. data/TODO +0 -4
  44. data/lib/fig/packageerror.rb +0 -8
  45. data/lib/fig/windows.rb +0 -44
@@ -0,0 +1,96 @@
1
+ require 'colorize'
2
+ require 'log4r/logger'
3
+ require 'log4r/outputter/iooutputter'
4
+
5
+ require 'fig/logging/colorizable'
6
+ require 'fig/operatingsystem'
7
+
8
+ module Fig; end
9
+ module Fig::Log4r; end
10
+
11
+ class Fig::Log4r::Outputter < Log4r::IOOutputter
12
+ def initialize(name, file_handle, hash = {})
13
+ @colors = hash.delete(:colors)
14
+ @colors ||= {
15
+ :debug => :white,
16
+ :info => :light_white,
17
+ :warn => :yellow,
18
+ :error => :red,
19
+ :fatal => {:color => :light_yellow, :background => :red}
20
+ }
21
+ @colorize = file_handle.tty? && Fig::OperatingSystem.unix?
22
+
23
+ super(name, file_handle, hash)
24
+
25
+ initialize_colors_by_level()
26
+ end
27
+
28
+ private
29
+
30
+ def initialize_colors_by_level()
31
+ @colors_by_level = {}
32
+
33
+ Log4r::LNAMES.each_index do
34
+ |index|
35
+
36
+ name_symbol = Log4r::LNAMES[index].downcase.to_sym
37
+ color = @colors[name_symbol]
38
+ if color
39
+ @colors_by_level[index] = color
40
+ end
41
+ end
42
+
43
+ return
44
+ end
45
+
46
+ def canonical_log(logevent)
47
+ synch { write( format(logevent), logevent ) }
48
+ end
49
+
50
+ def write(data, logevent)
51
+ begin
52
+ if not @colorize
53
+ @out.print data
54
+ else
55
+ if logevent.data.is_a? Fig::Logging::Colorizable
56
+ emit_colorizable(data, logevent.data)
57
+ else
58
+ color = @colors_by_level[logevent.level]
59
+ if color
60
+ @out.print data.colorize(color)
61
+ @out.print ''.uncolorize
62
+ else
63
+ @out.print data
64
+ end
65
+ end
66
+ end
67
+
68
+ @out.flush
69
+ rescue IOError => error # recover from this instead of crash
70
+ Log4r::Logger.log_internal {"IOError in Outputter '#{@name}'!"}
71
+ Log4r::Logger.log_internal {error}
72
+ close
73
+ rescue NameError => error
74
+ Log4r::Logger.log_internal {"Outputter '#{@name}' IO is #{@out.class}!"}
75
+ Log4r::Logger.log_internal {error}
76
+ close
77
+ end
78
+
79
+ return
80
+ end
81
+
82
+ def emit_colorizable(formatted_data, raw_data)
83
+ color = {}
84
+ if raw_data.foreground
85
+ color[:color] = raw_data.foreground
86
+ end
87
+ if raw_data.background
88
+ color[:background] = raw_data.background
89
+ end
90
+
91
+ @out.print formatted_data.colorize(color)
92
+ @out.print ''.uncolorize
93
+
94
+ return
95
+ end
96
+ end
@@ -4,6 +4,7 @@ require 'log4r/yamlconfigurator'
4
4
 
5
5
  require 'fig/configfileerror'
6
6
  require 'fig/log4rconfigerror'
7
+ require 'fig/log4r/outputter'
7
8
 
8
9
  module Fig; end
9
10
 
@@ -124,7 +125,7 @@ module Fig::Logging
124
125
  end
125
126
 
126
127
  def self.setup_default_outputter(logger)
127
- outputter = Log4r::Outputter.stderr
128
+ outputter = Fig::Log4r::Outputter.new('fig stderr', $stderr)
128
129
  logger.add outputter
129
130
  outputter.formatter = Log4r::PatternFormatter.new :pattern => '%M'
130
131
 
@@ -0,0 +1,14 @@
1
+ module Fig; end
2
+ module Fig::Logging; end
3
+
4
+ # A String that has colors associated with it.
5
+ class Fig::Logging::Colorizable < String
6
+ attr_reader :foreground, :background
7
+
8
+ def initialize(string = '', foreground = nil, background = nil)
9
+ super(string)
10
+
11
+ @foreground = foreground
12
+ @background = background
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'fig/packagedescriptor'
2
+ require 'fig/userinputerror'
3
+
4
+ module Fig
5
+ # User specified a configuration for a Package that does not exist.
6
+ class NoSuchPackageConfigError < UserInputError
7
+ attr_accessor :descriptor
8
+
9
+ def initialize(message, descriptor)
10
+ super(message)
11
+
12
+ @descriptor = descriptor
13
+ end
14
+ end
15
+ end
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'find'
2
3
  # Must specify absolute path of ::Archive when using
3
4
  # this module to avoid conflicts with Fig::Statement::Archive
4
5
  require 'libarchive_ruby' unless RUBY_PLATFORM == 'java'
@@ -12,10 +13,11 @@ require 'uri'
12
13
 
13
14
  require 'highline/import'
14
15
 
16
+ require 'fig/environmentvariables/caseinsensitive'
17
+ require 'fig/environmentvariables/casesensitive'
15
18
  require 'fig/logging'
16
19
  require 'fig/networkerror'
17
20
  require 'fig/notfounderror'
18
- require 'fig/windows'
19
21
 
20
22
  module Fig
21
23
  # Does things requiring real O/S interaction, primarilly taking care of file
@@ -100,7 +102,11 @@ module Fig
100
102
  packages
101
103
  when 'file'
102
104
  packages = []
103
- ls = %x<[ -d #{uri.path} ] && find #{uri.path}>
105
+ return packages if ! File.exist?(uri.path)
106
+
107
+ ls = ''
108
+ Find.find(uri.path) { |file| ls << file.to_s; ls << "\n" }
109
+
104
110
  strip_paths_for_list(ls, packages, uri.path)
105
111
  return packages
106
112
  else
@@ -347,25 +353,30 @@ module Fig
347
353
 
348
354
  def shell_exec(cmd)
349
355
  if OperatingSystem.windows?
350
- Windows.shell_exec_windows(cmd)
356
+ Kernel.exec(ENV['ComSpec'], '/c', cmd.join(' '))
351
357
  else
352
- shell_exec_unix(cmd)
358
+ Kernel.exec(ENV['SHELL'], '-c', cmd.join(' '))
353
359
  end
354
360
  end
355
361
 
356
- private
357
-
358
- def shell_exec_unix(cmd)
359
- Kernel.exec(ENV['SHELL'], '-c', cmd.join(' '))
362
+ def self.add_shell_variable_expansion(variable_name)
363
+ if OperatingSystem.windows?
364
+ return "%#{variable_name}%"
365
+ else
366
+ return "$#{variable_name}"
367
+ end
360
368
  end
361
369
 
362
- def shell_exec_windows(cmd)
363
- #command = ['C:/WINDOWS/system32/cmd.exe', '/C', 'call'] + cmd
364
- command = ['cmd.exe', '/C'] + cmd
365
- command = command.join(' ')
366
- Kernel.exec(command)
370
+ def self.get_environment_variables(initial_values = nil)
371
+ if OperatingSystem.windows?
372
+ return EnvironmentVariables::CaseInsensitive.new(initial_values)
373
+ end
374
+
375
+ return EnvironmentVariables::CaseSensitive.new(initial_values)
367
376
  end
368
377
 
378
+ private
379
+
369
380
  # path = The local path the file should be downloaded to.
370
381
  # cmd = The command to be run on the remote host.
371
382
  def ssh_download(user, host, path, cmd)
@@ -18,6 +18,7 @@ class Fig::Options
18
18
  Usage:
19
19
 
20
20
  fig [...] [DESCRIPTOR] [--update | --update-if-missing] [-- COMMAND]
21
+ fig [...] [DESCRIPTOR] [--update | --update-if-missing] [--command-extra-args VALUES]
21
22
 
22
23
  fig {--publish | --publish-local} DESCRIPTOR
23
24
  [--resource PATH]
@@ -31,12 +32,11 @@ Usage:
31
32
  fig --get VARIABLE [DESCRIPTOR] [...]
32
33
  fig --list-configs [DESCRIPTOR] [...]
33
34
  fig --list-dependencies [--list-tree] [--list-all-configs] [DESCRIPTOR] [...]
35
+ fig --list-variables [--list-tree] [--list-all-configs] [DESCRIPTOR] [...]
34
36
  fig {--list-local | --list-remote} [...]
35
37
 
36
38
  fig {--version | --help}
37
39
 
38
- Not yet implemented:
39
- fig --list-variables [--list-tree] [--list-all-configs] [DESCRIPTOR] [...]
40
40
 
41
41
  A DESCRIPTOR looks like <package name>[/<version>][:<config>] e.g. "foo",
42
42
  "foo/1.2.3", and "foo/1.2.3:default". Whether ":<config>" and "/<version>" are
@@ -51,6 +51,7 @@ Standard options (represented as "[...]" above):
51
51
  [--login]
52
52
  [--log-level LEVEL] [--log-config PATH]
53
53
  [--figrc PATH] [--no-figrc]
54
+ [--suppress-warning-include-statement-missing-version]
54
55
 
55
56
  Environment variables:
56
57
 
@@ -63,10 +64,12 @@ Environment variables:
63
64
  LOG_ALIASES = { 'warning' => 'warn' }
64
65
 
65
66
  attr_reader :shell_command
67
+ attr_reader :command_extra_argv
66
68
  attr_reader :descriptor
67
69
  attr_reader :exit_code
68
70
 
69
71
  def initialize(argv)
72
+ argv = argv.clone
70
73
  strip_shell_command(argv)
71
74
 
72
75
  @options = {}
@@ -75,7 +78,6 @@ Environment variables:
75
78
 
76
79
  parser = new_parser()
77
80
 
78
- # TODO: Need to catch the exception thrown from parser and retranslate into a fig exception
79
81
  begin
80
82
  parser.parse!(argv)
81
83
  rescue OptionParser::MissingArgument => error
@@ -97,6 +99,24 @@ Environment variables:
97
99
  package_text = argv.first
98
100
  if package_text
99
101
  @descriptor = Fig::PackageDescriptor.parse(package_text)
102
+ if not @descriptor.name
103
+ $stderr.puts %Q<No package name specified in descriptor "#{package_text}".>
104
+ @exit_code = 1
105
+ return
106
+ end
107
+
108
+ if not @descriptor.version
109
+ $stderr.puts %Q<No version specified in descriptor "#{package_text}".>
110
+ @exit_code = 1
111
+ return
112
+ end
113
+
114
+ if @descriptor.config && config()
115
+ $stderr.puts \
116
+ %Q<Cannot specify both --config and a config in the descriptor "#{package_text}".>
117
+ @exit_code = 1
118
+ return
119
+ end
100
120
  end
101
121
 
102
122
  return
@@ -182,6 +202,10 @@ Environment variables:
182
202
  return @options[:resources]
183
203
  end
184
204
 
205
+ def suppress_warning_include_statement_missing_version?()
206
+ return @options[:suppress_warning_include_statement_missing_version]
207
+ end
208
+
185
209
  def update?()
186
210
  return @options[:update]
187
211
  end
@@ -208,8 +232,18 @@ Environment variables:
208
232
 
209
233
  def strip_shell_command(argv)
210
234
  argv.each_with_index do |arg, i|
211
- if arg == '--'
212
- @shell_command = argv[(i+1)..-1]
235
+ terminating_option = nil
236
+
237
+ case arg
238
+ when '--'
239
+ terminating_option = arg
240
+ @shell_command = argv[(i+1)..-1]
241
+ when '--command-extra-args'
242
+ terminating_option = arg
243
+ @command_extra_argv = argv[(i+1)..-1]
244
+ end
245
+
246
+ if terminating_option
213
247
  argv.slice!(i..-1)
214
248
  break
215
249
  end
@@ -231,11 +265,11 @@ Environment variables:
231
265
 
232
266
  def set_up_queries(parser)
233
267
  parser.banner = USAGE
234
- parser.on('-?', '-h','--help','display this help text') do
268
+ parser.on_tail('-?', '-h','--help','display this help text') do
235
269
  help(parser)
236
270
  end
237
271
 
238
- parser.on('-v', '--version', 'Print fig version') do
272
+ parser.on_tail('-v', '--version', 'print Fig version') do
239
273
  version()
240
274
  end
241
275
 
@@ -334,7 +368,7 @@ Environment variables:
334
368
  @options[:package_config_file] = nil
335
369
  parser.on(
336
370
  '--file FILE',
337
- %q<read fig file FILE. Use '-' for stdin. See also --no-file>
371
+ %q<read Fig file FILE. Use '-' for stdin. See also --no-file>
338
372
  ) do |path|
339
373
  @options[:package_config_file] = path
340
374
  end
@@ -353,28 +387,32 @@ Environment variables:
353
387
  parser.on(
354
388
  '-p',
355
389
  '--append VARIABLE=VALUE',
356
- 'append (actually, prepend) VALUE to environment variable VARIABLE, delimited by separator'
390
+ 'append (actually, prepend) VALUE to PATH-like environment variable VARIABLE'
357
391
  ) do |var_val|
358
392
  var, val = var_val.split('=')
359
- @options[:non_command_package_statements] << Fig::Statement::Path.new(var, val)
393
+ @options[:non_command_package_statements] <<
394
+ Fig::Statement::Path.new(nil, var, val)
360
395
  end
361
396
 
362
397
  parser.on(
363
398
  '-i',
364
399
  '--include DESCRIPTOR',
365
- 'include package/version:config specified in DESCRIPTOR (with any variable prepends) in environment'
366
- ) do |descriptor|
367
- @options[:non_command_package_statements] <<
400
+ 'include package/version:config specified in DESCRIPTOR in environment'
401
+ ) do |descriptor_string|
402
+ statement =
368
403
  Fig::Statement::Include.new(
369
- Fig::PackageDescriptor.parse(descriptor), {}, nil
404
+ nil, Fig::PackageDescriptor.parse(descriptor_string), {}, nil
370
405
  )
406
+ statement.complain_if_version_missing()
407
+ @options[:non_command_package_statements] << statement
371
408
  end
372
409
 
373
410
  parser.on(
374
411
  '-s', '--set VARIABLE=VALUE', 'set environment variable VARIABLE to VALUE'
375
412
  ) do |var_val|
376
413
  var, val = var_val.split('=')
377
- @options[:non_command_package_statements] << Fig::Statement::Set.new(var, val)
414
+ @options[:non_command_package_statements] <<
415
+ Fig::Statement::Set.new(nil, var, val)
378
416
  end
379
417
 
380
418
  @options[:archives] = []
@@ -382,7 +420,7 @@ Environment variables:
382
420
  '--archive PATH',
383
421
  'include PATH archive in package (when using --publish)'
384
422
  ) do |path|
385
- @options[:archives] << Fig::Statement::Archive.new(path)
423
+ @options[:archives] << Fig::Statement::Archive.new(nil, path)
386
424
  end
387
425
 
388
426
  @options[:resources] =[]
@@ -390,7 +428,7 @@ Environment variables:
390
428
  '--resource PATH',
391
429
  'include PATH resource in package (when using --publish)'
392
430
  ) do |path|
393
- @options[:resources] << Fig::Statement::Resource.new(path)
431
+ @options[:resources] << Fig::Statement::Resource.new(nil, path)
394
432
  end
395
433
 
396
434
  return
@@ -456,12 +494,24 @@ Environment variables:
456
494
  @options[:log_level] = log_level
457
495
  end
458
496
 
497
+ parser.on(
498
+ '--suppress-warning-include-statement-missing-version',
499
+ %q<don't complain about "include package" without a version>
500
+ ) do
501
+ @options[:suppress_warning_include_statement_missing_version] = true
502
+ end
503
+
459
504
  return
460
505
  end
461
506
 
462
507
  def help(parser)
463
508
  puts parser.help
464
- puts " -- end of fig options; anything after this is used as a command to run\n\n"
509
+ puts <<-'END_MESSAGE'
510
+ -- end of Fig options; anything after this is used as a command to run
511
+ --command-extra-args end of Fig options; anything after this is appended to the end of a
512
+ "command" statement in a "config" block.
513
+
514
+ END_MESSAGE
465
515
 
466
516
  @exit_code = 0
467
517
 
@@ -478,14 +528,14 @@ Environment variables:
478
528
  line = file.gets
479
529
  end
480
530
  rescue
481
- $stderr.puts 'Could not retrieve version number. Something has mucked with your fig install.'
531
+ $stderr.puts 'Could not retrieve version number. Something has mucked with your Fig install.'
482
532
 
483
533
  @exit_code = 1
484
534
  return
485
535
  end
486
536
 
487
537
  if line !~ /\d+\.\d+\.\d+/
488
- $stderr.puts %Q<"#{line}" does not look like a version number. Something has mucked with your fig install.>
538
+ $stderr.puts %Q<"#{line}" does not look like a version number. Something has mucked with your Fig install.>
489
539
 
490
540
  @exit_code = 1
491
541
  return
@@ -1,5 +1,6 @@
1
1
  require 'fig/logging'
2
- require 'fig/packageerror'
2
+ require 'fig/nosuchpackageconfigerror'
3
+ require 'fig/packagedescriptor'
3
4
  require 'fig/statement/archive'
4
5
  require 'fig/statement/configuration'
5
6
  require 'fig/statement/resource'
@@ -7,20 +8,23 @@ require 'fig/statement/retrieve'
7
8
 
8
9
  module Fig; end
9
10
 
10
- # The parsed representation of a configuration file. Contains the statement
11
- # objects.
11
+ # The parsed representation of a configuration file for a specific version.
12
+ # Contains the statement objects.
13
+ #
14
+ # Unique identifier for this object: name and version. A different version of
15
+ # the same package will be a separate instance of this class.
12
16
  class Fig::Package
13
17
  include Comparable
14
18
 
15
19
  UNPUBLISHED = '<unpublished>'
16
20
  DEFAULT_CONFIG = 'default'
17
21
 
18
- attr_reader :package_name, :version_name, :directory, :statements
22
+ attr_reader :name, :version, :directory, :statements
19
23
  attr_accessor :backtrace
20
24
 
21
- def initialize(package_name, version_name, directory, statements)
22
- @package_name = package_name
23
- @version_name = version_name
25
+ def initialize(name, version, directory, statements)
26
+ @name = name
27
+ @version = version
24
28
  @directory = directory
25
29
  @statements = statements
26
30
  @applied_config_names = []
@@ -32,22 +36,17 @@ class Fig::Package
32
36
  return stmt if stmt.is_a?(Fig::Statement::Configuration) && stmt.name == config_name
33
37
  end
34
38
 
35
- message =
36
- 'Configuration not found: ' +
37
- (@package_name || '<empty>') +
38
- '/' +
39
- (@version_name || '<empty>') +
40
- ':' +
41
- (config_name || '<empty>')
39
+ descriptor = Fig::PackageDescriptor.new(@name, @version, config_name)
40
+ message = 'Configuration not found: ' + descriptor.to_string()
42
41
 
43
- raise Fig::PackageError.new(message)
42
+ raise Fig::NoSuchPackageConfigError.new(message, descriptor)
44
43
  end
45
44
 
46
45
  def <=>(other)
47
- compared = compare_components(package_name, other.package_name)
46
+ compared = compare_components(name, other.name)
48
47
  return compared if compared != 0
49
48
 
50
- return compare_components(version_name, other.version_name)
49
+ return compare_components(version, other.version)
51
50
  end
52
51
 
53
52
  def configs
@@ -91,14 +90,14 @@ class Fig::Package
91
90
  end
92
91
 
93
92
  # Returns an array of PackageDescriptors
94
- def package_dependencies(config_name)
93
+ def package_dependencies(config_name, backtrace)
95
94
  descriptors = []
96
95
 
97
96
  self[config_name || DEFAULT_CONFIG].walk_statements do
98
97
  |statement|
99
98
 
100
99
  if statement.is_a?(Fig::Statement::Include)
101
- descriptors << statement.resolved_dependency_descriptor(self)
100
+ descriptors << statement.resolved_dependency_descriptor(self, backtrace)
102
101
  end
103
102
  end
104
103
 
@@ -120,7 +119,7 @@ class Fig::Package
120
119
  @statements.each do |statement|
121
120
  yield self, statement
122
121
  statement.walk_statements_following_package_dependencies(
123
- repository, self, &block
122
+ repository, self, nil, &block
124
123
  )
125
124
  end
126
125
 
@@ -134,21 +133,21 @@ class Fig::Package
134
133
  def ==(other)
135
134
  return false if other.nil?
136
135
 
137
- return @package_name == other.package_name &&
138
- @version_name == other.version_name &&
136
+ return @name == other.name &&
137
+ @version == other.version &&
139
138
  @statements.to_yaml == other.statements.to_yaml
140
139
  end
141
140
 
142
141
  def to_s
143
- package_name = @package_name || '<empty>'
144
- version_name = @version_name || '<empty>'
145
- return package_name + '/' + version_name
142
+ name = @name || '<empty>'
143
+ version = @version || '<empty>'
144
+ return Fig::PackageDescriptor.format(name, version, nil)
146
145
  end
147
146
 
148
147
  def to_s_with_config(config_name)
149
148
  string = nil
150
149
 
151
- if package_name.nil?
150
+ if name.nil?
152
151
  string = UNPUBLISHED
153
152
  else
154
153
  string = to_s