reviser 0.0.1.1.pre.beta → 0.0.2.rc1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +18 -0
  3. data/README.md +46 -0
  4. data/ext/valgrind.rb +21 -18
  5. data/ext/web_validators.rb +132 -0
  6. data/lang/HTML.yml +2 -14
  7. data/lib/component.rb +41 -39
  8. data/lib/components/archiver.rb +105 -101
  9. data/lib/components/checker.rb +46 -52
  10. data/lib/components/extractors.rb +121 -120
  11. data/lib/components/generator.rb +40 -37
  12. data/lib/components/generators.rb +113 -109
  13. data/lib/components/organiser.rb +165 -153
  14. data/lib/config.rb +53 -35
  15. data/lib/criteria/code_analysis.rb +54 -0
  16. data/lib/criteria/compilation.rb +42 -0
  17. data/lib/criteria/execution.rb +78 -0
  18. data/lib/exec.rb +109 -94
  19. data/lib/helpers/criteria.rb +152 -154
  20. data/lib/helpers/git.rb +23 -21
  21. data/lib/helpers/project.rb +198 -19
  22. data/lib/helpers/system.rb +50 -39
  23. data/lib/loggers/logger.rb +39 -30
  24. data/lib/loggers/modes.rb +118 -54
  25. data/lib/reviser.rb +63 -41
  26. data/res/css/style_logs.css +166 -0
  27. data/res/css/web_validators/css-base.css +733 -0
  28. data/res/css/web_validators/css-results.css +257 -0
  29. data/res/css/web_validators/html-base.css +746 -0
  30. data/res/css/web_validators/html-results.css +489 -0
  31. data/res/labys/labfich11.txt +19 -0
  32. data/res/labys/test.txt +3 -0
  33. data/res/labys/yoda.txt +19 -0
  34. data/res/scss/style_logs.scss +134 -0
  35. data/type/JavaProject.yml +18 -0
  36. data/type/Pendu.yml +22 -0
  37. data/type/Web.yml +23 -0
  38. metadata +144 -10
  39. data/ext/html_validator.rb +0 -21
  40. data/lib/helpers/code_analysis.rb +0 -64
  41. data/lib/helpers/compilation.rb +0 -40
  42. data/lib/helpers/execution.rb +0 -83
  43. data/lib/project.rb +0 -155
@@ -1,5 +1,3 @@
1
- require_relative '../config'
2
-
3
1
  # Manage criteria and labels.
4
2
 
5
3
  # @example Call a criterion (in the config File):
@@ -11,176 +9,176 @@ require_relative '../config'
11
9
  # @author Yann Prono
12
10
  # @author Renan Strauss
13
11
  #
