tla-sbuilder 0.1.0 → 0.2.1

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 +116 -33
  3. data/VERSION +1 -1
  4. data/lib/cli/cli-customer.rb +41 -23
  5. data/lib/cli/cli-example.rb +1 -1
  6. data/lib/cli/cli-pet.rb +33 -30
  7. data/lib/cli/cli-text.rb +57 -17
  8. data/lib/cli/cli.rb +56 -10
  9. data/lib/sbuilder.rb +3 -1
  10. data/lib/sbuilder/constants.rb +5 -2
  11. data/lib/sbuilder/controller.rb +289 -59
  12. data/lib/sbuilder/default-sbuilder.yaml +25 -3
  13. data/lib/sbuilder/domain.rb +1 -1
  14. data/lib/sbuilder/domain_cardinality.rb +1 -1
  15. data/lib/sbuilder/domain_value.rb +1 -1
  16. data/lib/sbuilder/exception.rb +13 -7
  17. data/lib/sbuilder/extension_loader.rb +75 -18
  18. data/lib/sbuilder/facade/api_loader.rb +293 -0
  19. data/lib/sbuilder/factory.rb +66 -3
  20. data/lib/sbuilder/model.rb +59 -3
  21. data/lib/sbuilder/mustache/template.rb +13 -13
  22. data/lib/sbuilder/mustache/template_reader_context.rb +5 -3
  23. data/lib/sbuilder/param_set.rb +2 -1
  24. data/lib/sbuilder/param_set_db.rb +1 -1
  25. data/lib/sbuilder/param_set_def.rb +1 -1
  26. data/lib/sbuilder/param_set_if.rb +1 -1
  27. data/lib/sbuilder/param_set_loader_swagger.rb +122 -121
  28. data/lib/sbuilder/param_set_step.rb +1 -1
  29. data/lib/sbuilder/parameter.rb +1 -1
  30. data/lib/sbuilder/parameter_container.rb +1 -1
  31. data/lib/sbuilder/parameter_dom.rb +1 -1
  32. data/lib/sbuilder/parameter_ref.rb +2 -2
  33. data/lib/sbuilder/resolver_rule.rb +1 -1
  34. data/lib/sbuilder/resolver_rule_match.rb +1 -1
  35. data/lib/sbuilder/resolver_rule_ref.rb +1 -1
  36. data/lib/sbuilder/spec/README +5 -0
  37. data/lib/sbuilder/spec/api_loader_facade.rb +247 -0
  38. data/lib/utils/cache_lines.rb +21 -0
  39. data/lib/utils/netio.rb +5 -13
  40. data/mustache/cfg/macro_run.mustache +1 -0
  41. data/mustache/interface_processes.mustache +9 -2
  42. data/mustache/interface_stubs_dummy.mustache +7 -0
  43. data/mustache/interface_types.mustache +3 -3
  44. data/mustache/invariant_activate.mustache +16 -0
  45. data/mustache/setup/assumptions_activate.mustache +16 -0
  46. data/mustache/{domains_run.mustache → setup/domains_run.mustache} +2 -2
  47. data/mustache/setup/operator_run.mustache +2 -0
  48. data/mustache/setup/steps_run_bind_set.mustache +1 -1
  49. data/mustache/setup/steps_run_parameterBind.mustache +4 -2
  50. data/mustache/tla/macro_run.mustache +8 -0
  51. data/mustache/tla/operator_run.mustache +1 -0
  52. data/mustache/tla/plc_define_run.mustache +2 -4
  53. data/mustache/tla/plc_run_state.mustache +1 -1
  54. data/src-extend/extend/extend_invariant_cfg.mustache +1 -1
  55. data/src/pet/assumption_domains.tla +1 -1
  56. data/src/pet/correctness.cfg +4 -0
  57. data/tla-sbuilder.gemspec +3 -1
  58. metadata +14 -10
  59. data/lib/sbuilder/param_set_loader.rb +0 -77
  60. data/src-extend/extend_app/correctness.cfg +0 -9
@@ -2,43 +2,78 @@ module Sbuilder
2
2
 
3
3
  class CliText
4
4
 
5
- SBUILDER_RESOLVERS = <<-EOS
5
+ SBUILDER_EXTENSION = <<-EOS.unindent
6
+
7
+ # Load and configure sbuilder plugin extensions
8
+ #
9
+ # SCHEMA
10
+ #
11
+ # extend:
12
+ # loaders:
13
+ # - gem: <gem-name>
14
+ # className: <class name>
15
+ # configuration:
16
+ # <configuration-value>
17
+ #
18
+ # <gem-name>: gem name to require
19
+ # <class name>: name of interface loader in 'type' property in 'interfaces' array
20
+ # <configuration-value>: a (hash) value passed to 'className'::configure' -method
21
+ #
22
+ EOS
23
+
24
+ SBUILDER_INVARIANTS = <<-EOS.unindent
25
+
26
+ # Activate invariant operator defines in sBuilder code repository
27
+ #
28
+ # SCHEMA:
29
+ #
30
+ # invariants:
31
+ # - <invariant-name>: <invariant description>
32
+ #
33
+ #
34
+ # <invariant-name>: name of TlAplus operator defined in sBuilder code repository
35
+ # <invariant description>: documentantion text for the invariant
36
+ #
37
+ EOS
38
+
39
+
40
+
41
+ SBUILDER_RESOLVERS = <<-EOS.unindent
6
42
 
