CapicuaGen 0.0.2

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.
@@ -0,0 +1,216 @@
1
+ =begin
2
+
3
+ CapicuaGen
4
+
5
+ CapicuaGen es un software que ayuda a la creación automática de
6
+ sistemas empresariales a través de la definición y ensamblado de
7
+ diversos generadores de características.
8
+
9
+ El proyecto fue iniciado por José Luis Bautista Martin, el 6 de enero
10
+ del 2016.
11
+
12
+ Puede modificar y distribuir este software, según le plazca, y usarlo
13
+ para cualquier fin ya sea comercial, personal, educativo, o de cualquier
14
+ índole, siempre y cuando incluya este mensaje, y se permita acceso el
15
+ código fuente.
16
+
17
+ Este software es código libre, y se licencia bajo LGPL.
18
+
19
+ Para más información consultar http://www.gnu.org/licenses/lgpl.html
20
+ =end
21
+
22
+ require 'active_support/core_ext/object/blank'
23
+ require 'optparse'
24
+ require 'optparse/time'
25
+ require 'ostruct'
26
+ require 'pp'
27
+
28
+ require_relative 'Mixins/reflection_mixin'
29
+
30
+
31
+ module CapicuaGen
32
+
33
+ class Generator
34
+ include CapicuaGen
35
+
36
+ # Parsea un linea de comamdos
37
+ def parse_command_line(args)
38
+
39
+ options = OpenStruct.new
40
+
41
+ options.ignore_features=[]
42
+
43
+ opt_parser = OptionParser.new do |opts|
44
+ opts.banner = "Uso: <Script generador> [comandos] [opciones]"
45
+
46
+ opts.separator ""
47
+ subtext = <<HELP
48
+ Comandos:
49
+ generate : Genera las caracteriticas configuradas.
50
+ clean : Limpia los archivos generados.
51
+ cleanAndGenerate : Limpia los archivos generados y luego los vuelve a crear.
52
+ example : Genera un ejemplo
53
+
54
+
55
+ Ejecute 'opt.rb COMMAND --help' para obtener mas
56
+ HELP
57
+ opts.separator ""
58
+ opts.separator subtext
59
+ opts.separator ""
60
+
61
+ # No argument, shows at tail. This will print an options summary.
62
+ # Try it and see!
63
+ opts.on_tail("-h", "--help", "Muestra este mensaje") do
64
+ puts opts
65
+ options.help=true
66
+ options.exit=true
67
+ end
68
+
69
+ # Another typical switch to print the version.
70
+ opts.on_tail("--version", "Muestra la versión") do
71
+ puts ::Version.join('.')
72
+ options.version=true
73
+ options.exit =true
74
+ end
75
+
76
+ end
77
+
78
+ subcommands = {
79
+
80
+ 'generate' => OptionParser.new do |opts|
81
+
82
+ opts.banner = "Uso: generate [options]"
83
+ opts.separator ""
84
+
85
+ # List of arguments.
86
+ opts.on("--ignore featurename1, featurename2, featurename2", Array, "Lista de caracteristicas que sera omitidas") do |ignore_features|
87
+ options.ignore_features = ignore_features
88
+ end
89
+
90
+ opts.on("-f", "--force", "Fuerza que se sobreescriban las carateristicas generadas") do
91
+ options.force= true
92
+ end
93
+
94
+ opts.on_tail("-h", "--help", "Muestra este mensaje") do
95
+ puts opts
96
+ options.help=true
97
+ options.exit=true
98
+ end
99
+ end,
100
+
101
+
102
+ 'clean' => OptionParser.new do |opts|
103
+
104
+ opts.banner = "Uso: clean [options]"
105
+ opts.separator ""
106
+
107
+ # List of arguments.
108
+ opts.on("--ignore featurename1, featurename2, featurename2", Array, "Lista de caracteristicas que sera omitidas") do |ignore_features|
109
+ options.ignore_features = ignore_features
110
+ end
111
+
112
+ opts.on_tail("-h", "--help", "Muestra este mensaje") do
113
+ puts opts
114
+ options.help=true
115
+ options.exit=true
116
+ end
117
+ end,
118
+
119
+
120
+ 'cleanAndGenerate' => OptionParser.new do |opts|
121
+ opts.banner = "Uso: example [options]"
122
+ opts.separator ""
123
+ opts.separator "Opciones:"
124
+ opts.separator ""
125
+
126
+ # List of arguments.
127
+ opts.on("--ignore featurename1, featurename2, featurename2", Array, "Lista de caracteristicas que sera omitidas") do |ignore_features|
128
+ options.ignore_features = ignore_features
129
+ end
130
+
131
+ opts.on("-f", "--force", "Fuerza que se sobreescriban las carateristicas generadas") do
132
+ options.force= true
133
+ end
134
+
135
+ opts.on_tail("-h", "--help", "Muestra este mensaje") do
136
+ puts opts
137
+ options.help=true
138
+ options.exit=true
139
+ end
140
+
141
+ opts.separator ""
142
+ end,
143
+
144
+
145
+ 'example' => OptionParser.new do |opts|
146
+ opts.banner = "Uso: cleanAndGenerate [options]"
147
+ opts.separator ""
148
+ opts.separator "Opciones:"
149
+ opts.separator ""
150
+
151
+ # List of arguments.
152
+ opts.on("-o", "--out directorio", "") do |directorio|
153
+ options.out = directorio
154
+ end
155
+
156
+ opts.on_tail("-h", "--help", "Muestra este mensaje") do
157
+ puts opts
158
+ options.help=true
159
+ options.exit=true
160
+ end
161
+
162
+ opts.separator ""
163
+ end
164
+
165
+ }
166
+
167
+
168
+ begin
169
+ internal_args=args.clone
170
+ opt_parser.order!(internal_args)
171
+ command = internal_args.shift
172
+
173
+ if command
174
+
175
+ case command
176
+
177
+ when 'generate'
178
+ options.generate=true
179
+
180
+ when 'clean'
181
+ options.clean =true
182
+ options.generate=false
183
+
184
+ when 'cleanAndGenerate'
185
+ options.clean =true
186
+ options.generate=true
187
+
188
+ when 'example'
189
+ options.clean =false
190
+ options.generate=false
191
+ options.example =true
192
+ options.out ='.'
193
+
194
+ end
195
+
196
+ subcommands[command].order! internal_args
197
+
198
+
199
+ else
200
+ options.generate=true
201
+ end
202
+
203
+ rescue => e
204
+ $stderr.puts e
205
+ puts
206
+ puts opt_parser
207
+ puts
208
+ options.exit=true
209
+ end
210
+
211
+
212
+ return options
213
+ end
214
+
215
+ end
216
+ end
@@ -0,0 +1,49 @@
1
+ =begin
2
+
3
+ CapicuaGen
4
+
5
+ CapicuaGen es un software que ayuda a la creación automática de
6
+ sistemas empresariales a través de la definición y ensamblado de
7
+ diversos generadores de características.
8
+
9
+ El proyecto fue iniciado por José Luis Bautista Martin, el 6 de enero
10
+ del 2016.
11
+
12
+ Puede modificar y distribuir este software, según le plazca, y usarlo
13
+ para cualquier fin ya sea comercial, personal, educativo, o de cualquier
14
+ índole, siempre y cuando incluya este mensaje, y se permita acceso el
15
+ código fuente.
16
+
17
+ Este software es código libre, y se licencia bajo LGPL.
18
+
19
+ Para más información consultar http://www.gnu.org/licenses/lgpl.html
20
+ =end
21
+
22
+ require_relative 'Mixins/reflection_mixin'
23
+
24
+ module CapicuaGen
25
+
26
+ # Define un objtivo a contruir
27
+ class Target
28
+ include CapicuaGen
29
+
30
+
31
+ public
32
+
33
+ attr_accessor :name, :feature_name, :enable, :enable_generation, :group
34
+
35
+
36
+ def initialize(attributes= {})
37
+ @enable= true
38
+ @enable_generation= true
39
+
40
+ # Inicializo propiedades
41
+ initialize_properties(attributes, false)
42
+
43
+ @feature_name= @name unless @feature_name
44
+
45
+ end
46
+
47
+
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ =begin
2
+
3
+ CapicuaGen
4
+
5
+ CapicuaGen es un software que ayuda a la creación automática de
6
+ sistemas empresariales a través de la definición y ensamblado de
7
+ diversos generadores de características.
8
+
9
+ El proyecto fue iniciado por José Luis Bautista Martin, el 6 de enero
10
+ del 2016.
11
+
12
+ Puede modificar y distribuir este software, según le plazca, y usarlo
13
+ para cualquier fin ya sea comercial, personal, educativo, o de cualquier
14
+ índole, siempre y cuando incluya este mensaje, y se permita acceso el
15
+ código fuente.
16
+
17
+ Este software es código libre, y se licencia bajo LGPL.
18
+
19
+ Para más información consultar http://www.gnu.org/licenses/lgpl.html
20
+ =end
21
+
22
+ module CapicuaGen
23
+
24
+ # Define una plantilla para generar codigo
25
+ class Template
26
+
27
+
28
+
29
+ public
30
+ attr_accessor :name, :file
31
+
32
+ def initialize(atributes= {})
33
+ @name= atributes[:name] if atributes[:name]
34
+ @file= atributes[:file] if atributes[:file]
35
+ end
36
+
37
+
38
+ end
39
+ end
@@ -0,0 +1,331 @@
1
+ =begin
2
+
3
+ CapicuaGen
4
+
5
+ CapicuaGen es un software que ayuda a la creación automática de
6
+ sistemas empresariales a través de la definición y ensamblado de
7
+ diversos generadores de características.
8
+
9
+ El proyecto fue iniciado por José Luis Bautista Martin, el 6 de enero
10
+ del 2016.
11
+
12
+ Puede modificar y distribuir este software, según le plazca, y usarlo
13
+ para cualquier fin ya sea comercial, personal, educativo, o de cualquier
14
+ índole, siempre y cuando incluya este mensaje, y se permita acceso el
15
+ código fuente.
16
+
17
+ Este software es código libre, y se licencia bajo LGPL.
18
+
19
+ Para más información consultar http://www.gnu.org/licenses/lgpl.html
20
+ =end
21
+
22
+ require_relative 'feature'
23
+
24
+ module CapicuaGen
25
+
26
+ # Es un tipo de caracteristica especial que se basa en generación de codigo a travez de plantillas
27
+ class TemplateFeature < Feature
28
+
29
+
30
+ private
31
+
32
+ # Plantillas (archivos *.erb)
33
+ attr_accessor :templates
34
+
35
+ # Relacion de las Template con los objetivos
36
+ attr_accessor :template_targets
37
+
38
+ protected
39
+
40
+ attr_accessor :template_directories
41
+
42
+
43
+ public
44
+
45
+ # Inicializo el objeto
46
+ def initialize(atributes= {})
47
+ super(atributes)
48
+
49
+
50
+ # Define las interfaces del proyectowh
51
+ @templates = []
52
+
53
+ # Define los objetivos concretos de los templates
54
+ @template_targets = []
55
+
56
+ # Directorios donde conseguir los templates
57
+ @template_directories= []
58
+
59
+ end
60
+
61
+
62
+ # Coleccion de caracteristicas del generador
63
+ def templates
64
+ return @templates
65
+ end
66
+
67
+ # Agrega una caracteristica en el generador
68
+ def add_template(template)
69
+ @templates<<template
70
+ end
71
+
72
+ # Agrega una caracteristica en el generador
73
+ def set_template(name, template)
74
+ remove_template_by_name(name)
75
+ template.name= name
76
+ @templates<<template
77
+ end
78
+
79
+ # Quita la caracteristica
80
+ def remove_template(template)
81
+ @templates.delete(template)
82
+ end
83
+
84
+ # Quita la caracterisitca en base al nombre
85
+ def remove_template_by_name(template_name)
86
+ @templates.delete_if { |f| f.name==template_name }
87
+ end
88
+
89
+ # Obtiene la caracteristica en base al nombre
90
+ def get_template_by_name(template_name)
91
+ return @templates.detect { |f| f.name==template_name }
92
+ end
93
+
94
+ # Coleccion de template_targets del generador
95
+ def template_targets
96
+ return @template_targets
97
+ end
98
+
99
+ # Agrega una template_target en el generador
100
+ def add_template_target(template_target)
101
+ @template_targets<<template_target
102
+ end
103
+
104
+ # Agrega una template_target en el generador
105
+ def set_template_target(name, template_target)
106
+ remove_template_target_by_name(name)
107
+ template_target.name= name
108
+ if name=~ /^([^\/]+)\//
109
+ template_target.template_name= $1
110
+ else
111
+ template_target.template_name= name unless template_target.template_name
112
+ end
113
+
114
+ @template_targets<<template_target
115
+
116
+ # Devuelve el template recien configurado
117
+ return template_target
118
+
119
+ end
120
+
121
+ # Quita la template_target
122
+ def remove_template_target(template_target)
123
+ @template_targets.delete(template_target)
124
+ end
125
+
126
+ # Quita la caracterisitca en base al nombre
127
+ def remove_template_target_by_name(template_target_name)
128
+ @template_targets.delete_if { |f| f.name==template_target_name }
129
+ end
130
+
131
+ # Obtiene la template_target en base al nombre
132
+ def get_template_target_by_name(template_target_name)
133
+ return @template_targets.detect { |f| f.name==template_target_name }
134
+ end
135
+
136
+ # Configura el generador y se
137
+ def generator= (value)
138
+ super(value)
139
+
140
+ if @generator
141
+ configure_template_directories()
142
+ configure_template_targets()
143
+ end
144
+
145
+ end
146
+
147
+
148
+ def configure_template_directories
149
+ # Configuro las rutas de los templates
150
+ self.template_directories << get_template_local_dir(get_class_file)
151
+ self.template_directories << File.join(File.dirname(get_class_file), '../template')
152
+
153
+ end
154
+
155
+ # Configura los objetivos de las platillas (despues de establecer el generador)
156
+ def configure_template_targets
157
+
158
+ end
159
+
160
+ # Genero el codigo, usando todas las plantillas configuradas
161
+ def generate
162
+ super()
163
+
164
+ message_helper.add_indent
165
+
166
+ # Genera una a una todas los objetivos de los templates
167
+ self.template_targets.each do |t|
168
+ generate_template_target(t)
169
+ end
170
+
171
+ message_helper.remove_indent
172
+ puts
173
+ end
174
+
175
+ def clean
176
+ super()
177
+
178
+ message_helper.add_indent
179
+
180
+ # Genera una a una todas los objetivos de los templates
181
+ self.template_targets.each do |t|
182
+ clean_template_target(t)
183
+ end
184
+
185
+ message_helper.remove_indent
186
+ puts
187
+ end
188
+
189
+
190
+ protected
191
+
192
+ # Genero una plantilla en particular
193
+ def generate_template_target(template_target, current_binding= nil)
194
+
195
+ # Localizo la plantilla
196
+ template = self.get_template_by_name(template_target.template_name)
197
+
198
+ # Obtengo el archivo del template
199
+ template_file= ''
200
+ @template_directories.each do |template_directory|
201
+ template_file= File.join(template_directory, template.file)
202
+ break if File.exist?(template_file)
203
+ end
204
+
205
+
206
+ # Obtengo la salida
207
+ if template_target.out_file.blank?
208
+ out_file= nil
209
+ else
210
+ out_file= File.join(self.generation_attributes[:out_dir], template_target.out_file)
211
+ end
212
+
213
+ current_binding= binding unless current_binding
214
+
215
+ if template_target.copy_only
216
+
217
+ exists= File.exist?(out_file)
218
+
219
+ FileUtils.cp template_file, out_file
220
+
221
+ if exists
222
+ message_helper.puts_created_template(File.basename(out_file), out_file, :override)
223
+ else
224
+ message_helper.puts_created_template(File.basename(out_file), out_file, :new)
225
+ end
226
+
227
+
228
+ else
229
+ # Creo la salida
230
+ return TemplateHelper.generate_template(template_file, current_binding, :out_file => out_file, :feature => self, :force => argv_options.force)
231
+ end
232
+
233
+
234
+ end
235
+
236
+
237
+ # Limpio el resultado de una plantilla (borro archivos)
238
+ def clean_template_target(template_target, current_binding= nil)
239
+
240
+ # Localizo la plantilla
241
+ template= self.get_template_by_name(template_target.template_name)
242
+
243
+ # Obtengo la salida
244
+ if template_target.out_file.blank?
245
+ return
246
+ else
247
+ out_file= File.join(self.generation_attributes[:out_dir], template_target.out_file)
248
+ end
249
+
250
+ return if !File.exist?(out_file)
251
+
252
+ # Elimino el archivo
253
+ File.delete(out_file)
254
+
255
+ message_helper.puts_created_template(File.basename(template.file), out_file, :delete)
256
+
257
+
258
+ end
259
+
260
+
261
+ # Devuelve los archivos generados por esta caracteristicas
262
+ def get_out_file_information(values= {})
263
+
264
+ # Recupero los parametros
265
+ types = values[:types]
266
+ types = [types] if types and not types.instance_of?(Array)
267
+
268
+ #recupero los archivos pertinentes
269
+ result= []
270
+
271
+ self.template_targets.each do |t|
272
+ # si no hay tipos definidos o los tipos tienen algo en común, lo agrego a los resultados
273
+ next unless types.blank? or t.is_any_type?(types)
274
+ next unless t.respond_to?('out_file')
275
+ next if t.out_file.blank?
276
+
277
+
278
+ file_information= FileInformation.new(:file_name => File.join(self.generation_attributes[:out_dir], t.out_file))
279
+
280
+ result << file_information
281
+
282
+ end
283
+
284
+ return result
285
+
286
+ end
287
+
288
+
289
+ protected
290
+ # Directorio local para obtener los templates
291
+ def get_template_local_dir(file)
292
+ feacture_directory= File.dirname(file).split('/')
293
+ feacture_name = feacture_directory[feacture_directory.count-2]
294
+ package_name = feacture_directory[feacture_directory.count-3]
295
+ return File.join(@generator.local_feature_directory, package_name, feacture_name, 'Template')
296
+ end
297
+
298
+
299
+ # For instances of class A only, we use the __FILE__ keyword.
300
+ # This method is overwritten by the #get_file method defined above.
301
+ def get_class_file
302
+ __FILE__
303
+ end
304
+
305
+ private
306
+ # Called from b.rb at `class A < B`. `subclass` is the Class object B.
307
+ # This method makes sure every subclass (class B, class C...)
308
+ # has #get_file defined correctly for instances of the subclass.
309
+ def self.inherited (subclass)
310
+ subclass.instance_eval do
311
+ # This array contains strings like "/path/to/a.rb:3:in `instance_eval'".
312
+ strings_ary = caller
313
+
314
+ # We look for the last string containing "<top (required)>".
315
+ require_index = strings_ary.index { |x| x.include?("<top (required)>") }
316
+ require_string= strings_ary[require_index]
317
+
318
+ # We use a regex to extract the filepath from require_string.
319
+ filepath = require_string[/^(.*):\d+:in `<top \(required\)>'/, 1]
320
+
321
+ # This defines the method #get_file for instances of `subclass`.
322
+ define_method(:get_class_file) { filepath }
323
+ end
324
+ end
325
+
326
+
327
+ end
328
+
329
+
330
+ end
331
+