fig 0.1.65 → 0.1.67

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 (80) hide show
  1. data/Changes +29 -0
  2. data/bin/fig +1 -1
  3. data/bin/fig-debug +1 -1
  4. data/lib/fig.rb +3 -0
  5. data/lib/fig/{applicationconfiguration.rb → application_configuration.rb} +0 -0
  6. data/lib/fig/{atexit.rb → at_exit.rb} +0 -0
  7. data/lib/fig/command.rb +190 -200
  8. data/lib/fig/command/action.rb +83 -0
  9. data/lib/fig/command/action/clean.rb +33 -0
  10. data/lib/fig/command/action/get.rb +48 -0
  11. data/lib/fig/command/action/help.rb +29 -0
  12. data/lib/fig/command/action/list_configs.rb +39 -0
  13. data/lib/fig/command/action/list_dependencies.rb +19 -0
  14. data/lib/fig/command/action/list_dependencies/all_configs.rb +44 -0
  15. data/lib/fig/command/action/list_dependencies/default.rb +40 -0
  16. data/lib/fig/command/action/list_dependencies/tree.rb +40 -0
  17. data/lib/fig/command/action/list_dependencies/tree_all_configs.rb +40 -0
  18. data/lib/fig/command/action/list_local.rb +29 -0
  19. data/lib/fig/command/action/list_remote.rb +33 -0
  20. data/lib/fig/command/action/list_variables.rb +23 -0
  21. data/lib/fig/command/action/list_variables/all_configs.rb +61 -0
  22. data/lib/fig/command/action/list_variables/default.rb +48 -0
  23. data/lib/fig/command/action/list_variables/tree.rb +20 -0
  24. data/lib/fig/command/action/list_variables/tree_all_configs.rb +20 -0
  25. data/lib/fig/command/action/publish.rb +52 -0
  26. data/lib/fig/command/action/publish_local.rb +29 -0
  27. data/lib/fig/command/action/role/has_no_sub_action.rb +10 -0
  28. data/lib/fig/command/action/role/has_sub_action.rb +58 -0
  29. data/lib/fig/command/action/role/list_all_configs.rb +14 -0
  30. data/lib/fig/command/action/role/list_base_config.rb +14 -0
  31. data/lib/fig/command/action/role/list_dependencies_flat.rb +22 -0
  32. data/lib/fig/command/action/role/list_dependencies_in_a_tree.rb +21 -0
  33. data/lib/fig/command/action/role/list_variables_in_a_tree.rb +150 -0
  34. data/lib/fig/command/action/role/list_walking_dependency_tree.rb +90 -0
  35. data/lib/fig/command/action/role/publish.rb +90 -0
  36. data/lib/fig/command/action/role/update.rb +46 -0
  37. data/lib/fig/command/action/run_command_line.rb +45 -0
  38. data/lib/fig/command/action/run_command_statement.rb +52 -0
  39. data/lib/fig/command/action/update.rb +17 -0
  40. data/lib/fig/command/action/update_if_missing.rb +17 -0
  41. data/lib/fig/command/action/version.rb +27 -0
  42. data/lib/fig/command/{coveragesupport.rb → coverage_support.rb} +0 -0
  43. data/lib/fig/command/{optionerror.rb → option_error.rb} +1 -1
  44. data/lib/fig/command/options.rb +185 -127
  45. data/lib/fig/command/package_applier.rb +140 -0
  46. data/lib/fig/command/package_loader.rb +124 -0
  47. data/lib/fig/{configfileerror.rb → config_file_error.rb} +1 -1
  48. data/lib/fig/{environmentvariables.rb → environment_variables.rb} +0 -0
  49. data/lib/fig/{environmentvariables/caseinsensitive.rb → environment_variables/case_insensitive.rb} +1 -1
  50. data/lib/fig/{environmentvariables/casesensitive.rb → environment_variables/case_sensitive.rb} +1 -1
  51. data/lib/fig/figrc.rb +3 -3
  52. data/lib/fig/grammar.treetop +1 -1
  53. data/lib/fig/{backtrace.rb → include_backtrace.rb} +7 -2
  54. data/lib/fig/log4r/outputter.rb +1 -1
  55. data/lib/fig/{log4rconfigerror.rb → log4r_config_error.rb} +1 -1
  56. data/lib/fig/logging.rb +2 -2
  57. data/lib/fig/{networkerror.rb → network_error.rb} +1 -1
  58. data/lib/fig/{nosuchpackageconfigerror.rb → no_such_package_config_error.rb} +2 -2
  59. data/lib/fig/{notfounderror.rb → not_found_error.rb} +0 -0
  60. data/lib/fig/{operatingsystem.rb → operating_system.rb} +5 -5
  61. data/lib/fig/package.rb +3 -3
  62. data/lib/fig/{packagecache.rb → package_cache.rb} +0 -0
  63. data/lib/fig/{packagedescriptor.rb → package_descriptor.rb} +1 -1
  64. data/lib/fig/{packagedescriptorparseerror.rb → package_descriptor_parse_error.rb} +1 -1
  65. data/lib/fig/{packageparseerror.rb → package_parse_error.rb} +1 -1
  66. data/lib/fig/parser.rb +4 -4
  67. data/lib/fig/{parserpackagebuildstate.rb → parser_package_build_state.rb} +1 -1
  68. data/lib/fig/repository.rb +17 -17
  69. data/lib/fig/{repositoryerror.rb → repository_error.rb} +1 -1
  70. data/lib/fig/{environment.rb → runtime_environment.rb} +15 -8
  71. data/lib/fig/statement/include.rb +1 -1
  72. data/lib/fig/statement/override.rb +1 -1
  73. data/lib/fig/{urlaccesserror.rb → url_access_error.rb} +1 -1
  74. data/lib/fig/{userinputerror.rb → user_input_error.rb} +0 -0
  75. data/lib/fig/{workingdirectorymaintainer.rb → working_directory_maintainer.rb} +4 -4
  76. data/lib/fig/{workingdirectorymetadata.rb → working_directory_metadata.rb} +0 -0
  77. metadata +88 -54
  78. data/VERSION +0 -1
  79. data/lib/fig/command/listing.rb +0 -363
  80. data/lib/fig/command/packageload.rb +0 -236
