asker-tool 2.1.2 → 2.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +17 -18
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +43 -74
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +19 -3
  17. data/lib/asker/checker.rb +152 -53
  18. data/lib/asker/cli.rb +19 -22
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +58 -32
  26. data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +6 -6
  27. data/lib/asker/displayer/concept_ai_displayer.rb +132 -0
  28. data/lib/asker/displayer/concept_displayer.rb +29 -0
  29. data/lib/asker/displayer/stats_displayer.rb +14 -0
  30. data/lib/asker/exporter/code_gift_exporter.rb +10 -11
  31. data/lib/asker/exporter/concept_ai_gift_exporter.rb +23 -11
  32. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +9 -7
  33. data/lib/asker/exporter/concept_doc_exporter.rb +9 -15
  34. data/lib/asker/exporter/output_file_exporter.rb +18 -0
  35. data/lib/asker/files/config.ini +37 -0
  36. data/lib/asker/files/example-code.haml +0 -0
  37. data/lib/asker/files/example-concept.haml +29 -0
  38. data/lib/asker/files/language/du/templates.yaml +50 -0
  39. data/lib/asker/files/language/en/connectors.yaml +44 -0
  40. data/lib/asker/files/language/en/mistakes.yaml +37 -0
  41. data/lib/asker/files/language/en/templates.yaml +29 -0
  42. data/lib/asker/files/language/es/connectors.yaml +92 -0
  43. data/lib/asker/files/language/es/mistakes.yaml +82 -0
  44. data/lib/asker/files/language/es/templates.yaml +29 -0
  45. data/lib/asker/files/language/fr/connectors.yaml +92 -0
  46. data/lib/asker/files/language/fr/mistakes.yaml +82 -0
  47. data/lib/asker/files/language/fr/templates.yaml +29 -0
  48. data/lib/asker/files/language/javascript/connectors.yaml +11 -0
  49. data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
  50. data/lib/asker/files/language/javascript/templates.yaml +3 -0
  51. data/lib/asker/files/language/math/connectors.yaml +2 -0
  52. data/lib/asker/files/language/math/mistakes.yaml +2 -0
  53. data/lib/asker/files/language/math/templates.yaml +1 -0
  54. data/lib/asker/files/language/python/connectors.yaml +11 -0
  55. data/lib/asker/files/language/python/mistakes.yaml +26 -0
  56. data/lib/asker/files/language/python/templates.yaml +3 -0
  57. data/lib/asker/files/language/ruby/connectors.yaml +11 -0
  58. data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
  59. data/lib/asker/files/language/ruby/templates.yaml +3 -0
  60. data/lib/asker/files/language/sql/connectors.yaml +6 -0
  61. data/lib/asker/files/language/sql/mistakes.yaml +11 -0
  62. data/lib/asker/files/language/sql/templates.yaml +2 -0
  63. data/lib/asker/formatter/concept_string_formatter.rb +9 -8
  64. data/lib/asker/formatter/question_gift_formatter.rb +9 -1
  65. data/lib/asker/lang/lang.rb +18 -12
  66. data/lib/asker/lang/lang_factory.rb +26 -5
  67. data/lib/asker/lang/text_actions.rb +87 -69
  68. data/lib/asker/loader/code_loader.rb +3 -3
  69. data/lib/asker/loader/content_loader.rb +9 -5
  70. data/lib/asker/loader/file_loader.rb +2 -11
  71. data/lib/asker/loader/haml_loader.rb +15 -0
  72. data/lib/asker/loader/image_url_loader.rb +5 -8
  73. data/lib/asker/loader/input_loader.rb +23 -7
  74. data/lib/asker/loader/project_loader.rb +32 -29
  75. data/lib/asker/logger.rb +3 -4
  76. data/lib/asker/project.rb +28 -52
  77. data/lib/asker/skeleton.rb +73 -0
  78. metadata +62 -73
  79. data/docs/changelog/v2.1.md +0 -99
  80. data/docs/commands.md +0 -15
  81. data/docs/contributions.md +0 -18
  82. data/docs/history.md +0 -40
  83. data/docs/idea.md +0 -44
  84. data/docs/inputs/README.md +0 -39
  85. data/docs/inputs/code.md +0 -69
  86. data/docs/inputs/concepts.md +0 -142
  87. data/docs/inputs/jedi.md +0 -68
  88. data/docs/inputs/tables.md +0 -112
  89. data/docs/inputs/templates.md +0 -87
  90. data/docs/install/README.md +0 -38
  91. data/docs/install/manual.md +0 -26
  92. data/docs/install/scripts.md +0 -26
  93. data/docs/revise/asker-file.md +0 -41
  94. data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
  95. data/docs/revise/buenas-practicas/02-formulario.md +0 -35
  96. data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
  97. data/docs/revise/buenas-practicas/04-resultados.md +0 -17
  98. data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
  99. data/docs/revise/ejemplos/01/README.md +0 -27
  100. data/docs/revise/ejemplos/02/README.md +0 -31
  101. data/docs/revise/ejemplos/03/README.md +0 -31
  102. data/docs/revise/ejemplos/04/README.md +0 -37
  103. data/docs/revise/ejemplos/05/README.md +0 -25
  104. data/docs/revise/ejemplos/06/README.md +0 -43
  105. data/docs/revise/ejemplos/README.md +0 -11
  106. data/docs/revise/projects.md +0 -74
  107. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  108. data/lib/asker/code/code.rb +0 -53
  109. data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
  110. data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
  111. data/lib/asker/exporter/main.rb +0 -9
