ass_launcher 0.1.1.alpha → 0.2.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +69 -67
  3. data/Rakefile +19 -0
  4. data/ass_launcher.gemspec +8 -2
  5. data/bin/dev-helper +7 -0
  6. data/bin/lib/dev_helper/cli_def_report.rb +191 -0
  7. data/bin/lib/dev_helper/cli_def_snippets.rb +426 -0
  8. data/bin/lib/dev_helper/designer.rb +172 -0
  9. data/bin/lib/dev_helper.rb +59 -0
  10. data/examples/arguments_builder_example.rb +150 -0
  11. data/examples/binary_wrappers_example.rb +211 -0
  12. data/examples/connection_string_example.rb +59 -0
  13. data/examples/create_infobase_example.rb +45 -0
  14. data/examples/enterprise_ole_example.rb +238 -0
  15. data/examples/enterprise_out_example.rb +87 -0
  16. data/examples/enterprise_running_example.rb +103 -0
  17. data/examples/example_helper.rb +122 -0
  18. data/examples/templates/example_template.cf +0 -0
  19. data/examples/templates/example_template.v8i +9 -0
  20. data/examples/templates/hello.epf +0 -0
  21. data/examples/troubles/with_creteinfobase_example.rb +408 -0
  22. data/examples/troubles/with_running_1c_example.rb +212 -0
  23. data/examples/v8i_file_example.rb +72 -0
  24. data/examples/webclient_example.rb +67 -0
  25. data/lib/ass_launcher/api.rb +113 -0
  26. data/lib/ass_launcher/enterprise/binary_wrapper.rb +159 -144
  27. data/lib/ass_launcher/enterprise/cli/arguments_builder.rb +177 -16
  28. data/lib/ass_launcher/enterprise/cli/binary_matcher.rb +69 -0
  29. data/lib/ass_launcher/enterprise/cli/parameters.rb +297 -44
  30. data/lib/ass_launcher/enterprise/cli/spec_dsl/dsl_helpers.rb +111 -5
  31. data/lib/ass_launcher/enterprise/cli/spec_dsl.rb +102 -51
  32. data/lib/ass_launcher/enterprise/cli.rb +50 -90
  33. data/lib/ass_launcher/enterprise/cli_def/8.2.17.rb +317 -0
  34. data/lib/ass_launcher/enterprise/cli_def/8.2.18.rb +3 -0
  35. data/lib/ass_launcher/enterprise/cli_def/8.3.3.rb +90 -0
  36. data/lib/ass_launcher/enterprise/cli_def/8.3.4.rb +58 -0
  37. data/lib/ass_launcher/enterprise/cli_def/8.3.5.rb +21 -0
  38. data/lib/ass_launcher/enterprise/cli_def/8.3.6.rb +91 -0
  39. data/lib/ass_launcher/enterprise/cli_def/8.3.7.rb +34 -0
  40. data/lib/ass_launcher/enterprise/cli_def/8.3.8.rb +127 -0
  41. data/lib/ass_launcher/enterprise/cli_def/8.3.9.rb +131 -0
  42. data/lib/ass_launcher/enterprise/cli_def.rb +46 -0
  43. data/lib/ass_launcher/enterprise/cli_defs_loader.rb +36 -0
  44. data/lib/ass_launcher/enterprise/ole/ole_binaries.rb +9 -2
  45. data/lib/ass_launcher/enterprise/ole/win32ole.rb +1 -1
  46. data/lib/ass_launcher/enterprise/ole.rb +17 -1
  47. data/lib/ass_launcher/enterprise/web_client.rb +164 -0
  48. data/lib/ass_launcher/enterprise.rb +33 -6
  49. data/lib/ass_launcher/support/connection_string.rb +33 -8
  50. data/lib/ass_launcher/support/linux.rb +88 -0
  51. data/lib/ass_launcher/support/platforms.rb +42 -10
  52. data/lib/ass_launcher/support/shell.rb +33 -6
  53. data/lib/ass_launcher/support/v8i_file.rb +3 -1
  54. data/lib/ass_launcher/support/v8i_section.rb +88 -40
  55. data/lib/ass_launcher/support.rb +1 -0
  56. data/lib/ass_launcher/version.rb +8 -1
  57. data/lib/ass_launcher.rb +1 -0
  58. metadata +79 -17
  59. data/lib/ass_launcher/enterprise/cli/cli.spec +0 -256
  60. data/lib/ass_launcher/enterprise/web_clients.rb +0 -59