@@ -0,0 +1,90 @@
1
+ require 'set'
2
+
3
+ require 'fig/include_backtrace'
4
+ require 'fig/package_descriptor'
5
+
6
+ module Fig; end
7
+ class Fig::Command; end
8
+ module Fig::Command::Action; end
9
+ module Fig::Command::Action::Role; end
10
+
11
+ module Fig::Command::Action::Role::ListWalkingDependencyTree
12
+ def walk_dependency_tree(base_package, config_names, backtrace, depth, &block)
13
+ config_names.each do
14
+ |config_name|
15
+
16
+ if depth < 1
17
+ @execution_context.repository.reset_cached_data
18
+ end
19
+
20
+ yield base_package, config_name, depth
21
+
22
+ new_backtrace = Fig::IncludeBacktrace.new(
23
+ backtrace,
24
+ Fig::PackageDescriptor.new(
25
+ base_package.name(),
26
+ base_package.version(),
27
+ config_name
28
+ )
29
+ )
30
+
31
+ base_package.package_dependencies(config_name, new_backtrace).each do
32
+ |descriptor|
33
+
34
+ package = nil
35
+ if descriptor.name
36
+ package =
37
+ @execution_context.repository.get_package(
38
+ descriptor, :allow_any_version
39
+ )
40
+ else
41
+ package = base_package
42
+ end
43
+
44
+ walk_dependency_tree(
45
+ package, [descriptor.config], new_backtrace, depth + 1, &block
46
+ )
47
+ end
48
+ end
49
+
50
+ return
51
+ end
52
+
53
+ def configure(options)
54
+ @descriptor = options.descriptor
55
+ end
56
+
57
+ def gather_package_dependency_configurations()
58
+ packages = {}
59
+ starting_config_names = base_display_config_names()
60
+ base_package = @execution_context.base_package
61
+
62
+ if ! base_package.name.nil?
63
+ packages[base_package] = starting_config_names.to_set
64
+ end
65
+
66
+ walk_dependency_tree(base_package, starting_config_names, nil, 0) do
67
+ |package, config_name, depth|
68
+
69
+ if (
70
+ ! package.name.nil? \
71
+ && ! (
72
+ ! list_all_configs? \
73
+ && @descriptor \
74
+ && package.name == @descriptor.name
75
+ )
76
+ )
77
+ packages[package] ||= Set.new
78
+ packages[package] << config_name
79
+ end
80
+ end
81
+
82
+ if ! list_all_configs? && @descriptor
83
+ packages.reject! do |package, config_names|
84
+ package.name == @descriptor.name
85
+ end
86
+ end
87
+
88
+ return packages
89
+ end
90
+ end
@@ -0,0 +1,90 @@
1
+ require 'fig/package'
2
+ require 'fig/statement/configuration'
3
+ require 'fig/user_input_error'
4
+
5
+ module Fig; end
6
+ class Fig::Command; end
7
+ module Fig::Command::Action; end
8
+ module Fig::Command::Action::Role; end
9
+
10
+ module Fig::Command::Action::Role::Publish
11
+ def descriptor_requirement()
12
+ return :required
13
+ end
14
+
15
+ def allow_both_descriptor_and_file?()
16
+ # Actually, publishing requires a descriptor and another source of the base
17
+ # package.
18
+ return true
19
+ end
20
+
21
+ def load_base_package?()
22
+ return true
23
+ end
24
+
25
+ def base_package_can_come_from_descriptor?()
26
+ return false
27
+ end
28
+
29
+ def register_base_package?()
30
+ return false
31
+ end
32
+
33
+ def apply_config?()
34
+ return true
35
+ end
36
+
37
+ def apply_base_config?()
38
+ return nil # don't care
39
+ end
40
+
41
+ def configure(options)
42
+ @descriptor = options.descriptor
43
+ @environment_statements = options.environment_statements
44
+ @package_contents_statements = options.package_contents_statements
45
+ @force = options.force?
46
+
47
+ return
48
+ end
49
+
50
+ def publish_preflight()
51
+ if @descriptor.name.nil? || @descriptor.version.nil?
52
+ raise Fig::UserInputError.new(
53
+ 'Please specify a package name and a version name.'
54
+ )
55
+ end
56
+ if @descriptor.name == '_meta'
57
+ raise Fig::UserInputError.new(
58
+ %q<Due to implementation issues, cannot create a package named "_meta".>
59
+ )
60
+ end
61
+
62
+ # TODO: fail on environment statements && --file because the --file will
63
+ # get ignored as far as statements are concerned.
64
+ publish_statements = nil
65
+ if not @environment_statements.empty?
66
+ @publish_statements =
67
+ @package_contents_statements +
68
+ [
69
+ Fig::Statement::Configuration.new(
70
+ nil,
71
+ nil,
72
+ Fig::Package::DEFAULT_CONFIG,
73
+ @environment_statements
74
+ )
75
+ ]
76
+ elsif not @package_contents_statements.empty?
77
+ raise Fig::UserInputError.new(
78
+ '--resource/--archive options were specified, but no --set/--append option was given. Will not publish.'
79
+ )
80
+ else
81
+ if not @execution_context.base_package.statements.empty?
82
+ @publish_statements = @execution_context.base_package.statements
83
+ else
84
+ raise Fig::UserInputError.new('Nothing to publish.')
85
+ end
86
+ end
87
+
88
+ return
89
+ end
90
+ end
@@ -0,0 +1,46 @@
1
+ require 'fig/command/action'
2
+
3
+ module Fig; end
4
+ class Fig::Command; end
5
+ module Fig::Command::Action; end
6
+ module Fig::Command::Action::Role; end
7
+
8
+ module Fig::Command::Action::Role::Update
9
+ def descriptor_requirement()
10
+ return nil
11
+ end
12
+
13
+ def allow_both_descriptor_and_file?()
14
+ # We don't care, so we let the base action say what it wants.
15
+ return true
16
+ end
17
+
18
+ def load_base_package?()
19
+ return true
20
+ end
21
+
22
+ def register_base_package?()
23
+ return true
24
+ end
25
+
26
+ def apply_config?()
27
+ return true
28
+ end
29
+
30
+ def apply_base_config?()
31
+ return true
32
+ end
33
+
34
+ def retrieves_should_happen?()
35
+ return true
36
+ end
37
+
38
+ def remote_operation_necessary?()
39
+ return true
40
+ end
41
+
42
+ def execute()
43
+ # Don't do anything.
44
+ return Fig::Command::Action::EXIT_SUCCESS
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ require 'fig/command/action'
2
+ require 'fig/command/action/role/has_no_sub_action'
3
+
4
+ module Fig; end
5
+ class Fig::Command; end
6
+ module Fig::Command::Action; end
7
+
8
+ class Fig::Command::Action::RunCommandLine
9
+ include Fig::Command::Action
10
+ include Fig::Command::Action::Role::HasNoSubAction
11
+
12
+ def options()
13
+ return %w<-->
14
+ end
15
+
16
+ def descriptor_requirement()
17
+ return nil
18
+ end
19
+
20
+ def load_base_package?()
21
+ return true
22
+ end
23
+
24
+ def register_base_package?()
25
+ return true
26
+ end
27
+
28
+ def apply_config?()
29
+ return true
30
+ end
31
+
32
+ def apply_base_config?()
33
+ return true
34
+ end
35
+
36
+ def configure(options)
37
+ @command_line = options.shell_command
38
+ end
39
+
40
+ def execute()
41
+ @execution_context.environment.execute_shell(@command_line) do
42
+ |command| @execution_context.operating_system.shell_exec command
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ require 'fig/command/action'
2
+ require 'fig/command/action/role/has_no_sub_action'
3
+
4
+ module Fig; end
5
+ class Fig::Command; end
6
+ module Fig::Command::Action; end
7
+
8
+ class Fig::Command::Action::RunCommandStatement
9
+ include Fig::Command::Action
10
+ include Fig::Command::Action::Role::HasNoSubAction
11
+
12
+ def options()
13
+ return %w<--command-extra-args>
14
+ end
15
+
16
+ def descriptor_requirement()
17
+ return nil
18
+ end
19
+
20
+ def load_base_package?()
21
+ return true
22
+ end
23
+
24
+ def register_base_package?()
25
+ return true
26
+ end
27
+
28
+ def apply_config?()
29
+ return true
30
+ end
31
+
32
+ def apply_base_config?()
33
+ return true
34
+ end
35
+
36
+ def configure(options)
37
+ @extra_argv = options.command_extra_argv
38
+ @descriptor = options.descriptor
39
+ end
40
+
41
+ def execute()
42
+ environment = @execution_context.environment
43
+ base_package = @execution_context.base_package
44
+
45
+ # TODO: Elliot's current theory is that this is pointless as long as
46
+ # we've applied the config.
47
+ environment.include_config(base_package, @descriptor, nil)
48
+ environment.execute_config(
49
+ base_package, @descriptor, @extra_argv || []
50
+ ) { |command| @execution_context.operating_system.shell_exec command }
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ require 'fig/command/action'
2
+ require 'fig/command/action/role/has_no_sub_action'
3
+ require 'fig/command/action/role/update'
4
+
5
+ module Fig; end
6
+ class Fig::Command; end
7
+ module Fig::Command::Action; end
8
+
9
+ class Fig::Command::Action::Update
10
+ include Fig::Command::Action
11
+ include Fig::Command::Action::Role::HasNoSubAction
12
+ include Fig::Command::Action::Role::Update
13
+
14
+ def options()
15
+ return %w<--update>
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'fig/command/action'
2
+ require 'fig/command/action/role/has_no_sub_action'
3
+ require 'fig/command/action/role/update'
4
+
5
+ module Fig; end
6
+ class Fig::Command; end
7
+ module Fig::Command::Action; end
8
+
9
+ class Fig::Command::Action::UpdateIfMissing
10
+ include Fig::Command::Action
11
+ include Fig::Command::Action::Role::HasNoSubAction
12
+ include Fig::Command::Action::Role::Update
13
+
14
+ def options()
15
+ return %w<--update-if-missing>
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'fig'
2
+ require 'fig/command'
3
+ require 'fig/command/action'
4
+ require 'fig/command/action/role/has_no_sub_action'
5
+
6
+ module Fig; end
7
+ class Fig::Command; end
8
+ module Fig::Command::Action; end
9
+
10
+ class Fig::Command::Action::Version
11
+ include Fig::Command::Action
12
+ include Fig::Command::Action::Role::HasNoSubAction
13
+
14
+ def options()
15
+ return %w<--version>
16
+ end
17
+
18
+ def execute_immediately_after_command_line_parse?
19
+ return true
20
+ end
21
+
22
+ def execute()
23
+ puts File.basename($0) + ' v' + Fig::VERSION
24
+
25
+ return EXIT_SUCCESS
26
+ end
27
+ end
@@ -1,4 +1,4 @@
1
- require 'fig/userinputerror'
1
+ require 'fig/user_input_error'
2
2
 
