fig 0.1.67 → 0.1.69

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/Changes CHANGED
@@ -1,3 +1,65 @@
1
+ v0.1.69
2
+
3
+ Backwards incompatibilities:
4
+
5
+ - While publishing, you cannot simultaneously have a package definition file
6
+ (e.g. "package.fig") and use environment variable options (--set/--append).
7
+ Previous to now, any package definition file would simply be ignored and
8
+ the publish would happen based upon the environment variable options.
9
+
10
+ - Easier to understand, yet unlikely to already exist case:
11
+
12
+ fig package/1.2.3 --publish --set VARIABLE=VALUE --file non-default.fig
13
+
14
+ Is this supposed to mean publish based upon the --set option or the
15
+ --file option? Again, it was the former, but that was non-obvious.
16
+
17
+ - More likely existing case:
18
+
19
+ fig package/1.2.3 --publish --set VARIABLE=VALUE
20
+
21
+ while there is a "package.fig" file in the current directory.
22
+ Workaround: use the "--no-file" option:
23
+
24
+ fig package/1.2.3 --publish --set VARIABLE=VALUE --no-file
25
+
26
+ Just to be clear, it's perfectly fine (and useful) to have combined a
27
+ package definition file and environment variable options when not
28
+ publishing.
29
+
30
+ New feature (and backwards incompatibility):
31
+
32
+ - Locks FIG_HOME when updating. (Or attempts to. If FIG_HOME is on NFS, all
33
+ bets are off.) By default, if Fig is updating and notices another instance
34
+ updating, it will fail. You can override this behavior via
35
+ --update-lock-response. Specify "wait" to get Fig to wait for lock release
36
+ or "ignore" for it to skip lock checking.
37
+
38
+ The default behavior of failing was chosen to prevent surprises in the
39
+ scenario of starting multiple servers out of the same directory:
40
+
41
+ for exchange in cme ice liffe cboe
42
+ do
43
+ fig --update -- run-server $exchange &
44
+ done
45
+
46
+ If Fig defaulted to waiting, the above scenario would silently cause three
47
+ out of the four servers to block until the other one's updates were
48
+ finished.
49
+
50
+ Bug fixes:
51
+
52
+ - Specifying --update with FIG_REMOTE_URL using FTP should be fast as it used
53
+ to be.
54
+
55
+ - Skips retrieving directories and files to themselves. (Tragic accident of
56
+ retrieving "." onto itself resulted in a corrupted git repo.)
57
+
58
+ v0.1.68.beta.2
59
+ v0.1.68.beta.1
60
+
61
+ - Test releases
62
+
1
63
  v0.1.67
2
64
 
3
65
  Backwards incompatibilities:
@@ -462,7 +524,7 @@ v0.1.42
462
524
 
463
525
  - Fig::Package refactoring.
464
526
 
465
- - "file:" protocol works for FIG_REMOTE_HOME.
527
+ - "file:" protocol works for FIG_REMOTE_URL.
466
528
 
467
529
  - Testing no longer requires ssh.
468
530
 
data/lib/fig.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fig
2
- VERSION = '0.1.67'
2
+ VERSION = '0.1.69'
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'rubygems'
1
+ require 'fileutils'
2
2
  require 'net/ftp'
3
3
  require 'set'
4
4
 
@@ -16,6 +16,7 @@ require 'fig/repository'
16
16
  require 'fig/repository_error'
17
17
  require 'fig/runtime_environment'
18
18
  require 'fig/statement/configuration'
19
+ require 'fig/update_lock'
19
20
  require 'fig/user_input_error'
20
21
  require 'fig/working_directory_maintainer'
21
22
 
@@ -23,9 +24,10 @@ module Fig; end
23
24
 
24
25
  # Main program
25
26
  class Fig::Command
26
- def run_fig(argv)
27
+ def run_fig(argv, options = nil)
27
28
  begin
28
- @options = Fig::Command::Options.new(argv)
29
+ @options = options || Fig::Command::Options.new()
30
+ @options.process_command_line(argv)
29
31
  rescue Fig::UserInputError => error
30
32
  $stderr.puts error.to_s # Logging isn't set up yet.
31
33
  return Fig::Command::Action::EXIT_FAILURE
@@ -67,7 +69,8 @@ class Fig::Command
67
69
  base_config(),
68
70
  @environment,
69
71
  @repository,
70
- @operating_system
72
+ @operating_system,
73
+ @package_source_description
71
74
  )
72
75
 
73
76
  actions.each do
@@ -84,25 +87,40 @@ class Fig::Command
84
87
  return Fig::Command::Action::EXIT_SUCCESS
85
88
  end
86
89
 
87
- def run_with_exception_handling(argv)
90
+ def run_with_exception_handling(argv, options = nil)
88
91
  begin