7
43
  # Define how parameter names are mapped to domain
8
44
  #
9
45
  # SCHEMA:
10
46
  #
11
47
  # resolvers:
12
- # - type: <resolver load type>
13
- # file: <file name in cnf-dir>
48
+ # - file: <file name in cnf-dir>
14
49
  # url: <path or url>
15
50
  #
16
- # <resolver load type>: resolver loader type, valid values: [ 'resolver_yaml' ]
51
+ # Give either 'file' or 'url'
17
52
  # <file name in cnf-dir>: file name in cnf-directory
18
53
  # <path or url>: path relative to cwd, or http url
19
54
  #
20
55
  #
21
- # COMMENTS:
22
- # - give 'file' xor 'url' property
23
56
  #
24
57
 
25
58
  EOS
26
59
 
27
- SBUILBER_INTERFACES = <<-EOS
60
+ SBUILBER_INTERFACES = <<-EOS.unindent
28
61
 
29
62
  # Define how to load interfaces configuration
30
63
  #
31
64
  # SCHEMA:
32
65
  #
33
66
  # interfaces:
34
- # - type: <interface loader type>
67
+ # - type: <interface loader name>
35
68
  #
36
69
  # file: <file name in cnf-dir>
37
70
  # infrastructureServices: <is infrastructureService>
38
71
  # url: <path or url>
39
72
  # cache: <cache file path>
40
73
  #
41
- # <interface loader type>: interface loader type, valid values: [ 'swagger' ]
74
+ # <interface loader name>: name of interface loader,
75
+ # valid values: 'swagger' and className values
76
+ # given in 'extend.loaders' array
42
77
  # <is infrastructureService>: true or false (default false)
43
78
  # <file name in cnf-dir> : file name in cnf-directory
44
79
  # <path or url> : path relative to cwd, or http url,
@@ -55,7 +90,7 @@ module Sbuilder
55
90
  EOS
56
91
 
57
92
 
58
- SBUILER_SETUPS = <<-EOS
93
+ SBUILER_SETUPS = <<-EOS.unindent
59
94
 
60
95
  # Define environment setups
61
96
  #
@@ -67,17 +102,21 @@ module Sbuilder
67
102
  # url: <path or url>
68
103
  # preferences:
69
104
  # <hash-values>
105
+ # assumptions:
106
+ # <assume-op-names>
70
107
  #
71
108
  # <setupname> : name of setup = sub directory under <gen_dir>
72
109
  # <file name in cnf-dir>: name extension configurion file in cnf-directory
73
110
  # <path or url> : relative name or url of configurion file
74
111
  # <hash-values> : optional properties overriding global generate preferences
112
+ # <assume-op-names> : array of operator names to put into ASSUME directives
75
113
  #
76
114
  # COMMENTS:
77
115
  # - preferences property is optional
78
116
  EOS
79
117
 
80
- SBUILDER_GENERATE = <<-EOS
118
+ SBUILDER_GENERATE = <<-EOS.unindent
119
+
81
120
  # Generate definitions
82
121
  #
83
122
  # SCHEMA:
@@ -106,13 +145,14 @@ module Sbuilder
106
145
  #
107
146
  EOS
108
147
 
109
- SBUILDER_PREFERENCES = <<-EOS
148
+ SBUILDER_PREFERENCES = <<-EOS.unindent
149
+
110
150
  # Generate preferences
111
151
  #
112
152
  # preferences:
113
153
  # <hash-values>
114
154
  #
115
- # <hash-values> optional properties passes to templates in 'PREFERENCES' -property
155
+ # <hash-values> key-value pairs passed to mustache templates in 'PREFERENCES' -property
116
156
  #
117
157
  # Default templates use following propeties
118
158
  # debug-output: <true/false>, output call message in interface processes, default 'true'
@@ -120,7 +160,7 @@ module Sbuilder
120
160
  EOS
121
161
 
122
162
 
123
- EXTENSION_HEADER_DOM = <<-EOS
163
+ EXTENSION_HEADER_DOM = <<-EOS.unindent
124
164
 
125
165
  # Define extension for domains
126
166
  #
@@ -142,7 +182,7 @@ module Sbuilder
142
182
 
143
183
  EOS
144
184
 
145
- EXTENSION_HEADER_IF = <<-EOS
185
+ EXTENSION_HEADER_IF = <<-EOS.unindent
146
186
 
147
187
  # Define name of extension point for interface
148
188
  #
@@ -158,7 +198,7 @@ module Sbuilder
158
198
 
159
199
  EOS
160
200
 
161
- EXTENSION_HEADER_SETUP = <<-EOS
201
+ EXTENSION_HEADER_SETUP = <<-EOS.unindent
162
202
 
163
203
  # Define environment steps
164
204
  #
@@ -194,7 +234,7 @@ module Sbuilder
194
234
  EOS
195
235
 
196
236
 
197
- RESOLVER_HEADER = <<-EOS
237
+ RESOLVER_HEADER = <<-EOS.unindent
198
238
  # Example of an YAML resolver
199
239
  #
200
240
  # Contains array of hashes
@@ -184,16 +184,39 @@ module Sbuilder
184
184
  shared_options :verbosity
185
185
  shared_options :cnf_dir
