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
data/lib/config.rb CHANGED
@@ -4,45 +4,63 @@
4
4
  #
5
5
  require 'yaml'
6
6
 
7
- class Cfg
8
- # Path for specialized config files for projects
9
- ROOT = File.join(File.dirname(File.dirname(__FILE__)))
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
- # Is the config is loaded ?
12
- @@loaded = false
12
+ # Is the config is loaded ?
13
+ @@loaded = false
13
14
 
14
- def self.[](key)
15
- @@mem[key] if @@loaded
16
- end
15
+ def self.[](key)
16
+ @@mem[key] if @@loaded
17
+ end
17
18
 
18
- # @return true if there is the key in the config
19
- def self.has_key?(key)
20
- @@mem.has_key? key
21
- end
19
+ def self.[]=(key, value)
20
+ @@mem[key] = value if @@loaded
21
+ end
22
22
 
23
- # Method class alias
24
- # might remove this at some point ( sorry Yannou I know u worked hard :( )
25
- self.singleton_class.send(:alias_method, :=~, :has_key?)
26
-
27
- def self.load(cfg_file)
28
- @@loaded = true
29
- @@mem = {}
30
-
31
- populate YAML.load(File.read(cfg_file))
32
- type_file = File.join(ROOT,'type',"#{@@mem[:type]}.yml")
33
- type_cfg = YAML.load(File.read(type_file))
34
- populate YAML.load(File.read(File.join(ROOT,'lang',"#{type_cfg['language']}.yml")))
35
- # So that project's type Cfg overrides
36
- # lang Cfg
37
- populate type_cfg
38
- end
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
- # Handy method to convert string keys
43
- # read from Cfg file to symbols
44
- #
45
- def self.populate(hash)
46
- hash.each { |k, v| @@mem[k.to_sym] = v}
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 command line interfaces
11
+ # It use the powerful toolkit Thor for building command line interfaces
11
12
  #
12
13
  # @author Yann Prono
13
14
  #
14
- class Exec < Thor
15
+ module Reviser
16
+ class Exec < Thor
15
17
 
16
- @@setup = false
18
+ VERSION = '0.0.1.1'
17
19
 
18
- # path of config template file.
19
- $template_path = File.join(File.dirname(File.dirname(__FILE__)),'config.yml')
20
+ map '--version' => :version
21
+ map '-v' => :version
20
22
 
21
- def initialize(*args)
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
- # Say hello to the user !
31
- desc 'hello','Say hello to the user !'
32
- def hello
33
- puts 'Hello, I am reviser'
34
- end
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
- # Create a environnment for checking projects
38
- # This method only copies the config file into the current directory.
39
- desc 'init DIRECTORY', 'Create a new App project. By default,DIRECTORY is the current.'
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))
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
- setup File.expand_path(File.join(dir, File.basename($template_path))) unless @@setup
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
- # Clean the directory of logs, projects and results.
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
- FileUtils.rm_rf(Cfg[:res_dir], :verbose => true)
69
- else
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
- # Let do it for analysis.
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
- # Launch archiver !
89
- desc 'extract', 'Launch archiver and extract all projects.'
90
- def extract
91
- Reviser::load :component => 'archiver'
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
- # Launch organiser !
96
- desc 'organise', 'Launch organiser and prepare all projects for analysis'
97
- def organise
98
- Reviser::load :component => 'organiser'
99
- Reviser::run
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
- # Launch checker and generator as well !
103
- desc 'check', 'Launch checker for analysis and generate results.'
104
- def check
105
- Reviser::load :component => 'checker'
106
- Reviser::load :component => 'generator', :inputFrom => 'checker'
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
- # For the moment, associate a label to a criterion (method).
111
- desc 'add METH "LABEL" ', 'Add to the method METH a associated LABEL'
112
- def add meth, label
113
- res = Criteria::Labels.add meth, label
114
- message "#{res} label",meth + " => " + label
115
- end
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
- no_tasks do
119
- # A Formatter message for command line
120
- def message(keyword, desc)
121
- puts "\t#{keyword}\t\t#{desc}"
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
- path_res = File.join(File.dirname(File.dirname(__FILE__)),"#{Cfg[:res_dir]}")
128
- FileUtils.cp_r(path_res, FileUtils.pwd)
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
- @@setup = true
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)