89
- return_code = run_fig(argv)
90
- return return_code
92
+ return run_fig(argv, options)
91
93
  rescue Fig::URLAccessError => error
92
94
  urls = error.urls.join(', ')
93
- $stderr.puts "Access to #{urls} in #{error.package}/#{error.version} not allowed."
94
- return Fig::Command::Action::EXIT_FAILURE
95
+ $stderr.puts \
96
+ "Access to #{urls} in #{error.package}/#{error.version} not allowed."
95
97
  rescue Fig::UserInputError => error
96
98
  log_error_message(error)
97
- return Fig::Command::Action::EXIT_FAILURE
98
99
  end
100
+
101
+ return Fig::Command::Action::EXIT_FAILURE
102
+ end
103
+
104
+ def add_publish_listener(listener)
105
+ @publish_listeners << listener
106
+
107
+ return
108
+ end
109
+
110
+ def initialize()
111
+ @publish_listeners = []
99
112
  end
100
113
 
101
114
  private
102
115
 
103
116
  ExecutionContext =
104
117
  Struct.new(
105
- :base_package, :base_config, :environment, :repository, :operating_system
118
+ :base_package,
119
+ :base_config,
120
+ :environment,
121
+ :repository,
122
+ :operating_system,
123
+ :package_source_description
106
124
  )
107
125
 
108
126
  def derive_remote_url()
@@ -119,17 +137,18 @@ class Fig::Command
119
137
  def check_include_statements_versions?()
120
138
  return false if @options.suppress_warning_include_statement_missing_version?
121
139
 
122
- suppressed_warnings = @configuration['suppress warnings']
140
+ suppressed_warnings = @application_configuration['suppress warnings']
123
141
  return true if not suppressed_warnings
124
142
 
125
143
  return ! suppressed_warnings.include?('include statement missing version')
126
144
  end
127
145
 
128
146
  def configure()
147
+ set_up_update_lock()
129
148
  set_up_application_configuration()
130
149
 
131
150
  Fig::Logging.initialize_post_configuration(
132
- @options.log_config() || @configuration['log configuration'],
151
+ @options.log_config() || @application_configuration['log configuration'],
133
152
  @options.log_level()
134
153
  )
135
154
 
@@ -139,8 +158,23 @@ class Fig::Command
139
158
  prepare_environment()
140
159
  end
141
160
 
161
+ def set_up_update_lock()
162
+ return if not @options.update_packages
163
+
164
+ update_lock_response = @options.update_lock_response
165
+ return if update_lock_response == :ignore
166
+
167
+ @update_lock = Fig::UpdateLock.new(@options.home, update_lock_response)
168
+
169
+ # *sigh* Ruby 1.8 doesn't support close_on_exec(), so we've got to ensure
170
+ # this stuff on our own.
171
+ Fig::AtExit.add { @update_lock.close }
172
+
173
+ return
174
+ end
175
+
142
176
  def set_up_application_configuration()