186
186
  def list( what )
187
- whats = [ "setups", "setup" ]
188
- raise <<-EOS unless whats.include?( what )
189
- Unknown command 'list #{what}'
187
+ validateWhats( what )
188
+ ctrl = getCtrl
189
+ # puts "#{ctrl.getSetups().map { |setup| setup['setupDirectory']}.join(' ')}"
190
+ puts "#{getSetupNames(ctrl).join(' ')}"
191
+ end
190
192
 
191
- Valid list targets: #{whats.join(',')}
192
- EOS
193
-
194
- ctrl = getController( options )
195
- ctrl.load
196
- puts "#{ctrl.getSetups().map { |setup| setup['setupDirectory']}.join(' ')}"
193
+
194
+ desc "document [setup]", "Document configuration for all setups or for the given setup"
195
+ shared_options :verbosity
196
+ shared_options :cnf_dir
197
+ def document( what=nil )
198
+ controller = getCtrl
199
+ controller.load
200
+
201
+ validateWhats( what, getSetupNames(controller) ) if what
202
+
203
+ invariants = controller.templateData('invariants')['invariants']
204
+ puts "INVARIANTS:"
205
+ invariants.each do |invariant|
206
+ puts <<-EOS.unindent
207
+ - #{invariant[:name]}: #{invariant[:desc]}
208
+ EOS
209
+ end
210
+ puts "SETUPS:"
211
+ controller.processSetups( what ) do |setupName, setupConf, possibilities|
212
+ assumptions = controller.getSetupAssumptionList( setupConf )
213
+ puts <<-EOS.unindent
214
+ - #{setupName}: #{setupConf['desc']}
215
+ - possibilities: #{(setupConf['possibilities'] || [] ).join( ' ' )}
216
+ - assumptions: #{assumptions.join( ' ' )}
217
+ - interfaces: #{controller.templateData('steps' )['steps'].map {|step| step[:interface_operation] }.uniq.join( ' ' )}
218
+ EOS
219
+ end
197
220
  end
198
221
 
199
222
 
@@ -202,6 +225,22 @@ module Sbuilder
202
225
  # common routines
203
226
  no_commands do
204
227
 
228
+ # ensure that 'what' is correct
229
+ def validateWhats( what, whats = [ "setups", "setup" ] )
230
+ raise <<-EOS unless whats.include?( what )
231
+ Unknown target '#{what}'
232
+
233
+ Valid targets: #{whats.join(',')}
234
+ EOS
235
+
236
+ end
237
+
238
+ # @return [Sbuilder::Controller] contrller, which has loader configurations
239
+ def getCtrl
240
+ ctrl = getController( options )
241
+ return ctrl
242
+ end
243
+
205
244
  # Copy 'extendFile' file to 'dirPath', append {{>benchmark/basename(extendFile}}
206
245
  #
207
246
  # @param dirPath [String] directory where extension file created
@@ -240,6 +279,12 @@ module Sbuilder
240
279
 
241
280
  end
242
281
 
282
+ # @param controller [Sbuilder::Controller] controller to read the setups
283
+ # @return [String:Array] names of setups defined in 'ctrl'
284
+ def getSetupNames( ctrl )
285
+ ctrl.getSetups().map { |setup| setup['setupDirectory'] }
286
+ end
287
+
243
288
  # ------------------------------------------------------------------
244
289
 
245
290
  def init_files( options )