3
3
  module Fig; end
4
4
  class Fig::Command; end
@@ -1,8 +1,31 @@
1
1
  require 'optparse'
2
2
 
3
- require 'fig/command/optionerror'
3
+ require 'fig/command/action/clean'
4
+ require 'fig/command/action/get'
5
+ require 'fig/command/action/help'
6
+ require 'fig/command/action/list_configs'
7
+ require 'fig/command/action/list_dependencies'
8
+ require 'fig/command/action/list_dependencies/all_configs'
9
+ require 'fig/command/action/list_dependencies/default'
10
+ require 'fig/command/action/list_dependencies/tree'
11
+ require 'fig/command/action/list_dependencies/tree_all_configs'
12
+ require 'fig/command/action/list_local'
13
+ require 'fig/command/action/list_remote'
14
+ require 'fig/command/action/list_variables'
15
+ require 'fig/command/action/list_variables/all_configs'
16
+ require 'fig/command/action/list_variables/default'
17
+ require 'fig/command/action/list_variables/tree'
18
+ require 'fig/command/action/list_variables/tree_all_configs'
19
+ require 'fig/command/action/publish'
20
+ require 'fig/command/action/publish_local'
21
+ require 'fig/command/action/run_command_line'
22
+ require 'fig/command/action/run_command_statement'
23
+ require 'fig/command/action/update'
24
+ require 'fig/command/action/update_if_missing'
25
+ require 'fig/command/action/version'
26
+ require 'fig/command/option_error'
4
27
  require 'fig/package'