14
- module Helpers
15
- # This module enables to
16
- # imports automaticlly all modules for the analysis
17
- #
18
- # Convention over configuration !
19
- # A analysis module contains the word 'tool' in its filename.
20
- # You also have the possibility to put code in the ext folder.
21
- #
22
- # @example Call a criterion during analysis (in the config File):
23
- # criteria:
24
- # - :count_lines
25
- # - :list_files
26
- # - :<method>: <custom label>
27
- #
28
- # In the last item of the list, the custom label will overwrite the label
29
- # in labels.yml if it exist.
30
- #
31
- module Criteria
32
-
33
- # Where I am ?
34
- PWD = File.dirname __FILE__
35
- # Path of extensions
36
- EXT = File.join File.dirname(File.dirname(PWD)), 'ext'
37
-
38
- attr_reader :criteria
39
- attr_reader :output
40
-
41
- # All criterias available.
42
- # :criterion => Name of the module
43
- @criteria
44
-
45
- # :criterion => label of criterion
46
- @output
47
-
48
- # Enable to call a specified method.
49
- # @param meth [String] Method to call.
50
- # @return results of the method.
51
- def call meth
52
- if @criteria.key? meth
53
- @logger.h1(Logger::INFO, "Include methods of #{@criteria[meth]}") unless respond_to? meth
54
- self.class.send(:include, @criteria[meth]) unless respond_to? meth
55
-
56
- send meth
57
- else
58
- nil
12
+ module Reviser
13
+ module Helpers
14
+ # This module enables to
15
+ # imports automaticlly all modules for the analysis
16
+ #
17
+ # Convention over configuration !
18
+ # A analysis module contains the word 'tool' in its filename.
19
+ # You also have the possibility to put code in the ext folder.
20
+ #
21
+ # @example Call a criterion during analysis (in the config File):
22
+ # criteria:
23
+ # - :count_lines
24
+ # - :list_files
25
+ # - :<method>: <custom label>
26
+ #
27
+ # In the last item of the list, the custom label will overwrite the label
28
+ # in labels.yml if it exist.
29
+ #
30
+ module Criteria
31
+
32
+ # Where I am ?
33
+ PWD = File.dirname __FILE__
34
+ # Path of extensions
35
+ EXT = File.join File.dirname(File.dirname(PWD)), 'ext'
36
+
37
+ attr_reader :criteria
38
+ attr_reader :output
39
+
40
+ # All criterias available.
41
+ # :criterion => Name of the module
42
+ @criteria
43
+
44
+ # :criterion => label of criterion
45
+ @output
46
+
47
+ # Enable to call a specified method.
48
+ # @param meth [String] Method to call.
49
+ # @return results of the method.
50
+ def call meth
51
+ if @criteria.key? meth
52
+ @logger.h1(Logger::INFO, "Include methods of #{@criteria[meth]}") unless respond_to? meth
53
+ self.class.send(:include, @criteria[meth]) unless respond_to? meth
54
+
55
+ send meth
56
+ else
57
+ nil
58
+ end
59
59
  end
60
- end
61
60
 
62
61
 
63
- protected
62
+ protected
64
63
 
65
- # Get all criteria which can be used.
66
- # @return [Array] all criteria
67
- def all
68
- @criteria.keys.map &:to_sym
69
- end
64
+ # Get all criteria which can be used.
65
+ # @return [Array] all criteria
66
+ def all
67
+ @criteria.keys.map &:to_sym
68
+ end
70
69
 
71
- # from Cfg file to symbols
72
- # @param criterion The criteria
73
- # @param module_name The name of the module.
74
- def populate criterion, module_name
75
- raise "Criterion '#{criterion}' is already defined in #{@criteria[criterion.to_sym]} (#{criterion}/#{module_name}).\nPlease change the name of the method in one of modules." if @criteria.has_key? criterion.to_sym
76
- @criteria[criterion.to_sym] = module_name
77
- end
70
+ # from Cfg file to symbols
71
+ # @param criterion The criteria
72
+ # @param module_name The name of the module.
73
+ def populate criterion, module_name
74
+ raise "Criterion '#{criterion}' is already defined in #{@criteria[criterion.to_sym]} (#{criterion}/#{module_name}).\nPlease change the name of the method in one of modules." if @criteria.has_key? criterion.to_sym
75
+ @criteria[criterion.to_sym] = module_name
76
+ end
78
77
 
79
- # Load all of modules available for the analysis
80
- # @param directory Directory where search of modules is done.
81
- # @param regex regex to find name of modules.
82
- def load directory, regex = '*'
83
- @logger.h2 Logger::INFO, "Modules of #{directory}"
84
- modules = Dir[File.join(directory, regex)]
85
-
86
- namespace = directory == EXT && 'Extensions' || 'Helpers'
87
- modules.each do |m|
88
- next if m =~ /(criteria)/
89
-
90
- require_relative m
91
- ext = File.extname m
92
- module_name = Object.const_get "#{namespace}::#{camelize(File.basename(m,ext))}", false
93
- @logger.h3 Logger::INFO, "Load #{module_name}"
94
- methods = module_name.instance_methods false
95
- methods.each { |method| populate(method, module_name) }
96
- end
97
- end
98
-
99
- # Gets the name of module
100
- # @param file_module Name of the file module.
101
- def camelize file_module
102
- file_module.split('_').each {|s| s.capitalize! }.join('')
103
- end
78
+ # Load all of modules available for the analysis
79
+ # @param directory Directory where search of modules is done.
80
+ # @param regex regex to find name of modules.
81
+ def load directory, regex = '*'
82
+ @logger.h2 Logger::INFO, "Modules of #{directory}"
83
+ modules = Dir[File.join(directory, regex)]
84
+
85
+ namespace = directory == EXT && 'Reviser::Extensions' || 'Reviser::Criteria'
86
+ modules.each do |m|
87
+ require_relative m
88
+ ext = File.extname m
89
+ module_name = Object.const_get "#{namespace}::#{camelize(File.basename(m,ext))}", false
90
+ @logger.h3 Logger::INFO, "Load #{module_name}"
91
+ methods = module_name.instance_methods false
92
+ methods.each { |method| populate(method, module_name) }
93
+ end
94
+ end
95
+
96
+ # Gets the name of module
97
+ # @param file_module Name of the file module.
98
+ def camelize file_module
99
+ file_module.split('_').each {|s| s.capitalize! }.join('')
100
+ end
104
101
 