143
- @configuration = Fig::FigRC.find(
177
+ @application_configuration = Fig::FigRC.find(
144
178
  @options.figrc(),
145
179
  derive_remote_url(),
146
180
  @options.login?,
@@ -155,8 +189,8 @@ class Fig::Command
155
189
  @repository = Fig::Repository.new(
156
190
  @operating_system,
157
191
  @options.home(),
158
- @configuration,
159
- nil, # remote_user
192
+ @application_configuration,
193
+ @publish_listeners,
160
194
  check_include_statements_versions?
161
195
  )
162
196
 
@@ -209,8 +243,9 @@ class Fig::Command
209
243
  else
210
244
  @base_package = package_loader.load_package_object_from_file()
211
245
  end
246
+ @package_source_description = package_loader.package_source_description()
212
247
 
213
- applier = new_package_applier(package_loader.package_source_description())
248
+ applier = new_package_applier()
214
249
 
215
250
  if retrieves_should_happen
216
251
  applier.activate_retrieves()
@@ -233,7 +268,7 @@ class Fig::Command
233
268
 
234
269
  def new_package_loader()
235
270
  return Fig::Command::PackageLoader.new(
236
- @configuration,
271
+ @application_configuration,
237
272
  @descriptor,
238
273
  @options.package_definition_file,
239
274
  base_config(),
@@ -241,20 +276,20 @@ class Fig::Command
241
276
  )
242
277
  end
243
278
 
244
- def new_package_applier(package_source_description)
279
+ def new_package_applier()
245
280
  return Fig::Command::PackageApplier.new(
246
281
  @base_package,
247
282
  @environment,
248
283
  @options,
249
284
  @descriptor,
250
285
  base_config(),
251
- package_source_description
286
+ @package_source_description
252
287
  )
253
288
  end
254
289
 
255
- # If the user has specified a descriptor, than any package.fig or --file
256
- # option is ignored. Thus, in order to avoid confusing the user, we make
257
- # specifying both an error.
290
+ # If the user has specified a descriptor and we are not publishing, than any
291
+ # package.fig or --file option is ignored. Thus, in order to avoid confusing
292
+ # the user, we make specifying both an error.
258
293
  def ensure_descriptor_and_file_were_not_both_specified()
259
294
  file = @options.package_definition_file()
260
295
 
@@ -263,7 +298,7 @@ class Fig::Command
263
298
  # processed.
264
299
  file_specified = ! file.nil? && file != :none
265
300
 
266
- if @descriptor and file_specified
301
+ if @descriptor && file_specified
267
302
  raise Fig::UserInputError.new(
268
303
  %Q<Cannot specify both a package descriptor (#{@descriptor.original_string}) and the --file option (#{file}).>
269
304
  )
@@ -1,6 +1,13 @@
1
1
  module Fig; end
2
2
  class Fig::Command; end
3
3
 
4
+ # One of the main activities Fig should do as part of the current run.
5
+ #
6
+ # This exists because the code used to have complicated logic about whether a
7
+ # package.fig should be read, whether the Package object should be loaded,
8
+ # should a config be applied, when should some activity happen, etc. Now, we
9
+ # let the Action object say what it wants in terms of setup and then tell it to
10
+ # do whatever it needs to.
4
11
  module Fig::Command::Action
5
12
  EXIT_SUCCESS = 0
6
13
  EXIT_FAILURE = 1
@@ -34,7 +34,7 @@ class Fig::Command::Action::Publish
34
34
  Fig::Logging.info "#{@descriptor.to_string()} has already been published."
35
35
 
36
36
  if not @force
37
- raise UserInputError.new(
37
+ raise Fig::UserInputError.new(
38
38
  'Use the --force option if you really want to overwrite.'
39
39
  )
40
40
  else
@@ -44,7 +44,11 @@ class Fig::Command::Action::Publish
44
44
 
45
45
  Fig::Logging.info "Publishing #{@descriptor.to_string()}."
46
46
  @execution_context.repository.publish_package(
47
- @publish_statements, @descriptor, false
47
+ @publish_statements,
48
+ @descriptor,
49
+ false,
50
+ @execution_context.base_package,
51
+ @force
48
52
  )
49
53
 
50
54
  return EXIT_SUCCESS
@@ -21,7 +21,11 @@ class Fig::Command::Action::PublishLocal
21
21
 
22
22
  Fig::Logging.info "Publishing #{@descriptor.to_string()}."
23
23
  @execution_context.repository.publish_package(
24
- @publish_statements, @descriptor, :publish_local
24
+ @publish_statements,
25
+ @descriptor,
26
+ :publish_local,
27
+ @execution_context.base_package,
28
+ false
25
29
  )
26
30
 
27
31
  return EXIT_SUCCESS
@@ -1,3 +1,4 @@
1
+ require 'fig/command/package_loader'
1
2
  require 'fig/package'
2
3
  require 'fig/statement/configuration'
3
4
  require 'fig/user_input_error'
@@ -59,20 +60,8 @@ module Fig::Command::Action::Role::Publish
59
60
  )
60
61
  end
61
62
 
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
63
  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
- ]
64
+ derive_publish_statements_from_environment_statements
76
65
  elsif not @package_contents_statements.empty?
77
66
  raise Fig::UserInputError.new(
78
67
  '--resource/--archive options were specified, but no --set/--append option was given. Will not publish.'
@@ -87,4 +76,36 @@ module Fig::Command::Action::Role::Publish
87
76
 
88
77
  return
89
78
  end
79
+
80
+ def derive_publish_statements_from_environment_statements
81
+ if @execution_context.package_source_description
82
+ message = 'Cannot publish based upon both a package definition file ('
83
+ message << @execution_context.package_source_description
84
+ message << ') and --set/--append options.'
85
+
86
+ if @execution_context.package_source_description ==
87
+ Fig::Command::PackageLoader::DEFAULT_FIG_FILE
88
+
89
+ message << "\n\n"
90
+ message << 'You can avoid loading '
91
+ message << Fig::Command::PackageLoader::DEFAULT_FIG_FILE
92
+ message << ' by using the --no-file option.'
93
+ end
94
+
95
+ raise Fig::UserInputError.new(message)
96
+ end
97
+
98
+ @publish_statements =
99
+ @package_contents_statements +
100
+ [
101
+ Fig::Statement::Configuration.new(
102
+ nil,
103
+ nil,
104
+ Fig::Package::DEFAULT_CONFIG,
105
+ @environment_statements
106
+ )
107
+ ]
108
+
109
+ return
110
+ end
90
111
  end
@@ -19,8 +19,12 @@ class Fig::Command::Action::Version
19
19
  return true
20
20
  end
21
21
 
22
+ def configure(options)
23
+ @version_message = options.version_message
24
+ end
25
+
22
26
  def execute()
23
- puts File.basename($0) + ' v' + Fig::VERSION
27
+ puts @version_message || File.basename($0) + ' v' + Fig::VERSION
24
28
 
25
29
  return EXIT_SUCCESS
26
30
  end
@@ -1,5 +1,3 @@
1
- require 'optparse'
2
-
3
1
  require 'fig/command/action/clean'
4
2
  require 'fig/command/action/get'
5
3
  require 'fig/command/action/help'
@@ -24,7 +22,7 @@ require 'fig/command/action/update'
24
22
  require 'fig/command/action/update_if_missing'
25
23
  require 'fig/command/action/version'
26
24
  require 'fig/command/option_error'
27
- require 'fig/package'
25
+ require 'fig/command/options/parser'
28
26
  require 'fig/package_descriptor'
29
27
  require 'fig/statement/archive'
30
28
  require 'fig/statement/include'
@@ -37,55 +35,6 @@ class Fig::Command; end
37
35
 
38
36
  # Command-line processing.
39
37
  class Fig::Command::Options
40
- USAGE = <<-EOF
41
- Usage:
42
-
43
- fig [...] [DESCRIPTOR] [--update | --update-if-missing] [-- COMMAND]
44
- fig [...] [DESCRIPTOR] [--update | --update-if-missing] [--command-extra-args VALUES]
45
-
46
- fig {--publish | --publish-local} DESCRIPTOR
47
- [--resource PATH]
48
- [--archive PATH]
49
- [--include DESCRIPTOR]
50
- [--override DESCRIPTOR]
51
- [--force]
52
- [...]
53
-
54
- fig --clean DESCRIPTOR [...]
55
-
56
- fig --get VARIABLE [DESCRIPTOR] [...]
57
- fig --list-configs [DESCRIPTOR] [...]
58
- fig --list-dependencies [--list-tree] [--list-all-configs] [DESCRIPTOR] [...]
59
- fig --list-variables [--list-tree] [--list-all-configs] [DESCRIPTOR] [...]
60
- fig {--list-local | --list-remote} [...]
61
-
62
- fig {--version | --help}
63
-
64
-
65
- A DESCRIPTOR looks like <package name>[/<version>][:<config>] e.g. "foo",
66
- "foo/1.2.3", and "foo/1.2.3:default". Whether ":<config>" and "/<version>" are
67
- required or allowed is dependent upon what your are doing.
68
-
69
- Standard options (represented as "[...]" above):
70
-
71
- [--set VARIABLE=VALUE]
72
- [--append VARIABLE=VALUE]
73
- [--file PATH] [--no-file]
74
- [--config CONFIG]
75
- [--login]
76
- [--log-level LEVEL] [--log-config PATH]
77
- [--figrc PATH] [--no-figrc]
78
- [--suppress-warning-include-statement-missing-version]
79
-
80
- Environment variables:
81
-
82
- FIG_REMOTE_URL (required),
83
- FIG_HOME (path to local repository cache, defaults to $HOME/.fighome).
84
- EOF
85
-
86
- LOG_LEVELS = %w[ off fatal error warn info debug all ]
87
- LOG_ALIASES = { 'warning' => 'warn' }
88
-
89
38
  # Public version of #strip_shell_command() here so that it can be kept in
90
39
  # sync.
91
40
  def self.strip_shell_command(argv)
@@ -107,14 +56,57 @@ Environment variables:
107
56
  return argv
108
57
  end
109
58
 
110
- attr_reader :shell_command
111
- attr_reader :command_extra_argv
112
- attr_reader :descriptor
113
- attr_reader :exit_code
114
- attr_reader :update_packages
59
+ attr_reader :command_extra_argv
60
+ attr_reader :config
61
+ attr_reader :descriptor
62
+ attr_reader :environment_statements
63
+ attr_reader :exit_code
64
+ attr_reader :figrc
65
+ attr_reader :home
66
+ attr_reader :log_config
67
+ attr_reader :log_level
68
+ attr_reader :package_contents_statements
69
+ attr_reader :package_definition_file
70
+ attr_reader :parser
71
+ attr_reader :shell_command
72
+ attr_reader :update_lock_response
73
+ attr_reader :update_packages
74
+ attr_reader :variable_to_get
75
+ attr_accessor :version_message
76
+
77
+ def initialize()
78
+ @home = ENV['FIG_HOME'] || File.expand_path('~/.fighome')
79
+ @parser = Fig::Command::Options::Parser.new()
80
+ end
81
+
82
+ def process_command_line(argv)
83
+ argv = argv.clone
84
+ strip_shell_command(argv)
85
+
86
+ set_up_parser()
87
+ @help_message = @parser.help
88
+
89
+ @parser.parse!(argv)
90
+
91
+ if not exit_code.nil?
92
+ return
93
+ end
94
+
95
+ if argv.size > 1
96
+ $stderr.puts %q<Extra arguments. Should only have a package/version after all other options. Had "> + argv.join(%q<", ">) + %q<" left over.>
97
+ @exit_code = 1
98
+ return
99
+ end
100
+
101
+ derive_primary_descriptor(argv.first)
102
+ if not @base_action and @descriptor
103
+ set_base_action(Fig::Command::Action::RunCommandStatement)
104
+ end
105
+ set_up_sub_actions()
115
106
 
116
- def initialize(argv)
117
- process_command_line(argv)
107
+ actions().each {|action| action.configure(self)}
108
+
109
+ return
118
110
  end
119
111
 
120
112
  def actions()
@@ -132,65 +124,29 @@ Environment variables:
132
124
  return actions
133
125
  end
134
126
 
135
- def config()
136
- return @options[:config]
137
- end
138
-
139
- def figrc()
140
- return @options[:figrc]
141
- end
142
-
143
127
  def force?()
144
- return @options[:force]
128
+ return @force
145
129
  end
146
130
 
147
- def variable_to_get()
148
- return @options[:variable_to_get]
149
- end
150
-
151
- def home()
152
- return @options[:home]
153
- end
131
+ def help_message()
132
+ return @help_message + <<-'END_MESSAGE'
133
+ -- end of Fig options; anything after this is used as a command to run
134
+ --command-extra-args end of Fig options; anything after this is appended to the end of a
135
+ "command" statement in a "config" block.
154
136
 
155
- def log_config()
156
- return @options[:log_config]
137
+ END_MESSAGE
157
138
  end
158
139
 
159
140
  def login?()
160
- return @options[:login]
161
- end
162
-
163
- def log_level()
164
- return @options[:log_level]
141
+ return @login
165
142
  end
166
143
 
167
144
  def no_figrc?()
168
- return @options[:no_figrc]
169
- end
170
-
171
- def environment_statements()
172
- return @options[:environment_statements]
173
- end
174
-
175
- def package_definition_file()
176
- return @options[:package_definition_file]
177
- end
178
-
179
- def package_contents_statements()
180
- return @options[:package_contents_statements]
145
+ return @no_figrc
181
146
  end
182
147
 
183
148
  def suppress_warning_include_statement_missing_version?()
184
- return @options[:suppress_warning_include_statement_missing_version]
185
- end
186
-
187
- def help_message()
188
- return @help_message + <<-'END_MESSAGE'
189
- -- end of Fig options; anything after this is used as a command to run
190
- --command-extra-args end of Fig options; anything after this is appended to the end of a
191
- "command" statement in a "config" block.
192
-
193
- END_MESSAGE
149
+ return @suppress_warning_include_statement_missing_version
194
150
  end
195
151
 
196
152
  private
@@ -200,64 +156,12 @@ Environment variables:
200
156
  # regex with "\A" and "\z".
201
157
  STARTS_WITH_NON_HYPHEN = %r< \A [^-] .* >x
202
158
 
203
- ARGUMENT_DESCRIPTION = {
204
- '--set' => Fig::Statement::Set::ARGUMENT_DESCRIPTION,
205
- '--append' => Fig::Statement::Path::ARGUMENT_DESCRIPTION
206
- }
207
-
208
- def list_tree?()
209
- return @options[:list_tree]
210
- end
211
-
212
159
  def list_all_configs?()
213
- return @options[:list_all_configs]
160
+ return @list_all_configs
214
161
  end
215
162
 
216
- def process_command_line(argv)
217
- argv = argv.clone
218
- strip_shell_command(argv)
219
-
220
- @switches = []
221
- @options = {}
222
-
223
- @options[:home] = ENV['FIG_HOME'] || File.expand_path('~/.fighome')
224
-
225
- parser = new_parser()
226
- @help_message = parser.help
227
-
228
- begin
229
- parser.parse!(argv)
230
- rescue OptionParser::InvalidArgument => error
231
- raise_invalid_argument(error.args[0], error.args[1])
232
- rescue OptionParser::MissingArgument => error
233
- raise_missing_argument(error.args[0])
234
- rescue OptionParser::InvalidOption => error
235
- raise Fig::Command::OptionError.new(
236
- "Unknown option #{error.args[0]}.\n\n#{USAGE}"
237
- )
238
- rescue OptionParser::ParseError => error
239
- raise Fig::Command::OptionError.new(error.to_s)
240
- end
241
-
242
- if not exit_code.nil?
243
- return
244
- end
245
-
246
- if argv.size > 1
247
- $stderr.puts %q<Extra arguments. Should only have a package/version after all other options. Had "> + argv.join(%q<", ">) + %q<" left over.>
248
- @exit_code = 1
249
- return
250
- end
251
-
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
163
+ def list_tree?()
164
+ return @list_tree
261
165
  end
262
166
 
263
167
  def strip_shell_command(argv)
@@ -282,78 +186,45 @@ Environment variables:
282
186
  return
283
187
  end
284
188
 
285
- def raise_missing_argument(option)
286
- raise Fig::Command::OptionError.new(
287
- "Please provide a value for #{option}."
288
- )
289
- end
189
+ def set_up_parser
190
+ set_up_queries()
191
+ set_up_commands()
192
+ set_up_package_configuration_source()
193
+ set_up_environment_statements()
194
+ set_up_package_contents_statements()
195
+ set_up_remote_repository_access()
196
+ set_up_program_configuration()
290
197
 
291
- def raise_invalid_argument(option, value)
292
- # *sigh* OptionParser does not raise MissingArgument for the case of an
293
- # option with a required value being followed by another option. It
294
- # assigns the next option as the value instead. E.g. for
295
- #
296
- # fig --set --get FOO
297
- #
298
- # it assigns "--get" as the value of the "--set" option.
299
- switch_strings =
300
- (@switches.collect {|switch| [switch.short, switch.long]}).flatten
301
- if switch_strings.any? {|string| string == value}
302
- raise_missing_argument(option)
303
- end
304
-
305
- description = ARGUMENT_DESCRIPTION[option]
306
- if description.nil?
307
- description = ''
308
- else
309
- description = ' ' + description
310
- end
311
-
312
- raise Fig::Command::OptionError.new(
313
- %Q<Invalid value for #{option}: "#{value}".#{description}>
314
- )
315
- end
316
-
317
- def new_parser
318
- return OptionParser.new do |parser|
319
- set_up_queries(parser)
320
- set_up_commands(parser)
321
- set_up_package_configuration_source(parser)
322
- set_up_environment_statements(parser)
323
- set_up_package_contents_statements(parser)
324
- set_up_remote_repository_access(parser)
325
- set_up_program_configuration(parser)
326
- end
198
+ return
327
199
  end
328
200
 
329
- def set_up_queries(parser)
330
- parser.banner = "#{USAGE}\n"
331
- @switches << parser.define_tail(
201
+ def set_up_queries()
202
+ @parser.on_tail(
332
203
  '-?', '-h','--help','display this help text'
333
204
  ) do
334
205
  set_base_action(Fig::Command::Action::Help)
335
206
  end
336
207
 
337
- @switches << parser.define_tail('-v', '--version', 'print Fig version') do
208
+ @parser.on_tail('-v', '--version', 'print Fig version') do
338
209
  set_base_action(Fig::Command::Action::Version)
339
210
  end
340
211
 
341
- @switches << parser.define(
212
+ @parser.on(
342
213
  '-g',
343
214
  '--get VARIABLE',
344
215
  STARTS_WITH_NON_HYPHEN,
345
216
  'print value of environment variable VARIABLE'
346
217
  ) do |variable_to_get|
347
218
  set_base_action(Fig::Command::Action::Get)
348
- @options[:variable_to_get] = variable_to_get
219
+ @variable_to_get = variable_to_get
349
220
  end
350
221
 
351
- set_up_listings(parser)
222
+ set_up_listings()
352
223
 
353
224
  return
354
225
  end
355
226
 
356
- def set_up_listings(parser)
227
+ def set_up_listings()
357
228
  option_mapping = {
358
229
  :local_packages => [
359
230
  ['--list-local', '--list', 'list packages in $FIG_HOME'],
@@ -388,39 +259,39 @@ Environment variables:
388
259
  | type, specification_action_class |
389
260
 
390
261
  specification, action_class = *specification_action_class
391
- @switches << parser.define(*specification) do
262
+ @parser.on(*specification) do
392
263
  set_base_action(action_class)
393
264
  end
394
265
  end
395
266
 
396
- @switches << parser.define(
267
+ @parser.on(
397
268
  '--list-tree', 'for listings, output a tree instead of a list'
398
269
  ) do
399
- @options[:list_tree] = true
270
+ @list_tree = true
400
271
  end
401
272
 
402
- @switches << parser.define(
273
+ @parser.on(
403
274
  '--list-all-configs',
404
275
  'for listings, follow all configurations of the base package'
405
276
  ) do
406
- @options[:list_all_configs] = true
277
+ @list_all_configs = true
407
278
  end
408
279
 
409
280
  return
410
281
  end
411
282
 
412
- def set_up_commands(parser)
413
- @switches << parser.define('--clean', 'remove package from $FIG_HOME') do
283
+ def set_up_commands()
284
+ @parser.on('--clean', 'remove package from $FIG_HOME') do
414
285
  set_base_action(Fig::Command::Action::Clean)
415
286
  end
416
287
 
417
- @switches << parser.define(
288
+ @parser.on(
418
289
  '--publish', 'install package in $FIG_HOME and in remote repo'
419
290
  ) do |publish|
420
291
  set_base_action(Fig::Command::Action::Publish)
421
292
  end
422
293
 
423
- @switches << parser.define(
294
+ @parser.on(
424
295
  '--publish-local', 'install package only in $FIG_HOME'
425
296
  ) do |publish_local|
426
297
  set_base_action(Fig::Command::Action::PublishLocal)
@@ -439,57 +310,63 @@ Environment variables:
439
310
  \z
440
311
  >x
441
312
 
442
- def set_up_package_configuration_source(parser)
443
- @switches << parser.define(
313
+ def set_up_package_configuration_source()
314
+ @parser.on(
444
315
  '-c',
445
316
  '--config CONFIG',
446
317
  STARTS_WITH_NON_HYPHEN,
447
318
  %q<apply configuration CONFIG, default is "default">
448
319
  ) do |config|
449
- @options[:config] = config
320
+ @config = config
450
321
  end
451
322
 
452
- @options[:package_definition_file] = nil
453
- @switches << parser.define(
323
+ @package_definition_file = nil
324
+ @parser.on(
454
325
  '--file FILE',
455
326
  FILE_OPTION_VALUE_PATTERN,
456
327
  %q<read Fig file FILE. Use '-' for stdin. See also --no-file>
457
328
  ) do |path|
458
- @options[:package_definition_file] = path
329
+ @package_definition_file = path
459
330
  end
460
331
 
461
- @switches << parser.define(
332
+ @parser.on(
462
333
  '--no-file', 'ignore package.fig file in current directory'
463
334
  ) do |path|
464
- @options[:package_definition_file] = :none
335
+ @package_definition_file = :none
465
336
  end
466
337
 
467
338
  return
468
339
  end
469
340
 
470
- def set_up_environment_statements(parser)
471
- @options[:environment_statements] = []
472
- @switches << parser.define(
341
+ def set_up_environment_statements()
342
+ @environment_statements = []
343
+ @parser.on(
473
344
  '-p',
474
345
  '--append VARIABLE=VALUE',
475
346
  STARTS_WITH_NON_HYPHEN,
476
347
  'append (actually, prepend) VALUE to PATH-like environment variable VARIABLE'
477
348
  ) do |name_value|
478
- @options[:environment_statements] <<
349
+ @environment_statements <<
479
350
  new_variable_statement('--append', name_value, Fig::Statement::Path)
480
351
  end
352
+ @parser.add_argument_description(
353
+ %w<-p --append>, Fig::Statement::Path::ARGUMENT_DESCRIPTION
354
+ )
481
355
 
482
- @switches << parser.define(
356
+ @parser.on(
483
357
  '-s',
484
358
  '--set VARIABLE=VALUE',
485
359
  STARTS_WITH_NON_HYPHEN,
486
360
  'set environment variable VARIABLE to VALUE'
487
361
  ) do |name_value|
488
- @options[:environment_statements] <<
362
+ @environment_statements <<
489
363
  new_variable_statement('--set', name_value, Fig::Statement::Set)
490
364
  end
365
+ @parser.add_argument_description(
366
+ %w<-s --set>, Fig::Statement::Set::ARGUMENT_DESCRIPTION
367
+ )
491
368
 
492
- @switches << parser.define(
369
+ @parser.on(
493
370
  '-i',
494
371
  '--include DESCRIPTOR',
495
372
  STARTS_WITH_NON_HYPHEN,
@@ -509,10 +386,10 @@ Environment variables:
509
386
  # We've never allowed versionless includes from the command-line. Hooray!
510
387
  statement.complain_if_version_missing()
511
388
 
512
- @options[:environment_statements] << statement
389
+ @environment_statements << statement
513
390
  end
514
391
 
515
- @switches << parser.define(
392
+ @parser.on(
516
393
  '--override DESCRIPTOR',
517
394
  STARTS_WITH_NON_HYPHEN,
518
395
  'dictate version of package as specified in DESCRIPTOR'
@@ -527,37 +404,37 @@ Environment variables:
527
404
  nil, '--override option', descriptor.name, descriptor.version
528
405
  )
529
406
 
530
- @options[:environment_statements] << statement
407
+ @environment_statements << statement
531
408
  end
532
409
 
533
410
  return
534
411
  end
535
412
 
536
- def set_up_package_contents_statements(parser)
537
- @options[:package_contents_statements] = []
538
- @switches << parser.define(
413
+ def set_up_package_contents_statements()
414
+ @package_contents_statements = []
415
+ @parser.on(
539
416
  '--archive PATH',
540
417
  STARTS_WITH_NON_HYPHEN,
541
418
  'include PATH archive in package (when using --publish)'
542
419
  ) do |path|
543
- @options[:package_contents_statements] <<
420
+ @package_contents_statements <<
544
421
  Fig::Statement::Archive.new(nil, '--archive option', path)
545
422
  end
546
423
 
547
- @switches << parser.define(
424
+ @parser.on(
548
425
  '--resource PATH',
549
426
  STARTS_WITH_NON_HYPHEN,
550
427
  'include PATH resource in package (when using --publish)'
551
428
  ) do |path|
552
- @options[:package_contents_statements] <<
429
+ @package_contents_statements <<
553
430
  Fig::Statement::Resource.new(nil, '--resource option', path)
554
431
  end
555
432
 
556
433
  return
557
434
  end
558
435
 
559
- def set_up_remote_repository_access(parser)
560
- @switches << parser.define(
436
+ def set_up_remote_repository_access()
437
+ @parser.on(
561
438
  '-u',
562
439
  '--update',
563
440
  'check remote repo for updates and download to $FIG_HOME as necessary'
@@ -565,7 +442,7 @@ Environment variables:
565
442
  set_update_action(Fig::Command::Action::Update, :unconditionally)
566
443
  end
567
444
 
568
- @switches << parser.define(
445
+ @parser.on(
569
446
  '-m',
570
447
  '--update-if-missing',
571
448
  'check remote repo for updates only if package missing from $FIG_HOME'
@@ -573,58 +450,73 @@ Environment variables:
573
450
  set_update_action(Fig::Command::Action::UpdateIfMissing, :if_missing)
574
451
  end
575
452
 
576
- @switches << parser.define(
453
+ @parser.on(
577
454
  '-l', '--login', 'login to remote repo as a non-anonymous user'
578
455
  ) do
579
- @options[:login] = true
456
+ @login = true
580
457
  end
581
458
 
582
- @options[:force] = nil
583
- @switches << parser.define(
459
+ @force = nil
460
+ @parser.on(
584
461
  '--force',
585
462
  'force-overwrite existing version of a package to the remote repo'
586
463
  ) do |force|
587
- @options[:force] = force
464
+ @force = force
588
465
  end
589
466
 
590
467
  return
591
468
  end
592
469
 
593
- def set_up_program_configuration(parser)
594
- @switches << parser.define(
470
+ LOG_LEVELS = %w< off fatal error warn info debug all >
471
+ LOG_ALIASES = { 'warning' => 'warn' }
472
+
473
+ def set_up_program_configuration()
474
+ @parser.on(
595
475
  '--figrc PATH',
596
476
  STARTS_WITH_NON_HYPHEN,
597
477
  'add PATH to configuration used for Fig'
598
478
  ) do |path|
599
- @options[:figrc] = path
479
+ @figrc = path
600
480
  end
601
481
 
602
- @switches << parser.define('--no-figrc', 'ignore ~/.figrc') { @options[:no_figrc] = true }
482
+ @parser.on('--no-figrc', 'ignore ~/.figrc') { @no_figrc = true }
603
483
 
604
- @switches << parser.define(
484
+ @parser.on(
605
485
  '--log-config PATH',
606
486
  STARTS_WITH_NON_HYPHEN,
607
487
  'use PATH file as configuration for Log4r'
608
488
  ) do |path|
609
- @options[:log_config] = path
489
+ @log_config = path
610
490
  end
611
491
 
612
492
  level_list = LOG_LEVELS.join(', ')
613
- @switches << parser.define(
493
+ @parser.on(
614
494
  '--log-level LEVEL',
615
495
  LOG_LEVELS,
616
496
  LOG_ALIASES,
617
497
  'set logging level to LEVEL',
618
498
  " (#{level_list})"
619
499
  ) do |log_level|
620
- @options[:log_level] = log_level
500
+ @log_level = log_level
501
+ end
502
+
503
+ @update_lock_response = :fail
504
+ update_lock_responses = [:fail, :wait, :ignore]
505
+ response_list = update_lock_responses.join(', ')
506
+ @parser.on(
507
+ '--update-lock-response TYPE',
508
+ update_lock_responses,
509
+ 'what to do when update lock already exists',
510
+ " (#{response_list}, default is fail)"
511
+ ) do |response|
512
+ @update_lock_response = response
621
513
  end
622
514
 
623
- @switches << parser.define(
515
+ @parser.on(
624
516
  '--suppress-warning-include-statement-missing-version',
625
517
  %q<don't complain about "include package" without a version>
626
518
  ) do
627
- @options[:suppress_warning_include_statement_missing_version] = true
519
+ @suppress_warning_include_statement_missing_version = true
628
520
  end
629
521
 
630
522
  return
@@ -665,7 +557,7 @@ Environment variables:
665
557
 
666
558
  def new_variable_statement(option, name_value, statement_class)
667
559
  variable, value = statement_class.parse_name_value(name_value) {
668
- raise_invalid_argument(option, name_value)
560
+ @parser.raise_invalid_argument(option, name_value)
669
561
  }
670
562
 
671
563
  return statement_class.new(nil, "#{option} option", variable, value)