5
- require 'fig/packagedescriptor'
28
+ require 'fig/package_descriptor'
6
29
  require 'fig/statement/archive'
7
30
  require 'fig/statement/include'
8
31
  require 'fig/statement/path'
@@ -63,21 +86,50 @@ Environment variables:
63
86
  LOG_LEVELS = %w[ off fatal error warn info debug all ]
64
87
  LOG_ALIASES = { 'warning' => 'warn' }
65
88
 
89
+ # Public version of #strip_shell_command() here so that it can be kept in
90
+ # sync.
91
+ def self.strip_shell_command(argv)
92
+ argv.each_with_index do |arg, i|
93
+ found_command_line_end = false
94
+
95
+ case arg
96
+ when '--'
97
+ found_command_line_end = true
98
+ when '--command-extra-args'
99
+ found_command_line_end = true
100
+ end
101
+
102
+ if found_command_line_end
103
+ return argv.slice(i..-1)
104
+ end
105
+ end
106
+
107
+ return argv
108
+ end
109
+
66
110
  attr_reader :shell_command
67
111
  attr_reader :command_extra_argv
68
112
  attr_reader :descriptor
69
113
  attr_reader :exit_code
114
+ attr_reader :update_packages
70
115
 
71
116
  def initialize(argv)
72
117
  process_command_line(argv)
