ass_launcher 0.2.2 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26b10b3da2020233f1272057ad37c5104c75733e
4
- data.tar.gz: b6487231896541b539dfce02af37bd17c1506a3c
3
+ metadata.gz: 5f34851c8fc8124870441ee8daa7551e10a50ea2
4
+ data.tar.gz: fd4b54bd0505ba57b8ab32cad6c47d1b5591cacd
5
5
  SHA512:
6
- metadata.gz: d15a7c46c67149e3221cd878eec66d5936973230f516f136c01ae0fdd724917e645f7d4e4dc4bc1bb745503b26b46d2576fde1b326a28ad615c2544f22979be5
7
- data.tar.gz: 2c4b441db121c659012f57025ac99b69e778af0db4b107bed507d960ae007d6b60344416c830e8467d395d4570ac0a7d1521433a44309961f6eebd1a1f6123b0
6
+ metadata.gz: 97b9af2a7bfe6c63e8148e850186af7c3a4804ed191562d054dec877cf5f5886fa2b894175bebebb7012cc81ce5c221c1554c70b94b282b9be52009be21e415b
7
+ data.tar.gz: 0a98039ec4250d870fd78c561d0039b0ee85dbd35f58d5fb130fe4577176ff0cde719a437ecebc22760568f7d3108c331b738af3bdc2b792a26438808dcc0cda
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ Style/SignalException:
2
+ Enabled: false
3
+
4
+ Layout/EndOfLine:
5
+ Enabled: false
6
+
7
+ Metrics/AbcSize:
8
+ Max: 17
9
+
10
+ Style/RegexpLiteral:
11
+ Enabled: false
12
+
13
+ Style/PerlBackrefs:
14
+ Enabled: false
15
+
16
+ Style/SymbolArray:
17
+ Enabled: false
18
+
19
+ Layout/MultilineMethodCallIndentation:
20
+ Enabled: false
data/README.md CHANGED
@@ -15,6 +15,8 @@ In `Linux` don't support `OLE` feature. Don't known why I told it ;)
15
15
 
16
16
  ## Quick start
17
17
 
18
+ ### Using `AssLauncher` as a library
19
+
18
20
  Add this line to your application's Gemfile:
19
21
 
20
22
  ```ruby
@@ -59,6 +61,21 @@ end
59
61
  main ARGV[0]
60
62
  ```
61
63
 
64
+ ### Command line utility `ass-launcher`
65
+
66
+ From version `0.3.0` `AssLauncher` provides console tool `ass-launcher` wich has
67
+ features:
68
+
69
+ - make new 1C:Enterprise application instance (aka information base)
70
+ - run 1C:Enterprise
71
+ - show help about 1C:Enterprise CLI parameters
72
+ - and some more
73
+
74
+ For more info about `ass-launcher` execute:
75
+
76
+ $ass-launcer --help
77
+
78
+
62
79
  ## Usage
63
80
 
64
81
  ### Examples
data/ass_launcher.gemspec CHANGED
@@ -26,6 +26,9 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "inifile"
27
27
  spec.add_dependency "methadone"
28
28
  spec.add_dependency "addressable", "= 2.4.0"
29
+ spec.add_dependency "clamp"
30
+ spec.add_dependency "colorize"
31
+ spec.add_dependency "command_line_reporter", '>=3.0'
29
32
 
30
33
  spec.add_development_dependency "bundler", "~> 1.10"
31
34
  spec.add_development_dependency "rake", "~> 10.0"
@@ -33,6 +36,5 @@ Gem::Specification.new do |spec|
33
36
  spec.add_development_dependency "pry"
34
37
  spec.add_development_dependency "mocha", "= 1.1.0"
35
38
  spec.add_development_dependency "simplecov"
36
- spec.add_development_dependency "clamp"
37
39
  spec.add_development_dependency "coderay"
38
40
  end
@@ -39,10 +39,13 @@ module DevHelper
39
39
  require_relative './dev_helper/designer'
40
40
 
41
41
  class Main < Clamp::Command
42
+ include AssLauncher::Enterprise::CliDefsLoader
42
43
 
43
- subcommand 'show-version', 'show ass_launcher version' do
44
+ subcommand 'show-version', 'show ass_launcher and known 1C:Enterprise versions' do
44
45
  def execute