@@ -247,7 +292,8 @@ module Sbuilder
247
292
  [
248
293
  { :file => "#{options[:cnf_dir]}/#{Sbuilder::Constants::CNF_FILE }.example", :content => [ Sbuilder::CliCustomer::SBUILDER_YAML_CUSTOMER] },
249
294
  { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_RESOLVER_CUSTOMER}.example", :content => [ Sbuilder::CliCustomer::RESOLVER_CUSTOMER] },
250
- { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_EXTENSIONS_CUSTOMER_COMMON}.exmaple", :content => [Sbuilder::CliCustomer::EXTENSIONS_CUSTOMER_COMMON] },
295
+ { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_EXTENSIONS_CUSTOMER_COMMON}.example", :content => [Sbuilder::CliCustomer::EXTENSIONS_CUSTOMER_COMMON] },
296
+ { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_EXTENSIONS_CUSTOMER_IF}.example", :content => [Sbuilder::CliCustomer::EXTENSIONS_CUSTOMER_IF] },
251
297
  { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_EXTENSIONS_CUSTOMER_RUN1}.example", :content => [Sbuilder::CliCustomer::EXTENSIONS_CUSTOMER_RUN1] },
252
298
  { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_EXTENSIONS_CUSTOMER_RUN2}.example", :content => [Sbuilder::CliCustomer::EXTENSIONS_CUSTOMER_RUN2] },
253
299
  { :file => "#{options[:cnf_dir]}/#{Sbuilder::CliCustomer::FILE_INTERFACE_CUSTOMER}.example", :content => [Sbuilder::CliCustomer::INTERFACE_CUSTOMER_SWAGGER] },
@@ -4,6 +4,7 @@ require_relative "utils/string_inject"
4
4
 
5
5
  require_relative "utils/version"
6
6
  require_relative "utils/logger"
7
+ require_relative "utils/cache_lines"
7
8
  require_relative "utils/netio"
8
9
 
9
10
  require_relative "sbuilder/constants.rb"
@@ -36,7 +37,7 @@ require_relative "sbuilder/resolver.rb"
36
37
  require_relative "sbuilder/resolver_loader.rb"
37
38
  require_relative "sbuilder/resolver_loader_yaml.rb"
38
39
 
39
- require_relative "sbuilder/param_set_loader.rb"
40
+
40
41
  require_relative "sbuilder/param_set_loader_swagger.rb"
41
42
 
42
43
  require_relative "sbuilder/model.rb"
@@ -46,6 +47,7 @@ require_relative "sbuilder/extension_loader.rb"
46
47
  require_relative "sbuilder/factory.rb"
47
48
  require_relative "sbuilder/controller.rb"
48
49
 
50
+ require_relative "sbuilder/facade/api_loader.rb"
49
51
 
50
52
  require_relative "sbuilder/mustache/template_reader"
51
53
  require_relative "sbuilder/mustache/template_reader_context"
@@ -11,10 +11,13 @@ module Sbuilder
11
11
  EXTENSION_LOADER_YAML = "default-yaml"
12
12
 
13
13
  # supported paramter set types
14
- SWAGGER = "swagger"
14
+ INTERFACE_OPERATION = "operation"
15
15
  SWAGGER_DEFINITION="definition"
16
16
  PARAM_SET_STEPS = "steps"
17
17
 
18
+ # supported interfa loader
19
+ LOADER_SWAGGER = "swagger"
20
+
18
21
  # supported mapper types
19
22
  MAPPER_YAML = "resolver_yaml"
20
23
 
@@ -47,7 +50,7 @@ module Sbuilder
47
50
  CNF_FILE="sbuilder.yaml"
48
51
 
49
52
  # directory to cache loaded files
50
- CACHE_DIR = "tmp"
53
+ CACHE_DIR = "cache"
51
54
 
52
55
  # direcotory where to output rendered templates
53
56
  GEN_DIR = "gen"
@@ -13,8 +13,8 @@ module Sbuilder
13
13
 
14
14
  # model parts
15
15
  attr_reader :model # which contain values loaded
16
- def_delegators :model, :extendDomain, :extendInterface, :interfaceEncountered, :definitionEncountered,
17
- :domainEncountered, :templateData, :getInterface, :extendStep
16
+ def_delegators :model, :extendDomain, :extendInterface, :modelInterface, :modelDefinition,
17
+ :domainEncountered, :templateData, :getInterface, :extendStep, :defineSetup
18
18
 
19
19
  def_delegators :factory, :createParameter, :createParamSet
20
20
 
@@ -30,16 +30,35 @@ module Sbuilder
30
30
 
31
31
 
32
32
  @@validSetups_required = [ "setupDirectory", ]
33
- @@validSetups_allowed = @@validSetups_required + [ 'extensions', "desc", "preferences", "possibilities" ]
33
+ @@validSetups_allowed = @@validSetups_required + [ 'extensions', "desc", "preferences", "possibilities", 'assumptions', 'configuration']
34
+ @@validSetupConfiguration_required = []
35
+ @@validSetupConfiguration_allowed = ['allow_domain_nil_values']
34
36
 
35
- @@extensionLoaderDef_required = ['type' ]
36
- @@extensionLoaderDef_oneof = ["url", "file"]
37
- @@extensionLoaderDef_allowed = @@extensionLoaderDef_required + @@extensionLoaderDef_oneof
37
+
38
+ @@extensionLoaderDef_required = [ ]
39
+ @@extensionLoaderDef_oneof = ["url", "file",]
40
+ @@extensionLoaderDef_defaults = {
41
+ 'type' => Sbuilder::Constants::EXTENSION_LOADER_YAML
42
+ }
43
+ @@extensionLoaderDef_allowed = @@extensionLoaderDef_required + @@extensionLoaderDef_oneof + ['type']
38
44
 
39
- @@interfaceLoaderDef_required = ['type',]
40
- @@interfaceLoaderDef_oneof = [ 'url', "file", ]
41
- @@interfaceLoaderDef_allowed = @@interfaceLoaderDef_required + ["cache", "infrastructureServices" ] + @@interfaceLoaderDef_oneof
45
+
46
+ @@resolverLoader_required = [ ]
47
+ @@resolverLoader_oneof = ["url", "file",]
48
+ @@resolverLoader_defaults = {
49
+ 'type' => Sbuilder::Constants::MAPPER_YAML
50
+ }
51
+ @@resolverLoader_allowed = @@resolverLoader_required + @@resolverLoader_oneof + ['type']
42
52
 
53
+ @@interfaceLoaderDef_required = [ ]
54
+ @@interfaceLoaderDef_oneof = [ 'url', "file", ]
55
+ @@interfaceLoaderDef_oneof2 = [ 'type', "className", ]
56
+ @@interfaceLoaderDef_allowed = @@interfaceLoaderDef_required + ["cache", "infrastructureServices", "namespace" ] + @@interfaceLoaderDef_oneof + @@interfaceLoaderDef_oneof2
57
+
58
+ @@validExtendLoader = %w( gem className configuration )
59
+
60
+ @@validConfig = %w( generate )
61
+ @@allowConfig = @@validConfig + %w( extend extensions setups preferences resolvers interfaces invariants )
43
62
 
44
63
  @@validGenerateConfigs = ["output", "inputs"]
45
64
  @@allowedGenerateConfigs = @@validGenerateConfigs + ['category']
@@ -69,10 +88,17 @@ module Sbuilder
69
88
  :filter_src => options[:filter_src] || false,
70
89
  :templates => options[:templates],
71
90
  } #.merge( options[PROGNAME] || {} )
