codeclimate 0.14.0 → 0.14.1

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: d13448b3cac119e109b7c8803f6a9ad3d40c7cfc
4
- data.tar.gz: ca2b0a4d9ce066010654c5c4b33f648e671c80f1
3
+ metadata.gz: f7d10a3e340b114a674a576928f4fcfecf003804
4
+ data.tar.gz: f457eb3fc54b3e7e63aeb3d64010b57736c4165d
5
5
  SHA512:
6
- metadata.gz: af40f37bcad31b287e4e89cd903a327381c435d9925343aff88a05d3c15816e4f99a4c8cceb2de1f635bedbfc11544375fbabf662436473eb818069d3a6e43e1
7
- data.tar.gz: 0ebed34277ebffadb88133ffc92a61ec07c14f732ae3c67bb9d6e496cdf40590d40219d53d8f2c919cc4d5d79315b2110d7abf69bc2ed529e742936959698174
6
+ metadata.gz: 7abfdf98943e97e6a5c43cb5a63f767e15b98a5b2b67ad2353ed417e3ce2835f8478dbe7b38f7de025128c5f79245db70c67e2faacbff2538e7a237cb0e00265
7
+ data.tar.gz: f97c25a43e0e1b44b1f05c6e5bbff19fbbbe5a018bd4008dcadadf28ff233c9951c981c6c7a556cae2ef23a540792854afc22ef74a3f0c8c147b045e724c09e0
data/bin/codeclimate CHANGED
@@ -4,5 +4,6 @@ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
4
4
  require "cc/cli"
5
5
 
6
6
  ENV["FILESYSTEM_DIR"] ||= "."
7
+ ENV["CODE_PATH"] ||= ENV["PWD"]
7
8
 
8
9
  CC::CLI::Runner.run(ARGV)
@@ -0,0 +1,129 @@
1
+ {
2
+ "arrow_spacing": {
3
+ "level": "ignore"
4
+ },
5
+ "braces_spacing": {
6
+ "level": "ignore",
7
+ "spaces": 0,
8
+ "empty_object_spaces": 0
9
+ },
10
+ "camel_case_classes": {
11
+ "level": "error"
12
+ },
13
+ "coffeescript_error": {
14
+ "level": "error"
15
+ },
16
+ "colon_assignment_spacing": {
17
+ "level": "ignore",
18
+ "spacing": {
19
+ "left": 0,
20
+ "right": 0
21
+ }
22
+ },
23
+ "cyclomatic_complexity": {
24
+ "value": 10,
25
+ "level": "ignore"
26
+ },
27
+ "duplicate_key": {
28
+ "level": "error"
29
+ },
30
+ "empty_constructor_needs_parens": {
31
+ "level": "ignore"
32
+ },
33
+ "ensure_comprehensions": {
34
+ "level": "warn"
35
+ },
36
+ "eol_last": {
37
+ "level": "ignore"
38
+ },
39
+ "indentation": {
40
+ "value": 2,
41
+ "level": "error"
42
+ },
43
+ "line_endings": {
44
+ "level": "ignore",
45
+ "value": "unix"
46
+ },
47
+ "max_line_length": {
48
+ "value": 80,
49
+ "level": "error",
50
+ "limitComments": true
51
+ },
52
+ "missing_fat_arrows": {
53
+ "level": "ignore",
54
+ "is_strict": false
55
+ },
56
+ "newlines_after_classes": {
57
+ "value": 3,
58
+ "level": "ignore"
59
+ },
60
+ "no_backticks": {
61
+ "level": "error"
62
+ },
63
+ "no_debugger": {
64
+ "level": "warn",
65
+ "console": false
66
+ },
67
+ "no_empty_functions": {
68
+ "level": "ignore"
69
+ },
70
+ "no_empty_param_list": {
71
+ "level": "ignore"
72
+ },
73
+ "no_implicit_braces": {
74
+ "level": "ignore",
75
+ "strict": true
76
+ },
77
+ "no_implicit_parens": {
78
+ "strict": true,
79
+ "level": "ignore"
80
+ },
81
+ "no_interpolation_in_single_quotes": {
82
+ "level": "ignore"
83
+ },
84
+ "no_plusplus": {
85
+ "level": "ignore"
86
+ },
87
+ "no_stand_alone_at": {
88
+ "level": "ignore"
89
+ },
90
+ "no_tabs": {
91
+ "level": "error"
92
+ },
93
+ "no_this": {
94
+ "level": "ignore"
95
+ },
96
+ "no_throwing_strings": {
97
+ "level": "error"
98
+ },
99
+ "no_trailing_semicolons": {
100
+ "level": "error"
101
+ },
102
+ "no_trailing_whitespace": {
103
+ "level": "error",
104
+ "allowed_in_comments": false,
105
+ "allowed_in_empty_lines": true
106
+ },
107
+ "no_unnecessary_double_quotes": {
108
+ "level": "ignore"
109
+ },
110
+ "no_unnecessary_fat_arrows": {
111
+ "level": "warn"
112
+ },
113
+ "non_empty_constructor_needs_parens": {
114
+ "level": "ignore"
115
+ },
116
+ "prefer_english_operator": {
117
+ "level": "ignore",
118
+ "doubleNotLevel": "ignore"
119
+ },
120
+ "space_operators": {
121
+ "level": "ignore"
122
+ },
123
+ "spacing_after_comma": {
124
+ "level": "ignore"
125
+ },
126
+ "transform_messes_up_line_numbers": {
127
+ "level": "warn"
128
+ }
129
+ }
@@ -63,6 +63,7 @@ module CC
63
63
 
