ass_launcher 0.2.2 → 0.3.0

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