@@ -4,29 +4,6 @@ module AssLauncher
4
4
  #
5
5
  module Enterprise
6
6
  require 'ass_launcher/enterprise/cli'
7
- # rubocop:disable all
8
- # TODO: перенести этот текст в другое место
9
- # fucking 1C: команда `CEATEINFOBASE` принимает фаловую строку
10
- # соединения в котрой путь должен быть в формате win т.е. H:\bla\bla.
11
- # При этом команды `ETERPRISE` и `DESIGNER` понимают и смешаный формат пути:
12
- # H:/bla/bla. При передаче команде `CREATEINFOBASE` некорректного пути
13
- # база будет создана абы где и в косоль вернется успех $?=0. Какие бывают
14
- # некоректные пути:
15
- # - (!! Похоже в v 8.3.8 устранили) H:/bla/bla - будет создана база H: где? Да прямо в корне диска H:. Вывод 1С win-xp:
16
- # `Создание информационной базы ("File=H:;Locale = "ru_RU";") успешно завершено`
17
- # - (!! Похоже в v 8.3.8 устранили) H:/путь/котрого/нет/имябазы - будет оздана база в каталоге по умолчанию
18
- # с именем InfoBase[N]. Вывод 1С win-xp:
19
- # `Создание информационной базы ("File = "C:\Documents and Settings\vlv\Мои документы\InfoBase41";Locale = "ru_RU";") успешно завершено`
20
- # в linux отработает корректно и попытается содать каталоги или вылитит с
21
- # ошибкой ?$>0
22
- # - ../empty.ib - использование относительного пути в win создает базу по
23
- # умолчанию как в предидущем пункте в linux создаст базу empty.ib в текущем
24
- # каталоге при этом вывод 1C в linux:
25
- # `Создание информационной базы ("File=../empty.ib;Locale = "en_US";") успешно завершено`
26
- # - H(!! Похоже в v 8.3.8 устранили):\путь\содержит-тире - в win создаст базу H:\путь\содержит вывод 1С:
27
- # `Создание информационной базы ("File=H:\genm\содержит;Locale = "ru_RU";") успешно завершено`
28
- # в linux отработет корректно
29
- # rubocop:enable all
30
7
 
31
8
  # Class for wrapping 1C:Enterprise platform binary executables such as
32
9
  # 1cv8.exe and 1cv8c.exe.
@@ -45,16 +22,18 @@ module AssLauncher
45
22
  @path = platform.path(binpath).realpath
46
23
  fail ArgumentError, "Is not a file `#{binpath}'" unless @path.file?
47
24
  fail ArgumentError,
48
- "Invalid binary #{@path.basename} for #{self.class}"\
49
- unless @path.basename.to_s.upcase == expects_basename.upcase
25
+ "Invalid binary #{@path.basename} for #{self.class}" unless\
26
+ @path.basename.to_s.upcase == expects_basename.upcase
50
27
  end
51
28
 
52
29
  # Define version of 1C platform.
53
- # @note version parsed from path and may content incorrect value - not
54
- # real 1C platform version see {#extract_version}. In windows,
55
- # if 1C platform instaled in standart directories it work correctly.
56
- # In Linux it have only 2 major
57
- # digits.
30
+ # @note In Windows version parsed from path and may
31
+ # content incorrect value - not
32
+ # real 1C platform version see {#extract_version}. For platform > 8.2
33
+ # if 1C platform instaled in standart directories it works correctly.
34
+ #
35
+ # In linux version returns from method
36
+ # {AssLauncher::Support::Linux.get_pkg_version}
58
37
  #