72
- @factory = factory
91
+ setFactory( factory )
73
92
  start
74
93
  end
75
94
 
95
+ # @param factory [Sbuilder::Factory] to build objects
96
+ def setFactory( factory )
97
+ @factory = factory
98
+ # add loaders configured in 'sbuilder.yaml'
99
+ factory.addLoaders( getConfiguredLoaders )
100
+ end
101
+
76
102
  # @param possibilities [String:Array] possibilities defined in setup
77
103
  def start
78
104
  # init state
@@ -81,11 +107,62 @@ module Sbuilder
81
107
 
82
108
  end
83
109
 
110
+ # Iterate 'assumptions' and add to model assumption descritptions.
111
+ # Issue a warning if assumptions not defined
112
+ #
113
+ # @param assumption [String:Array] name of assumption to activate
114
+
115
+
116
+ def loadAssumptions( assumptions )
117
+
118
+ @logger.info "#{__method__}: assumptions=#{assumptions}"
119
+ assumptions.each do |assumption|
120
+ model.addAssumption( { :name => assumption, :desc => "Assume #{assumption}" } )
121
+ end # else - not nil
122
+ end
123
+
124
+ # Iterate 'invariants' and add to model invariant descritptions.
125
+ # Isse a warning if invarients not defined
126
+ #
127
+ # @param invariants [Hash:Array] with properties 'key'=>'description'
128
+
129
+ def loadInvariants( invariants )
130
+
131
+ if invariants.nil? then
132
+ msg = <<-EOS
133
+ No invariants section defined in #{getConfigFilePath}.
134
+
135
+ Suggestion add section 'invariants' defining invariants.
136
+ For example:
137
+
138
+ invariants:
139
+ - MustNotHappen: Invariant 'MustNotHappen' verified in the model
140
+
141
+ EOS
142
+ warn msg
143
+ else
144
+ @logger.info "#{__method__}: invariants=#{invariants}"
145
+ invariants = [invariants] if invariants.is_a?( Hash )
146
+ invariants.each do |invariant|
147
+ invariant.each do |k,v|
148
+ model.addInvariant( { :name => k, :desc => v } )
149
+ end
150
+ end
151
+ end # else - not nil
152
+ end
153
+
84
154
  # ------------------------------------------------------------------
85
155
  # build controller: load (domain) resolvers
156
+ # @param arrOfmappersTypePath [Hash:Array] of :type,:url
86
157
 
87
158
  def loadResolvers( arrOfmappersTypePath )
88
159
  !arrOfmappersTypePath.nil? && arrOfmappersTypePath.each do |mapperDef|
160
+ # add defaults to 'mapperDef'
161
+ mapperDef = defaultProps( mapperDef, @@resolverLoader_defaults )
162
+ validateProperties( mapperDef, @@resolverLoader_required, @@resolverLoader_allowed )
163
+ validateOne( mapperDef, @@resolverLoader_oneof )
164
+
165
+
89
166
  @logger.debug( "#{__method__} mapperDef=#{mapperDef} " )
90
167
 
91
168
  # find correct loader based on type
@@ -112,12 +189,21 @@ module Sbuilder
112
189
  # ------------------------------------------------------------------
113
190
  # load extensions
114
191
 
115
- # create load && add let it load
116
- def loadExtensions( arrayOfExtensionDefs )
192
+ # Load exntesion for setup
193
+ #
194
+ # @param setupName [String] name of setup, currently = extensionDirectory
195
+ # def loadExtensions( arrayOfExtensionDefs )
196
+ def loadExtensions( setupName )
197
+
198
+ # access sbuilder.yaml configuration
199
+ arrayOfExtensionDefs = getSetupExtensions( setupName )
117
200
 
201
+ # iteratio
118
202
  arrayOfExtensionDefs && arrayOfExtensionDefs.each do |extensionLoaderDef|
119
203
  validateProperties( extensionLoaderDef, @@extensionLoaderDef_required, @@extensionLoaderDef_allowed )
120
204
  validateOne( extensionLoaderDef, @@extensionLoaderDef_oneof )
205
+ # ensure defaults in properties
206
+ extensionLoaderDef = defaultProps( extensionLoaderDef, @@extensionLoaderDef_defaults )
121
207
 
122
208
 
123
209
  @logger.info( "#{__method__} extensionLoaderDef=#{extensionLoaderDef}" )
@@ -127,7 +213,7 @@ module Sbuilder
127
213
  rescue Exception => ee
128
214
  msg = "Error #{ee} caused by #{ee.backtrace.join("\n")} when loading '#{extensionLoaderDef['url']}'\n\n"
129
215
  @logger.error( "#{__method__} #{msg}" )
130
- raise ControllerException.new msg
216
+ raise ControllerException.new, msg, ee.backtrace
131
217
  end
132
218
  end
133
219
  # domainLoader = factory.get
@@ -135,26 +221,73 @@ module Sbuilder
135
221
 
