codeclimate 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0c3efb6cbbf82988bd5889f5205532c2f04d3059
4
- data.tar.gz: e86fa7a9230c80c97701b61887b39754c028c5dc
3
+ metadata.gz: 4205b1614e474d25d9204cd7e22fdcb8752592c5
4
+ data.tar.gz: c23dcf718de6df7c4957c5b86fb824545fda2db2
5
5
  SHA512:
6
- metadata.gz: 5a906af804ecd6d8c676bba731c0a424baa562ee32b37ddc21d16807a409ff37366b9e8e99b176cda66ac9c7f36fdf95976e96cdfe1bd64a1b1dcd18121b0fcc
7
- data.tar.gz: 34d2b20fe51337abcbe87976e130e162ce829f0c33ff515c538e2751ccea72bbaa19f779834080c6edc5454f04c09942dedbfc84a93d21de2fd09fa3fa6d9e45
6
+ metadata.gz: be5215a861e099009c59b4f60450ec4f9db007023ead307c165eceb09a150709975bf4e60c7828bc4e6761a0fa0ed7381440a49db112106e2c0642048b3dec15
7
+ data.tar.gz: b001996f081fa00473933c00e85c716ffef13baa7d454adc7a89830f0adb479d693cf101feaff91b19be0d5eb7a8f093f253c0bb318a906c7454f4a759e5e644
data/lib/cc/analyzer.rb CHANGED
@@ -10,6 +10,7 @@ module CC
10
10
  autoload :EnginesRunner, "cc/analyzer/engines_runner"
11
11
  autoload :Filesystem, "cc/analyzer/filesystem"
12
12
  autoload :Formatters, "cc/analyzer/formatters"
13
+ autoload :IncludePathsBuilder, "cc/analyzer/include_paths_builder"
13
14
  autoload :IssueSorter, "cc/analyzer/issue_sorter"
14
15
  autoload :LocationDescription, "cc/analyzer/location_description"
15
16
  autoload :LoggingContainerListener, "cc/analyzer/logging_container_listener"
@@ -33,5 +34,7 @@ module CC
33
34
  cattr_accessor :statsd, :logger
34
35
  self.statsd = DummyStatsd.new
35
36
  self.logger = DummyLogger.new
37
+
38
+ UnreadableFileError = Class.new(StandardError)
36
39
  end
37
40
  end
@@ -43,7 +43,10 @@ module CC
43
43
  end
44
44
 
45
45
  def engine_config(config)
46
- config = config.merge(exclude_paths: exclude_paths)
46
+ config = config.merge(
47
+ exclude_paths: exclude_paths,
48
+ include_paths: include_paths
49
+ )
47
50
 
48
51
  # The yaml gem turns a config file string into a hash, but engines expect the string
49
52
  # So we (for now) need to turn it into a string in that one scenario.
@@ -73,6 +76,10 @@ module CC
73
76
  PathPatterns.new(@config.exclude_paths || []).expanded + gitignore_paths
74
77
  end
75
78
 
79
+ def include_paths
80
+ IncludePathsBuilder.new(@config.exclude_paths || []).build
81
+ end
82
+
76
83
  def gitignore_paths
77
84
  if File.exist?(".gitignore")
78
85
  `git ls-files --others -i -z --exclude-from .gitignore`.split("\0")
