CapicuaGen 0.0.2

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