73
118
  end
74
119
 
75
- def archives()
76
- return @options[:archives]
77
- end
120
+ def actions()
121
+ actions = []
78
122
 
79
- def clean?()
80
- return @options[:clean]
123
+ # Update has got to come first so that the Repository knows what's going
124
+ # on.
125
+ if @update_action
126
+ actions << @update_action
127
+ end
128
+ if @base_action
129
+ actions << @base_action
130
+ end
131
+
132
+ return actions
81
133
  end
82
134
 
83
135
  def config()
@@ -92,30 +144,14 @@ Environment variables:
92
144
  return @options[:force]
93
145
  end
94
146
 
95
- def get()
96
- return @options[:get]
97
- end
98
-
99
- def help?()
100
- return @options[:help]
147
+ def variable_to_get()
148
+ return @options[:variable_to_get]
101
149
  end
102
150
 
103
151
  def home()
104
152
  return @options[:home]
105
153
  end
106
154
 
107
- def listing()
108
- return @options[:listing]
109
- end
110
-
111
- def list_tree?()
112
- return @options[:list_tree]
113
- end
114
-
115
- def list_all_configs?()
116
- return @options[:list_all_configs]
117
- end
118
-
119
155
  def log_config()
120
156
  return @options[:log_config]
121
157
  end