105
- # Load labels given by the user.
106
- # If the label doesn't exist, it will created with the name of the method.
107
- # @param key Key of criteria in config file
108
- def load_labels key
109
- labels = Labels.load
110
-
111
- if Cfg.has_key?(key) && Cfg[key].respond_to?('each')
112
- Cfg[key].each do |meth|
113
- if meth.respond_to?('each') && meth.respond_to?('[]')
114
- label = meth[meth.keys[0]]
115
- @logger.h2(Logger::ERROR, "Undefined label for #{meth.keys[0]}, check your config file") if label == nil
116
- label = create_label(meth.keys[0]) if label == nil
117
- @output[meth.keys[0].to_sym] = label
118
- else
119
- label = (labels.respond_to?('[]') && labels.key?(meth.to_sym)) ? labels[meth.to_sym] : create_label(meth)
120
- @output[meth.to_sym] = label
102
+ # Load labels given by the user.
103
+ # If the label doesn't exist, it will created with the name of the method.
104
+ # @param key Key of criteria in config file
105
+ def load_labels key
106
+ labels = Labels.load
107
+
108
+ if Cfg.has_key?(key) && Cfg[key].respond_to?('each')
109
+ Cfg[key].each do |meth|
110
+ if meth.respond_to?('each') && meth.respond_to?('[]')
111
+ label = meth[meth.keys[0]]
112
+ @logger.h2(Logger::ERROR, "Undefined label for #{meth.keys[0]}, check your config file") if label == nil
113
+ label = create_label(meth.keys[0]) if label == nil
114
+ @output[meth.keys[0].to_sym] = label
115
+ else
116
+ label = (labels.respond_to?('[]') && labels.key?(meth.to_sym)) ? labels[meth.to_sym] : create_label(meth)
117
+ @output[meth.to_sym] = label
118
+ end
121
119
  end
122
120
  end
123
121
  end
124
- end
125
122
 
126
- # Create label for a method.
127
- # @param meth [String] method linked to the label
128
- # @return [String] Renamed Label inspired of the name of the method
129
- def create_label meth
130
- @logger.h2 Logger::ERROR, "Create label for #{meth}. You should custom your label (see 'reviser add')"
131
- meth.to_s.split('_').each {|s| s.capitalize! }.join(' ')
123
+ # Create label for a method.
124
+ # @param meth [String] method linked to the label
125
+ # @return [String] Renamed Label inspired of the name of the method
126
+ def create_label meth
127
+ @logger.h2 Logger::ERROR, "Create label for #{meth}. You should custom your label (see 'reviser add')"
128
+ meth.to_s.split('_').each {|s| s.capitalize! }.join(' ')
129
+ end
132
130
  end
133
- end
134
-
135
-
136
- # Manage all actions for adding, updating or getting labels of Reviser.
137
- # A label is a a group of words, describing the associated criterion (method).
138
- #
139
- # @example
140
- # criterion => label
141
- # all_files => all files of project
142
- #
143
- # known Labels are in the labels.yml file.
144
- #
145
- # @author Yann Prono
146
- class Labels
147
-
148
- # Current directory of this file
149
- PWD = File.dirname __FILE__
150
131
 
