asker-tool 2.1.5 → 2.1.6
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.
- checksums.yaml +4 -4
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +2 -3
- data/bin/asker +1 -0
- data/lib/asker.rb +10 -6
- data/lib/asker/ai/ai.rb +4 -0
- data/lib/asker/ai/code/base_code_ai.rb +104 -0
- data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
- data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
- data/lib/asker/ai/code/problem_code_ai.rb +176 -0
- data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
- data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
- data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
- data/lib/asker/ai/concept_ai.rb +1 -0
- data/lib/asker/ai/stages/stage_t.rb +76 -76
- data/lib/asker/application.rb +18 -2
- data/lib/asker/checker.rb +112 -30
- data/lib/asker/cli.rb +12 -25
- data/lib/asker/data/code.rb +73 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +42 -45
- data/lib/asker/data/data_field.rb +14 -0
- data/lib/asker/data/row.rb +75 -52
- data/lib/asker/data/table.rb +89 -42
- data/lib/asker/data/world.rb +57 -33
- data/lib/asker/displayer/concept_ai_displayer.rb +56 -37
- data/lib/asker/displayer/concept_displayer.rb +7 -5
- data/lib/asker/displayer/stats_displayer.rb +4 -3
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +5 -3
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -3
- data/lib/asker/exporter/output_file_exporter.rb +1 -1
- data/lib/asker/files/config.ini +37 -0
- data/lib/asker/files/example-concept.haml +0 -1
- data/lib/asker/{lang/locales → files/language}/du/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/es/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/es/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/fr/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/fr/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/fr/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
- data/lib/asker/lang/lang.rb +17 -10
- data/lib/asker/lang/lang_factory.rb +26 -5
- data/lib/asker/lang/text_actions.rb +87 -69
- data/lib/asker/loader/code_loader.rb +3 -3
- data/lib/asker/loader/content_loader.rb +9 -5
- data/lib/asker/loader/file_loader.rb +2 -11
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +5 -8
- data/lib/asker/loader/input_loader.rb +8 -9
- data/lib/asker/loader/project_loader.rb +10 -8
- data/lib/asker/logger.rb +3 -3
- data/lib/asker/project.rb +24 -50
- data/lib/asker/skeleton.rb +22 -13
- metadata +39 -37
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
@@ -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(
|
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
|
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(
|
8
|
-
@data_object = data_object
|
9
|
-
@lines = data_object.lines
|
7
|
+
def initialize(code)
|
10
8
|
@lang = LangFactory.instance.get('sql')
|
11
|
-
|
12
|
-
@questions = []
|
9
|
+
super code
|
13
10
|
end
|
14
11
|
|
15
12
|
def make_comment_error
|
data/lib/asker/ai/concept_ai.rb
CHANGED
@@ -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
|
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==
|
13
|
+
return questions unless type == 'text'
|
13
14
|
|
14
|
-
if pTable.fields.count>1
|
15
|
+
if pTable.fields.count > 1
|
15
16
|
questions = questions + process_table2fields(pTable, pRow, pList, 0, 1)
|
16
|
-
elsif pTable.fields.count>2
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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(
|
138
|
+
q.shorts << lRow[:data][0].gsub('-', ' ').gsub('_', ' ')
|
138
139
|
questions << q
|
139
|
-
elsif lang.count_words(lRow[:data][0])==2
|
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(
|
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
|
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(
|
157
|
+
q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
|
157
158
|
questions << q
|
158
|
-
elsif lang.count_words(lRow[:data][1])==2
|
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(
|
165
|
+
q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
|
165
166
|
questions << q
|
166
167
|
end
|
167
|
-
|
168
|
+
questions
|
168
169
|
end
|
169
|
-
|
170
170
|
end
|
data/lib/asker/application.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
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.
|
11
|
+
VERSION = '2.1.6' # Application version
|
11
12
|
NAME = 'asker' # Application name
|
12
13
|
GEM = 'asker-tool' # Gem name
|
13
14
|
attr_reader :config
|
@@ -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
|
-
|
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
|
data/lib/asker/checker.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'rainbow'
|
3
4
|
|
@@ -12,11 +13,11 @@ module Checker
|
|
12
13
|
# @param filepath (String)
|
13
14
|
def self.check(filepath)
|
14
15
|
unless File.exist? filepath
|
15
|
-
puts Rainbow(
|
16
|
+
puts Rainbow('File not found!').red.bright
|
16
17
|
return false
|
17
18
|
end
|
18
19
|
unless File.extname(filepath) == '.haml'
|
19
|
-
puts Rainbow(
|
20
|
+
puts Rainbow('Only check HAML files!').yellow.bright
|
20
21
|
return false
|
21
22
|
end
|
22
23
|
check_filepath(filepath)
|
@@ -29,12 +30,17 @@ module Checker
|
|
29
30
|
data = Data.new(filepath)
|
30
31
|
data.check
|
31
32
|
data.show_errors
|
32
|
-
data.
|
33
|
+
data.ok?
|
33
34
|
end
|
34
35
|
|
36
|
+
##
|
37
|
+
# Internal class that revise syntax
|
38
|
+
# rubocop:disable Metrics/ClassLength
|
35
39
|
class Data
|
36
40
|
attr_reader :inputs
|
37
41
|
attr_reader :outputs
|
42
|
+
|
43
|
+
# rubocop:disable Metrics/MethodLength
|
38
44
|
def initialize(filepath)
|
39
45
|
@inputs = File.read(filepath).split("\n")
|
40
46
|
@outputs = []
|
@@ -49,8 +55,9 @@ module Checker
|
|
49
55
|
end
|
50
56
|
@ok = false
|
51
57
|
end
|
58
|
+
# rubocop:enable Metrics/MethodLength
|
52
59
|
|
53
|
-
def
|
60
|
+
def ok?
|
54
61
|
@ok
|
55
62
|
end
|
56
63
|
|
@@ -60,18 +67,33 @@ module Checker
|
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
70
|
+
# rubocop:disable Metrics/AbcSize
|
71
|
+
# rubocop:disable Metrics/MethodLength
|
63
72
|
def show_errors
|
64
73
|
errors = 0
|
74
|
+
# puts "Line : Error description"
|
65
75
|
@outputs.each do |i|
|
66
76
|
next if i[:state] == :ok
|
77
|
+
|
67
78
|
errors += 1
|
68
|
-
|
69
|
-
|
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
|
70
84
|
end
|
71
|
-
|
72
|
-
|
85
|
+
|
86
|
+
if errors.positive?
|
87
|
+
puts Rainbow("[ERROR] #{errors} errors " \
|
88
|
+
"from #{@inputs.size} lines!").red.bright
|
89
|
+
end
|
90
|
+
puts Rainbow('Syntax OK!').green if errors.zero?
|
73
91
|
end
|
92
|
+
# rubocop:enable Metrics/AbcSize
|
93
|
+
# rubocop:enable Metrics/MethodLength
|
74
94
|
|
95
|
+
# rubocop:disable Metrics/MethodLength
|
96
|
+
# rubocop:disable Metrics/AbcSize
|
75
97
|
def check
|
76
98
|
@ok = true
|
77
99
|
@inputs.each_with_index do |line, index|
|
@@ -95,19 +117,22 @@ module Checker
|
|
95
117
|
end
|
96
118
|
@ok
|
97
119
|
end
|
120
|
+
# rubocop:enable Metrics/MethodLength
|
121
|
+
# rubocop:enable Metrics/AbcSize
|
98
122
|
|
99
123
|
private
|
100
124
|
|
101
125
|
def check_empty_lines(line, index)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
107
131
|
end
|
108
132
|
|
133
|
+
# rubocop:disable Metrics/MethodLength
|
109
134
|
def check_map(line, index)
|
110
|
-
if index
|
135
|
+
if index.zero?
|
111
136
|
@outputs[index][:type] = :map
|
112
137
|
if line.start_with?('%map{')
|
113
138
|
@outputs[index][:state] = :ok
|
@@ -115,13 +140,15 @@ module Checker
|
|
115
140
|
@outputs[index][:state] = :err
|
116
141
|
@outputs[index][:msg] = 'Start with %map{'
|
117
142
|
end
|
118
|
-
elsif index
|
143
|
+
elsif index.positive? && line.include?('%map{')
|
119
144
|
@outputs[index][:state] = :err
|
120
145
|
@outputs[index][:type] = :map
|
121
146
|
@outputs[index][:msg] = 'Write %map on line 0'
|
122
147
|
end
|
123
148
|
end
|
149
|
+
# rubocop:enable Metrics/MethodLength
|
124
150
|
|
151
|
+
# rubocop:disable Metrics/MethodLength
|
125
152
|
def check_concept(line, index)
|
126
153
|
return unless @outputs[index][:state] == :none
|
127
154
|
return unless line.include? '%concept'
|
@@ -137,7 +164,10 @@ module Checker
|
|
137
164
|
@outputs[index][:msg] = 'Write 2 spaces before %concept'
|
138
165
|
end
|
139
166
|
end
|
167
|
+
# rubocop:enable Metrics/MethodLength
|
140
168
|
|
169
|
+
# rubocop:disable Metrics/AbcSize
|
170
|
+
# rubocop:disable Metrics/MethodLength
|
141
171
|
def check_names(line, index)
|
142
172
|
return unless @outputs[index][:state] == :none
|
143
173
|
return unless line.include? '%names'
|
@@ -153,7 +183,11 @@ module Checker
|
|
153
183
|
@outputs[index][:msg] = 'Write 4 spaces before %names'
|
154
184
|
end
|
155
185
|
end
|
186
|
+
# rubocop:enable Metrics/AbcSize
|
187
|
+
# rubocop:enable Metrics/MethodLength
|
156
188
|
|
189
|
+
# rubocop:disable Metrics/AbcSize
|
190
|
+
# rubocop:disable Metrics/MethodLength
|
157
191
|
def check_tags(line, index)
|
158
192
|
return unless @outputs[index][:state] == :none
|
159
193
|
return unless line.include? '%tags'
|
@@ -169,7 +203,11 @@ module Checker
|
|
169
203
|
@outputs[index][:msg] = 'Write 4 spaces before %tags'
|
170
204
|
end
|
171
205
|
end
|
206
|
+
# rubocop:enable Metrics/AbcSize
|
207
|
+
# rubocop:enable Metrics/MethodLength
|
172
208
|
|
209
|
+
# rubocop:disable Metrics/AbcSize
|
210
|
+
# rubocop:disable Metrics/MethodLength
|
173
211
|
def check_def(line, index)
|
174
212
|
return unless @outputs[index][:state] == :none
|
175
213
|
return unless line.include? '%def'
|
@@ -185,7 +223,11 @@ module Checker
|
|
185
223
|
@outputs[index][:msg] = 'Write 4 spaces before %def'
|
186
224
|
end
|
187
225
|
end
|
226
|
+
# rubocop:enable Metrics/AbcSize
|
227
|
+
# rubocop:enable Metrics/MethodLength
|
188
228
|
|
229
|
+
# rubocop:disable Metrics/AbcSize
|
230
|
+
# rubocop:disable Metrics/MethodLength
|
189
231
|
def check_table(line, index)
|
190
232
|
return unless @outputs[index][:state] == :none
|
191
233
|
return unless line.include? '%table'
|
@@ -201,7 +243,13 @@ module Checker
|
|
201
243
|
@outputs[index][:msg] = 'Write 4 spaces before %table'
|
202
244
|
end
|
203
245
|
end
|
246
|
+
# rubocop:enable Metrics/AbcSize
|
247
|
+
# rubocop:enable Metrics/MethodLength
|
204
248
|
|
249
|
+
# rubocop:disable Metrics/AbcSize
|
250
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
251
|
+
# rubocop:disable Metrics/MethodLength
|
252
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
205
253
|
def check_row(line, index)
|
206
254
|
return unless @outputs[index][:state] == :none
|
207
255
|
return unless line.include? '%row'
|
@@ -212,7 +260,7 @@ module Checker
|
|
212
260
|
if count_spaces(line) == 6
|
213
261
|
@outputs[index][:level] = 3
|
214
262
|
parent = find_parent(index)
|
215
|
-
unless [
|
263
|
+
unless %i[table features].include? parent
|
216
264
|
@outputs[index][:state] = :err
|
217
265
|
@outputs[index][:msg] = 'Parent(table/features) not found!'
|
218
266
|
end
|
@@ -227,7 +275,15 @@ module Checker
|
|
227
275
|
@outputs[index][:msg] = 'Write 6 or 8 spaces before %row'
|
228
276
|
end
|
229
277
|
end
|
230
|
-
|
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
|
231
287
|
def check_col(line, index)
|
232
288
|
return unless @outputs[index][:state] == :none
|
233
289
|
return unless line.include? '%col'
|
@@ -250,8 +306,28 @@ module Checker
|
|
250
306
|
@outputs[index][:state] = :err
|
251
307
|
@outputs[index][:msg] = 'Write 8 or 10 spaces before %col'
|
252
308
|
end
|
309
|
+
check_text(line, index)
|
310
|
+
end
|
311
|
+
# rubocop:enable Metrics/AbcSize
|
312
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
313
|
+
# rubocop:enable Metrics/MethodLength
|
314
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
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!"
|
253
327
|
end
|
254
328
|
|
329
|
+
# rubocop:disable Metrics/MethodLength
|
330
|
+
# rubocop:disable Metrics/AbcSize
|
255
331
|
def check_template(line, index)
|
256
332
|
return unless @outputs[index][:state] == :none
|
257
333
|
return unless line.include? '%template'
|
@@ -267,7 +343,10 @@ module Checker
|
|
267
343
|
@outputs[index][:msg] = 'Write 6 spaces before %template'
|
268
344
|
end
|
269
345
|
end
|
346
|
+
# rubocop:enable Metrics/AbcSize
|
347
|
+
# rubocop:enable Metrics/MethodLength
|
270
348
|
|
349
|
+
# rubocop:disable Metrics/MethodLength
|
271
350
|
def check_code(line, index)
|
272
351
|
return unless @outputs[index][:state] == :none
|
273
352
|
return unless line.include? '%code'
|
@@ -283,7 +362,10 @@ module Checker
|
|
283
362
|
@outputs[index][:msg] = 'Write 2 spaces before %code'
|
284
363
|
end
|
285
364
|
end
|
365
|
+
# rubocop:enable Metrics/MethodLength
|
286
366
|
|
367
|
+
# rubocop:disable Metrics/MethodLength
|
368
|
+
# rubocop:disable Metrics/AbcSize
|
287
369
|
def check_type(line, index)
|
288
370
|
return unless @outputs[index][:state] == :none
|
289
371
|
return unless line.include? '%type'
|
@@ -299,7 +381,11 @@ module Checker
|
|
299
381
|
@outputs[index][:msg] = 'Write 4 spaces before %type'
|
300
382
|
end
|
301
383
|
end
|
384
|
+
# rubocop:enable Metrics/AbcSize
|
385
|
+
# rubocop:enable Metrics/MethodLength
|
302
386
|
|
387
|
+
# rubocop:disable Metrics/MethodLength
|
388
|
+
# rubocop:disable Metrics/AbcSize
|
303
389
|
def check_path(line, index)
|
304
390
|
return unless @outputs[index][:state] == :none
|
305
391
|
return unless line.include? '%path'
|
@@ -315,7 +401,11 @@ module Checker
|
|
315
401
|
@outputs[index][:msg] = 'Write 4 spaces before %type'
|
316
402
|
end
|
317
403
|
end
|
404
|
+
# rubocop:enable Metrics/AbcSize
|
405
|
+
# rubocop:enable Metrics/MethodLength
|
318
406
|
|
407
|
+
# rubocop:disable Metrics/MethodLength
|
408
|
+
# rubocop:disable Metrics/AbcSize
|
319
409
|
def check_features(line, index)
|
320
410
|
return unless @outputs[index][:state] == :none
|
321
411
|
return unless line.include? '%features'
|
@@ -331,6 +421,8 @@ module Checker
|
|
331
421
|
@outputs[index][:msg] = 'Write 4 spaces before %features'
|
332
422
|
end
|
333
423
|
end
|
424
|
+
# rubocop:enable Metrics/AbcSize
|
425
|
+
# rubocop:enable Metrics/MethodLength
|
334
426
|
|
335
427
|
def check_unknown(line, index)
|
336
428
|
return unless @outputs[index][:state] == :none
|
@@ -355,19 +447,9 @@ module Checker
|
|
355
447
|
end
|
356
448
|
|
357
449
|
def count_spaces(line)
|
358
|
-
|
359
|
-
|
360
|
-
return 2 if line.start_with? ' %'
|
361
|
-
return 3 if line.start_with? ' %'
|
362
|
-
return 4 if line.start_with? ' %'
|
363
|
-
return 5 if line.start_with? ' %'
|
364
|
-
return 6 if line.start_with? ' %'
|
365
|
-
return 7 if line.start_with? ' %'
|
366
|
-
return 8 if line.start_with? ' %'
|
367
|
-
return 9 if line.start_with? ' %'
|
368
|
-
return 10 if line.start_with? ' %'
|
369
|
-
|
370
|
-
-1
|
450
|
+
a = line.split('%')
|
451
|
+
a[0].count(' ')
|
371
452
|
end
|
372
453
|
end
|
454
|
+
# rubocop:enable Metrics/ClassLength
|
373
455
|
end
|