fig 0.1.57 → 0.1.59

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.
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