codeclimate 0.3.2 → 0.4.0

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 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