@@ -140,86 +176,21 @@ Environment variables:
140
176
  return @options[:package_definition_file]
141
177
  end
142
178
 
143
- def publish?()
144
- return @options[:publish]
145
- end
146
-
147
- def publish_local?()
148
- return @options[:publish_local]
149
- end
150
-
151
- def publishing?()
152
- return publish? || publish_local?
153
- end
154
-
155
- def resources()
156
- return @options[:resources]
179
+ def package_contents_statements()
180
+ return @options[:package_contents_statements]
157
181
  end
158
182
 
159
183
  def suppress_warning_include_statement_missing_version?()
160
184
  return @options[:suppress_warning_include_statement_missing_version]
161
185
  end
162
186
 
163
- def update?()
164
- return @options[:update]
165
- end
166
-
167
- def update_if_missing?()
168
- return @options[:update_if_missing]
169
- end
170
-
171
- def updating?()
172
- return update? || update_if_missing?
173
- end
174
-
175
- def version?()
176
- return @options[:version]
177
- end
178
-
179
- # Answers whether we should reset the environment to nothing, sort of like
180
- # the standardized environment that cron(1) creates. At present, we're only
181
- # setting this when we're listing variables. One could imagine allowing this
182
- # to be set by a command-line option in general; if we do this, the
183
- # Environment class will need to be changed to support deletion of values
184
- # from ENV.
185
- def reset_environment?()
186
- return listing() == :variables
187
- end
188
-
189
- # This needs to be public for efficient use of custom command.rb wrappers.
190
- def strip_shell_command(argv)
191
- argv.each_with_index do |arg, i|
192
- terminating_option = nil
193
-
194
- case arg
195
- when '--'
196
- terminating_option = arg
197
- @shell_command = argv[(i+1)..-1]
198
- when '--command-extra-args'
199
- terminating_option = arg
200
- @command_extra_argv = argv[(i+1)..-1]
201
- end
202
-
203
- if terminating_option
204
- argv.slice!(i..-1)
205
- break
206
- end
207
- end
208
-
209
- return
210
- end
211
-
212
- # This needs to be public for efficient use of custom command.rb wrappers.
213
- def help()
214
- puts @help_message
215
- puts <<-'END_MESSAGE'
187
+ def help_message()
188
+ return @help_message + <<-'END_MESSAGE'
216
189
  -- end of Fig options; anything after this is used as a command to run
217
190
  --command-extra-args end of Fig options; anything after this is appended to the end of a
218
191
  "command" statement in a "config" block.
219
192
 
220
193
  END_MESSAGE
221
-
222
- return 0
223
194
  end
224
195
 
225
196
  private
@@ -234,6 +205,14 @@ Environment variables:
234
205
  '--append' => Fig::Statement::Path::ARGUMENT_DESCRIPTION
235
206
  }
236
207
 
208
+ def list_tree?()
209
+ return @options[:list_tree]
210
+ end
211
+
212
+ def list_all_configs?()
213
+ return @options[:list_all_configs]
214
+ end
215
+
237
216
  def process_command_line(argv)
238
217
  argv = argv.clone
239
218
  strip_shell_command(argv)
@@ -271,6 +250,34 @@ Environment variables:
271
250
  end
272
251
 
273
252
  derive_primary_descriptor(argv.first)
253
+ if not @base_action and @descriptor
254
+ set_base_action(Fig::Command::Action::RunCommandStatement)
255
+ end
256
+ set_up_sub_actions()
257
+
258
+ actions().each {|action| action.configure(self)}
259
+
260
+ return
261
+ end
262
+
263
+ def strip_shell_command(argv)
264
+ argv.each_with_index do |arg, i|
265
+ terminating_option = nil
266
+
267
+ case arg
268
+ when '--'
269
+ set_base_action(Fig::Command::Action::RunCommandLine)
270
+ @shell_command = argv[(i+1)..-1]
271
+ when '--command-extra-args'
272
+ set_base_action(Fig::Command::Action::RunCommandStatement)
273
+ @command_extra_argv = argv[(i+1)..-1]
274
+ end
275
+
276
+ if @base_action
277
+ argv.slice!(i..-1)
278
+ break
279
+ end
280
+ end
274
281
 
