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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a5b8798a403c888bd5947f3edb2030e81f17c68
4
- data.tar.gz: 762c0454cbc5b5505b090bc94112c929de13a624
3
+ metadata.gz: c6b94d52dbe7ef1d1765d781154d6ace91eb0341
4
+ data.tar.gz: 9869be552aafa7badc2150e4c9e9ad41ccd99bb0
5
5
  SHA512:
6
- metadata.gz: 9a010b42049e37397630746ec11ec815bde30b4205ded2aeeea658adc37e4de9296cc95a36f915b3269d5c89c40ef0774bfcb8e285860127a200779d2348e1f5
7
- data.tar.gz: 5a642317ae14b69c5a8b9c3181eb29ed023a34e636b5e4364a8987ed30fd010b8e70d604fd66625b9522aaf057056377410d2c4aa071c10f94e2c959fe07ce62
6
+ metadata.gz: 87421d5aad3ed605426ff419c02101cbed5354c45139d961db4a3e0cfc194f4ca6cd544fa48ed5977ad541e3e072a9fcdb100f6ca1ae92c9a622c59ba0c70c95
7
+ data.tar.gz: 9f40bbfdfd74bbfc56ae5e76f2be176feddb9e19ad245ea9c0b5b0259cac8a141d6f85288ff94a594bc2ffb906c4a4304fd4bbe417987f11003e3180106c7d55
data/README.md CHANGED
@@ -1,8 +1,18 @@
1
+
2
+ [![Code Climate](https://codeclimate.com/github/leoniv/ass_launcher/badges/gpa.svg)](https://codeclimate.com/github/leoniv/ass_launcher)
1
3
  # AssLauncher
2
4
 
3
- Ruby wrapper for 1C:Enterprise platform. Don't ask why this necessary. Believe this necessary!
5
+ Ruby wrapper for 1C:Enterprise platform.
6
+
7
+ Goal of this to make easily and friendly writing scripts for development
8
+ and support lifecycle of 1C:Enterprise applications
9
+
10
+ `AssLauncher` is cross platform but **it full tested in `Cygwin` only!**. In `Windows` and `Linux` it works too.
11
+
12
+ In `Linux` don't support `OLE` feature. Don't known why I told it ;)
4
13
 
5
- ## Installation
14
+
15
+ ## Quick start
6
16
 
7
17
  Add this line to your application's Gemfile:
8
18
 
@@ -18,97 +28,72 @@ Or install it yourself as:
18
28
 
19
29
  $ gem install ass_launcher
20
30
 
21
- ## Usage
22
-
23
- For example:
31
+ For example, writing script which dumping 1C:Enterprise application
24
32
 
25
33
  ```ruby
26
34
  require 'ass_launcher'
27
35
 
28
- include AssLauncher::API
36
+ include AssLauncher::Api
29
37
 
30
- #
31
- # Get 1C:Enterprise v8.3.7 binary wrapper
32
- #
38
+ def main(dupm_path)
39
+ # Get wrapper for the thck client
40
+ thick_client = thicks('~> 8.3.8.0').last
33
41
 
34
- cl = thick_clients('~> 8.3.7').last
42
+ # Fail if 1C:Enterprise installation not found
43
+ fail '1C:Enterprise not found' if thick_client.nil?
35
44
 
36
- raise '1C:Enterprise v8.3.7 not found' if cl.nil?
45
+ # Build designer command
46
+ designer = thick_client.command :designer do
47
+ _S 'enterprse_server/application_name'
48
+ dumpIB dupm_path
49
+ end
37
50
 
38
- #
39
- # create new infobase
40
- #
51
+ # Execute command
52
+ designer.run.wait
41
53
 
42
- conn_str = connection_string 'File="./new.ib"'
54
+ # Verify result
55
+ designer.process_holder.result.verify!
56
+ end
43
57
 
44
- ph = cl.command(:createinfobase) do
45
- connection_string conn_str
46
- _AddInList
47
- end.run.wait
58
+ main ARGV[0]
59
+ ```
48
60
 
49
- raise 'Error while create infobase' if ph.result.success?
61
+ ## Usage
50
62
 
51
- #
52
- # dump infobase
53
- #
63
+ ### Examples
54
64
 
55
- command = cl.command(:designer) do
56
- connection_string 'File="./new.ib"'
57
- _DumpIB './new.ib.dt'
58
- end
65
+ For more usage examples see [examples](examples/)
59
66
 
60
- ph = command.run
61
- ph.wait
67
+ For beginning look at
68
+ [examples/enterprise_running_example.rb](examples/enterprise_running_example.rb)
62
69
 
63
- ph.result.verify! # raised error unless executing success
70
+ All [examples](examples/) executable. For run them require
71
+ 1C:Enterprise platform version defined in `Examples::MIN_PLATFORM_VERSION`
64
72
 
65
- #
66
- # run designer for development
67
- #
73
+ Run all examples:
68
74
 
69
- ph = cl.command(:designer) do
70
- connection_string 'File="./new.ib"'
71
- end.run
75
+ $rake run_examples
72
76
 
73
- # .... do in designer
77
+ Or run specified example:
74
78
 
75
- ph.kill # kill designer
79
+ $rake run_examples TEST=examples/enterprise_running_example.rb
76
80
 
77
- ```
81
+ ### Troubles
78
82
 
79
- ## Releases
83
+ Directory [examples/troubles](examples/troubles) contains examples
84
+ which describe troubles with executing 1C:Enterprise binary.
80
85
 
81
- ### 0.1.1.alpha
82
- - ```Cli::ArgumentsBuilder``` not implements
83
- - ```Cli::CliSpec``` require extracts in standalone ```gem```
84
- - ```WebClients``` not implements
85
- - ```API``` not implements
86
- - ```Support::``` stable
87
- - ```Enterprse``` stable
88
- - ```BinaryWrapper``` mostly stable, depends ```Cli::ArgumentsBuilder```
89
- - ```Enterprse::Ole``` stable
86
+ All [examples/troubles](examples/troubles) are executable too.
90
87
 
91
- #### Small exaple:
88
+ Run all troubles:
92
89
 
93
- ```ruby
94
- require 'ass_launcher'
95
- cs = AssLauncher::Support::ConnectionString.new('File="tmp/tmp.i";Usr="root"')
96
- tc = AssLauncher::Enterprise.thick_clients('~> 8.3').last
97
- cmd = tc.command :designer, cs.to_args
98
- cmd.run # Opens 1C Designer
90
+ $rake run_trouble_examples
99
91
 
100
- com_conn = AssLauncher::Enterprise::Ole::IbConnection.new '~>8.3'
101
- com_conn.__open__ cs # Open ole connection into infobase
92
+ **Be careful to run [examples/troubles](examples/troubles)! Learn sources before run it.**
102
93
 
103
- a = com_conn.newObject 'array'
104
- a.add 'Hello World'
94
+ ## Help
105
95
 
106
- puts com_con.string a.get(0) # => "Hello World"
107
-
108
- com_con.__close__
109
-
110
- cmd.process_holder.kill # Not forget to kill 1C Designer process!
111
- ```
96
+ If you have any questions open issue with `question` lable
112
97
 
113
98
  ## Development
114
99
 
@@ -116,7 +101,24 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
116
101
 
117
102
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
118
103
 
104
+ ### Development helper
105
+
106
+ `AssLauncher` include [bin/dev-helper](bin/dev-helper) utility for contributors.
107
+
108
+ $bin/dev-helper --help
109
+
110
+ ### Testing
111
+
112
+ #### Run unit tests:
113
+
114
+ $export SIMPLECOV=YES && rake test
115
+
116
+ Unit tests is isolated and doesn't require installation of 1C:Enterprise
117
+
118
+ #### Run examples:
119
+
120
+ Examples writed as `Minitest::Spec`. About run examples see above
121
+
119
122
  ## Contributing
120
123
 
121
124
  Bug reports and pull requests are welcome on GitHub at https://github.com/leoniv/ass_launcher.
122
-
data/Rakefile CHANGED
@@ -7,4 +7,23 @@ Rake::TestTask.new(:test) do |t|
7
7
  t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
+ Rake::TestTask.new(:run_examples) do |t|
11
+ exec_ole = RbConfig::CONFIG['host_os'].downcase =~ %r{mingw|mswin|cygwin}
12
+ t.libs << 'examples'
13
+ t.libs << 'lib'
14
+ examples = FileList['examples/**/*_example.rb']
15
+ if exec_ole
16
+ t.test_files = examples - examples.grep(%r{troubles/}i)
17
+ else
18
+ t.test_files = examples - examples.grep(%r{troubles/|enterprise_ole_example}i)
19
+ end
20
+ end
21
+
22
+ Rake::TestTask.new(:run_trouble_examples) do |t|
23
+ t.libs << 'examples'
24
+ t.libs << 'lib'
25
+ examples = FileList['examples/**/*_example.rb']
26
+ t.test_files = examples.grep(%r{trouble}i)
27
+ end
28
+
10
29
  task :default => :test
data/ass_launcher.gemspec CHANGED
@@ -19,14 +19,20 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
  spec.license = 'MIT'
21
21
 
22
+ spec.required_ruby_version = '~> 2.0'
23
+
24
+ spec.metadata = {'known_enterprise_versions' => AssLauncher::KNOWN_ENTERPRISE_VERSIONS.get.join(', ')}
25
+
22
26
  spec.add_dependency "inifile"
23
- spec.add_dependency "ffi"
24
27
  spec.add_dependency "methadone"
28
+ spec.add_dependency "addressable", "= 2.4.0"
25
29
 
26
30
  spec.add_development_dependency "bundler", "~> 1.10"
27
31
  spec.add_development_dependency "rake", "~> 10.0"
28
32
  spec.add_development_dependency "minitest"
29
33
  spec.add_development_dependency "pry"
30
- spec.add_development_dependency "mocha"
34
+ spec.add_development_dependency "mocha", "= 1.1.0"
31
35
  spec.add_development_dependency "simplecov"
36
+ spec.add_development_dependency "clamp"
37
+ spec.add_development_dependency "coderay"
32
38
  end
data/bin/dev-helper ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'ass_launcher'
5
+ require_relative './lib/dev_helper'
6
+
7
+ DevHelper::Cmd::Main.run
@@ -0,0 +1,191 @@
1
+ module DevHelper
2
+ class CliDefReport
3
+ module Cmd
4
+ require 'clamp'
5
+ class AbstractCommand < Clamp::Command
6
+ option ['-v', '--version'], 'VERSION',
7
+ 'specific 1C:Enterprise version'
8
+ end
9
+
10
+ class Report < AbstractCommand
11
+ option '--clients', 'CLIENTS ...', 'specific clients' do |s|
12
+ s.split.map(&:to_sym).map(&:downcase)
13
+ end
14
+
15
+ option '--modes', 'MODES ...', 'specific run modes' do |s|
16
+ s.split.map(&:to_sym).map(&:downcase)
17
+ end
18
+
19
+ option ['-c', '--columns'], 'COLUMNS ...',
20
+ 'specific report columns' do |s|
21
+ s.split.map(&:to_sym).map(&:downcase)
22
+ end
23
+
24
+ option ['-a', '--show-appiared-only'], :flag,
25
+ 'show parameters which appiared in --version only'
26
+
27
+ option ['-s', '--skipped-only'], :flag,
28
+ 'show skipped parameters'
29
+
30
+ def execute
31
+ $stdout.puts DevHelper::CliDefReport
32
+ .for(version, clients: clients, modes: modes,
33
+ appiared_only: show_appiared_only?,
34
+ skipped_only: skipped_only?).to_csv(columns)
35
+ rescue ArgumentError => e
36
+ signal_usage_error e.message
37
+ end
38
+ end
39
+ end
40
+
41
+ COLUMS = [:full_name, :parameter, :klass, :parent, :group, :modes,
42
+ :clients, :requirement, :have_value_validator,
43
+ :have_switch_value, :accepted_values, :desc]
44
+ class ParamReport
45
+ CliDefReport::COLUMS.each do |col|
46
+ attr_accessor col
47
+ end
48
+
49
+ def initialize
50
+ yield self
51
+ end
52
+
53
+ def to_csv(columns)
54
+ r = ''
55
+ columns.each do |col|
56
+ r << "\"#{self.send(col).to_s.gsub('"','\'')}\";"
57
+ end
58
+ r.gsub(/;$/,'')
59
+ end
60
+ end
61
+
62
+ def self.for(version = nil, **filter)
63
+ new(version, **filter).execute
64
+ end
65
+
66
+ DEF_FILER = {clients: nil,
67
+ modes: nil,
68
+ skipped_only: false,
69
+ appiared_only: nil}
70
+
71
+ include DevHelper::CliDefValidator
72
+
73
+ attr_reader :version
74
+ def initialize(version = nil, **filter)
75
+ @version = version
76
+ @filter = DEF_FILER.merge filter
77
+ validate_modes
78
+ validate_clients
79
+ end
80
+
81
+ def version
82
+ Gem::Version.new(@version.to_s) if @version
83
+ end
84
+
85
+ def filter(name)
86
+ @filter[name] || instance_eval("valid_#{name}")
87
+ end
88
+
89
+ def skipped_only?
90
+ @filter[:skipped_only]
91
+ end
92
+
93
+ def appiared_only
94
+ @filter[:appiared_only] || false
95
+ end
96
+
97
+ def to_csv(columns = nil)
98
+ _columns = columns || COLUMS
99
+ r = "#{_columns.join(';')}\n"
100
+ rows.each do |row|
101
+ r << row.to_csv(_columns)
102
+ r << "\n"
103
+ end
104
+ r
105
+ end
106
+
107
+ def clients
108
+ filter(:clients)
109
+ end
110
+
111
+ def modes
112
+ filter(:modes)
113
+ end
114
+
115
+ def new_row(p)
116
+ ParamReport.new do |pr|
117
+ pr.parameter = p
118
+ pr.full_name = p.full_name
119
+ pr.klass = p.class
120
+ pr.parent = p.parent
121
+ pr.group = p.group
122
+ pr.modes = p.modes
123
+ pr.clients = p.binary_matcher.clients
124
+ pr.requirement = p.binary_matcher.requirement
125
+ pr.have_value_validator = !p.options[:value_validator].nil?
126
+ pr.have_switch_value = !p.options[:switch_value].nil?
127
+ pr.accepted_values = accepted_values_get(p)
128
+ pr.desc = p.desc
129
+ end
130
+ end
131
+
132
+ def accepted_values_get(p)
133
+ xxx_list_keys(:switch ,p) + xxx_list_keys(:chose, p)
134
+ end
135
+
136
+ def xxx_list_keys(list, p)
137
+ list = p.send("#{list}_list".to_sym)
138
+ return list.keys if list
139
+ []
140
+ end
141
+
142
+ def write(file, format = :csv)
143
+ fail "Fiele #{file} exists. Use #write!" if File.exists?(file)
144
+ write!(file, format)
145
+ end
146
+
147
+ def write!(file, format = :csv)
148
+ f = File.new(file, 'w')
149
+ f.write send("to_#{format}".to_sym)
150
+ f.close
151
+ end
152
+
153
+ def rows
154
+ @rows ||= []
155
+ end
156
+
157
+ def not_filtred?(p)
158
+ return skip?(p) if skipped_only?
159
+ clients?(p) && modes?(p)
160
+ end
161
+
162
+ def clients?(p)
163
+ (p.binary_matcher.clients & filter(:clients)).size > 0
164
+ end
165
+
166
+ def modes?(p)
167
+ (p.modes & filter(:modes)).size > 0
168
+ end
169
+
170
+ def skip?(p)
171
+ p.is_a? AssLauncher::Enterprise::Cli::Parameters::Skip
172
+ end
173
+
174
+ def execute
175
+ AssLauncher::Enterprise::Cli::CliSpec
176
+ .cli_def.parameters.parameters.each do |p|
177
+ rows << new_row(p) if match_version?(p) && not_filtred?(p)
178
+ end
179
+ self
180
+ end
181
+
182
+ def match_version?(p)
183
+ return true if version.nil?
184
+ if appiared_only
185
+ p.binary_matcher.requirement.to_s =~ /^>=\s*#{version}/
186
+ else
187
+ p.match_version?(version) unless appiared_only
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,426 @@
1
+ class String
2
+ def snakize
3
+ gsub(/(.)([A-Z])/,'\1_\2').downcase
4
+ end
5
+ end
6
+ module DevHelper
7
+ module CliDefSnippets
8
+ require 'clamp'
9
+ module Cmd
10
+ module Colorize
11
+ require 'coderay'
12
+ CodeRay::Encoders::Terminal::TOKEN_COLORS[:comment][:self] = "\e[1;34m"
13
+
14
+ def colorize_puts(str)
15
+ $stdout.puts colorize(str)
16
+ end
17
+
18
+ def colorize(str)
19
+ return CodeRay.scan(str, :ruby).terminal if colorize?
20
+ str
21
+ end
22
+ private :colorize
23
+
24
+ def self.included(klass)
25
+ klass.instance_eval do
26
+ option "--colorize", :flag, "colorize out"
27
+ end
28
+ end
29
+ end
30
+
31
+ module SpecDsl
32
+ class AbstractSpecDsl < Clamp::Command
33
+ include Colorize
34
+ option ['-n', '--name'], 'NAME', 'parameter name', required: true
35
+
36
+ def self.banner
37
+ "snippet for <#{dsl_method}> DSL method"
38
+ end
39
+
40
+ def self.dsl_method
41
+ name.split('::').last.snakize
42
+ end
43
+
44
+ def dsl_method
45
+ self.class.dsl_method
46
+ end
47
+ end
48
+
49
+ class New < Clamp::Command
50
+ BANNER = 'snippet for specification parameter'
51
+ class Abstract < AbstractSpecDsl
52
+ option ['-s', '--subparameters'], 'SPECS ...',
53
+ 'generate reduced snippet'\
54
+ ' for subparameters like "type \'NAME\' ..."' do |s|
55
+ s.split
56
+ end
57
+
58
+ option ['-g', '--group'], 'GROUP', 'group of parameter.'\
59
+ ' Uses with --modes' do |s|
60
+ s.downcase.to_sym
61
+ end
62
+
63
+ option ['-m', '--modes'], 'MODES ...',
64
+ 'run modes for which parameter defined'\
65
+ ' Uses with --group' do |s|
66
+ s.split.map(&:downcase).map(&:to_sym)
67
+ end
68
+
69
+ option ['-d', '--desc'], 'DESC', 'parameter description.'
70
+
71
+ option ['-c','--clients'], 'CLIENTS ...',
72
+ 'clients for which parameter defined' do |s|
73
+ s.split.map(&:to_sym).map(&:downcase)
74
+ end
75
+
76
+ option '--validator', :flag,
77
+ 'snippet will be generate with :value_validator stub'
78
+
79
+ option '--required', :flag,
80
+ 'snippet will be generate with option :required => true'
81
+
82
+ def args
83
+ r = {}
84
+ r[:name] = name
85
+ r[:subparameters] = subparameters if subparameters
86
+ r[:group] = group if group
87
+ r[:modes] = modes if modes
88
+ r[:desc] = desc if desc
89
+ r[:clients] = clients if clients
90
+ r[:value_validator] = validator? if validator?
91
+ r[:required] = required? if required?
92
+ r
93
+ end
94
+
95
+ def execute
96
+ signal_usage_error 'Use --group & --modes together' if\
97
+ (group.nil? ^ modes.nil?)
98
+ begin
99
+ #$stdout.puts\
100
+ colorize_puts\
101
+ CliDefSnippets::SpecDsl::Param.new(dsl_method, **args)\
102
+ .to_snippet
103
+ rescue ArgumentError => e
104
+ signal_usage_error e.message
105
+ end
106
+ end
107
+ end
108
+
109
+ class String < New::Abstract; end
110
+ class Flag < String; end
111
+ class Path < New::Abstract; end
112
+ class PathExist < New::Abstract; end
113
+ class PathNotExist < New::Abstract; end
114
+ class Url < New::Abstract; end
115
+ class Num < New::Abstract; end
116
+ class Switch < New::Abstract
117
+ option ['-l', '--switch-list'], 'VALUES ...', 'list of accepted values',
118
+ required: true do |s|
119
+ s.split.map(&:to_sym)
120
+ end
121
+
122
+ def args
123
+ r = super
124
+ r[:switch_list] = switch_list
125
+ r
126
+ end
127
+ end
128
+
129
+ class Chose < New::Abstract
130
+ option ['-l', '--chose-list'], 'VALUES ...', 'list of accepted values',
131
+ required: true do |s|
132
+ s.split.map(&:to_sym)
133
+ end
134
+
135
+ def args
136
+ r = super
137
+ r[:chose_list] = chose_list
138
+ r
139
+ end
140
+ end
141
+
142
+ DSL_METHODS = {
143
+ 'string' => [String.banner, String],
144
+ 'flag' => [Flag.banner, Flag],
145
+ 'path' => [Path.banner, Path],
146
+ 'path_exist' => [Path.banner, PathExist],
147
+ 'path_not_exist' => [Path.banner, PathNotExist],
148
+ 'url' => [Url.banner, Url],
149
+ 'num' => [Num.banner, Num],
150
+ 'switch' => [Switch.banner, Switch],
151
+ 'chose' => [Chose.banner, Chose]
152
+ }
153
+
154
+ DSL_METHODS.each do |k,v|
155
+ subcommand k, *v
156
+ end
157
+
158
+ # subcommand 'string', String.banner, String
159
+ # subcommand 'path', Path.banner, Path
160
+ # subcommand 'path_exist', Path.banner, PathExist
161
+ # subcommand 'path_not_exist', Path.banner, PathNotExist
162
+ # subcommand 'url', Url.banner, Url
163
+ # subcommand 'num', Num.banner, Num
164
+ # subcommand 'switch', Switch.banner, Switch
165
+ # subcommand 'chose', Chose.banner, Chose
166
+ end
167
+
168
+ class Restrict < AbstractSpecDsl
169
+ BANNER = 'snippet for restrict parameter'
170
+
171
+ def execute
172
+ begin
173
+ #$stdout.puts\
174
+ colorize_puts\
175
+ CliDefSnippets::SpecDsl::Restrict.new(name)\
176
+ .to_s
177
+ rescue ArgumentError => e
178
+ signal_usage_error e.message
179
+ end
180
+ end
181
+ end
182
+
183
+ class Change < AbstractSpecDsl
184
+ BANNER = 'snippet for change parameter specification'
185
+
186
+ option ['-s', '--subparameters'], 'SPECS ...',
187
+ 'generate reduced snippet'\
188
+ ' for subparameters like "type \'NAME\' ..."' do |s|
189
+ s.split
190
+ end
191
+
192
+ def args
193
+ r = {}
194
+ r[:name] = name
195
+ r[:subparameters] = subparameters if subparameters
196
+ # r[:group] = group if group
197
+ # r[:modes] = modes if modes
198
+ # r[:desc] = desc if desc
199
+ # r[:clients] = clients if clients
200
+ # r[:value_validator] = validator? if validator?
201
+ # r[:required] = required? if required?
202
+ r
203
+ end
204
+
205
+ def execute
206
+ begin
207
+ # colorize_puts\
208
+ # CliDefSnippets::SpecDsl::Restrict.new(name)\
209
+ # .to_s
210
+ # $stdout.puts fail('FIXME')
211
+ colorize_puts\
212
+ CliDefSnippets::SpecDsl::Change.new(name, **args).to_snippet
213
+ rescue ArgumentError => e
214
+ signal_usage_error e.message
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ class Main < Clamp::Command
221
+ def self._banner
222
+ 'generator snippets on DSL (see AssLauncher::Enterprise::Cli::SpdecDsl)'
223
+ end
224
+
225
+ subcommand 'new', SpecDsl::New::BANNER, SpecDsl::New
226
+ subcommand 'restrict', SpecDsl::Restrict::BANNER, SpecDsl::Restrict
227
+ subcommand 'change', SpecDsl::Change::BANNER, SpecDsl::Change
228
+ end
229
+ end
230
+
231
+ module SpecDsl
232
+ class Group
233
+ include DevHelper::CliDefValidator
234
+ attr_reader :name
235
+ def initialize(name)
236
+ @name = name
237
+ validate_group if self.class == Group
238
+ end
239
+
240
+ def group_name
241
+ name
242
+ end
243
+
244
+ def self.dsl_method
245
+ name.split('::').last.snakize
246
+ end
247
+
248
+ def dsl_method
249
+ self.class.dsl_method
250
+ end
251
+
252
+ def indents
253
+ 2
254
+ end
255
+
256
+ def indent(inclosure)
257
+ inclosure.gsub(/^/,' ' * indents)
258
+ end
259
+
260
+ def dsl_method_args
261
+ ":#{name.to_sym.downcase}"
262
+ end
263
+
264
+ def to_s(inclosure = '')
265
+ r = ''
266
+ r << "#{dsl_method} #{dsl_method_args} do\n"
267
+ r << indent(inclosure) + "\n"
268
+ r << 'end'
269
+ end
270
+ end
271
+
272
+ class Restrict < Group
273
+ def to_s
274
+ "#{dsl_method} '#{name}'"
275
+ end
276
+ end
277
+
278
+ class Mode < Group
279
+ attr_reader :modes
280
+ def initialize(modes)
281
+ @modes = modes
282
+ validate_modes
283
+ end
284
+
285
+ def dsl_method_args
286
+ modes.map(&:to_sym).map(&:downcase).to_s.gsub(/(\[|\])/,'')
287
+ end
288
+ end
289
+
290
+ class Param < Group
291
+ DEFAULT_ARGS = {
292
+ subparameters: [],
293
+ group: nil,
294
+ modes: nil,
295
+ desc: nil,
296
+ clients: nil,
297
+ value_validator: nil,
298
+ required: nil,
299
+ chose_list: nil,
300
+ switch_list: nil
301
+ }
302
+ def initialize(dsl_method, **args)
303
+ @name = args[:name]
304
+ @dsl_method = dsl_method
305
+ @args = DEFAULT_ARGS.merge args
306
+ validate_clients if clients
307
+ end
308
+
309
+ def DSL_METHODS
310
+ Cmd::SpecDsl::New::DSL_METHODS
311
+ end
312
+
313
+ def valid_dsl_method(method)
314
+ fail ArgumentError, "Invalid DSL method `#{method}'."\
315
+ " Expects: #{DSL_METHODS().keys.to_s}" unless\
316
+ DSL_METHODS().keys.include? method
317
+ method
318
+ end
319
+
320
+ attr_reader :args, :dsl_method
321
+
322
+ def to_dsl_method(name)
323
+ signal_usage_error "--subparameters SPECS format:"\
324
+ " `ptype:pname' or `pname'" if name.split(':').size > 2
325
+ return '#FIXME: ptype' if name.split(':').size == 1
326
+ valid_dsl_method name.split(':')[0]
327
+ end
328
+
329
+ def subparameters_to_s
330
+ subparameters.map do |name|
331
+ Param.new(to_dsl_method(name),
332
+ name: name.split(':').last,
333
+ desc: 'FIXME: description',
334
+ clients: clients,
335
+ required: '#FIXME: bool',
336
+ ).to_snippet
337
+ end.join("\n")
338
+ end
339
+
340
+ def method_missing(m, *_)
341
+ fail NoMethodError unless args.key? m
342
+ args[m]
343
+ end
344
+
345
+ def switch_list_stub(i)
346
+ list_stub(switch_list, i)
347
+ end
348
+
349
+ def chose_list_stub(i)
350
+ list_stub(chose_list, i)
351
+ end
352
+
353
+ def list_stub(list, i)
354
+ list.map(&:to_sym).to_s.gsub(/(\[|\])/,'').split(',').map do |item|
355
+ "#{item} => 'FIXME: description'"
356
+ end.join(",#{nl(i)}")
357
+ end
358
+
359
+ def nl(i)
360
+ "\n#{' '*i}"
361
+ end
362
+
363
+ def dsl_method_args(i)
364
+ r = "'#{name}'"
365
+ r << ", '#{desc}'" if desc
366
+ r << ", #{clients.map(&:to_s).map(&:downcase)
367
+ .to_s.gsub(/(\[|\]|")/,'')}" if clients
368
+ r << ", required: #{required}" if required
369
+ if switch_list
370
+ h = ",#{nl(i)}switch_list: switch_list("
371
+ r << "#{h}#{switch_list_stub(h.size - 3)})"\
372
+ end
373
+ if chose_list
374
+ h = ",#{nl(i)}chose_list: chose_list("
375
+ r << "#{h}#{chose_list_stub(h.size - 3)})"\
376
+ end
377
+ r << ",#{nl(i)}value_validator: proc {|value| fail 'FIXME'}" if\
378
+ value_validator
379
+ r
380
+ end
381
+
382
+ def to_s(inclosure = '')
383
+ r = "#{dsl_method} #{dsl_method_args(dsl_method.size + 1)}"
384
+ unless inclosure.empty?
385
+ r << " do\n"
386
+ r << indent(inclosure) + "\n"
387
+ r << 'end'
388
+ end
389
+ r
390
+ end
391
+
392
+ def wrrapp(s)
393
+ g = Group.new(group)
394
+ m = Mode.new(modes)
395
+ g.to_s(m.to_s(s))
396
+ end
397
+
398
+ def to_snippet
399
+ return wrrapp(to_s(subparameters_to_s)) if group
400
+ to_s(subparameters_to_s)
401
+ end
402
+ end
403
+
404
+ class Change < Param
405
+ def subparameters_to_s
406
+ subparameters.map do |name|
407
+ r = ''
408
+ r << Restrict.new(name.split(':').last).to_s
409
+ r << "\n"
410
+ r << Param.new(to_dsl_method(name),
411
+ name: name.split(':').last,
412
+ desc: 'FIXME: description',
413
+ clients: clients,
414
+ required: '#FIXME: bool',
415
+ ).to_snippet
416
+ r
417
+ end.join("\n")
418
+ end
419
+
420
+ def dsl_method
421
+ :change
422
+ end
423
+ end
424
+ end
425
+ end
426
+ end