151
- # Path of label.yml file
152
- LABELS = File.join(File.dirname(File.dirname(PWD)), 'labels.yml')
153
132
 
133
+ # Manage all actions for adding, updating or getting labels of Reviser.
134
+ # A label is a a group of words, describing the associated criterion (method).
154
135
  #
155
- # Enable to associate a label to a criterion (method).
156
- # The label will be saved in the 'labels.yml' file
157
- # @param meth Method to link.
158
- # @param label Label to link with the method.
159
- def self.add meth, label
160
- res = "Create"
161
- labels = YAML.load File.open(LABELS)
162
- if labels.respond_to? '[]'
163
- res = "Update" if labels.key? meth
164
- labels[meth] = label
165
- File.open(LABELS, 'w') { |f| f.write labels.to_yaml }
136
+ # @example
137
+ # criterion => label
138
+ # all_files => all files of project
139
+ #
140
+ # known Labels are in the labels.yml file.
141
+ #
142
+ # @author Yann Prono
143
+ class Labels
144
+
145
+ # Current directory of this file
146
+ PWD = File.dirname __FILE__
147
+
148
+ # Path of label.yml file
149
+ LABELS = File.join(File.dirname(File.dirname(PWD)), 'labels.yml')
150
+
151
+ #
152
+ # Enable to associate a label to a criterion (method).
153
+ # The label will be saved in the 'labels.yml' file
154
+ # @param meth Method to link.
155
+ # @param label Label to link with the method.
156
+ def self.add meth, label
157
+ res = "Create"
158
+ labels = YAML.load File.open(LABELS)
159
+ if labels.respond_to? '[]'
160
+ res = "Update" if labels.key? meth
161
+ labels[meth] = label
162
+ File.open(LABELS, 'w') { |f| f.write labels.to_yaml }
163
+ end
164
+ res
166
165
  end
167
- res
168
- end
169
166
 
170
- # @return Hash all known labels by reviser.
171
- # :criterion => label
172
- def self.load
173
- Labels.populate(YAML.load(File.open(LABELS)))
174
- end
167
+ # @return Hash all known labels by reviser.
168
+ # :criterion => label
169
+ def self.load
170
+ Labels.populate(YAML.load(File.open(LABELS)))
171
+ end
175
172
 
176
- def self.populate hash
177
- labels = {}
178
- if hash.respond_to?('each')
179
- hash.each do |meth, label|
180
- labels[meth.to_sym] = label
173
+ def self.populate hash
174
+ labels = {}
175
+ if hash.respond_to?('each')
176
+ hash.each do |meth, label|
177
+ labels[meth.to_sym] = label
178
+ end
181
179
  end
180
+ labels
182
181
  end
183
- labels
184
- end
185
- end
182
+ end
183
+ end
186
184
  end
data/lib/helpers/git.rb CHANGED
@@ -6,32 +6,34 @@
6
6
  #
7
7
  require 'git'
8
8
 
9
- module Helpers
10
- module Git
11
- # method which initialize a git repository
12
- def git_init
13
- @git = ::Git.init
14
- end
9
+ module Reviser
10
+ module Helpers
11
+ module Git
12
+ # method which initialize a git repository
13
+ def git_init
14
+ @git = ::Git.init
15
+ end
15
16
 
16
- # method which allows the user to add something on the repository
17
- def git_add
18
- @git.add(:all=>true)
19
- end
17
+ # method which allows the user to add something on the repository
18
+ def git_add
19
+ @git.add(:all=>true)
20
+ end
20
21
 
21
- # method for displaying a message when the repository is configured
22
- def git_commit
23
- @git.commit_all('initialization of git repertory')
24
- end
22
+ # method for displaying a message when the repository is configured
23
+ def git_commit
24
+ @git.commit_all('initialization of git repertory')
25
+ end
25
26
 
26
- def git_push
27
- @git.push
28
- end
27
+ def git_push
28
+ @git.push
29
+ end
29
30
 
