asker-tool 2.1.2 → 2.1.7

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.
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