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.
- checksums.yaml +4 -4
- data/Gemfile +18 -0
- data/README.md +46 -0
- data/ext/valgrind.rb +21 -18
- data/ext/web_validators.rb +132 -0
- data/lang/HTML.yml +2 -14
- data/lib/component.rb +41 -39
- data/lib/components/archiver.rb +105 -101
- data/lib/components/checker.rb +46 -52
- data/lib/components/extractors.rb +121 -120
- data/lib/components/generator.rb +40 -37
- data/lib/components/generators.rb +113 -109
- data/lib/components/organiser.rb +165 -153
- data/lib/config.rb +53 -35
- data/lib/criteria/code_analysis.rb +54 -0
- data/lib/criteria/compilation.rb +42 -0
- data/lib/criteria/execution.rb +78 -0
- data/lib/exec.rb +109 -94
- data/lib/helpers/criteria.rb +152 -154
- data/lib/helpers/git.rb +23 -21
- data/lib/helpers/project.rb +198 -19
- data/lib/helpers/system.rb +50 -39
- data/lib/loggers/logger.rb +39 -30
- data/lib/loggers/modes.rb +118 -54
- data/lib/reviser.rb +63 -41
- data/res/css/style_logs.css +166 -0
- data/res/css/web_validators/css-base.css +733 -0
- data/res/css/web_validators/css-results.css +257 -0
- data/res/css/web_validators/html-base.css +746 -0
- data/res/css/web_validators/html-results.css +489 -0
- data/res/labys/labfich11.txt +19 -0
- data/res/labys/test.txt +3 -0
- data/res/labys/yoda.txt +19 -0
- data/res/scss/style_logs.scss +134 -0
- data/type/JavaProject.yml +18 -0
- data/type/Pendu.yml +22 -0
- data/type/Web.yml +23 -0
- metadata +144 -10
- data/ext/html_validator.rb +0 -21
- data/lib/helpers/code_analysis.rb +0 -64
- data/lib/helpers/compilation.rb +0 -40
- data/lib/helpers/execution.rb +0 -83
- data/lib/project.rb +0 -155
data/lib/config.rb
CHANGED
@@ -4,45 +4,63 @@
|
|
4
4
|
#
|
5
5
|
require 'yaml'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
module Reviser
|
8
|
+
class Cfg
|
9
|
+
# Path for specialized config files for projects
|
10
|
+
ROOT = File.join(File.dirname(File.dirname(__FILE__)))
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
# Is the config is loaded ?
|
13
|
+
@@loaded = false
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def self.[](key)
|
16
|
+
@@mem[key] if @@loaded
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
19
|
+
def self.[]=(key, value)
|
20
|
+
@@mem[key] = value if @@loaded
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
# @return true if there is the key in the config
|
24
|
+
def self.has_key?(key)
|
25
|
+
@@mem.has_key? key
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# @returns The specified resource path
|
30
|
+
# TODO : put resources in dedicated folders
|
31
|
+
# for each component or extension, so that
|
32
|
+
# the user can omit <lang>/<ext_name>/ when
|
33
|
+
# calling this method
|
34
|
+
#
|
35
|
+
def self.resource path
|
36
|
+
abs = File.join(ROOT, Cfg[:res_dir], path)
|
37
|
+
File.new abs if File.exists? abs
|
38
|
+
end
|
39
|
+
|
40
|
+
# Method class alias
|
41
|
+
# might remove this at some point ( sorry Yannou I know u worked hard :( )
|
42
|
+
self.singleton_class.send(:alias_method, :=~, :has_key?)
|
43
|
+
|
44
|
+
def self.load(cfg_file)
|
45
|
+
@@loaded = true
|
46
|
+
@@mem = {}
|
47
|
+
|
48
|
+
populate YAML.load(File.read(cfg_file))
|
49
|
+
type_file = File.join(ROOT,'type',"#{@@mem[:type]}.yml")
|
50
|
+
type_cfg = YAML.load(File.read(type_file))
|
51
|
+
populate YAML.load(File.read(File.join(ROOT,'lang',"#{type_cfg['language']}.yml")))
|
52
|
+
# So that project's type Cfg overrides
|
53
|
+
# lang Cfg
|
54
|
+
populate type_cfg
|
55
|
+
end
|
39
56
|
|
40
|
-
private
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
57
|
+
private
|
58
|
+
#
|
59
|
+
# Handy method to convert string keys
|
60
|
+
# read from Cfg file to symbols
|
61
|
+
#
|
62
|
+
def self.populate(hash)
|
63
|
+
hash.each { |k, v| @@mem[k.to_sym] = v}
|
64
|
+
end
|
47
65
|
end
|
48
66
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# @Author Renan Strauss
|
3
|
+
#
|
4
|
+
# Basic stuff needed for Checker
|
5
|
+
#
|
6
|
+
|
7
|
+
module Reviser
|
8
|
+
module Criteria
|
9
|
+
module CodeAnalysis
|
10
|
+
include Helpers::Project
|
11
|
+
|
12
|
+
def all_files
|
13
|
+
files.join("\r")
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# @return all files matching the
|
18
|
+
# extenstion language list (note that Cfg[:extension] must be an array)
|
19
|
+
#
|
20
|
+
def src_files
|
21
|
+
sources.join("\r")
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @return the total amount of lines of code
|
26
|
+
#
|
27
|
+
def lines_count
|
28
|
+
count = sources.inject(0) { |sum, f|
|
29
|
+
sum + File.open(f).readlines.select { |l| !l.chomp.empty? }.size
|
30
|
+
}
|
31
|
+
|
32
|
+
count - comments_count # FIXME
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @return the number of lines of comments
|
37
|
+
#
|
38
|
+
def comments_count
|
39
|
+
tab_comments = sources.inject([]) { |t, f| t << IO.read(f).scrub.scan(Cfg[:regex_comments]) }
|
40
|
+
lines = tab_comments.inject('') { |s, comm| s << find_comments(comm) }.split "\n"
|
41
|
+
|
42
|
+
lines.size
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Translates a sub-match returned by scan
|
47
|
+
# into raw comments string
|
48
|
+
#
|
49
|
+
def find_comments(comm)
|
50
|
+
comm.inject('') { |t, l| t << l.detect { |a| (a != nil) && !a.strip.empty? } + "\n" }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# @Author Yann Prono
|
3
|
+
# @Author Renan Strauss
|
4
|
+
#
|
5
|
+
# Needed stuff for compiled languages
|
6
|
+
# such as C, Java, and so on.
|
7
|
+
#
|
8
|
+
|
9
|
+
module Reviser
|
10
|
+
module Criteria
|
11
|
+
module Compilation
|
12
|
+
include Helpers::Project
|
13
|
+
include Helpers::System
|
14
|
+
|
15
|
+
#
|
16
|
+
# Only here for compiled language,
|
17
|
+
#
|
18
|
+
def compile
|
19
|
+
#
|
20
|
+
# For now, we compile only if there's
|
21
|
+
# no missing file
|
22
|
+
# We should maybe make it more
|
23
|
+
# understandable in the Cfg
|
24
|
+
#
|
25
|
+
if missing_files.empty?
|
26
|
+
cmd = "#{Cfg[(Cfg.has_key? :preferred_build_command) && :preferred_build_command || :default_build_command]}"
|
27
|
+
out = exec_with_timeout cmd
|
28
|
+
|
29
|
+
if out.has_key? :process_status
|
30
|
+
return "Exit status: 0\r#{out[:stdout]}" unless out[:process_status].exitstatus != 0
|
31
|
+
end
|
32
|
+
|
33
|
+
if Cfg.has_key? :preferred_build_command
|
34
|
+
out = exec_with_timeout Cfg[:default_build_command]
|
35
|
+
end
|
36
|
+
|
37
|
+
(out[:process_status].exitstatus == 0) ? "Exit status: 0\r#{out[:stdout]}" : "#{out[:stdout]}\r#{out[:stderr]}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#
|
2
|
+
# @Author Renan Strauss
|
3
|
+
#
|
4
|
+
# Needed stuff for Checker
|
5
|
+
# when it comes to executing
|
6
|
+
# both compiled and interpreted
|
7
|
+
# languages
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'timeout'
|
11
|
+
|
12
|
+
module Reviser
|
13
|
+
module Criteria
|
14
|
+
module Execution
|
15
|
+
#
|
16
|
+
# Determines how to execute the program
|
17
|
+
# thanks to Cfg, then returns its exec
|
18
|
+
# status(es)
|
19
|
+
#
|
20
|
+
def execute
|
21
|
+
outputs = []
|
22
|
+
if Cfg.has_key? :execution_value
|
23
|
+
if Cfg[:execution_value].respond_to? 'each'
|
24
|
+
Cfg[:execution_value].each do |v|
|
25
|
+
outputs << exec(v)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
if Cfg.has_key? :execution_count
|
29
|
+
outputs[Cfg[:execution_value]] = []
|
30
|
+
Cfg[:execution_count].times do
|
31
|
+
outputs << exec(Cfg[:execution_value])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
outputs << exec(Cfg[:execution_value])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
if Cfg.has_key? :execution_count
|
39
|
+
Cfg[:execution_count].times do
|
40
|
+
outputs << exec
|
41
|
+
end
|
42
|
+
else
|
43
|
+
return exec
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
outputs.join("\r")
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
#
|
53
|
+
# The method that actually
|
54
|
+
# executes the program.
|
55
|
+
# If no program name is specified
|
56
|
+
# in the Cfg, it executes the
|
57
|
+
# first executable found.
|
58
|
+
# It helps with C (a.out) when no
|
59
|
+
# Makefile is avalaible, but it
|
60
|
+
# might not be a good idea regarding
|
61
|
+
# security
|
62
|
+
#
|
63
|
+
def exec(param = nil)
|
64
|
+
program = (Cfg.has_key? :program_name) && Cfg[:program_name] || find_executable
|
65
|
+
|
66
|
+
return 'Program not found' unless program != nil
|
67
|
+
|
68
|
+
program = "#{Cfg[:program_prefix]}#{program}"
|
69
|
+
argument = (param == nil) && '' || param
|
70
|
+
|
71
|
+
cmd = "#{(Cfg.has_key? :execute_command) && Cfg[:execute_command] || ''} #{program} #{argument}"
|
72
|
+
out = exec_with_timeout cmd
|
73
|
+
|
74
|
+
"$ #{cmd}\r#{out[:stdout]}\r#{out[:stderr]}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/exec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'colorize'
|
3
4
|
|
4
5
|
require_relative 'reviser'
|
5
6
|
require_relative 'helpers/criteria'
|
@@ -7,130 +8,144 @@ require_relative 'helpers/criteria'
|
|
7
8
|
#
|
8
9
|
# Module used for managing all actions in command line
|
9
10
|
# This module enables to user the programm in command line.
|
10
|
-
# It use the powerful toolkit Thor for building
|
11
|
+
# It use the powerful toolkit Thor for building command line interfaces
|
11
12
|
#
|
12
13
|
# @author Yann Prono
|
13
14
|
#
|
14
|
-
|
15
|
+
module Reviser
|
16
|
+
class Exec < Thor
|
15
17
|
|
16
|
-
|
18
|
+
VERSION = '0.0.1.1'
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
map '--version' => :version
|
21
|
+
map '-v' => :version
|
20
22
|
|
21
|
-
|
22
|
-
super
|
23
|
-
# If config.yml already exists in the working
|
24
|
-
# directory, then we setup reviser here
|
25
|
-
config_file = File.expand_path('config.yml')
|
26
|
-
setup config_file if File.exist? config_file
|
27
|
-
end
|
23
|
+
@@setup = false
|
28
24
|
|
25
|
+
# path of config template file.
|
26
|
+
$template_path = File.join(File.dirname(File.dirname(__FILE__)),'config.yml')
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
def initialize(*args)
|
29
|
+
super
|
30
|
+
# If config.yml already exists in the working
|
31
|
+
# directory, then we setup reviser here
|
32
|
+
config_file = File.expand_path('config.yml')
|
33
|
+
setup config_file if File.exist? config_file
|
34
|
+
end
|
35
35
|
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
37
|
+
# Create a environnment for checking projects
|
38
|
+
# This method only copies the config file into the current directory.
|
39
|
+
desc 'init DIRECTORY', 'Initialize Reviser workspace. DIRECTORY ||= \'.\''
|
40
|
+
def init(dir = '.')
|
41
|
+
pwd = FileUtils.pwd
|
42
|
+
msg = File.exist?(File.join(pwd,dir,File.basename($template_path))) && 'Recreate' || 'Create'
|
43
|
+
FileUtils.mkdir_p dir unless Dir.exist?(File.join(pwd, dir))
|
44
|
+
FileUtils.cp($template_path, dir)
|
45
|
+
message(msg, File.basename($template_path))
|
46
46
|
|
47
|
-
|
48
|
-
end
|
47
|
+
setup File.expand_path(File.join(dir, File.basename($template_path))) unless @@setup
|
49
48
|
|
49
|
+
if not File.exist?(File.join(FileUtils.pwd, Cfg[:res_dir]))
|
50
|
+
path_res = File.join(File.dirname(File.dirname(__FILE__)),"#{Cfg[:res_dir]}")
|
51
|
+
FileUtils.cp_r(path_res, FileUtils.pwd) unless
|
50
52
|
|
51
|
-
|
52
|
-
desc 'clean', 'Delete datas creating by the App (logs, projects, results files ...).'
|
53
|
-
def clean
|
54
|
-
if File.exist? 'config.yml'
|
55
|
-
FileUtils.rm_rf(Cfg[:dest], :verbose => true)
|
56
|
-
if Cfg.has_key?(:options) && Cfg[:options].has_key?(:log_dir)
|
57
|
-
FileUtils.rm_rf(Cfg[:options][:log_dir], :verbose => true)
|
58
|
-
else
|
59
|
-
FileUtils.rm_f(Dir['*.txt'], :verbose => true)
|
60
|
-
end
|
61
|
-
|
62
|
-
if Cfg[:out_format].respond_to? 'each'
|
63
|
-
Cfg[:out_format].each { |format| FileUtils.rm_f(Dir["*.#{format}"], :verbose => true) }
|
64
|
-
else
|
65
|
-
FileUtils.rm_f(Dir["*.#{Cfg[:out_format]}"], :verbose => true)
|
53
|
+
message('Create', File.join(dir, Cfg[:res_dir]))
|
66
54
|
end
|
67
55
|
|
68
|
-
|
69
|
-
|
70
|
-
message("Error", "'config.yml' doesn't exist! Check if you are in the good directory.")
|
56
|
+
puts "Customize config.yml to your needs @see docs".yellow
|
57
|
+
puts 'Then simply execute \'reviser work\' to launch analysis.'.yellow
|
71
58
|
end
|
72
59
|
|
73
|
-
end
|
74
60
|
|
61
|
+
# Clean the directory of logs, projects and results.
|
62
|
+
desc 'clean', 'Remove generated files (logs, projects, results files ...)'
|
63
|
+
def clean
|
64
|
+
if File.exist? 'config.yml'
|
65
|
+
FileUtils.rm_rf(Cfg[:dest], :verbose => true)
|
66
|
+
if Cfg.has_key?(:options) && Cfg[:options].has_key?(:log_dir)
|
67
|
+
FileUtils.rm_rf(Cfg[:options][:log_dir], :verbose => true)
|
68
|
+
else
|
69
|
+
FileUtils.rm_f(Dir['*.txt'], :verbose => true)
|
70
|
+
end
|
71
|
+
|
72
|
+
if Cfg[:out_format].respond_to? 'each'
|
73
|
+
Cfg[:out_format].each { |format| FileUtils.rm_f(Dir["*.#{format}"], :verbose => true) }
|
74
|
+
else
|
75
|
+
FileUtils.rm_f(Dir["*.#{Cfg[:out_format]}"], :verbose => true)
|
76
|
+
end
|
77
|
+
|
78
|
+
# We shall not delete it because the user is likely to
|
79
|
+
# add his own files and doesn't want to lose them every
|
80
|
+
# single time
|
81
|
+
#FileUtils.rm_rf(Cfg[:res_dir], :verbose => true)
|
82
|
+
else
|
83
|
+
message("Error".red, "'config.yml' doesn't exist! Check if you are in the good directory.")
|
84
|
+
end
|
75
85
|
|
76
|
-
|
77
|
-
# @param current_dir [String] the directory where the programm has to be launched.
|
78
|
-
desc 'work', 'Run components to analysis computing projects.'
|
79
|
-
def work
|
80
|
-
Reviser::load :component => 'archiver'
|
81
|
-
Reviser::load :component => 'organiser', :inputFrom => 'archiver'
|
82
|
-
Reviser::load :component => 'checker', :inputFrom => 'organiser'
|
83
|
-
Reviser::load :component => 'generator', :inputFrom => 'checker'
|
86
|
+
end
|
84
87
|
|
85
|
-
Reviser::run
|
86
|
-
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
Reviser::run
|
93
|
-
end
|
89
|
+
# Let do it for analysis.
|
90
|
+
# @param current_dir [String] the directory where the programm has to be launched.
|
91
|
+
desc 'work', 'Run components to analysis computing projects'
|
92
|
+
def work
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
94
|
+
if File.exists? 'config.yml'
|
95
|
+
Reviser::load :component => 'archiver'
|
96
|
+
Reviser::load :component => 'organiser', :inputFrom => 'archiver'
|
97
|
+
Reviser::load :component => 'checker', :inputFrom => 'organiser'
|
98
|
+
Reviser::load :component => 'generator', :inputFrom => 'checker'
|
101
99
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
Reviser::run
|
108
|
-
end
|
100
|
+
Reviser::run
|
101
|
+
else
|
102
|
+
message('Error'.red, "'config.yml' file doesn't exist! @see 'reviser init'")
|
103
|
+
end
|
104
|
+
end
|
109
105
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
106
|
+
desc 'extract', 'Extract and organise all computing projects'
|
107
|
+
def extract
|
108
|
+
Reviser::load :component => 'archiver'
|
109
|
+
Reviser::load :component => 'organiser', :inputFrom => 'archiver'
|
110
|
+
|
111
|
+
Reviser::run
|
112
|
+
end
|
116
113
|
|
114
|
+
#
|
115
|
+
# For the moment, associate a label to a criterion (method).
|
116
|
+
#
|
117
|
+
# Cette methode me fait penser qu'on devrait vraiment configurer
|
118
|
+
# le dossier de base ici, et le passer dans la config parce que,
|
119
|
+
# par defaut, les modifs sur le fichier labels.yml seront faites
|
120
|
+
# sur le fichier labels.yml dans le dossier ou est le programme,
|
121
|
+
# et non dans le dossier ou travaille l'utilisateur
|
122
|
+
#
|
123
|
+
desc 'add METH \'LABEL\'', 'Associates LABEL with METH analysis def'
|
124
|
+
def add meth, label
|
125
|
+
res = Helpers::Labels.add meth, label
|
126
|
+
message "#{res} label".green,meth + " => " + label
|
127
|
+
end
|
117
128
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
129
|
+
desc 'version', 'Print out version information'
|
130
|
+
def version
|
131
|
+
puts "Reviser #{VERSION}"
|
132
|
+
puts 'Released under the MIT License.'
|
122
133
|
end
|
123
134
|
|
124
|
-
def setup(config_file)
|
125
|
-
Reviser::setup config_file
|
126
135
|
|
127
|
-
|
128
|
-
|
136
|
+
no_tasks do
|
137
|
+
# A Formatter message for command line
|
138
|
+
def message(keyword, desc)
|
139
|
+
puts "\t#{keyword}\t\t#{desc}"
|
140
|
+
end
|
141
|
+
|
142
|
+
def setup(config_file)
|
143
|
+
Reviser::setup config_file
|
129
144
|
|
130
|
-
|
145
|
+
@@setup = true
|
146
|
+
end
|
131
147
|
end
|
132
|
-
end
|
133
148
|
|
149
|
+
end
|
134
150
|
end
|
135
|
-
|
136
|
-
Exec.start(ARGV)
|
151
|
+
Reviser::Exec.start(ARGV)
|