136
222
  # ------------------------------------------------------------------
137
223
  # load interfaces
224
+
225
+ # @param arrOfparamsetTypePath [Hash:Array] of :type,:file|:url,:cache properties
138
226
 
139
227
  def loadInterfaces( arrOfparamsetTypePath )
140
228
  !arrOfparamsetTypePath.nil? && arrOfparamsetTypePath.each do |interfaceParamsetDef|
141
229
 
142
- validateProperties( interfaceParamsetDef, @@interfaceLoaderDef_required, @@interfaceLoaderDef_allowed )
143
- validateOne( interfaceParamsetDef, @@interfaceLoaderDef_oneof )
144
-
230
+ begin
231
+ validateProperties( interfaceParamsetDef, @@interfaceLoaderDef_required, @@interfaceLoaderDef_allowed )
232
+ validateOne( interfaceParamsetDef, @@interfaceLoaderDef_oneof )
233
+ validateOne( interfaceParamsetDef, @@interfaceLoaderDef_oneof2 )
234
+ rescue ControllerException => e
235
+ msg = <<-EOS
236
+ Error:
237
+
238
+ #{e}
239
+
240
+ in
241
+
242
+ #{interfaceParamsetDef.to_yaml}
243
+
244
+
245
+ EOS
246
+ @logger.error( "#{__method__} #{msg}" )
247
+ raise ControllerException.new, msg, e.backtrace
248
+ end
249
+ warn <<-EOS if interfaceParamsetDef['type']
250
+ Interface loader configuration
251
+
252
+ #{interfaceParamsetDef.to_yaml}
253
+
254
+ uses property 'type', which is depracted.
255
+
256
+
257
+
258
+ Use property 'className' instead.
259
+
260
+ Particularly
261
+
262
+ type: #{Sbuilder::Constants::LOADER_SWAGGER}
263
+
264
+ should be replaced with
265
+
266
+ className: Sbuilder::ParamSetLoaderSwagger
267
+
268
+ EOS
145
269
 
146
270
  # find correct loader based on type & configure it
147
271
  loader = factory.getParamSetLoader( getParamsetType( interfaceParamsetDef ))
148
- loader.configure( interfaceParamsetDef )
272
+
273
+ # configure facade && pass it to loader
274
+ facade = factory.getFacade(self)
275
+ # facada loading instrcture services
276
+ facade.configureInfrastructureService( interfaceParamsetDef['infrastructureServices'] == true )
277
+ # facade creates definitions in 'namespace' (default nil = no group)
278
+ facade.configureNamespace( interfaceParamsetDef['namespace'] )
279
+ facade.setInterfaceCacheFilePath(getParamsetCacheFilePath(interfaceParamsetDef))
280
+ loader.setFacade( facade )
281
+
149
282
  # load an put array
150
- loader.load( self, getFileUrlOrPath( interfaceParamsetDef ), getParamsetCacheFilePath(interfaceParamsetDef) )
283
+ loader.load( getFileUrlOrPath( interfaceParamsetDef ), )
151
284
  # @paramSets = paramSets.concat( loaded ) if loaded && loaded.any?
152
285
  end
153
286
  end
154
287
 
155
288
  # # accept parameters set to model
156
- # def interfaceEncountered( paramSet )
157
- # model.interfaceEncountered( paramSet )
289
+ # def modelInterface( paramSet )
290
+ # model.modelInterface( paramSet )
158
291
  # end
159
292
 
160
293
  # def paramSets
@@ -180,12 +313,13 @@ module Sbuilder
180
313
  @logger.info( "#{__method__} load started" )
181
314
  loadResolvers( getResolversConfig )
182
315
  loadInterfaces( getInterfaceConfig )
316
+ loadInvariants( getInvariantConfig )
183
317
  end
184
318
 
185
319
 
186
- def extend
187
- loadExtensions( getExtensionConfigs )
188
- end
320
+ # def extend
321
+ # loadExtensions( getExtensionConfigs )
322
+ # end
189
323
 
190
324
  # ------------------------------------------------------------------
191
325
  # iterate setups
@@ -201,14 +335,15 @@ module Sbuilder
201
335
 
202
336
  validateProperties( setupDef, @@validSetups_required, @@validSetups_allowed )
203
337
  @logger.info( "#{__method__} -->next" ) if setupDirectory && (setupDef['setupDirectory'] != setupDirectory)
204
- next if setupDirectory && setupDef['setupDirectory'] != setupDirectory
338
+ next if setupDirectory && setupDef['setupDirectory'] != setupDirectory
339
+ validateProperties( setupDef['configuration'], @@validSetupConfiguration_required, @@validSetupConfiguration_allowed ) if setupDef['configuration']
205
340
 
206
341
  # process one setupDirectory
207
342
  @logger.info( "#{__method__} start to generate setupDirectory=#{setupDirectory} for #{setupDef}" )
208
343
 
209
344
  output( 1, "------------------------------------------------------------------" ) if isOptFilterSrc
210
345
  output( 1, "generate setup: #{setupDef['setupDirectory']}" )
211
- generate( setupDef['setupDirectory'], setupDef['setupDirectory'], setupDef['extensions'], setupDef['possibilities'] )
346
+ generate( setupDef['setupDirectory'], setupDef['setupDirectory'] )
212
347
  @logger.info( "#{__method__} done to generate setupDirectory=#{setupDirectory} for #{setupDef}" )