30
- # method which allows the user to see the differences between two last commits
31
- # I have to know the current commit and the last but how ?
32
- # and do a diff between these 2 commits.
33
- def git_diff
31
+ # method which allows the user to see the differences between two last commits
32
+ # I have to know the current commit and the last but how ?
33
+ # and do a diff between these 2 commits.
34
+ def git_diff
34
35
 
36
+ end
35
37
  end
36
38
  end
37
39
  end
@@ -5,35 +5,214 @@
5
5
  # @author Renan Strauss
6
6
  # @author Yann Prono
7
7
  #
8
- module Helpers
9
- module Project
8
+ module Reviser
9
+ module Helpers
10
+ module Project
11
+ #
12
+ # For interpreted languages
13
+ # We only check for missing files
14
+ #
15
+ def prepare
16
+ missing_files.empty? && 'None' || res
17
+ end
18
+
19
+ # Check if the project has all files needed
20
+ def missing_files
21
+ return [] unless Cfg =~ :required_files
22
+
23
+ dir = Dir['*']
24
+
25
+ #
26
+ # Check if there is any regexp
27
+ # If it's the case, if any file
28
+ # matches, we delete the entry
29
+ # for diff to work properly
30
+ #
31
+ Cfg[:required_files].each_with_index do |e, i|
32
+ if dir.any? { |f| (e.respond_to?(:match)) && (e =~ f) }
33
+ Cfg[:required_files].delete_at i
34
+ end
35
+ end
36
+
37
+ Cfg[:required_files] - dir
38
+ end
39
+
10
40
  #
11
- # For interpreted languages
12
- # We only check for missing files
41
+ # @return all the files in the project's folder
13
42
  #
14
- def prepare
15
- missing_files.empty? && 'None' || res
43
+ def files
44
+ Dir.glob("**/*").select { |f| (File.file?(f)) }
16
45
  end
17
46
 
18
- # Check if the project has all files needed
19
- def missing_files
20
- return [] unless Cfg =~ :required_files
47
+ def sources
48
+ files.select { |f| Cfg[:extension].include? File.extname(f) }
49
+ end
21
50
 
22
- dir = Dir['*']
23
51
 
52
+ # This modules is used to scan the name of project
53
+ # in order to get all students who worked.
54
+ # This analysis uses regex of convention given by teachers (config file).
24
55
  #
25
- # Check if there is any regexp
26
- # If it's the case, if any file
27
- # matches, we delete the entry
28
- # for diff to work properly
56
+ # @author Yann Prono
29
57
  #
30
- Cfg[:required_files].each_with_index do |e, i|
31
- if dir.any? { |f| (e.respond_to?(:match)) && (e =~ f) }
32
- Cfg[:required_files].delete_at i
58
+
59
+ module Naming
60
+
61
+ # Dictionnary for regex in config file
62
+ SYMBOLS = {
63
+ :group => 'GROUP',
64
+ :firstname => 'FIRSTN',
65
+ :name => 'NAME',
66
+ :user => 'USER',
67
+ :lambda => 'LAMBDA'
68
+ }
69
+
70
+ # Regex to associate, depending the used word in Cfg
71
+ REGEX = {
72
+ :group => '([A-Za-z0-9]{3,4})',
73
+ :firstname => '([A-Za-z\-]+)',
74
+ :name => '([A-Za-z]+)',
75
+ :user => '([^_]*)',
76
+ :lambda => '[a-zA-Z0-9 _]*'
77
+ }
78
+
79
+
80
+ # Get formatter written in the config file
81
+ # and count occurences of each word in the dictionnary SYMBOLS.
82
+ # @return [Hash] sym => count.
83
+ #
84
+ def analyze_formatter
85
+ regex = Cfg[:projects_names]
86
+ # Foreach known symbols
87
+ SYMBOLS.each do |k, _|
88
+ # Get numbers of occurences of the word k in regex
89
+ matches = regex.scan(SYMBOLS[k]).size
90
+ # the word K => number of occurences
91
+ @count_patterns[k] = matches if matches > 0
92
+ end
33
93
  end