59
38
  # @api public
60
39
  # @return [Gem::Version]
@@ -77,6 +56,8 @@ module AssLauncher
77
56
  # - In Linux 1V default install into path:
78
57
  # +/opt/1C/v8.3/i386/1cv8+
79
58
  def extract_version(realpath)
59
+ return AssLauncher::Support::Linux.get_pkg_version(realpath) if\
60
+ platform.linux?
80
61
  extracted = realpath.to_s.split('/')[-3]
81
62
  extracted =~ /(\d+\.\d+\.?\d*\.?\d*)/i
82
63
  extracted = (Regexp.last_match(1).to_s.split('.')\
@@ -144,8 +125,9 @@ module AssLauncher
144
125
  private :to_script
145
126
 
146
127
  def fail_if_wrong_mode(run_mode)
147
- fail ArgumentError, "Invalid run_mode `#{run_mode}' for #{self.class}"\
148
- unless run_modes.include? run_mode
128
+ fail ArgumentError,
129
+ "Invalid run_mode `#{run_mode}' for #{self.class}" unless\
130
+ run_modes.include? run_mode
149
131
  run_mode
150
132
  end
151
133
  private :fail_if_wrong_mode
@@ -161,133 +143,31 @@ module AssLauncher
161
143
 
162
144
  # @api public
163
145
  # @return (see Cli.defined_modes_for)
164
- def run_modes
146
+ def self.run_modes
165
147
  Cli.defined_modes_for(self)
166
148
  end
167
149
 
168
- # @return (see Cli::CliSpec#parameters)
169
- def defined_parameters(run_mode)
170
- cli_spec(run_mode).parameters
150
+ # @api public
151
+ # @return (see Cli.defined_modes_for)
152
+ def run_modes
153
+ self.class.run_modes
171
154
  end
172
- private :defined_parameters
173
155
 
174
156
  # @api public
175
- # @param run_mode [Symbol] run mode 1C binary.
176
157
  # @return [Cli::CliSpec]
177
- def cli_spec(run_mode = :enterprise)
178
- Cli::CliSpec.for(self, fail_if_wrong_mode(run_mode))
158
+ def cli_spec
159
+ @cli_spec ||= Cli::CliSpec.for(self)
179
160
  end
180
161
 
181
162
  def build_args(run_mode, &block)
182
- arguments_builder = Cli::ArgumentsBuilder\
183
- .new(defined_parameters(run_mode), run_mode)
184
- arguments_builder.instance_eval(&block)
185
- arguments_builder.builded_args
163
+ Cli::ArgumentsBuilder.build_args(self, run_mode, &block)
186
164
  end
187
165
  private :build_args
188
166
 
189
167
  # Wrapper for 1C thick client binary
190
168
  # @api public
191
- #
192
- # @example
193
- #
194
- # script = cl.script(:createinfobase, 'File="path\\new.ib"')
195
- # ph = script.run # this waiting until process executing
196
- # ph.result.expected_assout = /\("File="path\\new.ib";.*"\)/i
197
- # ph.result.verify!
198
- #
199
- # @example
200
- #
201
- # # Get 1C:Enterprise last release for 8.3.6 version:
202
- #
203
- # cl = AssLauncher::Enterprise.thick_clients('~> 8.3.6').last
204
- # raise 'Can\'t find 1C binary' if cl.nil?
205
- #
206
- # @example
207
- #
208
- # # Run 1C:Enterprise designer
209
- # # Directly pass parameters:
210
- #
211
- # args = ['/F', 'path/to/file/infobase']
212
- # ph = cl.command(:designer, args).run
213
- #
214
- # ph.wait.result.assout # => "Информационная база не обнаружена!"
215
- # ph.result.exitstatus # => 0
216
- #
217
- # # Fucking 1C: "Информационная база не обнаружена!" but exit with 0 ????
218
- #
219
- # @example
220
- #
221
- # # Dump infobase
222
- # # Directly pass parameters:
223
- #
224
- # args = ['/F', 'path/infobase', '/DumpIB', 'dump/path/file.dt']
225
- # cm = cl.command(:designer, args)
226
- #
227
- # cm.run.wait.result.verify!
228
- # #=> RunAssResult::RunAssError: Информационная база не обнаружена!
229
- #
230
- # @example
231
- #
232
- # TODO `verify' exaples:
233
- #
234
- # # Dump infobase
235
- # # Uses Cli::ArgumentsBuilder:
236
- #
237
- # conn_str = AssLauncher::Support::ConnectionString.\
238
- # new('File="//host/infobase"')
239
- #
240
- # command = cl.command(:designer) do
241
- # connection_string conn_str
242
- # DumpIB './infobase.dt'
243
- # end
244
- # ph = command.run.wait
245
- #
246
- # ph.result.verify!
247
- #
248
- # # Crete info base
249
- #
250
- # ph = cl.command(:createinfobase) do
251
- # connection_string "File='//host/new.ib';"
252
- # _UseTemplate './application.cf'
253
- # _AddInList
254
- # end.run.wait
255
- #
256
- # ph.result.verify!
257
- #
258
- # # Check configuration
259
- #
260
- # ph = cl.command(:designer) do
261
- # _S '1c-server/infobase'
262
- # _N 'admin'
263
- # _P 'password'
264
- # _CheckConfig do
265
- # _ConfigLogIntegrity
266
- # _IncorrectReferences
267
- # _Extension :all
268
- # end
269
- # end.run.wait
270
- #
271
- # ph.result.verify!
272
- #
273
- # # Run enterprise Hello World
274
- #
275
- # # Prepare external data processor 'processor.epf'
276
- # # Make OnOpen form handler for main form of processor:
277
- # # procedure OnOpen(Cansel)
278
- # # message("Ass listen: " + LaunchParameter)
279
- # # exit()
280
- # # endprocedure
281
- #
282
- # ph = cl.command(:enterprise) do
283
- # connection_string 'File="./infobase";Usr="admin";Pwd="password"'
284
- # _Execute './processor.epf'
285
- # _C 'Hello World'
286
- # end.run.wait
287
- #
288
- # ph.result.verify!
289
- #
290
- # puts ph.result.assout #=> 'Ass listen: Hello World'
169
+ # @example (see #script)
170
+ # @example (see #command)
291
171
  #
292
172
  class ThickClient < BinaryWrapper
293
173
  # (see ThinClient#accepted_connstr)
@@ -311,13 +191,105 @@ module AssLauncher
311
191
  # @param args (see BinaryWrapper#to_command)
312
192
  # @option options (see BinaryWrapper#to_command)
313
193
  # @return (see #to_command)
194
+ # @example
195
+ #
196
+ # # Get 1C:Enterprise last release for 8.3.6 version:
197
+ #
198
+ # cl = AssLauncher::Enterprise.thick_clients('~> 8.3.6').last
199
+ # raise 'Can\'t find 1C binary' if cl.nil?
200
+ #
201
+ # @example
202
+ #
203
+ # # Run 1C:Enterprise designer
204
+ # # Directly pass parameters:
205
+ #
206
+ # args = ['/F', 'path/to/file/infobase', '/L', 'en']
207
+ # ph = cl.command(:designer, args).run
208
+ #
209
+ # ph.wait.result.assout # => "Infobase not found!"
210
+ # ph.result.exitstatus # => 0
211
+ #
212
+ # # Fucking 1C: "Infobase not found!" but exit with 0 ????
213
+ #
214
+ # @example
215
+ #
216
+ # # Dump infobase
217
+ # # Directly pass parameters:
218
+ #
219
+ # args = ['/F', 'path/infobase', '/DumpIB', 'dump/path/file.dt', '/L',
220
+ # 'en']
221
+ # cm = cl.command(:designer, args)
222
+ #
223
+ # cm.run.wait.result.verify!
224
+ # #=> RunAssResult::RunAssError: Infobase not found!
225
+ #
226
+ # @example
227
+ #
228
+ # # Dump infobase
229
+ # # Uses Cli::ArgumentsBuilder:
230
+ #
231
+ # conn_str = AssLauncher::Support::ConnectionString.\
232
+ # new('File="//host/infobase"')
233
+ #
234
+ # command = cl.command(:designer) do
235
+ # connection_string conn_str
236
+ # DumpIB './infobase.dt'
237
+ # end
238
+ # ph = command.run.wait
239
+ #
240
+ # ph.result.verify!
241
+ # @example
242
+ # # Open thick client and attache into debuger
243
+ #
244
+ # conn_str = AssLauncher::Support::ConnectionString.\
245
+ # new('srvr="localhost"; ref="infobase"')
246
+ #
247
+ # command = cl.command(:enterprise) do
248
+ # connection_string conn_str
249
+ # debug
250
+ # debuggerUrl 'localhost'
251
+ # end
252
+ # ph = command.run.wait # Fucking 1C: If infobase not exists
253
+ # #will be opened GUI window with info similar 'Inforamation base
254
+ # #not found. Create new?" and exit whith status 0
255
+ #
256
+ # #Fucking 1C:
257
+ # #USES GUI DIALOG FOR ERROR REPORTING WHEN RUN IN NO GUI MODE
314
258
  def command(run_mode, args = [], **options, &block)
315
259
  args_ = args.dup
316
260
  args_.unshift mode(run_mode)
317
261
  args_ += build_args(run_mode, &block) if block_given?
262
+ verify_createinfobase_param_order! args_ if\
263
+ run_mode == :createinfobase
318
264
  to_command(args_, options)
319
265
  end
320
266
 
267
+ # Fucking 1C not check CLI parameter
268
+ # In create infobase mode create default infobase in user profile
269
+ # directory if the first parameter is not connection string!!!
270
+ def verify_createinfobase_param_order!(args)
271
+ cs = parse_cs args[1]
272
+ fail ArgumentError, ':createinfobase expects file or server'\
273
+ " connection string in first argument but given `#{args[1]}'" unless\
274
+ good_cs?(cs)
275
+ args
276
+ end
277
+ private :verify_createinfobase_param_order!
278
+
279
+ def good_cs?(cs)
280
+ return false unless cs
281
+ cs.is?(:file) || cs.is?(:server)
282
+ end
283
+ private :good_cs?
284
+
285
+ def parse_cs(string)
286
+ AssLauncher::Support::ConnectionString\
287
+ .new(string.to_s.tr('\'', '"'))
288
+ rescue AssLauncher::Support::ConnectionString::ParseError
289
+ nil
290
+ end
291
+ private :parse_cs
292
+
321
293
  # Run 1C:Enterprise client as cmd or shell script.
322
294
  # @note It waiting for script
323
295
  # execution.
@@ -327,6 +299,14 @@ module AssLauncher
327
299
  # @param run_mode (see #command)
328
300
  # @param args (see #to_script)
329
301
  # @option options (see #to_script)
302
+ # @example
303
+ #
304
+ # cl = AssLauncher::Enterprise.thick_clients('~> 8.3.6').last
305
+ # script = cl.script(:createinfobase, 'File="path\\new.ib"')
306
+ # ph = script.run # this waiting until process executing
307
+ # ph.result.expected_assout = /\("File="path\\new.ib";.*"\)/i
308
+ # ph.result.verify!
309
+ #
330
310
  # @return (see #to_script)
331
311
  def script(run_mode, args = '', **options)
332
312
  args_ = "#{mode(run_mode)} #{args}"
@@ -336,6 +316,9 @@ module AssLauncher
336
316
 
337
317
  # Wrapper for 1C thin client binary
338
318
  # @api public
319
+ # @example (see #script)
320
+ # @example (see #command)
321
+ #
339
322
  class ThinClient < ThickClient
340
323
  # Define type of connection_string
341
324
  # suitable for 1C binary
@@ -349,6 +332,32 @@ module AssLauncher
349
332
  # @param args (see ThickClient#command)
350
333
  # @option options (see ThickClient#command)
351
334
  # @return (see ThickClient#command)
335
+ # @example
336
+ #
337
+ # cl = AssLauncher::Enterprise.thin_clients('~> 8.3.6').last
338
+ # args = ['/F', 'path/to/file/infobase']
339
+ # ph = cl.command(args).run # Fucking 1C: If infobase not exists
340
+ # #will be opened GUI window with error info similar 'Inforamation base
341
+ # #not found"
342
+ #
343
+ # ph.wait # => waiting wile execiting
344
+ # ph.result.exitstatus # => 0
345
+ #
346
+ # # Uses Cli::ArgumentsBuilder:
347
+ #
348
+ # conn_str = AssLauncher::Support::ConnectionString.\
349
+ # new('File="//host/infobase"')
350
+ #
351
+ # command = cl.command do
352
+ # connection_string conn_str
353
+ # debug
354
+ # debuggerUrl 'localhost'
355
+ # end
356
+ # ph = command.run.wait # Fucking 1C: If infobase not exists
357
+ # #will be opened GUI window with error info similar 'Inforamation base
358
+ # #not found"
359
+ #
360
+
352
361
  def command(args = [], **options, &block)
353
362
  super(:enterprise, args, options, &block)
354
363
  end
@@ -358,6 +367,12 @@ module AssLauncher
358
367
  # @param args (see ThickClient#script)
359
368
  # @option options (see ThickClient#script)
360
369
  # @return (see ThickClient#script)
370
+ # @example
371
+ # cl = AssLauncher::Enterprise.thin_clients('~> 8.3.6').last
372
+ # script = cl.script('File="path\\new.ib"')
373
+ # ph = script.run # this waiting until process executing
374
+ # # Fucking 1C: if infobase not exists will be opened GUI window
375
+ # #for infobase choice!
361
376
  def script(args = '', **options)
362
377
  super(:enterprise, args, options)
363
378
  end
@@ -4,37 +4,198 @@ module AssLauncher
4
4
  module Enterprise
5
5
  module Cli
6
6
  # @api private
7
+ # Provides DSL for build arguments for run 1C:Enterprise clients.
8
+ #
9
+ # DSL dynamically generated based on CLI specifications {Cli::CliSpec}
10
+ # For each CLI parameter is assigned a DSL method called
11
+ # like a parameter but whitout parameter key such as
12
+ # {TOP_LEVEL_PARAM_KEY} or {NESTED_LEVEL_PARAM_KEY}.
13
+ # DSL methods may be prefixed +_+ char for
14
+ # escape uppercase name of method. DSL method +_SomeParameter+ and
15
+ # +someParameter+ equal and assigned for +/SomParameter+ or
16
+ # +-SomeParameter+ CLI parameter. DLS methods case insensitive.
17
+ # Top level builder have method
18
+ # {IncludeConnectionString#connection_string} for pass connection
19
+ # string and convert him into arguments array.
20
+ # @example
21
+ # client = AssLauncher::Enterprise.thick_clients('> 0').sort.last
22
+ # # Builds arguments for check configuration:
23
+ #
24
+ # # 1) Use #connection_string DLS method
25
+ # args = AssLauncher::Enterprise::Cli::ArgumentsBuilder.build_args(
26
+ # client, :designer) do
27
+ # connection_string 'File="tmp/new.ib";Usr="user";Pwd="password";'
28
+ # checkConfig do # top level CLI parameter '/CheckConfig'
29
+ # unreferenceProcedures # nested parameter '-UnreferenceProcedures'
30
+ # end
31
+ # end
32
+ # args #=> ["/N", "user",\
33
+ # # "/P", "password",
34
+ # # "/F", "C:/cygwin/home/vlv/workspace/ass_launcher/tmp/new.ib",
35
+ # # "/CheckConfig", "", "-UnreferenceProcedures", ""]
36
+ #
37
+ # # 2) Without #connection_string DLS method
38
+ # args = AssLauncher::Enterprise::Cli::ArgumentsBuilder.build_args(
39
+ # client, :designer) do
40
+ # _N 'user'
41
+ # _P 'password'
42
+ # _F 'tmp/new.ib'
43
+ # _CheckConfig do
44
+ # _UnreferenceProcedures
45
+ # end
46
+ # end
47
+ # args #=> ["/N", "user",
48
+ # # "/P", "password",
49
+ # # "/F", "C:/cygwin/home/vlv/workspace/ass_launcher/tmp/new.ib",
50
+ # # "/CheckConfig", "", "-UnreferenceProcedures", ""]
51
+ #
52
+ # @raise (see #method_missing )
7
53
  class ArgumentsBuilder
8
- attr_reader :run_mode, :defined_parameters, :builded_args
54
+ class BuildError < StandardError; end
55
+ METHOD_TO_PARAM_NAME = /^_/i
56
+ TOP_LEVEL_PARAM_KEY = '/'
57
+ NESTED_LEVEL_PARAM_KEY = '-'
9
58
 
10
- # @param defined_arguments [Parameters::ParamtersList]
11
- def initialize(defined_arguments, run_mode)
59
+ # DSL method {#connection_string} for top level arguments builder
60
+ # @api public
61
+ module IncludeConnectionString
62
+ # DLS method for convert connection string into 1C:Enterprise cli
63
+ # arguments and add them on the head of arguments array.
64
+ #
65
+ # @param conn_str [String
66
+ # AssLauncher::Support::ConnectionString::Server
67
+ # AssLauncher::Support::ConnectionString::File
68
+ # AssLauncher::Support::ConnectionString::Http] connection string
69
+ #
70
+ def connection_string(conn_str)
71
+ conn_str = AssLauncher::Support::ConnectionString\
72
+ .new(conn_str) if conn_str.is_a? String
73
+ args = conn_str_to_args(conn_str)
74
+ self.builded_args = args + builded_args
75
+ end
76
+
77
+ def conn_str_to_args(conn_str)
78
+ return conn_str.createinfobase_args if run_mode == :createinfobase
79
+ conn_str.to_args
80
+ end
81
+ private :conn_str_to_args
82
+ end
83
+
84
+ # @param binary_wrapper [AssLauncher::Enterprise::BinaryWrapper]
85
+ # subclass
86
+ # @param run_mode [Symbol]
87
+ # @return [Array] arguments for run 1C:Enterprise client
88
+ def self.build_args(binary_wrapper, run_mode, &block)
89
+ new(binary_wrapper.cli_spec, run_mode).build_args(&block)
90
+ end
91
+
92
+ attr_reader :cli_spec, :params_stack, :parent_parameter, :run_mode
93
+ private :cli_spec, :params_stack, :parent_parameter, :run_mode
94
+ attr_accessor :builded_args
95
+ protected :builded_args, :builded_args=
96
+
97
+ # @param cli_spec [CliSpec]
98
+ # @param parent_parameter [Cli::Parameters] parent for nested params
99
+ def initialize(cli_spec, run_mode, parent_parameter = nil)
12
100
  @builded_args = []
13
- @defined_parameters = defined_arguments
101
+ @cli_spec = cli_spec
102
+ @parent_parameter = parent_parameter
103
+ @params_stack = []
14
104
  @run_mode = run_mode
15
105
  end
16
106
 
17
- def connection_string(conn_str)
18
- conn_str = AssLauncher::Support::ConnectionString.\
19
- new(conn_str) if conn_str.is_a? String
20
- args = conn_str_to_args(conn_str)
21
- args += build_args
107
+ def defined_parameters
108
+ cli_spec.parameters(run_mode)
22
109
  end
110
+ private :defined_parameters
23
111
 
24
- def conn_str_to_args(conn_str)
25
- return conn_str.createinfobase_args if run_mode == :createinfobase
26
- conn_str.to_args
112
+ def binary_wrapper
113
+ cli_spec.binary_wrapper
27
114
  end
115
+ private :binary_wrapper
28
116
 
117
+ # Evaluate &block return array of arguments
118
+ # @raise [ArgumentError] unless block given
119
+ def build_args(&block)
120
+ fail ArgumentError, 'Block require' unless block_given?
121
+ extend IncludeConnectionString\
122
+ if (parent_parameter.nil? && run_mode != :webclient)
123
+ instance_eval(&block)
124
+ builded_args
125
+ end
126
+
127
+ def nested_builder(parent_parameter)
128
+ self.class.new(cli_spec, run_mode, parent_parameter)
129
+ end
130
+ private :nested_builder
131
+
132
+ # @raise [BuildError] if could not find parameter
133
+ # @raise [BuildError] if argument already build
134
+ # @raise [ArgumentError] if invlid value passed in parameter
29
135
  def method_missing(method, *args, &block)
30
- param_name = method_to_param_name(method)
31
- FIXME
136
+ param = param_find(method)
137
+ fail_no_parameter_error(method) unless param
138
+ fail_if_parameter_exist(param)
139
+ add_args(param.to_args(*param_argument_get(param, args)))
140
+ self.builded_args += nested_builder(param).build_args(&block)\
141
+ if block_given?
142
+ end
143
+
144
+ def fail_if_parameter_exist(param)
145
+ fail(BuildError, "Parameter `#{param.full_name}' alrady build.")\
146
+ if params_stack.include? param
147
+ params_stack << param
148
+ end
149
+ private :fail_if_parameter_exist
150
+
151
+ def param_argument_get(param, args)
152
+ v = args[0, param.arguments_count]
153
+ fail_wrong_number_arguments(param.full_name, param.arguments_count,
154
+ v.size) if param.argument_require
155
+ v
156
+ end
157
+ private :param_argument_get
158
+
159
+ def fail_wrong_number_arguments(name, req, act)
160
+ fail ArgumentError, "Parameter #{name}"\
161
+ " wrong number of arguments (#{req} for #{act})" if req != act
162
+
32
163
  end
164
+ private :fail_wrong_number_arguments
33
165
 
34
- def method_to_param_name(method)
35
- FIXME
166
+ def add_args(args)
167
+ self.builded_args = builded_args + args
36
168
  end
169
+ private :add_args
37
170
 
171
+ def fail_no_parameter_error(method)
172
+ fail BuildError,
173
+ "CLI parameter `#{to_param_name(method)}' not definded"\
174
+ " for `#{bw_pesentation}' in `#{run_mode}' run mode."\
175
+ end
176
+ private :fail_no_parameter_error
177
+
178
+ def bw_pesentation
179
+ "#{binary_wrapper.class.name.split('::').last}"\
180
+ " #{binary_wrapper.version}"
181
+ end
182
+ private :bw_pesentation
183
+
184
+ def param_find(method)
185
+ defined_parameters.find(to_param_name(method), parent_parameter)
186
+ end
187
+ private :param_find
188
+
189
+ def to_param_name(method)
190
+ param_key + method.to_s.gsub(METHOD_TO_PARAM_NAME, '')
191
+ end
192
+ private :to_param_name
193
+
194
+ def param_key
195
+ return TOP_LEVEL_PARAM_KEY unless parent_parameter
196
+ NESTED_LEVEL_PARAM_KEY
197
+ end
198
+ private :param_key
38
199
  end
39
200
  end
40
201
  end