213
348
  output( 2, "\n" )
214
349
 
@@ -253,6 +388,10 @@ module Sbuilder
253
388
  # delegate action
254
389
  begin
255
390
  resolver.resolveDomains( paramSet, model )
391
+
392
+ # resolve also response
393
+ resolver.resolveDomains( paramSet.response, model ) if paramSet.respond_to?( :response )
394
+
256
395
  rescue ResolverException => e
257
396
  msg = "Error '#{e}' when mapping domains for parameter set '#{paramSet.getId}'"
258
397
  puts msg
@@ -272,11 +411,48 @@ module Sbuilder
272
411
  #
273
412
  # @param setupName [String] name of setup, currently = extensionDirectory
274
413
  # @param extensionDirectory [String] directory where setup generated
275
- # @arrayOfExtensionDefs [Hash:Array] of extenstions to load
276
414
 
277
- def generate( setupName="default", extensionDirectory="default", arrayOfExtensionDefs=[], possibilities=[] )
415
+ def generate( setupName="default", extensionDirectory="default" )
278
416
  @logger.info( "#{__method__} setupName=#{setupName}, extensionDirectory=#{extensionDirectory}" )
279
- @logger.debug( "#{__method__} arrayOfExtensionDefs=#{arrayOfExtensionDefs}, possibilities=#{possibilities}" )
417
+
418
+ processSetup( setupName ) do |name, setupConf, possibilities|
419
+
420
+ # config && get renderes
421
+ mustache = prepareRender( setupName )
422
+
423
+ # path to directory where setup output is done
424
+ directoryPath = prepareSetupDir( extensionDirectory )
425
+
426
+ # output 'normal templates' - one generate def/one output
427
+ generateCase( setupName, directoryPath, nil, mustache )
428
+
429
+ # For 'possibities': map array of possibilities to array
430
+ # of filenames created using an output -property on
431
+ # 'generate' definition
432
+ possibilities && possibilities.any? && generateCase( setupName, directoryPath, 'possibility', mustache ) do |output|
433
+ # use output as template rendering
434
+ possibilities.map do |p|
435
+ {
436
+ :possibility => p,
437
+ :outputFile => mustache.render_str( output, { "possibility" => p } ),
438
+ }
439
+ end # map
440
+ end
441
+
442
+ end
443
+
444
+ end
445
+
446
+ # @param chosenSetup [String] optional string for the setup to process
447
+ def processSetups(chosenSetup=nil, &blk )
448
+ setups = Marshal.load( Marshal.dump( getSetups ) || [] ).select { |s| chosenSetup.nil? || s['setupDirectory'] == chosenSetup }
449
+ setups.each do |setup|
450
+ setupName = setup['setupDirectory']
451
+ processSetup( setupName, &blk )
452
+ end
453
+ end
454
+
455
+ def processSetup( setupName, &blk )
280
456
 
281
457
  # init state
282
458
  start
@@ -287,35 +463,24 @@ module Sbuilder
287
463
  # resolve domain
288
464
  resolve
289
465
 
466
+ # access config && put to model
467
+ setupConf = getSetup( setupName )
468
+ defineSetup( setupConf )
469
+
470
+ # add assumptions to model
471
+ loadAssumptions( getSetupAssumptionList( setupConf ) )
472
+
290
473
  # extensions
291
- loadExtensions( arrayOfExtensionDefs )
474
+ loadExtensions( setupName )
292
475
 
293
476
  # config model - before config rendering
477
+ possibilities= getSetupPossibilitiesList( setupName )
294
478
  model.setPossibilities( possibilities )
295
-
296
- # config && get renderes
297
- mustache = prepareRender( setupName )
298
479
 
299
- # path to directory where setup output is done
300
- directoryPath = prepareSetupDir( extensionDirectory )
301
-
302
- # output 'normal templates' - one generate def/one output
303
- generateCase( setupName, directoryPath, nil, mustache )
304
-
305
- # For 'possibities': map array of possibilities to array
306
- # of filenames created using an output -property on
307
- # 'generate' definition
308
- possibilities && generateCase( setupName, directoryPath, 'possibility', mustache ) do |output|
309
- # use output as template rendering
310
- possibilities.map do |p|
311
- {
312
- :possibility => p,
313
- :outputFile => mustache.render_str( output, { "possibility" => p } ),
314
- }
315
- end # map
316
- end
480
+ yield setupName, setupConf, possibilities
317
481
 
318
482
  end
483
+
319
484
 
320
485
 
321
486
  # Ensure that directory 'extensionDirectory' exists under
@@ -505,7 +670,7 @@ module Sbuilder
505
670
  #
506
671
  # @param modelData [String] type of data (see model#templateData)
507
672
  #
508
- # @param d [Hash] data element, content depends on 'modelData'
673
+ # @param renderData [Hash] data element to filter, content depends on 'modelData'
509
674
  #
510
675
  # @return [Boolean] true when show the elmement
511
676
  def setupFilter( modelData, renderData )
@@ -582,10 +747,24 @@ module Sbuilder
582
747
  return setupPossis
583
748
  end
584
749
 
