ass_launcher 0.1.1.alpha → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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