64
64
  def config_file
65
65
  path = File.join("/tmp/cc", SecureRandom.uuid)
66
+ FileUtils.mkdir_p("/tmp/cc")
66
67
  File.write(path, @config.to_json)
67
68
  path
68
69
  end
data/lib/cc/cli.rb CHANGED
@@ -12,6 +12,7 @@ module CC
12
12
  autoload :Help, "cc/cli/help"
13
13
  autoload :Init, "cc/cli/init"
14
14
  autoload :Runner, "cc/cli/runner"
15
+ autoload :Test, "cc/cli/test"
15
16
  autoload :ValidateConfig, "cc/cli/validate_config"
16
17
  autoload :Version, "cc/cli/version"
17
18
  end
@@ -0,0 +1,270 @@
1
+ require "shellwords"
2
+ require "cc/yaml"
3
+
4
+ module CC
5
+ module CLI
6
+ class Marker
7
+ def self.from_text(engine_name, test_file, line_number, text)
8
+ marker = Marker.new(line_number, text)
9
+ attrs = attrs_from_marker(text.sub(/^.*\[issue\] ?/, ""))
10
+
11
+ marker.issue = attrs.merge(
12
+ "engine_name" => engine_name,
13
+ "location" => {
14
+ "path" => test_file,
15
+ "lines" => {
16
+ "begin" => line_number + 1,
17
+ "end" => line_number + 1,
18
+ },
19
+ },
20
+ )
21
+
22
+ if marker.issue["category"]
23
+ marker.issue["categories"] = Array.wrap(marker.issue["category"])
24
+ marker.issue.delete("category")
25
+ end
26
+
27
+ marker
28
+ end
29
+
30
+ def self.attrs_from_marker(text)
31
+ if text.blank?
32
+ {}
33
+ else
34
+ matches = text.scan(/([a-z\._-]+)=(?:(")((?:\\.|[^"])*)"|([^\s]*))/).map(&:compact)
35
+
36
+ key_values = matches.map do |match|
37
+ munge_match(match)
38
+ end
39
+
40
+ Hash[key_values]
41
+ end
42
+ end
43
+
44
+ def self.munge_match(match)
45
+ if match.size == 3 # Quoted
46
+ key, _, value = match
47
+ value = '"' + value + '"'
48
+ else
49
+ key, value = match
50
+ end
51
+
52
+ [key, munge_value(value)]
53
+ end
54
+
55
+ def self.munge_value(value)
56
+ JSON.load(value)
57
+ rescue JSON::ParserError
58
+ value
59
+ end
60
+
61
+ attr_reader :line, :line_text
62
+ attr_accessor :issue
63
+
64
+ def initialize(line, line_text)
65
+ @line = line
66
+ @line_text = line_text
67
+ @issue = issue
68
+ end
69
+ end
70
+
71
+ class Test < Command
72
+ def run
73
+ @engine_name = @args.first
74
+
75
+ if @engine_name.blank?
76
+ fatal "Usage: codeclimate test #{rainbow.wrap('engine_name').underline}"
77
+ end
78
+
79
+ test_engine
80
+ end
81
+
82
+ def test_engine
83
+ within_tempdir do
84
+ prepare_working_dir
85
+ unpack_tests
86
+ run_tests
87
+ end
88
+ ensure
89
+ remove_null_container
90
+ end
91
+
92
+ def within_tempdir
93
+ tmpdir = create_tmpdir
94
+
95
+ Dir.chdir(tmpdir) do
96
+ yield
97
+ end
98
+ ensure
99
+ FileUtils.rm_rf(tmpdir)
100
+ end
101
+
102
+ def unpack_tests
103
+ test_paths.each do |test_path|
104
+ unpack(test_path)
105
+ end
106
+ end
107
+
108
+ def run_tests
109
+ Dir["**/*"].each do |test_file|
110
+ next unless File.file?(test_file)
111
+ process_file(test_file)
112
+ end
113
+ end
114
+
115
+ def process_file(test_file)
116
+ markers = markers_in(test_file)
117
+
118
+ actual_issues = issues_in(test_file)
119
+ compare_issues(actual_issues, markers)
120
+ end
121
+
122
+ def compare_issues(actual_issues, markers)
123
+ markers.each do |marker|
124
+ validate_issue(marker, actual_issues)
125
+ end
126
+
127
+ validate_unexpected_issues(actual_issues)
128
+ end
129
+
130
+ def validate_issue(marker, actual_issues)
131
+ if (index = locate_match(actual_issues, marker))
132
+ announce_pass(marker)
133
+ actual_issues.delete_at(index)
134
+ else
135
+ announce_fail(marker, actual_issues)
136
+ fatal "Expected issue not found."
137
+ end
138
+ end
139
+
140
+ def locate_match(actual_issues, marker)
141
+ actual_issues.each_with_index do |actual, index|
142
+ if fuzzy_match(marker.issue, actual)
143
+ return index
144
+ end
145
+ end
146
+
147
+ nil
148
+ end
149
+
150
+ def announce_pass(marker)
151
+ say format("PASS %3d: %s", marker.line, marker.line_text)
152
+ end
153
+
154
+ def announce_fail(marker, actual_issues)
155
+ say colorize(format("FAIL %3d: %s", marker.line, marker.line_text), :red)
156
+ say colorize("Expected:", :yellow)
157
+ say colorize(JSON.pretty_generate(marker.issue), :yellow)
158
+ say "\n"
159
+ say colorize("Actual:", :yellow)
160
+ say colorize(JSON.pretty_generate(actual_issues), :yellow)
161
+ end
162
+
163
+ def validate_unexpected_issues(actual_issues)
164
+ if actual_issues.any?
165
+ say colorize("Actuals not empty after matching.", :red)
166
+ say
167
+ say colorize("#{actual_issues.size} remaining:", :yellow)
168
+ say colorize(JSON.pretty_generate(actual_issues), :yellow)
169
+ fatal "Unexpected issue found."
170
+ end
171
+ end
172
+
173
+ def fuzzy_match(expected, actual)
174
+ expected.all? do |key, value|
175
+ actual[key] == value
176
+ end
177
+ end
178
+
179
+ def issues_in(test_file)
180
+ issue_docs = capture_stdout do
181
+ codeclimate_analyze(test_file)
182
+ end
183
+
184
+ JSON.parse(issue_docs)
185
+ end
186
+
187
+ def codeclimate_analyze(relative_path)
188
+ codeclimate_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../bin/codeclimate"))
189
+
190
+ system([
191
+ "unset CODE_PATH &&",
192
+ "unset FILESYSTEM_DIR &&",
193
+ Shellwords.escape(codeclimate_path),
194
+ "analyze",
195
+ "--engine", Shellwords.escape(@engine_name),
196
+ "-f", "json",
197
+ Shellwords.escape(relative_path)
198
+ ].join(" "))
199
+ end
200
+
201
+ def prepare_working_dir
202
+ `git init`
203
+
204
+ File.open(".codeclimate.yml", "w") do |config|
205
+ config.write("engines:\n #{@engine_name}:\n enabled: true")
206
+ end
207
+ end
208
+
209
+ def markers_in(test_file)
210
+ lines = File.readlines(test_file)
211
+
212
+ [].tap do |markers|
213
+ lines.each_with_index do |line, index|
214
+ if line =~ /\[issue\].*/
215
+ markers << Marker.from_text(@engine_name, test_file, index + 1, line)
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ def create_tmpdir
222
+ tmpdir = File.join("/tmp/cc", SecureRandom.uuid)
223
+ FileUtils.mkdir_p(tmpdir)
224
+ tmpdir
225
+ end
226
+
227
+ def unpack(path)
228
+ system("docker cp #{null_container_id}:#{path} .")
229
+ end
230
+
231
+ def null_container_id
232
+ # docker cp only works with containers, not images so
233
+ # workaround it by creating a throwaway container
234
+ @null_container_id = `docker run -d #{engine_image} false`.chomp
235
+ end
236
+
237
+ def remove_null_container
238
+ `docker rm -f #{null_container_id}` if null_container_id
239
+ end
240
+
241
+ def test_paths
242
+ Array.wrap(engine_spec["test_paths"])
243
+ end
244
+
245
+ def engine_spec
246
+ @engine_spec ||= JSON.parse(`docker run --rm #{engine_image} cat /engine.json`)
247
+ end
248
+
249
+ def engine_image
250
+ engine_registry[@engine_name]["image"]
251
+ end
252
+
253
+ # Stolen from ActiveSupport (where it was deprecated)
254
+ def capture_stdout
255
+ captured_stream = Tempfile.new("stdout")
256
+ origin_stream = $stdout.dup
257
+ $stdout.reopen(captured_stream)
258
+
259
+ yield
260
+
261
+ $stdout.rewind
262
+ return captured_stream.read
263
+ ensure
264
+ captured_stream.close
265
+ captured_stream.unlink
266
+ $stdout.reopen(origin_stream)
267
+ end
268
+ end
269
+ end
270
+ 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.14.0
4
+ version: 0.14.1
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-11-05 00:00:00.000000000 Z
11
+ date: 2015-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 0.4.0
53
+ version: 0.5.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 0.4.0
60
+ version: 0.5.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: faraday
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +193,7 @@ files:
193
193
  - bin/codeclimate-init
194
194
  - bin/prep-release
195
195
  - bin/release
196
+ - config/coffeelint/coffeelint.json
196
197
  - config/csslint/.csslintrc
197
198
  - config/engines.yml
198
199
  - config/eslint/.eslintrc
@@ -237,6 +238,7 @@ files:
237
238
  - lib/cc/cli/help.rb
238
239
  - lib/cc/cli/init.rb
239
240
  - lib/cc/cli/runner.rb
241
+ - lib/cc/cli/test.rb
240
242
  - lib/cc/cli/upgrade_config_generator.rb
241
243
  - lib/cc/cli/validate_config.rb
242
244
  - lib/cc/cli/version.rb
@@ -261,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
263
  version: '0'
262
264
  requirements: []
263
265
  rubyforge_project:
264
- rubygems_version: 2.4.8
266
+ rubygems_version: 2.4.5
265
267
  signing_key:
266
268
  specification_version: 4
267
269
  summary: Code Climate CLI