585
- # create data to pass to template generateion
586
- # def templateData
587
- # return model.templateData
588
- # end
750
+
751
+
752
+ # Return model invariant defined in sbuilder
753
+ #
754
+ # @return [String:Array] of invariant names
755
+ def getModelInvariants
756
+ names = []
757
+ getInvariantConfig.each { |invariant| names += invariant.keys }
758
+ @logger.info "#{__method__} invariants=#{names.join(',')}"
759
+ return names
760
+ end
761
+
762
+
763
+ # @return [String:Array] names of setup assumes from
764
+ # 'setups.{supet}.assumptions' property
765
+ def getSetupAssumes
766
+ model.assumptions.map{|a| a[:name] }
767
+ end
589
768
 
590
769
  # ------------------------------------------------------------------
591
770
  # configuration
@@ -611,7 +790,8 @@ module Sbuilder
611
790
 
612
791
  @logger.debug( "#{__method__} config in #{getInternalConfigFilePath} internal_config= #{internal_config.to_yaml}" )
613
792
  @controller_config['generate'] = @controller_config['generate'] + internal_config['generate']
614
- @logger.debug( "#{__method__} @controller_config=#{@controller_config.to_yaml}" )
793
+ @logger.debug( "#{__method__} @controller_config=#{@controller_config.to_yaml}" )
794
+ validateProperties( @controller_config, @@validConfig, @@allowConfig )
615
795
  @controller_config
616
796
  end
617
797
 
@@ -626,6 +806,25 @@ module Sbuilder
626
806
  @logger.debug( "#{__method__} setupName=#{setupName}, setup=#{setup} " )
627
807
  setup
628
808
  end
809
+
810
+ # @return [Hash:Array] of 'type', 'url'|'file' properties
811
+ def getSetupExtensions( setupName )
812
+ @logger.debug( "#{__method__} setupName=#{setupName}" )
813
+ getSetup( setupName )['extensions'] || []
814
+ end
815
+
816
+ # @return [String:Array] of setup possibilities
817
+ def getSetupPossibilitiesList( setupName )
818
+ @logger.debug( "#{__method__} setupName=#{setupName}" )
819
+ getSetup( setupName )['possibilities'] || []
820
+ end
821
+
822
+ # @param setupDef [Hash] setup configuration
823
+ # @return [String:Array] name of assumption in setup, [] if none
824
+ def getSetupAssumptionList( setupDef )
825
+ return setupDef['assumptions'] || []
826
+ end
827
+
629
828
 
630
829
 
631
830
  def getPreferencesData( setupName )
@@ -680,11 +879,34 @@ module Sbuilder
680
879
  getConfig()['extensions']
681
880
  end
682
881
 
882
+ # @return [Hash] of extension properties
883
+ def getExtensions
884
+ getConfig()['extend'] || {}
885
+ end
886
+
887
+ # Api loaders configured in sbuilder.yaml['extend']['loaders']
888
+ #
889
+ # @return [Hash:Array] with :name,:className,:configuration properties
890
+ def getConfiguredLoaders
891
+ loaders = getExtensions()['loaders'] || []
892
+ loaders.each do |loader|
893
+ validateProperties( loader, @@validExtendLoader )
894
+ end
895
+ loaders
896
+ end
683
897
 
684
898
  def getResolversConfig
685
899
  getConfig()['resolvers']
686
900
  end
687
901
 
902
+ # @return [Hash:Array] of invariants defined
903
+ def getInvariantConfig
904
+ invariants = getConfig()['invariants']
905
+ invariants = [invariants] if invariants.is_a?( Hash )
906
+ return invariants || []
907
+ end
908
+
909
+
688
910
  # @param generateCategory [Nil|String] choose templates in
689
911
  # 'generateCategory', @return [Hash:Array] of {'output', 'inputs'}
690
912
  # defining a file to render using templates in 'inputs'
@@ -717,15 +939,16 @@ module Sbuilder
717
939
 
718
940
  end
719
941
 
720
- # return optional cacheFilePath from paramSetDef, nil if no 'cache' -property
942
+ # @return [String] path to cacheFilePath, if no 'cache' -property
721
943
  def getParamsetCacheFilePath( paramSetDef )
722
944
  return "#{getOpt(:cache_dir)}/#{paramSetDef['cache']}" if paramSetDef['cache'] && getOpt(:cache_dir)
723
945
  return paramSetDef['cache'] if paramSetDef['cache']
724
946
  return nil
725
947
  end
726
-
948
+
949
+ # @return [String] loader type (className/type)
727
950
  def getParamsetType( paramSetDef )
728
- paramSetDef['type']
951
+ paramSetDef['className'] ? paramSetDef['className'] : paramSetDef['type']
729
952
  end
730
953
 
731
954
  # def getResolverDefPath( mapperDef )
@@ -790,6 +1013,13 @@ module Sbuilder
790
1013
  private def validateOne( defintionHash, propList )
791
1014
  raise ControllerException.new "Must give one #{propList} in #{defintionHash}" unless propList.select {|prop| defintionHash.has_key?(prop) }.length == 1
792
1015
  end
1016
+
1017
+ # add default properties in 'defaults' to 'defintionHash'
1018
+ private def defaultProps( defintionHash, defaults )
1019
+ defintionHash = defintionHash.merge( defaults ) do |k,orig,default|
1020
+ orig.nil? ? default : orig
1021
+ end
1022
+ end
793
1023
 
794
1024
 
795
1025