@@ -4,12 +4,9 @@ require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
6
  class PythonCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
7
+ def initialize(code)
10
8
  @lang = LangFactory.instance.get('python')
11
- @num = 0
12
- @questions = []
9
+ super code
13
10
  end
14
11
 
15
12
  def make_comment_error
@@ -3,17 +3,18 @@ require_relative '../../lang/lang_factory'
3
3
  require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
+ ##
7
+ # Class for RubyCodeAI objects
6
8
  class RubyCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
10
- @lang = LangFactory.instance.get('ruby')
11
- @num = 0
12
- @questions = []
9
+ def initialize(code)
13
10
  @reduce = 1
14
- @reduce = 4 if @lines.size > 25
11
+ @reduce = 4 if code.lines.size > 25
12
+ @lang = LangFactory.instance.get('ruby')
13
+ super code
15
14
  end
16
15
 
16
+ ##
17
+ # Make errors about comments
17
18
  def make_comment_error
18
19
  questions = []
19
20
  error_lines = []
@@ -43,6 +44,8 @@ class RubyCodeAI < BaseCodeAI
43
44
  questions.shuffle[0,@lines.size/@reduce]
44
45
  end
45
46
 
47
+ ##
48
+ # Make questions without errors
46
49
  def make_no_error_changes
47
50
  questions = []
48
51
  empty_lines = []
@@ -81,6 +84,8 @@ class RubyCodeAI < BaseCodeAI
81
84
  questions.shuffle[0,@lines.size/@reduce]
82
85
  end
83
86
 
87
+ ##
88
+ # Make questions with syntax errors
84
89
  def make_syntax_error
85
90
  questions = []
86
91
 
@@ -120,6 +125,8 @@ class RubyCodeAI < BaseCodeAI
120
125
  questions.shuffle[0,@lines.size/@reduce]
121
126
  end
122
127
 
128
+ ##
129
+ # Make questions with variable errors
123
130
  def make_variable_error
124
131
  questions = []
125
132
  error_lines = []
@@ -4,12 +4,9 @@ require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
6
  class SQLCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
7
+ def initialize(code)
10
8
  @lang = LangFactory.instance.get('sql')
11
- @num = 0
12
- @questions = []
9
+ super code
13
10
  end
14
11
 
15
12
  def make_comment_error
@@ -23,6 +23,7 @@ class ConceptAI
23
23
  @questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
24
24
  @excluded_questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
25
25
  @num = 0 # Used to add a unique number to every question
26
+ make_questions
26
27
  end
27
28
 
28
29
  def num
@@ -1,41 +1,42 @@
1
- # encoding: utf-8
2
1
 
3
2
  require 'set'
4
3
  require_relative 'base_stage'
5
4
  require_relative '../question'
6
5
 
6
+ ##
7
+ # StageT create questions based con Table data
7
8
  class StageT < BaseStage
8
- #range t1-t9...c1-c9
9
+ # range t1-t9
9
10
 
10
- def run(pTable, pRow, pList) #process_tableXfields
11
+ def run(pTable, pRow, pList) # process_tableXfields
11
12
  questions = []
12
- return questions unless type=="text"
13
+ return questions unless type == 'text'
13
14
 
14
- if pTable.fields.count>1 then
15
+ if pTable.fields.count > 1
15
16
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 1)
16
- elsif pTable.fields.count>2 then
17
+ elsif pTable.fields.count > 2
17
18
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 2)
18
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
19
- elsif pTable.fields.count>3 then
19
+ # questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
20
+ elsif pTable.fields.count > 3
20
21
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 3)
21
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
22
- questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
22
+ # questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
23
+ # questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
23
24
  end
24
25
 
25
- return questions
26
+ questions
26
27
  end