275
282
  return
276
283
  end
@@ -324,11 +331,11 @@ Environment variables:
324
331
  @switches << parser.define_tail(
325
332
  '-?', '-h','--help','display this help text'
326
333
  ) do
327
- @options[:help] = true
334
+ set_base_action(Fig::Command::Action::Help)
328
335
  end
329
336
 
330
337
  @switches << parser.define_tail('-v', '--version', 'print Fig version') do
331
- @options[:version] = true
338
+ set_base_action(Fig::Command::Action::Version)
332
339
  end
333
340
 
334
341
  @switches << parser.define(
@@ -336,8 +343,9 @@ Environment variables:
336
343
  '--get VARIABLE',
337
344
  STARTS_WITH_NON_HYPHEN,
338
345
  'print value of environment variable VARIABLE'
339
- ) do |get|
340
- @options[:get] = get
346
+ ) do |variable_to_get|
347
+ set_base_action(Fig::Command::Action::Get)
348
+ @options[:variable_to_get] = variable_to_get
341
349
  end
342
350
 
343
351
  set_up_listings(parser)
@@ -347,40 +355,41 @@ Environment variables:
347
355
 
348
356
  def set_up_listings(parser)
349
357
  option_mapping = {
350
- :local_packages =>
351
- [ '--list-local', '--list', 'list packages in $FIG_HOME' ],
358
+ :local_packages => [
359
+ ['--list-local', '--list', 'list packages in $FIG_HOME'],
360
+ Fig::Command::Action::ListLocal
361
+ ],
352
362
 
353
- :configs =>
363
+ :configs => [
354
364
  ['--list-configs', 'list configurations'],
365
+ Fig::Command::Action::ListConfigs
366
+ ],
355
367
 
356
- :dependencies =>
368
+ :dependencies => [
357
369
  ['--list-dependencies', 'list package dependencies, recursively'],
370
+ Fig::Command::Action::ListDependencies
371
+ ],
358
372
 
359
- :variables =>
373
+ :variables => [
360
374
  [
361
375
  '--list-variables',
362
376
  'list all variables defined/used by package and its dependencies'
363
377
  ],
378
+ Fig::Command::Action::ListVariables
379
+ ],
364
380
 
365
- :remote_packages =>
366
- ['--list-remote', 'list packages in remote repo']
381
+ :remote_packages => [
382
+ ['--list-remote', 'list packages in remote repo'],
383
+ Fig::Command::Action::ListRemote
384
+ ],
367
385
  }
368
386
 
369
387
  option_mapping.each_pair do
370
- | type, specification |
388
+ | type, specification_action_class |
371
389
 
390
+ specification, action_class = *specification_action_class
372
391
  @switches << parser.define(*specification) do
373
- if @options[:listing]
374
- options_string =
375
- (
376
- option_mapping.values.collect {|specification| specification[0]}
377
- ).join(', ')
378
-
379
- $stderr.puts "Can only specify one of #{options_string}."
380
- @exit_code = 1
381
- else
382
- @options[:listing] = type
383
- end
392
+ set_base_action(action_class)
384
393
  end
385
394
  end
386
395
 
@@ -402,19 +411,19 @@ Environment variables:
402
411
 
403
412
  def set_up_commands(parser)
404
413
  @switches << parser.define('--clean', 'remove package from $FIG_HOME') do
405
- @options[:clean] = true
414
+ set_base_action(Fig::Command::Action::Clean)
406
415
  end
407
416
 
408
417
  @switches << parser.define(
409
418
  '--publish', 'install package in $FIG_HOME and in remote repo'
410
419
  ) do |publish|
411
- @options[:publish] = true
420
+ set_base_action(Fig::Command::Action::Publish)
412
421
  end
413
422
 
414
423
  @switches << parser.define(
415
424
  '--publish-local', 'install package only in $FIG_HOME'
416
425
  ) do |publish_local|
417
- @options[:publish_local] = true
426
+ set_base_action(Fig::Command::Action::PublishLocal)
418
427
  end
419
428
 