45
- $stdout.puts AssLauncher::VERSION
46
+ $stdout.puts "AssLauncher::VERSION: #{AssLauncher::VERSION}"
47
+ $stdout.puts "Known 1C:Enterprise CLI definitions:"
48
+ $stdout.puts " - #{defs_versions.map(&:to_s).join("\n - ")}"
46
49
  end
47
50
  end
48
51
  subcommand 'cli-def-report',
data/exe/ass-launcher ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ass_launcher'
4
+ require 'ass_launcher/cmd'
5
+
6
+ AssLauncher::Cmd::Main.run
@@ -0,0 +1,903 @@
1
+ require 'clamp'
2
+ module AssLauncher
3
+ # AssLauncher command-line untils
4
+ # @example
5
+ # $ass-launcher --help
6
+ # @api private
7
+ #
8
+ module Cmd
9
+ # Colorize string for console output
10
+ # It's stupid wrapper for ColorizedString
11
+ # @api private
12
+ module Colorize
13
+ require 'colorized_string'
14
+
15
+ # rubocop:disable Style/MethodMissing
16
+ def self.method_missing(m, s)
17
+ colorized(s).send(m)
18
+ end
19
+ # rubocop:enable Style/MethodMissing
20
+
21
+ def self.colorized(mes)
22
+ ColorizedString[mes]
23
+ end
24
+ end
25
+
26
+ # @api private
27
+ module Support
28
+ # Mixin
29
+ # @api private
30
+ module SrvStrParser
31
+ # Parse string like +user:password@host:port+
32
+ # @param s [String]
33
+ # @return [Array] ['host:port', 'user', 'password']
34
+ def parse_srv_str(s)
35
+ split = s.split('@')
36
+ fail ArgumentError if split.size > 2
37
+
38
+ host = split.pop
39
+ return [host, nil, nil] if split.size.zero?
40
+
41
+ split = split[0].split(':')
42
+ fail ArgumentError if split.size > 2
43
+
44
+ user = split.shift
45
+ pass = split.shift
46
+
47
+ [host, user, pass]
48
+ end
49
+ end
50
+
51
+ # Mixin for validate version
52
+ # @api private
53
+ module VersionValidator
54
+ include AssLauncher::Enterprise::CliDefsLoader
55
+
56
+ def validate_version
57
+ return known_version.sort.last if version.to_s.empty?
58
+ unless known_version.include? version
59
+ signal_usage_error "Unknown 1C:Enterprise v#{version}\n"\
60
+ "Execute `ass-launcher show-version' command"
61
+ end
62
+ version
63
+ end
64
+
65
+ def known_version
66
+ @known_version ||= defs_versions.sort
67
+ end
68
+ end
69
+
70
+ # Mixin for cli reporters
71
+ # @api private
72
+ module AcceptedValuesGet
73
+ def accepted_values_get
74
+ xxx_list_keys(:switch, param) + xxx_list_keys(:chose, param)
75
+ end
76
+
77
+ def xxx_list_keys(list, p)
78
+ list = p.send("#{list}_list".to_sym)
79
+ return list.keys if list
80
+ []
81
+ end
82
+ end
83
+ end
84
+
85
+ # @api private
86
+ # Abstract things
87
+ module Abstract
88
+ # Abstarct subcommand
89
+ # @api private
90
+ class SubCommand < Clamp::Command
91
+ # :nodoc:
92
+ module Declaration
93
+ def subcommand_(klass)
94
+ subcommand(klass.command_name, klass._banner, klass)
95
+ end
96
+
97
+ def declare_subcommands
98
+ self::SubCommands.constants.each do |c|
99
+ subcommand_ self::SubCommands.const_get(c)
100
+ end
101
+ end
102
+ end
103
+
104
+ extend Declaration
105
+
106
+ # :nocov:
107
+ def self.command_name
108
+ fail 'Abstract'
109
+ end
110
+
111
+ def self._banner
112
+ fail 'Abstract'
113
+ end
114
+ # :nocov:
115
+ end
116
+
117
+ # Mixin
118
+ # @api private
119
+ module ClientMode
120
+ def parrent_command
121
+ invocation_path.to_s.split[1]
122
+ end
123
+
124
+ def client
125
+ case parrent_command
126
+ when 'designer' then :thick
127
+ when 'thick' then :thick
128
+ when 'thin' then :thin
129
+ when 'web' then :web
130
+ when 'makeib' then :thick
131
+ end
132
+ end
133
+
134
+ def mode
135
+ case parrent_command
136
+ when 'designer' then :designer
137
+ when 'thick' then :enterprise
138
+ when 'thin' then :enterprise
139
+ when 'web' then :webclient
140
+ when 'makeib' then :createinfobase
141
+ end
142
+ end
143
+ end
144
+
145
+ # Mixin
146
+ # @api private
147
+ module BinaryWrapper
148
+ include AssLauncher::Api
149
+ include ClientMode
150
+
151
+ def binary_wrapper
152
+ binary_get || (fail Clamp::ExecutionError
153
+ .new(not_inst_message, invocation_path, 1))
154
+ end
155
+
156
+ def not_inst_message
157
+ "1C:Enterprise #{client} v #{vrequrement} not installed"
158
+ end
159
+ private :not_inst_message
160
+
161
+ def vrequrement
162
+ return '' unless version
163
+ case version.segments.size
164
+ when 3 then "~> #{version}.0"
165
+ when 2 then "~> #{version}.0"
166
+ else "= #{version}"
167
+ end
168
+ end
169
+
170
+ def binary_get
171
+ case client
172
+ when :thick then thicks(vrequrement).last
173
+ when :thin then thins(vrequrement).last
174
+ end
175
+ end
176
+ private :binary_get
177
+
178
+ # rubocop:disable all
179
+ def dry_run(cmd)
180
+ r = "#{cmd.cmd.gsub(' ', '\\ ')} "
181
+ if mode == :createinfobase
182
+ r << cmd.args.join(' ')
183
+ else
184
+ r << cmd.args.map do |a|
185
+ unless a =~ %r{^(/|-|'|"|DESIGNER|ENTERPRISE)}
186
+ "\'#{a}\'" unless a.to_s.empty?
187
+ else
188
+ a
189
+ end
190
+ end.join(' ')
191
+ end
192
+ end
193
+
194
+ def run_enterprise(cmd)
195
+ if respond_to?(:dry_run?) && dry_run?
196
+ puts Colorize.yellow(dry_run(cmd))
197
+ else
198
+ begin
199
+ cmd.run.wait.result.verify!
200
+ rescue AssLauncher::Support::Shell::RunAssResult::RunAssError => e
201
+ raise Clamp::ExecutionError.new(e.message, invocation_path,
202
+ cmd.process_holder.result.exitstatus)
203
+ end
204
+ end
205
+ cmd
206
+ end
207
+ # rubocop:enable all
208
+ end
209
+
210
+ # @api private
211
+ module Option
212
+ # Mixin
213
+ # Command option
214
+ module SearchPath
215
+ def self.included(base)
216
+ base.option %w[--search-path -I], 'PATH',
217
+ 'specify 1C:Enterprise installation path' do |s|
218
+ AssLauncher.config.search_path = s
219
+ s
220
+ end
221
+ end
222
+ end
223
+
224
+ # Mixin
225
+ # Command option
226
+ module Version
227
+ def self.included(base)
228
+ base.option %w[--version -v], 'VERSION',
229
+ "specify 1C:Enterprise version requiremet.\n"\
230
+ " Expected full version number or only major\n"\
231
+ ' part of version number' do |s|
232
+ Gem::Version.new(s)
233
+ end
234
+ end
235
+ end
236
+
237
+ # Mixin
238
+ # Command option
239
+ module Verbose
240
+ def self.included(base)
241
+ base.option '--verbose', :flag, 'show more information'
242
+ end
243
+ end
244
+
245
+ # Mixin
246
+ # Command option
247
+ module Query
248
+ def self.included(base)
249
+ base.option %w[--query -q], 'REGEX',
250
+ 'regular expression based filter' do |s|
251
+ begin
252
+ Regexp.new(s, Regexp::IGNORECASE)
253
+ rescue RegexpError => e
254
+ fail ArgumentError, e.message
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ # Mixin
261
+ # Command option
262
+ module Dbms
263
+ # rubocop:disable all
264
+ def self.included(base)
265
+ dbtypes = AssLauncher::Support::ConnectionString::DBMS_VALUES\
266
+ + ['File']
267
+
268
+ define_method :valid_db_types do
269
+ dbtypes
270
+ end
271
+
272
+ base.option '--dbms', 'DB_TYPE',
273
+ "db type: #{dbtypes}.\nValue \"File\""\
274
+ ' for make file infobase', default: 'File' do |s|
275
+ raise ArgumentError,
276
+ "valid values: [#{valid_db_types.join(' ')}]" unless\
277
+ valid_db_types.include? s
278
+ s
279
+ end
280
+ end
281
+ # rubocop:enable all
282
+ end
283
+
284
+ # Mixin
285
+ # Command option
286
+ module Dbsrv
287
+ attr_reader :dbsrv_user, :dbsrv_pass, :dbsrv_host
288
+ include Support::SrvStrParser
289
+ def parse_dbsrv(s)
290
+ @dbsrv_host, @dbsrv_user, @dbsrv_pass = parse_srv_str(s)
291
+ end
292
+
293
+ def self.included(base)
294
+ base.option '--dbsrv', 'user:pass@dbsrv', 'db server address' do |s|
295
+ parse_dbsrv s
296
+ s
297
+ end
298
+ end
299
+ end
300
+
301
+ # Mixin
302
+ # Command option
303
+ module Esrv
304
+ attr_reader :esrv_user, :esrv_pass, :esrv_host
305
+ include Support::SrvStrParser
306
+ def parse_esrv(s)
307
+ @esrv_host, @esrv_user, @esrv_pass = parse_srv_str(s)
308
+ end
309
+
310
+ def self.included(base)
311
+ base.option '--esrv', 'user:pass@esrv',
312
+ 'enterprise server address' do |s|
313
+ parse_esrv(s)
314
+ s
315
+ end
316
+ end
317
+ end
318
+
319
+ # Mixin
320
+ # Command option
321
+ module User
322
+ def self.included(base)
323
+ base.option %w[--user -u], 'NAME', 'infobase user name'
324
+ end
325
+ end
326
+
327
+ # Mixin
328
+ # Command option
329
+ module Password
330
+ def self.included(base)
331
+ base.option %w[--password -p], 'PASSWORD', 'infobase user password'
332
+ end
333
+ end
334
+
335
+ # Mixin
336
+ # Command option
337
+ module Pattern
338
+ def self.included(base)
339
+ base.option %w[--pattern -P], 'PATH',
340
+ 'Template for make infobase.'\
341
+ ' Path to .cf, .dt files' do |s|
342
+ fail ArgumentError, "Path not exist: #{s}" unless File.exist?(s)
343
+ s
344
+ end
345
+ end
346
+ end
347
+
348
+ # Mixin
349
+ # Command option
350
+ module Uc
351
+ def self.included(base)
352
+ base.option '--uc', 'LOCK_CODE', 'infobase lock code'
353
+ end
354
+ end
355
+
356
+ # Mixin
357
+ # Command option
358
+ module DryRun
359
+ def self.included(base)
360
+ base.option %w[--dry-run], :flag,
361
+ 'will not realy run 1C:Enterprise only puts cmd string'
362
+ end
363
+ end
364
+
365
+ # Mixin
366
+ # Command option
367
+ module Raw
368
+ def parse_raw(s)
369
+ split = s.split(%r{(?<!\\),\s}).map(&:strip)
370
+
371
+ split.map do |pv|
372
+ fail ArgumentError, "Parse error in: #{pv}" unless\
373
+ pv =~ %r{^(/|-)}
374
+ pv =~ %r{^(\/|-)([^\s]+)+(.*)?}
375
+ ["#{$1}#{$2}", $3.strip].map { |i| i.gsub('\\,', ',') }
376
+ end
377
+ end
378
+
379
+ def raw_param
380
+ r = []
381
+ raw_list.each do |params|
382
+ r += params
383
+ end
384
+ r
385
+ end
386
+
387
+ def self.included(base)
388
+ description = "other 1C CLI parameters in raw(native) format.\n"\
389
+ 'Parameters and their arguments must be delimited'\
390
+ " comma-space sequence: `, '\n"\
391
+ "If values includes comma comma must be slashed `\\\\,'\n"\
392
+ 'WARNING: correctness of parsing will not guaranteed!'
393
+
394
+ base.option '--raw', '"/Par VAL, -SubPar VAL"', description,
395
+ multivalued: true do |s|
396
+ parse_raw s
397
+ end
398
+ end
399
+ end
400
+
401
+ # Mixin
402
+ # Command option
403
+ module ShowAppiaredOnly
404
+ def self.included(base)
405
+ base.option ['--show-appiared-only', '-a'], :flag,
406
+ 'show parameters which appiared in --version only'
407
+ end
408
+ end
409
+
410
+ # Mixin
411
+ # Command option
412
+ module DevMode
413
+ def self.included(base)
414
+ base.option ['--dev-mode', '-d'], :flag,
415
+ "for developers mode. Show DSL methods\n"\
416
+ " specifications for builds commands in ruby scripts\n"
417
+ end
418
+ end
419
+
420
+ # Mixin
421
+ # Command option
422
+ module Format
423
+ def self.included(base)
424
+ base.option ['--format', '-f'], 'ascii|csv', 'output format',
425
+ default: :ascii do |s|
426
+ fail ArgumentError, "Invalid format `#{s}'" unless\
427
+ %w[csv ascii].include? s
428
+ s.to_sym
429
+ end
430
+ end
431
+ end
432
+ end
433
+
434
+ # @api private
435
+ # rubocop:disable Style/ClassAndModuleCamelCase
436
+ module Parameter
437
+ # Mixin
438
+ # Command parameter
439
+ module IB_PATH
440
+ def self.included(base)
441
+ base.parameter 'IB_PATH', 'path to infobase like a strings'\
442
+ " 'tcp://srv/ref' or 'http[s]://host/path'"\
443
+ " or 'path/to/ib'", attribute_name: :ib_path do |s|
444
+ s
445
+ end
446
+ end
447
+ end
448
+
449
+ # Mixin
450
+ # Command parameter
451
+ module IB_PATH_NAME
452
+ def self.included(base)
453
+ base.parameter 'IB_PATH | IB_NAME',
454
+ 'PATH for file or NAME for server infobase',
455
+ attribute_name: :ib_path do |s|
456
+ s
457
+ end
458
+ end
459
+ end
460
+ end
461
+ # rubocop:enable Style/ClassAndModuleCamelCase
462
+
463
+ # Abstarct cli-help command
464
+ # @api private
465
+ class Cli < SubCommand
466
+ include Support::VersionValidator
467
+ include Option::Version
468
+ include Option::ShowAppiaredOnly
469
+ include Option::DevMode
470
+ include Option::Query
471
+ include Option::Format
472
+ include Option::Verbose
473
+ include ClientMode
474
+
475
+ # Reporter
476
+ # @api private
477
+ # rubocop:disable Metrics/ClassLength
478
+ class Report
479
+ USAGE_COLUMNS = [:usage,
480
+ :argument,
481
+ :parent,
482
+ :group,
483
+ :desc].freeze
484
+
485
+ DEVEL_COLUMNS = [:parameter,
486
+ :dsl_method,
487
+ :accepted_values,
488
+ :parent,
489
+ :param_klass,
490
+ :group,
491
+ :require,
492
+ :desc].freeze
493
+
494
+ # Report's row
495
+ class Row
496
+ include Support::AcceptedValuesGet
497
+
498
+ (USAGE_COLUMNS + DEVEL_COLUMNS).uniq.each do |col|
499
+ attr_accessor col
500
+ end
501
+
502
+ attr_reader :param
503
+ def initialize(param)
504
+ @param = param
505
+ fill
506
+ end
507
+
508
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
509
+ # rubocop:disable Metrics/MethodLength
510
+ def fill
511
+ self.parameter = basic_usage
512
+ self.dsl_method = dsl_method_get
513
+ self.parent = param.parent
514
+ self.require = param.binary_matcher.requirement
515
+ self.accepted_values = accepted_values_get
516
+ .to_s.gsub(/(^\[|\]$)/, '')
517
+ self.usage, self.argument = usage_full
518
+ self.desc = param.desc
519
+ self.param_klass = param.class.name.split('::').last
520
+ self.group = param.group
521
+ end
522
+ private :fill
523
+
524
+ def usage_full
525
+ case param.class.name.split('::').last
526
+ when 'Switch' then
527
+ ["#{basic_usage}(#{accepted_values_get.join('|')})"]
528
+ when 'Chose' then
529
+ [basic_usage, accepted_values_get.join(', ')]
530
+ when 'StringParam' then [basic_usage, 'VALUE']
531
+ when 'Path' then [basic_usage, 'PATH']
532
+ when 'Flag' then [basic_usage]
533
+ when 'PathTwice' then [basic_usage, 'PATH PATH']
534
+ else basic_usage
535
+ end
536
+ end
537
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
538
+ # rubocop:enable Metrics/MethodLength
539
+
540
+ def basic_usage
541
+ return " #{param.name}" if param.parent
542
+ param.name
543
+ end
544
+
545
+ def dsl_method_get
546
+ method = param.name.gsub(%r{^\s*(/|-)}, '_')
547
+ return " #{method}" if param.parent
548
+ method
549
+ end
550
+
551
+ def to_csv(columns)
552
+ r = ''
553
+ columns.each do |col|
554
+ r << "\"#{send(col).to_s.tr('"', '\'')}\";"
555
+ end
556
+ r.gsub(/;$/, '')
557
+ end
558
+ end
559
+
560
+ attr_reader :client, :mode, :version, :query, :appiared_only,
561
+ :dev_mode
562
+ # rubocop:disable Metrics/ParameterLists
563
+ def initialize(client, mode, version, appiared_only, query, dev_mode)
564
+ @client = client
565
+ @mode = mode
566
+ @version = version
567
+ @appiared_only = appiared_only
568
+ @query = query
569
+ @dev_mode = dev_mode
570
+ end
571
+ # rubocop:enable Metrics/ParameterLists
572
+
573
+ def clients?(p)
574
+ p.binary_matcher.clients.include? client
575
+ end
576
+
577
+ def modes?(p)
578
+ p.modes.include? mode
579
+ end
580
+
581
+ def version?(p)
582
+ return true if version.nil?
583
+ if appiared_only
584
+ p.binary_matcher.requirement.to_s =~ /^>=\s*#{version}/
585
+ else
586
+ p.match_version?(version) unless appiared_only
587
+ end
588
+ end
589
+
590
+ def match?(p)
591
+ clients?(p) && modes?(p) && version?(p)
592
+ end
593
+
594
+ def not_filtred?(p)
595
+ return true unless query
596
+ coll_match?(:desc, p) || coll_match?(:parent, p) || \
597
+ coll_match?(:name, p)
598
+ end
599
+
600
+ def coll_match?(prop, p)
601
+ !(p.send(prop).to_s =~ query).nil?
602
+ end
603
+
604
+ def groups
605
+ AssLauncher::Enterprise::Cli::CliSpec.cli_def.parameters_groups
606
+ end
607
+
608
+ def grouped_rows
609
+ r = {}
610
+ groups.each do |gname, _|
611
+ r[gname] = rows.select { |row| row.group == gname }
612
+ .sort_by { |row| row.param.full_name }
613
+ end
614
+ r
615
+ end
616
+
617
+ def rows
618
+ @rows ||= execute
619
+ end
620
+
621
+ def select_parameters
622
+ r = []
623
+ AssLauncher::Enterprise::Cli::CliSpec
624
+ .cli_def.parameters.parameters.each do |p|
625
+ if match?(p) && not_filtred?(p)
626
+ r << p
627
+ r << p.parent if p.parent && !r.include?(p.parent)
628
+ end
629
+ end
630
+ r
631
+ end
632
+
633
+ def execute
634
+ r = select_parameters.map do |p|
635
+ Row.new(p)
636
+ end
637
+ r.sort_by { |row| row.param.full_name }
638
+ end
639
+
640
+ def max_col_width(col, rows)
641
+ [rows.map do |r|
642
+ r.send(col).to_s.length
643
+ end.max, col.to_s.length].max
644
+ end
645
+
646
+ require 'io/console'
647
+ def term_width(trim = 0)
648
+ IO.console.winsize[1] - trim
649
+ end
650
+
651
+ def eval_width(col, total, r, trim, rows)
652
+ [(term_width(trim) - r.values.inject(0) { |i, o| o + i }) / total,
653
+ max_col_width(col, rows)].min
654
+ end
655
+
656
+ # rubocop:disable Style/ConditionalAssignment
657
+ def columns_width(columns, rows)
658
+ total = columns.size + 1
659
+ columns.each_with_object({}) do |col, r|
660
+ total -= 1
661
+ if [:usage, :parameter, :dsl_method].include? col
662
+ r[col] = max_col_width(col, rows)
663
+ else
664
+ r[col] = eval_width(col, total, r,
665
+ 4 + (columns.size - 1) * 3, rows)
666
+ end
667
+ end
668
+ end
669
+
670
+ def main_header
671
+ if dev_mode
672
+ r = 'DSL METHODS'
673
+ else
674
+ r = 'CLI PARAMETERS'
675
+ end
676
+ r << " AVAILABLE FOR: \"#{client}\" CLIENT V#{version}"
677
+ r << " IN \"#{mode}\" RUNING MODE" if client == :thick
678
+ r.upcase
679
+ end
680
+ # rubocop:enable Style/ConditionalAssignment
681
+
682
+ def filter_header
683
+ "FILTERED BY: #{query}" if query
684
+ end
685
+
686
+ # rubocop:disable all
687
+ # @doto: refactoring and tests require
688
+ def to_table(columns)
689
+ require 'command_line_reporter'
690
+ extend CommandLineReporter
691
+
692
+ header title: main_header, width: main_header.length, rule: true,
693
+ align: 'center', bold: true, spacing: 0
694
+
695
+ header title: filter_header, width: filter_header.length, rule: true,
696
+ align: 'center', bold: false, color: 'yellow', spacing: 0 if\
697
+ filter_header
698
+
699
+ grouped_rows.each do |gname, rows|
700
+ next if rows.size.zero?
701
+ table(border: true, encoding: :ascii) do
702
+ header title: "PARAMTERS GROUP: \"#{groups[gname][:desc]}\"",
703
+ bold: true
704
+
705
+ row header: true do
706
+ columns_width(columns, rows).each do |col, width|
707
+ column(col.upcase, width: width)
708
+ end
709
+ end
710
+ rows.each do |row_|
711
+ row do
712
+ columns.each do |col|
713
+ column(row_.send(col))
714
+ end
715
+ end
716
+ end
717
+ end
718
+ end
719
+ nil
720
+ end
721
+ # rubocop:enable all
722
+
723
+ def to_csv(columns)
724
+ r = "#{columns.join(';')}\n"
725
+ rows.each do |row|
726
+ r << row.to_csv(columns)
727
+ r << "\n"
728
+ end
729
+ r
730
+ end
731
+ end
732
+ # rubocop:enable Metrics/ClassLength
733
+
734
+ def self.command_name
735
+ 'cli-help'
736
+ end
737
+
738
+ def self._banner
739
+ 'show help for 1C:Enterprise CLI parameters'
740
+ end
741
+
742
+ def columns
743
+ cols = dev_mode? ? Report::DEVEL_COLUMNS : Report::USAGE_COLUMNS
744
+ cols -= [:parent, :parameter, :group, :require] unless verbose?
745
+ cols
746
+ end
747
+
748
+ def formating(report)
749
+ return report.to_table(columns) if format == :ascii
750
+ report.to_csv(columns)
751
+ end
752
+
753
+ def execute
754
+ $stdout.puts formating Report.new(client, mode, validate_version,
755
+ show_appiared_only?, query,
756
+ dev_mode?)
757
+ end
758
+ end
759
+
760
+ # Mixin
761
+ # @api private
762
+ module ParseIbPath
763
+ include AssLauncher::Api
764
+ require 'uri'
765
+ def connection_string
766
+ case ib_path
767
+ when %r{https?://}i then cs_http(ws: ib_path)
768
+ when %r{tcp://}i then parse_tcp_path
769
+ else cs_file(file: ib_path)
770
+ end
771
+ end
772
+
773
+ def parse_tcp_path
774
+ u = URI(ib_path)
775
+ cs_srv(srvr: "#{u.host}:#{u.port}", ref: u.path.gsub(%r{^/}, ''))
776
+ end
777
+ end
778
+
779
+ # Abstarct run command
780
+ # @api private
781
+ class Run < SubCommand
782
+ include Option::Version
783
+ include Option::DryRun
784
+ include Option::SearchPath
785
+ include Option::User
786
+ include Option::Password
787
+ include Option::Uc
788
+ include Option::Raw
789
+ include BinaryWrapper
790
+ include ParseIbPath
791
+
792
+ def self.command_name
793
+ 'run'
794
+ end
795
+
796
+ def self._banner
797
+ 'run 1C:Enterprise'
798
+ end
799
+
800
+ def command_(&block)
801
+ if client == :thin
802
+ binary_wrapper.command((raw_param.flatten || []), &block)
803
+ else
804
+ binary_wrapper.command(mode, (raw_param.flatten || []), &block)
805
+ end
806
+ end
807
+
808
+ # rubocop:disable Metrics/MethodLength
809
+ def make_command
810
+ usr = user
811
+ pass = password
812
+ uc_ = uc
813
+ cs = connection_string
814
+ cmd = command_ do
815
+ connection_string cs
816
+ _N usr if usr
817
+ _P pass if pass
818
+ _UC uc_ if uc_
819
+ _AppAutoCheckVersion(:-) if Gem::Requirement.new('>= 8.3.8')
820
+ .satisfied_by? binary_wrapper.version
821
+ end
822
+ cmd
823
+ end
824
+ # rubocop:enable Metrics/MethodLength
825
+
826
+ def execute
827
+ cmd = run_enterprise(make_command)
828
+ puts Colorize.green(cmd.process_holder.result.assout) unless dry_run?
829
+ end
830
+ end
831
+ end
832
+
833
+ # @api private
834
+ # Root of all subcommands
835
+ class Main < Clamp::Command
836
+ module SubCommands
837
+ # show-version subcommand
838
+ class ShowVersion < Abstract::SubCommand
839
+ include AssLauncher::Enterprise::CliDefsLoader
840
+
841
+ def self.command_name
842
+ 'show-version'
843
+ end
844
+
845
+ def self._banner
846
+ 'Show version of ass_launcher gem and'\
847
+ ' list of known 1C:Enterprise'
848
+ end
849
+
850
+ def known_versions_list
851
+ " - v#{defs_versions.reverse.map(&:to_s).join("\n - v")}"
852
+ end
853
+
854
+ def execute
855
+ puts Colorize.yellow('ass_launcher:')\
856
+ + Colorize.green(" v#{AssLauncher::VERSION}")
857
+ puts Colorize.yellow('Known 1C:Enterprise:')
858
+ puts Colorize.green(known_versions_list)
859
+ end
860
+ end
861
+
862
+ # env subcommand
863
+ class Env < Abstract::SubCommand
864
+ include Abstract::Option::SearchPath
865
+ include AssLauncher::Api
866
+
867
+ def self.command_name
868
+ 'env'
869
+ end
870
+
871
+ def self._banner
872
+ 'Show 1C:Enterprise installations'
873
+ end
874
+
875
+ def list(clients)
876
+ " - v#{clients.map(&:version).sort.reverse.join("\n - v")}"
877
+ end
878
+
879
+ # rubocop:disable Metrics/AbcSize
880
+ def execute
881
+ puts Colorize.yellow '1C:Enterprise installations was searching in:'
882
+ puts Colorize
883
+ .green " - #{AssLauncher::Enterprise.search_paths.join("\n - ")}"
884
+ puts Colorize.yellow 'Thick client installations:'
885
+ puts Colorize.green list(thicks)
886
+ puts Colorize.yellow 'Thin client installations:'
887
+ puts Colorize.green list(thins)
888
+ end
889
+ # rubocop:enable Metrics/AbcSize
890
+ end
891
+ end
892
+
893
+ # Main cmd invoker
894
+ Dir.glob File.join(File.expand_path('../cmd', __FILE__), '*.rb') do |lib|
895
+ require lib if File.basename(lib) != 'abstract.rb'
896
+ end
897
+
898
+ extend Abstract::SubCommand::Declaration
899
+
900
+ declare_subcommands
901
+ end
902
+ end
903
+ end