codercmp 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/codercmp +101 -0
- data/lib/codercompanion/api.rb +47 -0
- data/lib/codercompanion/cachehandler.rb +94 -0
- data/lib/codercompanion/codercompanion_exception.rb +4 -0
- data/lib/codercompanion/common/common.rb +44 -0
- data/lib/codercompanion/common/literals.rb +58 -0
- data/lib/codercompanion/common_namespace.rb +2 -0
- data/lib/codercompanion/cpp/cpp_parser.rb +31 -0
- data/lib/codercompanion/cpp/cpp_tree_walker.rb +20 -0
- data/lib/codercompanion/java/java.rb +365 -0
- data/lib/codercompanion/java/java_grammar.treetop +283 -0
- data/lib/codercompanion/java/java_parser.rb +62 -0
- data/lib/codercompanion/java/java_tree_walker.rb +114 -0
- data/lib/codercompanion/language_parser.rb +54 -0
- data/lib/codercompanion/languages.rb +23 -0
- data/lib/codercompanion/parser_factory.rb +27 -0
- data/lib/codercompanion/ruby/ruby_annotations.rb +8 -0
- data/lib/codercompanion/ruby/ruby_parser.rb +45 -0
- data/lib/codercompanion/ruby/ruby_tree_walker.rb +229 -0
- data/lib/codercompanion/s3_client.rb +32 -0
- data/lib/codercompanion/tree_walker.rb +8 -0
- data/lib/codercompanion.rb +410 -0
- data/lib/codercompanion_version.rb +3 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f7eb5cfcf5bedbc117d1fd4f9f4d0c4283abf372
|
4
|
+
data.tar.gz: 590499c02a93be6bc554b245876fd728789b9506
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 898f86b675cb21ed3cdba632f0d7978cc36f9d2ad52f3ea8d695badf9db9646537ee0ee60c5be27c6baf080fba33f1d3d4784523f73407e9ecbfc512c6bdaa32
|
7
|
+
data.tar.gz: 39b2dc40462b7fba5c0d673d314250ac4e6f46131e8a06376d601a71f3af093cfedc667cf7ad2419c0252d6c0cb37b95ea54446012aea4fbebcface0d832c7a9
|
data/bin/codercmp
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
$LOAD_PATH.unshift lib_dir if File.directory?(lib_dir)
|
4
|
+
|
5
|
+
require 'codercompanion.rb'
|
6
|
+
require 'codercompanion_version.rb'
|
7
|
+
require "optparse"
|
8
|
+
|
9
|
+
options = {}
|
10
|
+
location = "." # Default to the current directory
|
11
|
+
exclude = []
|
12
|
+
test = false
|
13
|
+
|
14
|
+
option_parser = OptionParser.new do |opts|
|
15
|
+
opts.banner = <<INFO
|
16
|
+
|
17
|
+
Usage:
|
18
|
+
#{File.basename($PROGRAM_NAME)} [OPTIONS] # See OPTIONS for the options available
|
19
|
+
|
20
|
+
Examples:
|
21
|
+
#{File.basename($PROGRAM_NAME)} # Run codercmp. Looks for codercmp.conf file in current working directory.
|
22
|
+
Parses all eligible files in working directory tree
|
23
|
+
#{File.basename($PROGRAM_NAME)} -c FILE -d DIR # Uses a specified configuration file [must end in .conf] and a directory
|
24
|
+
to parse files e.g.: 'path_to/lib'
|
25
|
+
#{File.basename($PROGRAM_NAME)} -x GLOB # Specifies a directory or file pattern to exclude.
|
26
|
+
where 'GLOB' could be a file, directory or pattern e.g. '-x vendor/bundle/**/*.rb'
|
27
|
+
#{File.basename($PROGRAM_NAME)} -x 'GLOB GLOB' # Specify multiple file patterns or directories to exclude.
|
28
|
+
|
29
|
+
INFO
|
30
|
+
|
31
|
+
opts.separator ""
|
32
|
+
opts.separator "OPTIONS:"
|
33
|
+
|
34
|
+
opts.on( "--directory DIRECTORY", "-d DIRECTORY", "Directory to find parsable files. The default is the current working directory.") do |directory|
|
35
|
+
location = directory
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on( "--config-file FILE", "-c FILE", "Configuration file to use; must end in '*.conf'. By default codercmp will look for 'codercmp.conf' in the current directory.") do |config|
|
39
|
+
correct_extension = config.match(/.*\.conf$/)
|
40
|
+
if !correct_extension
|
41
|
+
CoderCompanion::j_print CoderCompanion::error_format("The configuration file must end in .conf")
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
options[:config_file] = config
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on( "--fresh", "-f" , "Delete caches and run a fresh pass on the source code.") do
|
48
|
+
options[:fresh_run] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on( "--silent", "-s" , "Run codercmp without printing messages") do
|
52
|
+
options[:silent_run] = true
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on( "--[no-]color", "By default codercmp will show color. Specifiy --no-color to disable the color.") do |val|
|
56
|
+
options[:no_color] = !val
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on( "--show-output", "-o", "Display the output after parsing the project") do
|
60
|
+
options[:show_output] = true
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on( "--dry-run", "Performs dry run. Does not actually upload data. The purpose of this command is to test the parsing of your files. " +
|
64
|
+
"Becomes even more useful when used with --show-output to see the result of the parse") do
|
65
|
+
options[:dry_run] = true
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.on( "--exclude FILES", "-x FILES", "This is to used to exclude files. Specify a list of files seperated by a space (wrapped in \" quotations).") do |files|
|
69
|
+
multiple_files = files.split(/\s+/)
|
70
|
+
multiple_files.each do |file|
|
71
|
+
exclude += Dir.glob(file.gsub(/\/$/, ''))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
opts.on( "--languages", "-l", "Get the supported languages") do
|
76
|
+
CoderCompanion.display_supported_languages
|
77
|
+
exit 0
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.separator "Common Options:"
|
81
|
+
|
82
|
+
opts.on( "-h", "--help", "Show this message." ) do
|
83
|
+
puts opts
|
84
|
+
exit 0
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.on( "--version", "-v", "Find out the version of codercmp you are running") do
|
88
|
+
puts CoderCompanion::VERSION
|
89
|
+
exit 0
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
option_parser.parse!
|
94
|
+
|
95
|
+
options[:exclude] = exclude
|
96
|
+
begin
|
97
|
+
CoderCompanion::start(options, location)
|
98
|
+
rescue CoderCompanion::CoderCompanionException => e
|
99
|
+
CoderCompanion::j_print CoderCompanion::error_format(e.message)
|
100
|
+
exit 1
|
101
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
class API
|
3
|
+
def initialize()
|
4
|
+
# puts CoderCompanion::config
|
5
|
+
end
|
6
|
+
|
7
|
+
def upload(file)
|
8
|
+
response = nil
|
9
|
+
begin
|
10
|
+
response = RestClient.post(CoderCompanion::config["host"] + '/update_project.json', :myfile => File.new(file),# /Users/oseghale/Projects/JinglePage/JingleParser/test_upload.jingle'),
|
11
|
+
:access_key => CoderCompanion::config["project"]["access_key"], :access_id => CoderCompanion::config["user"]["access_id"]) { |response, request, result, &block|
|
12
|
+
return response.code || nil
|
13
|
+
}
|
14
|
+
rescue
|
15
|
+
return CoderCompanion::GENERIC_ERROR
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_temporary_access_key
|
22
|
+
begin
|
23
|
+
RestClient.post("#{CoderCompanion::config["host"]}/project/get_temporary_access_key.json",
|
24
|
+
:access_key => CoderCompanion::config["project"]["access_key"],
|
25
|
+
:access_id => CoderCompanion::config["user"]["access_id"]) { |response, request, result, &block|
|
26
|
+
return (response.code == CoderCompanion::STATUS_OK) ? response : nil
|
27
|
+
}
|
28
|
+
rescue
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def notify_s3_upload(key)
|
34
|
+
begin
|
35
|
+
RestClient.post("#{CoderCompanion::config["host"]}/project/notify_project_upload.json",
|
36
|
+
:s3_key => key,
|
37
|
+
:access_key => CoderCompanion::config["project"]["access_key"],
|
38
|
+
:access_id => CoderCompanion::config["user"]["access_id"]) { |response, request, result, &block|
|
39
|
+
return (response.code == CoderCompanion::STATUS_OK) ? response : nil
|
40
|
+
}
|
41
|
+
rescue
|
42
|
+
return nil
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
class CacheHandler
|
3
|
+
CACHE_DIR = './codercompanion_cache_data'
|
4
|
+
|
5
|
+
# @return [Object]
|
6
|
+
attr_accessor :file_cache
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@file_cache = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [File, nil]
|
13
|
+
def open_cache
|
14
|
+
file = nil
|
15
|
+
begin
|
16
|
+
file = File.open(CACHE_DIR + '/cache.data')
|
17
|
+
rescue
|
18
|
+
CoderCompanion::warning_format("Could not find cache")
|
19
|
+
end
|
20
|
+
file
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param fresh_run [Boolean] should we use cache for this run?
|
24
|
+
def load_cache(fresh_run)
|
25
|
+
if !CoderCompanion.dry_run?
|
26
|
+
if fresh_run
|
27
|
+
delete_cache
|
28
|
+
else
|
29
|
+
find_cache
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [String] file_path
|
35
|
+
# @return [Boolean]
|
36
|
+
def is_file_modified?(file_path)
|
37
|
+
cache = encrypt(File.open(file_path).read)
|
38
|
+
if self.file_cache && self.file_cache[ file_path ] && (self.file_cache[ file_path ] == cache)
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete_cache
|
45
|
+
if !CoderCompanion.dry_run?
|
46
|
+
begin
|
47
|
+
File.delete(CACHE_DIR + '/cache.data')
|
48
|
+
CoderCompanion::j_print CoderCompanion::warning_format("Running a fresh sesh")
|
49
|
+
rescue
|
50
|
+
CoderCompanion::j_print CoderCompanion::warning_format("No cache to delete. Running a fresh sesh")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [String] file_path
|
56
|
+
def update_cache_path(file_path)
|
57
|
+
if !CoderCompanion.dry_run?
|
58
|
+
if !self.file_cache
|
59
|
+
self.file_cache = {}
|
60
|
+
end
|
61
|
+
self.file_cache[file_path] = encrypt(File.open(file_path).read)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [nil]
|
66
|
+
def write_cached_data
|
67
|
+
if !CoderCompanion.dry_run?
|
68
|
+
if !Dir.exists?(CACHE_DIR)
|
69
|
+
Dir.mkdir(CACHE_DIR)
|
70
|
+
end
|
71
|
+
File.open(CACHE_DIR + '/cache.data', 'w+') do |f|
|
72
|
+
f.write(self.file_cache.to_json)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [JSON]
|
78
|
+
def find_cache
|
79
|
+
begin
|
80
|
+
file = open_cache
|
81
|
+
self.file_cache = JSON.parse(file.read)
|
82
|
+
rescue
|
83
|
+
CoderCompanion::j_print CoderCompanion::warning_format("Cache not found running a fresh sesh")
|
84
|
+
end
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def encrypt(file)
|
91
|
+
return Digest::SHA1.hexdigest(file)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
module Common
|
3
|
+
class SourceFile < Treetop::Runtime::SyntaxNode
|
4
|
+
def build
|
5
|
+
els = nil
|
6
|
+
elements.each do |e|
|
7
|
+
els = e.build if e.respond_to? :build
|
8
|
+
end
|
9
|
+
return {:type => 'source', :value => els}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Body < Treetop::Runtime::SyntaxNode
|
14
|
+
def build
|
15
|
+
els = []
|
16
|
+
elements[0].elements.each do |e|
|
17
|
+
built = e.build if e.respond_to? :build
|
18
|
+
els.push(built) if built
|
19
|
+
end
|
20
|
+
return {:type => 'body', :value => els}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Method < Treetop::Runtime::SyntaxNode
|
25
|
+
def build
|
26
|
+
els = []
|
27
|
+
elements.each do |e|
|
28
|
+
built = e.build if e.respond_to? :build
|
29
|
+
els.push built if built
|
30
|
+
end
|
31
|
+
return {:type => :method, :value => els}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Identifier < Treetop::Runtime::SyntaxNode
|
36
|
+
def build
|
37
|
+
text_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class WhiteSpace < Treetop::Runtime::SyntaxNode
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
module Common
|
3
|
+
|
4
|
+
class BooleanLiteral < Treetop::Runtime::SyntaxNode
|
5
|
+
end
|
6
|
+
|
7
|
+
class Literal < Treetop::Runtime::SyntaxNode
|
8
|
+
end
|
9
|
+
|
10
|
+
class IntegerLiteral < Treetop::Runtime::SyntaxNode
|
11
|
+
def build
|
12
|
+
{:type => :integer, :value => text_value}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class FloatLiteral < Treetop::Runtime::SyntaxNode
|
17
|
+
def build
|
18
|
+
{:type => :float, :value => text_value}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class StringLiteral < Treetop::Runtime::SyntaxNode
|
23
|
+
def build
|
24
|
+
{:type => :string, :value => text_value}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class ArrayLiteral < Treetop::Runtime::SyntaxNode
|
29
|
+
|
30
|
+
def build
|
31
|
+
els = []
|
32
|
+
elements.map do |e|
|
33
|
+
if e.respond_to? :first_element
|
34
|
+
els.push(e.elements[1].build)
|
35
|
+
end
|
36
|
+
els += e.build if e.respond_to? :build
|
37
|
+
# els.push(e.text_value) if e.respond_to? :build
|
38
|
+
end
|
39
|
+
{:type => :array, :value => els}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class RestOfElements < Treetop::Runtime::SyntaxNode
|
44
|
+
def build
|
45
|
+
els = []
|
46
|
+
elements.map do |e|
|
47
|
+
if e.respond_to? :another_element
|
48
|
+
e.elements.map do |f|
|
49
|
+
els.push(f.build) if f.respond_to? :build
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
els
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
module Cpp
|
3
|
+
class CppParser < CoderCompanion::LanguageParser
|
4
|
+
|
5
|
+
CPP_EXTENSIONS = ['.h', '.hpp']
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@tree_walker = CoderCompanion::Cpp::CppTreeWalker.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(files)
|
12
|
+
raise NotImplementedError, "cpp parser is not yet implemented"
|
13
|
+
=begin
|
14
|
+
begin
|
15
|
+
results = RbGCCXML.parse(files, :cxxflags => ["--debug", "-stdlib=libstdc++"])
|
16
|
+
return [results]
|
17
|
+
rescue RuntimeError => e
|
18
|
+
CoderCompanion::j_print CoderCompanion::error_format("An error occured while parsing your code.")
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
=end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def is_valid_file(ext)
|
27
|
+
return CPP_EXTENSIONS.include?(ext)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
module Cpp
|
3
|
+
class CppTreeWalker < CoderCompanion::TreeWalker
|
4
|
+
def create_uploadable(results)
|
5
|
+
obj = {}
|
6
|
+
namespace = results.first
|
7
|
+
namespace.classes.each do |klass|
|
8
|
+
modified = CoderCompanion::CacheHandler.is_file_modified?(klass.file)
|
9
|
+
CoderCompanion::CacheHandler.update_cache_path(klass.file)
|
10
|
+
|
11
|
+
obj[klass] = build_class(klass, modified)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_class(klass, modified)
|
16
|
+
puts klass.name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|