420
429
  return
@@ -525,23 +534,22 @@ Environment variables:
525
534
  end
526
535
 
527
536
  def set_up_package_contents_statements(parser)
528
- @options[:archives] = []
537
+ @options[:package_contents_statements] = []
529
538
  @switches << parser.define(
530
539
  '--archive PATH',
531
540
  STARTS_WITH_NON_HYPHEN,
532
541
  'include PATH archive in package (when using --publish)'
533
542
  ) do |path|
534
- @options[:archives] <<
543
+ @options[:package_contents_statements] <<
535
544
  Fig::Statement::Archive.new(nil, '--archive option', path)
536
545
  end
537
546
 
538
- @options[:resources] =[]
539
547
  @switches << parser.define(
540
548
  '--resource PATH',
541
549
  STARTS_WITH_NON_HYPHEN,
542
550
  'include PATH resource in package (when using --publish)'
543
551
  ) do |path|
544
- @options[:resources] <<
552
+ @options[:package_contents_statements] <<
545
553
  Fig::Statement::Resource.new(nil, '--resource option', path)
546
554
  end
547
555
 
@@ -554,7 +562,7 @@ Environment variables:
554
562
  '--update',
555
563
  'check remote repo for updates and download to $FIG_HOME as necessary'
556
564
  ) do
557
- @options[:update] = true
565
+ set_update_action(Fig::Command::Action::Update, :unconditionally)
558
566
  end
559
567
 
560
568
  @switches << parser.define(
@@ -562,7 +570,7 @@ Environment variables:
562
570
  '--update-if-missing',
563
571
  'check remote repo for updates only if package missing from $FIG_HOME'
564
572
  ) do
565
- @options[:update_if_missing] = true
573
+ set_update_action(Fig::Command::Action::UpdateIfMissing, :if_missing)
566
574
  end
567
575
 
568
576
  @switches << parser.define(
@@ -622,6 +630,39 @@ Environment variables:
622
630
  return
623
631
  end
624
632
 
633
+ def set_base_action(action_class)
634
+ action = action_class.new
635
+ # Help overrides anything.
636
+ if action_class == Fig::Command::Action::Help
637
+ @base_action = action
638
+ return
639
+ end
640
+
641
+ return if @base_action && @base_action == Fig::Command::Action::Help
642
+
643
+ if @base_action
644
+ raise Fig::Command::OptionError.new(
645
+ "Cannot specify both #{@base_action.primary_option()} and #{action.primary_option()}."
646
+ )
647
+ end
648
+
649
+ @base_action = action
650
+
651
+ return
652
+ end
653
+
654
+ def set_update_action(update_action_class, update_packages)
655
+ update_action = update_action_class.new
656
+ if @update_action
657
+ raise Fig::Command::OptionError.new(
658
+ "Cannot specify both #{@update_action.primary_option()} and #{update_action.primary_option()}."
659
+ )
660
+ end
661
+
662
+ @update_action = update_action
663
+ @update_packages = update_packages
664
+ end
665
+
625
666
  def new_variable_statement(option, name_value, statement_class)
626
667
  variable, value = statement_class.parse_name_value(name_value) {
627
668
  raise_invalid_argument(option, name_value)
@@ -630,8 +671,25 @@ Environment variables:
630
671
  return statement_class.new(nil, "#{option} option", variable, value)
631
672
  end
632
673
 
674
+ def set_up_sub_actions()
675
+ if @base_action and @base_action.sub_action?
676
+ # This is a cheat because the only things with sub-actions at present are
677
+ # --list-dependencies and --list-variables. This will need to be
678
+ # refactored if we get further sub-action actions.
679
+ sub_action_name = :Default
680
+ if list_tree?
681
+ sub_action_name = list_all_configs? ? :TreeAllConfigs : :Tree
682
+ elsif list_all_configs?
683
+ sub_action_name = :AllConfigs
684
+ end
685
+
686
+ @base_action.sub_action =
687
+ @base_action.class.const_get(sub_action_name).new
688
+ end
689
+ end
690
+
633
691
  # This will be the base package, unless we're publishing (in which case it's
634
- # the name to publish to.
692
+ # the name to publish to).
635
693
  def derive_primary_descriptor(raw_string)
636
694
  return if raw_string.nil?
637
695