34
- end
35
94
 
36
- Cfg[:required_files] - dir
95
+
96
+ # Analyze et get all informations
97
+ # that could be useful in the name of the
98
+ # directory project.
99
+ # @param entry [String] name of directory to analysis.
100
+ #
101
+ def format entry
102
+ ext = File.extname entry
103
+ entry = File.basename entry, ext
104
+
105
+ analyze_formatter if @count_patterns.empty?
106
+
107
+ group = check_entry_name entry
108
+ generate_label group
109
+ end
110
+
111
+
112
+ # Generate new name of project.
113
+ # @param infos [Hash] All informations used for generate a name for the directory.
114
+ # @return [String] the formatted name for directory project
115
+ #
116
+ def generate_label infos
117
+ unless infos.empty?
118
+ label = ''
119
+ infos.reject { |k| k == :group }.each { |_, v|
120
+ if v.respond_to?('each')
121
+ v.each { |data|
122
+ label += data +' '
123
+ }
124
+ else
125
+ label += v + ' '
126
+ end
127
+ }
128
+ # Inject group of project before name : group/name
129
+ label = infos.key?(:group) && File.join(infos[:group], label) || label
130
+ label
131
+ end
132
+ end
133
+
134
+ # I'm not pround of this method ...
135
+ # associate to a symbol, his position in the regex
136
+ # @example NAME_FIRSTN
137
+ # will give : {
138
+ # 1 => :name,
139
+ # 2 => :firstname
140
+ #}
141
+ def get_position regex
142
+ res = {}
143
+ SYMBOLS.each do |k,v|
144
+ regex.scan(v) do |_|
145
+ res[$~.offset(0)[0]] = k
146
+ end
147
+ end
148
+
149
+ res = (res.sort_by { |k, _| k }).to_h
150
+ tmp = {}
151
+
152
+ index = 1
153
+ res.each do |_,v|
154
+ tmp[index] = v
155
+ index += 1
156
+ end
157
+ tmp
158
+ end
159
+
160
+
161
+ # Apply regex of user on the entry name
162
+ # and try to get all interested matched values.
163
+ def check_entry_name entry
164
+ regex = Cfg[:projects_names]
165
+ # who work on the current project (entry) ?
166
+ position = get_position regex
167
+
168
+ @count_patterns.each do |k, _|
169
+ regex = regex.gsub SYMBOLS[k], REGEX[k]
170
+ end
171
+
172
+ # Apply created regex
173
+ entry.match Regexp.new(regex)
174
+ pos = 1
175
+ infos = {}
176
+
177
+ # Get matched values
178
+ begin
179
+ tmp = eval "$#{pos}"
180
+ if tmp != nil && tmp != ''
181
+ tmp = tmp.delete '_'
182
+ infos.has_key?(position[pos]) && infos[position[pos]] << tmp || infos[position[pos]] = [tmp]
183
+ end
184
+ pos += 1
185
+ end while pos <= position.size
186
+
187
+ if infos.empty?
188
+ infos[:unknown] = entry
189
+ end
190
+ sort_infos infos
191
+ infos
192
+ end
193
+
194
+
195
+ # Put all datas found in respective variables (students, groups, teams ...).
196
+ # @param infos [Hash] Informations found by regex.
197
+ def sort_infos infos
198
+ if infos.has_key?(:name)
199
+ infos[:name].respond_to?('each') && infos[:name].each { |n| @students << n } || @students << infos[:name]
200
+ @binoms << infos[:name]
201
+ end
202
+ if infos.has_key?(:group)
203
+ infos[:group] = infos[:group][0].upcase
204
+ sym_group = infos[:group].to_sym
205
+ @projects_per_group[sym_group] = @projects_per_group.key?(sym_group) && @projects_per_group[sym_group] + 1 || 1
206
+ end
207
+
208
+ @unknown << infos[:unknown] if infos.key? :unknown
209
+ end
210
+
211
+
212
+ def ask entry
213
+ end
214
+
215
+ end
37
216
  end
38
217
  end
39
218
  end