27
28
 
28
29
  private
29
30
  def process_table2fields(lTable, lRow, pList, pCol1, pCol2)
30
31
  questions = []
31
- #create gift questions
32
+ # create questions
32
33
 
33
34
  # Using the column #0
34
- s=Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
+ s = Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
36
  pList.each { |i| s.add( i[:data][0] ) }
36
- a=s.to_a
37
+ a = s.to_a
37
38
 
38
- if s.count>3 then
39
+ if s.count > 3
39
40
  q=Question.new
40
41
  q.name="#{name}-#{num.to_s}-t1table-#{lTable.name}"
41
42
  q.text=lang.text_for(:t1table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
@@ -46,15 +47,15 @@ private
46
47
  questions << q
47
48
  end
48
49
 
49
- s=Set.new [ lRow[:data][0], lang.text_for(:none) ]
50
+ s = Set.new [ lRow[:data][0], lang.text_for(:none) ]
50
51
  pList.each { |i| s.add( i[:data][0] ) }
51
- a=s.to_a
52
+ a = s.to_a
52
53
 
53
- if s.count>4 then
54
- q=Question.new
55
- q.name="#{name}-#{num.to_s}-t2table-#{lTable.name}"
56
- q.text=lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
57
- q.good=lang.text_for(:none)
54
+ if s.count > 4
55
+ q = Question.new
56
+ q.name = "#{name}-#{num.to_s}-t2table-#{lTable.name}"
57
+ q.text = lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
58
+ q.good = lang.text_for(:none)
58
59
  q.bads << a[2]
59
60
  q.bads << a[3]
60
61
  q.bads << a[4]
@@ -62,30 +63,30 @@ private
62
63
  end
63
64
 
64
65
  # Using the column #1
65
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
66
+ s = Set.new [ lRow[:data][1], lang.text_for(:none) ]
66
67
  pList.each { |i| s.add( i[:data][1] ) }
67
- a=s.to_a
68
+ a = s.to_a
68
69
 
69
- if s.count>3 then
70
- q=Question.new
71
- q.name="#{name}-#{num.to_s}-t3table-#{lTable.name}"
72
- q.text=lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
73
- q.good=a[0]
70
+ if s.count > 3
71
+ q = Question.new
72
+ q.name = "#{name}-#{num.to_s}-t3table-#{lTable.name}"
73
+ q.text = lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
74
+ q.good = a[0]
74
75
  q.bads << lang.text_for(:none)
75
76
  q.bads << a[2]
76
77
  q.bads << a[3]
77
78
  questions << q
78
79
  end
79
80
 
80
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
81
+ s = Set.new [ lRow[:data][1], lang.text_for(:none) ]
81
82
  pList.each { |i| s.add( i[:data][1] ) }
82
- a=s.to_a
83
+ a = s.to_a
83
84
 
84
- if s.count>4 then
85
- q=Question.new
86
- q.name="#{name}-#{num.to_s}-t4table-#{lTable.name}"
87
- q.text=lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
88
- q.good=lang.text_for(:none)
85
+ if s.count > 4
86
+ q = Question.new
87
+ q.name = "#{name}-#{num.to_s}-t4table-#{lTable.name}"
88
+ q.text = lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
89
+ q.good = lang.text_for(:none)
89
90
  q.bads << a[2]
90
91
  q.bads << a[3]
91
92
  q.bads << a[4]
@@ -93,78 +94,77 @@ private
93
94
  end
94
95
 
95
96
  # Boolean association TRUE
96
- q=Question.new
97
+ q = Question.new
97
98
  q.set_boolean
98
- q.name="#{name}-#{num.to_s}t5table-#{lTable.name}"
99
- q.text=lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
100
- q.good="TRUE"
99
+ q.name = "#{name}-#{num.to_s}t5table-#{lTable.name}"
100
+ q.text = lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
101
+ q.good = "TRUE"
101
102
  questions << q
102
103
 
103
104
  # Boolean association FALSE
104
- s=Set.new [ lRow[:data][1] ]
105
+ s = Set.new [ lRow[:data][1] ]
105
106
  pList.each { |i| s.add( i[:data][1] ) }
106
- a=s.to_a
107
+ a = s.to_a
107
108
 
108
- if s.count>1 then
109
- q=Question.new
109
+ if s.count > 1
110
+ q = Question.new
110
111
  q.set_boolean
111
- q.name="#{name}-#{num.to_s}-t6table-#{lTable.name}"
112
- q.text=lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
113
- q.good="FALSE"
112
+ q.name = "#{name}-#{num.to_s}-t6table-#{lTable.name}"
113
+ q.text = lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
114
+ q.good = "FALSE"
114
115
  questions << q
115
116
  end
116
117
 
117
- s=Set.new [ lRow[:data][0] ]
118
+ s = Set.new [ lRow[:data][0] ]
118
119
  pList.each { |i| s.add( i[:data][0] ) }
119
- a=s.to_a
120
+ a = s.to_a
120
121
 
121
- if s.count>1 then
122
- q=Question.new
122
+ if s.count > 1
123
+ q = Question.new
123
124
  q.set_boolean
124
- q.name="#{name}-#{num.to_s}t7table-#{lTable.name}"
125
- q.text=lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
126
- q.good="FALSE"
125
+ q.name = "#{name}-#{num.to_s}t7table-#{lTable.name}"
126
+ q.text = lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
127
+ q.good = "FALSE"
127
128
  questions << q
128
129
  end
129
130
 
130
131
  # Short answer with column #0, 1 word
131
- if lang.count_words(lRow[:data][0])==1 then
132
- q=Question.new
132
+ if lang.count_words(lRow[:data][0]) == 1
133
+ q = Question.new
133
134
  q.set_short
134
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
135
- q.text=lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
135
+ q.name = "#{name}-#{num.to_s}t8table-#{lTable.name}"
136
+ q.text = lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
136
137
  q.shorts << lRow[:data][0]
137
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
138
+ q.shorts << lRow[:data][0].gsub('-', ' ').gsub('_', ' ')
138
139
  questions << q
139
- elsif lang.count_words(lRow[:data][0])==2 then
140
- q=Question.new
140
+ elsif lang.count_words(lRow[:data][0]) == 2
141
+ q = Question.new
141
142
  q.set_short
142
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
143
- q.text=lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
143
+ q.name = "#{name}-#{num.to_s}t9table-#{lTable.name}"
144
+ q.text = lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
144
145
  q.shorts << lRow[:data][0]
145
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
146
+ q.shorts << lRow[:data][0].gsub('-', ' ').gsub('_', ' ')
146
147
  questions << q
147
148
  end
148
149
 
149
150
  # Short answer with column #1, 1 word
150
- if lang.count_words(lRow[:data][1])==1 then
151
- q=Question.new
151
+ if lang.count_words(lRow[:data][1]) == 1
152
+ q = Question.new
152
153
  q.set_short
153
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
154
- q.text=lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
154
+ q.name = "#{name}-#{num.to_s}t8table-#{lTable.name}"
155
+ q.text = lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
155
156
  q.shorts << lRow[:data][1]
156
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
157
+ q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
157
158
  questions << q
158
- elsif lang.count_words(lRow[:data][1])==2 then
159
- q=Question.new
159
+ elsif lang.count_words(lRow[:data][1]) == 2
160
+ q = Question.new
160
161
  q.set_short
161
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
162
- q.text=lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
162
+ q.name = "#{name}-#{num.to_s}t9table-#{lTable.name}"
163
+ q.text = lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
163
164
  q.shorts << lRow[:data][1]
164
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
165
+ q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
165
166
  questions << q
166
167
  end
167
- return questions
168
+ questions
168
169
  end
169
-
170
170
  end
@@ -2,13 +2,14 @@
2
2
 
3
3
  require 'singleton'
4
4
  require 'inifile'
5
+ require 'rainbow'
5
6
 
6
7
  # Global parameters
7
8
  class Application
8
9
  include Singleton
9
10
 
10
- VERSION = '2.1.2' # Application version
11
- NAME = 'asker' # Application name
11
+ VERSION = '2.1.7' # Application version
12
+ NAME = 'asker' # Application name
12
13
  GEM = 'asker-tool' # Gem name
13
14
  attr_reader :config
14
15
 
@@ -20,11 +21,26 @@ class Application
20
21
 
21
22
  ##
22
23
  # Initialize config values from external "config.ini" file.
24
+ # rubocop:disable Metrics/AbcSize
25
+ # rubocop:disable Metrics/MethodLength
23
26
  def reset
24
27
  filename = File.join(Dir.pwd, 'config.ini')
25
28
  unless File.exist? filename
26
29
  filename = File.join(File.dirname(__FILE__), 'files', 'config.ini')
27
30
  end
28
- @config = IniFile.load(filename)
31
+ begin
32
+ @config = IniFile.load(filename)
33
+ rescue StandardError => e
34
+ puts e.display
35
+ puts Rainbow('[ERROR] Revise configuration file:').red.bright
36
+ puts Rainbow(" #{filename}").red.bright
37
+ exit 1
38
+ end
39
+ stages = @config['questions']['stages'].split(',')
40
+ @config['questions']['stages'] = stages.map(&:to_sym)
41
+ Rainbow.enabled = false
42
+ Rainbow.enabled = true if @config['global']['color'].downcase == 'yes'
29
43
  end
44
+ # rubocop:enable Metrics/MethodLength
45
+ # rubocop:enable Metrics/AbcSize
30
46
  end
@@ -1,29 +1,46 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require 'rainbow'
3
4
 
5
+ ##
6
+ # Check HAML file syntax
4
7
  module Checker
8
+ ##
9
+ # Check:
10
+ # * file exist
11
+ # * filename extension
12
+ # * and HAML syntax
13
+ # @param filepath (String)
5
14
  def self.check(filepath)
6
15
  unless File.exist? filepath
7
- puts Rainbow("File not found!").red.bright
16
+ puts Rainbow('File not found!').red.bright
8
17
  return false
9
18
  end
10
19
  unless File.extname(filepath) == '.haml'
11
- puts Rainbow("Only check HAML files!").yellow.bright
20
+ puts Rainbow('Only check HAML files!').yellow.bright
12
21
  return false
13
22
  end
14
23
  check_filepath(filepath)
15
24
  end
16
25
 
26
+ ##
27
+ # Check HAML syntax
28
+ # @param filepath (String)
17
29
  def self.check_filepath(filepath)
18
30
  data = Data.new(filepath)
19
31
  data.check
20
32
  data.show_errors
21
- data.is_ok?
33
+ data.ok?
22
34
  end
23
35
 
36
+ ##
37
+ # Internal class that revise syntax
38
+ # rubocop:disable Metrics/ClassLength
24
39
  class Data
25
40
  attr_reader :inputs
26
41
  attr_reader :outputs
42
+
43
+ # rubocop:disable Metrics/MethodLength
27
44
  def initialize(filepath)
28
45
  @inputs = File.read(filepath).split("\n")
29
46
  @outputs = []
@@ -38,8 +55,9 @@ module Checker
38
55
  end
39
56
  @ok = false
40
57
  end
58
+ # rubocop:enable Metrics/MethodLength
41
59
 
42
- def is_ok?
60
+ def ok?
43
61
  @ok
44
62
  end
45
63
 
@@ -49,18 +67,33 @@ module Checker
49
67
  end
50
68
  end
51
69
 
70
+ # rubocop:disable Metrics/AbcSize
71
+ # rubocop:disable Metrics/MethodLength
52
72
  def show_errors
53
73
  errors = 0
74
+ # puts "Line : Error description"
54
75
  @outputs.each do |i|
55
76
  next if i[:state] == :ok
77
+
56
78
  errors += 1
57
- puts "%02d" % i[:id] + ": %s." % i[:msg] + " => #{i[:source][0,40]}" if errors < 11
58
- puts "..." if errors == 11
79
+ if errors < 11
80
+ data = { id: i[:id], msg: i[:msg], source: i[:source][0, 40] }
81
+ puts format(' %<id>03d : %<msg>s. => %<source>s', data)
82
+ end
83
+ puts '...' if errors == 11
84
+ end
85
+
86
+ if errors.positive?
87
+ puts Rainbow("[ERROR] #{errors} errors " \
88
+ "from #{@inputs.size} lines!").red.bright
59
89
  end
60
- puts Rainbow("[ERROR] #{errors} errors from #{@inputs.size} lines!").red.bright if errors > 0
61
- puts Rainbow("Syntax OK!").green if errors == 0
90
+ puts Rainbow('Syntax OK!').green if errors.zero?
62
91
  end
92
+ # rubocop:enable Metrics/AbcSize
93
+ # rubocop:enable Metrics/MethodLength
63
94
 
95
+ # rubocop:disable Metrics/MethodLength
96
+ # rubocop:disable Metrics/AbcSize
64
97
  def check
65
98
  @ok = true
66
99
  @inputs.each_with_index do |line, index|
@@ -84,31 +117,38 @@ module Checker
84
117
  end
85
118
  @ok
86
119
  end
120
+ # rubocop:enable Metrics/MethodLength
121
+ # rubocop:enable Metrics/AbcSize
122
+
123
+ private
87
124
 
88
125
  def check_empty_lines(line, index)
89
- if line.strip.size.zero? or line.start_with? '#'
90
- @outputs[index][:type] = :empty
91
- @outputs[index][:level] = -1
92
- @outputs[index][:state] = :ok
93
- end
126
+ return unless line.strip.size.zero? || line.start_with?('#')
127
+
128
+ @outputs[index][:type] = :empty
129
+ @outputs[index][:level] = -1
130
+ @outputs[index][:state] = :ok
94
131
  end
95
132
 
133
+ # rubocop:disable Metrics/MethodLength
96
134
  def check_map(line, index)
97
- if index == 0
135
+ if index.zero?
98
136
  @outputs[index][:type] = :map
99
137
  if line.start_with?('%map{')
100
138
  @outputs[index][:state] = :ok
101
139
  else
102
140
  @outputs[index][:state] = :err
103
- @outputs[index][:msg] = "Start with '%map{'"
141
+ @outputs[index][:msg] = 'Start with %map{'
104
142
  end
105
- elsif index > 0 and line.include?('%map{')
143
+ elsif index.positive? && line.include?('%map{')
106
144
  @outputs[index][:state] = :err
107
145
  @outputs[index][:type] = :map
108
- @outputs[index][:msg] = "Write '%map' on line 0"
146
+ @outputs[index][:msg] = 'Write %map on line 0'
109
147
  end
110
148
  end
149
+ # rubocop:enable Metrics/MethodLength
111
150
 
151
+ # rubocop:disable Metrics/MethodLength
112
152
  def check_concept(line, index)
113
153
  return unless @outputs[index][:state] == :none
114
154
  return unless line.include? '%concept'
@@ -124,7 +164,10 @@ module Checker
124
164
  @outputs[index][:msg] = 'Write 2 spaces before %concept'
125
165
  end
126
166
  end
167
+ # rubocop:enable Metrics/MethodLength
127
168
 
169
+ # rubocop:disable Metrics/AbcSize
170
+ # rubocop:disable Metrics/MethodLength
128
171
  def check_names(line, index)
129
172
  return unless @outputs[index][:state] == :none
130
173
  return unless line.include? '%names'
@@ -135,12 +178,16 @@ module Checker
135
178
  if find_parent(index) != :concept
136
179
  @outputs[index][:state] = :err
137
180
  @outputs[index][:msg] = 'Parent(concept) not found!'
138
- elsif not line.start_with? ' %names'
181
+ elsif !line.start_with? ' %names'
139
182
  @outputs[index][:state] = :err
140
- @outputs[index][:msg] = "Write 4 spaces before %names"
183
+ @outputs[index][:msg] = 'Write 4 spaces before %names'
141
184
  end
142
185
  end
186
+ # rubocop:enable Metrics/AbcSize
187
+ # rubocop:enable Metrics/MethodLength
143
188
 
189
+ # rubocop:disable Metrics/AbcSize
190
+ # rubocop:disable Metrics/MethodLength
144
191
  def check_tags(line, index)
145
192
  return unless @outputs[index][:state] == :none
146
193
  return unless line.include? '%tags'
@@ -151,12 +198,16 @@ module Checker
151
198
  if find_parent(index) != :concept
152
199
  @outputs[index][:state] = :err
153
200
  @outputs[index][:msg] = 'Parent(concept) not found!'
154
- elsif not line.start_with? ' %tags'
201
+ elsif !line.start_with? ' %tags'
155
202
  @outputs[index][:state] = :err
156
- @outputs[index][:msg] = "Write 4 spaces before %tags"
203
+ @outputs[index][:msg] = 'Write 4 spaces before %tags'
157
204
  end
158
205
  end
206
+ # rubocop:enable Metrics/AbcSize
207
+ # rubocop:enable Metrics/MethodLength
159
208
 
209
+ # rubocop:disable Metrics/AbcSize
210
+ # rubocop:disable Metrics/MethodLength
160
211
  def check_def(line, index)
161
212
  return unless @outputs[index][:state] == :none
162
213
  return unless line.include? '%def'
@@ -167,12 +218,16 @@ module Checker
167
218
  if find_parent(index) != :concept
168
219
  @outputs[index][:state] = :err
169
220
  @outputs[index][:msg] = 'Parent(concept) not found!'
170
- elsif not line.start_with? ' %def'
221
+ elsif !line.start_with? ' %def'
171
222
  @outputs[index][:state] = :err
172
- @outputs[index][:msg] = "Write 4 spaces before %def"
223
+ @outputs[index][:msg] = 'Write 4 spaces before %def'
173
224
  end
174
225
  end
226
+ # rubocop:enable Metrics/AbcSize
227
+ # rubocop:enable Metrics/MethodLength
175
228
 
229
+ # rubocop:disable Metrics/AbcSize
230
+ # rubocop:disable Metrics/MethodLength
176
231
  def check_table(line, index)
177
232
  return unless @outputs[index][:state] == :none
178
233
  return unless line.include? '%table'
@@ -183,12 +238,18 @@ module Checker
183
238
  if find_parent(index) != :concept
184
239
  @outputs[index][:state] = :err
185
240
  @outputs[index][:msg] = 'Parent(concept) not found!'
186
- elsif not line.start_with? ' %table'
241
+ elsif !line.start_with? ' %table'
187
242
  @outputs[index][:state] = :err
188
- @outputs[index][:msg] = "Write 4 spaces before %table"
243
+ @outputs[index][:msg] = 'Write 4 spaces before %table'
189
244
  end
190
245
  end
246
+ # rubocop:enable Metrics/AbcSize
247
+ # rubocop:enable Metrics/MethodLength
191
248
 
249
+ # rubocop:disable Metrics/AbcSize
250
+ # rubocop:disable Metrics/CyclomaticComplexity
251
+ # rubocop:disable Metrics/MethodLength
252
+ # rubocop:disable Metrics/PerceivedComplexity
192
253
  def check_row(line, index)
193
254
  return unless @outputs[index][:state] == :none
194
255
  return unless line.include? '%row'
@@ -199,7 +260,7 @@ module Checker
199
260
  if count_spaces(line) == 6
200
261
  @outputs[index][:level] = 3
201
262
  parent = find_parent(index)
202
- unless [:table, :features].include? parent
263
+ unless %i[table features].include? parent
203
264
  @outputs[index][:state] = :err
204
265
  @outputs[index][:msg] = 'Parent(table/features) not found!'
205
266
  end
@@ -211,10 +272,18 @@ module Checker
211
272
  end
212
273
  else
213
274
  @outputs[index][:state] = :err
214
- @outputs[index][:msg] = "Write 6 or 8 spaces before %row"
275
+ @outputs[index][:msg] = 'Write 6 or 8 spaces before %row'
215
276
  end
216
277
  end
217
-
278
+ # rubocop:enable Metrics/AbcSize
279
+ # rubocop:enable Metrics/CyclomaticComplexity
280
+ # rubocop:enable Metrics/MethodLength
281
+ # rubocop:enable Metrics/PerceivedComplexity
282
+
283
+ # rubocop:disable Metrics/AbcSize
284
+ # rubocop:disable Metrics/CyclomaticComplexity
285
+ # rubocop:disable Metrics/MethodLength
286
+ # rubocop:disable Metrics/PerceivedComplexity
218
287
  def check_col(line, index)
219
288
  return unless @outputs[index][:state] == :none
220
289
  return unless line.include? '%col'
@@ -235,10 +304,30 @@ module Checker
235
304
  end
236
305
  else
237
306
  @outputs[index][:state] = :err
238
- @outputs[index][:msg] = "Write 8 or 10 spaces before %col"
307
+ @outputs[index][:msg] = 'Write 8 or 10 spaces before %col'
239
308
  end
309
+ check_text(line, index)
240
310
  end
311
+ # rubocop:enable Metrics/AbcSize
312
+ # rubocop:enable Metrics/CyclomaticComplexity
313
+ # rubocop:enable Metrics/MethodLength
314
+ # rubocop:enable Metrics/PerceivedComplexity
241
315
 
316
+ def check_text(line, index)
317
+ return unless @outputs[index][:state] == :ok
318
+
319
+ ok = ''
320
+ %w[< >].each do |char|
321
+ ok = char if line.include? char
322
+ end
323
+ return if ok == ''
324
+
325
+ @outputs[index][:state] = :err
326
+ @outputs[index][:msg] = "Char #{ok} not allow!"
327
+ end
328
+
329
+ # rubocop:disable Metrics/MethodLength
330
+ # rubocop:disable Metrics/AbcSize
242
331
  def check_template(line, index)
243
332
  return unless @outputs[index][:state] == :none
244
333
  return unless line.include? '%template'
@@ -249,12 +338,15 @@ module Checker
249
338
  if find_parent(index) != :table
250
339
  @outputs[index][:state] = :err
251
340
  @outputs[index][:msg] = 'Parent(concept) not found!'
252
- elsif not line.start_with? ' %template'
341
+ elsif !line.start_with? ' %template'
253
342
  @outputs[index][:state] = :err
254
- @outputs[index][:msg] = "Write 6 spaces before %template"
343
+ @outputs[index][:msg] = 'Write 6 spaces before %template'
255
344
  end
256
345
  end
346
+ # rubocop:enable Metrics/AbcSize
347
+ # rubocop:enable Metrics/MethodLength
257
348
 
349
+ # rubocop:disable Metrics/MethodLength
258
350
  def check_code(line, index)
259
351
  return unless @outputs[index][:state] == :none
260
352
  return unless line.include? '%code'
@@ -270,7 +362,10 @@ module Checker
270
362
  @outputs[index][:msg] = 'Write 2 spaces before %code'
271
363
  end
272
364
  end
365
+ # rubocop:enable Metrics/MethodLength
273
366
 
367
+ # rubocop:disable Metrics/MethodLength
368
+ # rubocop:disable Metrics/AbcSize
274
369
  def check_type(line, index)
275
370
  return unless @outputs[index][:state] == :none
276
371
  return unless line.include? '%type'
@@ -281,12 +376,16 @@ module Checker
281
376
  if find_parent(index) != :code
282
377
  @outputs[index][:state] = :err
283
378
  @outputs[index][:msg] = 'Parent(code) not found!'
284
- elsif not line.start_with? ' %type'
379
+ elsif !line.start_with? ' %type'
285
380
  @outputs[index][:state] = :err
286
- @outputs[index][:msg] = "Write 4 spaces before %type"
381
+ @outputs[index][:msg] = 'Write 4 spaces before %type'
287
382
  end
288
383
  end
384
+ # rubocop:enable Metrics/AbcSize
385
+ # rubocop:enable Metrics/MethodLength
289
386
 
387
+ # rubocop:disable Metrics/MethodLength
388
+ # rubocop:disable Metrics/AbcSize
290
389
  def check_path(line, index)
291
390
  return unless @outputs[index][:state] == :none
292
391
  return unless line.include? '%path'
@@ -297,12 +396,16 @@ module Checker
297
396
  if find_parent(index) != :code
298
397
  @outputs[index][:state] = :err
299
398
  @outputs[index][:msg] = 'Parent(code) not found!'
300
- elsif not line.start_with? ' %path'
399
+ elsif !line.start_with? ' %path'
301
400
  @outputs[index][:state] = :err
302
- @outputs[index][:msg] = "Write 4 spaces before %type"
401
+ @outputs[index][:msg] = 'Write 4 spaces before %type'
303
402
  end
304
403
  end
404
+ # rubocop:enable Metrics/AbcSize
405
+ # rubocop:enable Metrics/MethodLength
305
406
 
407
+ # rubocop:disable Metrics/MethodLength
408
+ # rubocop:disable Metrics/AbcSize
306
409
  def check_features(line, index)
307
410
  return unless @outputs[index][:state] == :none
308
411
  return unless line.include? '%features'
@@ -313,16 +416,19 @@ module Checker
313
416
  if find_parent(index) != :code
314
417
  @outputs[index][:state] = :err
315
418
  @outputs[index][:msg] = 'Parent(code) not found!'
316
- elsif not line.start_with? ' %features'
419
+ elsif !line.start_with? ' %features'
317
420
  @outputs[index][:state] = :err
318
- @outputs[index][:msg] = "Write 4 spaces before %features"
421
+ @outputs[index][:msg] = 'Write 4 spaces before %features'
319
422
  end
320
423
  end
424
+ # rubocop:enable Metrics/AbcSize
425
+ # rubocop:enable Metrics/MethodLength
321
426
 
322
427
  def check_unknown(line, index)
323
428
  return unless @outputs[index][:state] == :none
429
+
324
430
  @outputs[index][:type] = :unknown
325
- @outputs[index][:level] = count_spaces(line)/2
431
+ @outputs[index][:level] = count_spaces(line) / 2
326
432
  @outputs[index][:state] = :err
327
433
  @outputs[index][:msg] = "Unknown tag with parent(#{find_parent(index)})!"
328
434
  end
@@ -330,27 +436,20 @@ module Checker
330
436
  def find_parent(index)
331
437
  current_level = @outputs[index][:level]
332
438
  return :noparent if current_level.zero?
439
+
333
440
  i = index - 1
334
- while(i >= 0)
441
+ while i >= 0
335
442
  return @outputs[i][:type] if @outputs[i][:level] == current_level - 1
336
- i = i - 1
443
+
444
+ i -= 1
337
445
  end
338
- return :noparent
446
+ :noparent
339
447
  end
340
448
 
341
449
  def count_spaces(line)
342
- return 0 if line.start_with? '%'
343
- return 1 if line.start_with? ' %'
344
- return 2 if line.start_with? ' %'
345
- return 3 if line.start_with? ' %'
346
- return 4 if line.start_with? ' %'
347
- return 5 if line.start_with? ' %'
348
- return 6 if line.start_with? ' %'
349
- return 7 if line.start_with? ' %'
350
- return 8 if line.start_with? ' %'
351
- return 9 if line.start_with? ' %'
352
- return 10 if line.start_with? ' %'
353
- return -1
450
+ a = line.split('%')
451
+ a[0].count(' ')
354
452
  end
355
453
  end
454
+ # rubocop:enable Metrics/ClassLength
356
455
  end