@@ -0,0 +1,147 @@
1
+ module CC
2
+ module Analyzer
3
+ class IncludePathsBuilder
4
+ def self.relevant_entries(path)
5
+ Dir.entries(path).reject do |e|
6
+ %w(. .. .git).include?(e)
7
+ end
8
+ end
9
+
10
+ def initialize(cc_exclude_paths)
11
+ @cc_exclude_paths = cc_exclude_paths
12
+ end
13
+
14
+ def build
15
+ root = Directory.new('.', ignored_files)
16
+ paths = root.included_paths
17
+ paths.each do |path|
18
+ raise_on_unreadable_files(path)
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def ignored_files
25
+ Tempfile.open(".cc_gitignore") do |tmp|
26
+ tmp.write(File.read(".gitignore")) if File.exist?(".gitignore")
27
+ tmp << @cc_exclude_paths.join("\n")
28
+ tmp.close
29
+ tracked_and_ignored = `git ls-files -zi -X #{tmp.path}`.split("\0")
30
+ untracked_and_ignored = `git ls-files -zio -X #{tmp.path}`.split("\0")
31
+ tracked_and_ignored + untracked_and_ignored
32
+ end
33
+ end
34
+
35
+ def raise_on_unreadable_files(path)
36
+ if File.directory?(path)
37
+ raise_on_unreadable_files_in_directory(path)
38
+ elsif !FileUtils.readable_by_all?(path)
39
+ raise CC::Analyzer::UnreadableFileError, "Can't read #{path}"
40
+ end
41
+ end
42
+
43
+ def raise_on_unreadable_files_in_directory(path)
44
+ IncludePathsBuilder.relevant_entries(path).each do |entry|
45
+ sub_path = File.join(path, entry)
46
+ raise_on_unreadable_files(sub_path)
47
+ end
48
+ end
49
+
50
+ class Directory
51
+ def initialize(path, excluded_files)
52
+ @path = path
53
+ @excluded_files = ensure_hashified(excluded_files)
54
+ end
55
+
56
+ def all_included?
57
+ readable_by_all? &&
58
+ files_all_included? &&
59
+ subdirectories_all_included?
60
+ end
61
+
62
+ def included_paths
63
+ if all_included?
64
+ [@path + "/"]
65
+ elsif readable_by_all?
66
+ result = []
67
+ result += included_file_entries
68
+ result += included_subdirectory_results
69
+ result
70
+ else
71
+ []
72
+ end
73
+ end
74
+
75
+ protected
76
+
77
+ def ensure_hashified(obj)
78
+ if obj.is_a?(Array)
79
+ obj.each_with_object({}) do |included, result|
80
+ result[included] = true
81
+ end
82
+ else
83
+ obj
84
+ end
85
+ end
86
+
87
+ def files_all_included?
88
+ file_entries.none? { |e| @excluded_files[e] }
89
+ end
90
+
91
+ def file_entries
92
+ @file_entries ||= relevant_full_entries.reject do |e|
93
+ File.directory?(e)
94
+ end
95
+ end
96
+
97
+ def full_entry(entry)
98
+ if @path == "."
99
+ entry
100
+ else
101
+ File.join(@path, entry)
102
+ end
103
+ end
104
+
105
+ def included_file_entries
106
+ file_entries.reject { |file_entry| @excluded_files[file_entry] }
107
+ end
108
+
109
+ def included_subdirectory_results
110
+ subdirectories.each_with_object([]) do |subdirectory, result|
111
+ result.concat(subdirectory.included_paths)
112
+ end
113
+ end
114
+
115
+ def readable_by_all?
116
+ FileUtils.readable_by_all?(@path)
117
+ end
118
+
119
+ def relevant_full_entries
120
+ unless @relevant_full_entries
121
+ raw_entries = IncludePathsBuilder.relevant_entries(@path)
122
+ @relevant_full_entries = raw_entries.map do |e|
123
+ full_entry(e)
124
+ end
125
+ end
126
+ @relevant_full_entries
127
+ end
128
+
129
+ def subdirectories
130
+ unless @subdirectories
131
+ entries = relevant_full_entries.select do |e|
132
+ File.directory?(e)
133
+ end
134
+ @subdirectories = entries.map do |e|
135
+ Directory.new(e, @excluded_files)
136
+ end
137
+ end
138
+ @subdirectories
139
+ end
140
+
141
+ def subdirectories_all_included?
142
+ subdirectories.all?(&:all_included?)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
data/lib/cc/cli.rb CHANGED
@@ -2,6 +2,7 @@ require "active_support"
2
2
  require "active_support/core_ext"
3
3
  require "cc/analyzer"
4
4
  require "cc/yaml"
5
+ require "file_utils_ext"
5
6
 
6
7
  module CC
7
8
  module CLI
@@ -0,0 +1,7 @@
1
+ require 'fileutils'
2
+
3
+ module FileUtils
4
+ def self.readable_by_all?(path)
5
+ (File.stat(path).mode & 004) != 0
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codeclimate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code Climate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-09 00:00:00.000000000 Z
11
+ date: 2015-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -205,6 +205,7 @@ files:
205
205
  - lib/cc/analyzer/formatters/json_formatter.rb
206
206
  - lib/cc/analyzer/formatters/plain_text_formatter.rb
207
207
  - lib/cc/analyzer/formatters/spinner.rb
208
+ - lib/cc/analyzer/include_paths_builder.rb
208
209
  - lib/cc/analyzer/issue_sorter.rb
209
210
  - lib/cc/analyzer/location_description.rb
210
211
  - lib/cc/analyzer/logging_container_listener.rb
@@ -228,6 +229,7 @@ files:
228
229
  - lib/cc/cli/runner.rb
229
230
  - lib/cc/cli/validate_config.rb
230
231
  - lib/cc/cli/version.rb
232
+ - lib/file_utils_ext.rb
231
233
  homepage: https://codeclimate.com
232
234
  licenses:
233
235
  - MIT
@@ -248,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
248
250
  version: '0'
249
251
  requirements: []
250
252
  rubyforge_project:
251
- rubygems_version: 2.4.5
253
+ rubygems_version: 2.4.8
252
254
  signing_key:
253
255
  specification_version: 4
254
256
  summary: Code Climate CLI