codeclimate 0.2.9 → 0.2.11

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: b5b6caa0a6dc7642c6e5abb6533c8c24c7bd49f4
4
- data.tar.gz: 98bb65ce704a03ba8ed98a4ff697d2a424ef0fd3
3
+ metadata.gz: 32566ddd677d0f2659e3a463d78a2a41e78eee0e
4
+ data.tar.gz: 650ce0df21367faa2b8f94362a01ed46c9057620
5
5
  SHA512:
6
- metadata.gz: 17ecabe1ace73fbd5f37c83a78b2bd1e5a683aa1b518684a33ebd8885246c8bb289f804c692d63bd443b35ef1f0f576cfbc382691c6c89368516c8aa8a6edc1c
7
- data.tar.gz: f62c7be59d492698e22496c265b4f6c3c9993100ec861bce94227f9e4ffceda8bc8809ba2c75be9fae94a3d7d355c5b167ba30119e03ee42835d0e80b77e6906
6
+ metadata.gz: bbeaad0b4a597ccbefcd387eca14627711d5e1b43184d1c65f414dfd9c2af4774b4867a19493292f6d904a1cce9182be69d0767789afc0585662b32e9176fabd
7
+ data.tar.gz: cb8c64a2ddac15d5c9c65de165e0ed9c84a09a2f5d2f6d3aeeeac63759b550f1f8c45518d28da30776aae954e81ad9fc679797a1cb80c0e311912c3824d95f8d
data/bin/check CHANGED
@@ -4,7 +4,7 @@ command -v docker > /dev/null 2>&1 || {
4
4
  exit 1
5
5
  }
6
6
 
7
- docker version | grep -Fq "Server version" || {
7
+ docker version | grep -q "Server version\|Server:" || {
8
8
  echo "Unable to run \`docker version', the docker daemon may not be running" >&2
9
9
 
10
10
  if command -v boot2docker > /dev/null 2>&1; then
@@ -0,0 +1,41 @@
1
+ #!/bin/sh
2
+ #
3
+ # Release a new version of this repository
4
+ #
5
+ # Usage: bin/release VERSION
6
+ #
7
+ ###
8
+ set -e
9
+
10
+ set -- 0.2.11
11
+ if [ -z "$1" ]; then
12
+ echo "usage: bin/release VERSION" >&2
13
+ exit 64
14
+ fi
15
+
16
+ version=$1
17
+
18
+ if ! bundle exec rake; then
19
+ echo "test failure, not releasing" >&2
20
+ exit 1
21
+ fi
22
+
23
+ printf "RELEASE %s => %s\n" "$(< VERSION)" "$version"
24
+ # git checkout master
25
+ # git pull
26
+
27
+ # printf "%s\n" "$version" > VERSION
28
+ # bundle
29
+ # git add VERSION Gemfile.lock
30
+ # git commit -m "Release v$version"
31
+
32
+ rake release
33
+
34
+ # docker build --rm -t codeclimate/codeclimate .
35
+ # docker push codeclimate/codeclimate
36
+
37
+ # (cd ../homebrew-formulae/ && bin/release "$version")
38
+
39
+ # TODO: automate this final step
40
+ echo "Be sure to update release notes:"
41
+ echo "- TODO URL"
@@ -1,22 +1,22 @@
1
1
  module CC
2
2
  module Analyzer
3
- autoload :Accumulator, "cc/analyzer/accumulator"
4
- autoload :Config, "cc/analyzer/config"
5
- autoload :Container, "cc/analyzer/container"
6
- autoload :Engine, "cc/analyzer/engine"
7
- autoload :EngineClient, "cc/analyzer/engine_client"
3
+ autoload :CompositeContainerListener, "cc/analyzer/composite_container_listener"
4
+ autoload :Config, "cc/analyzer/config"
5
+ autoload :Container, "cc/analyzer/container"
6
+ autoload :ContainerListener, "cc/analyzer/container_listener"
7
+ autoload :Engine, "cc/analyzer/engine"
8
8
  autoload :EngineOutputFilter, "cc/analyzer/engine_output_filter"
9
- autoload :EngineRegistry, "cc/analyzer/engine_registry"
10
- autoload :EnginesRunner, "cc/analyzer/engines_runner"
11
- autoload :Filesystem, "cc/analyzer/filesystem"
12
- autoload :Formatters, "cc/analyzer/formatters"
13
- autoload :IssueSorter, "cc/analyzer/issue_sorter"
14
- autoload :LocationDescription,"cc/analyzer/location_description"
15
- autoload :NullConfig, "cc/analyzer/null_config"
16
- autoload :NullContainerLog, "cc/analyzer/null_container_log"
17
- autoload :PathPatterns, "cc/analyzer/path_patterns"
18
- autoload :SourceBuffer, "cc/analyzer/source_buffer"
19
- autoload :UnitName, "cc/analyzer/unit_name"
9
+ autoload :EngineRegistry, "cc/analyzer/engine_registry"
10
+ autoload :EnginesRunner, "cc/analyzer/engines_runner"
11
+ autoload :Filesystem, "cc/analyzer/filesystem"
12
+ autoload :Formatters, "cc/analyzer/formatters"
13
+ autoload :IssueSorter, "cc/analyzer/issue_sorter"
14
+ autoload :LocationDescription, "cc/analyzer/location_description"
15
+ autoload :LoggingContainerListener, "cc/analyzer/logging_container_listener"
16
+ autoload :PathPatterns, "cc/analyzer/path_patterns"
17
+ autoload :RaisingContainerListener, "cc/analyzer/raising_container_listener"
18
+ autoload :SourceBuffer, "cc/analyzer/source_buffer"
19
+ autoload :StatsdContainerListener, "cc/analyzer/statsd_container_listener"
20
20
 
21
21
  class DummyStatsd
22
22
  def method_missing(*)
@@ -0,0 +1,25 @@
1
+ module CC
2
+ module Analyzer
3
+ class CompositeContainerListener < ContainerListener
4
+ def initialize(*listeners)
5
+ @listeners = listeners
6
+ end
7
+
8
+ def started(data)
9
+ listeners.each { |listener| listener.started(data) }
10
+ end
11
+
12
+ def timed_out(data)
13
+ listeners.each { |listener| listener.timed_out(data) }
14
+ end
15
+
16
+ def finished(data)
17
+ listeners.each { |listener| listener.finished(data) }
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :listeners
23
+ end
24
+ end
25
+ end
@@ -3,19 +3,27 @@ require "posix/spawn"
3
3
  module CC
4
4
  module Analyzer
5
5
  class Container
6
+ ContainerData = Struct.new(
7
+ :image, # image used to create the container
8
+ :name, # name given to the container when created
9
+ :duration, # duration, for a finished event
10
+ :status, # status, for a finished event
11
+ :stderr, # stderr, for a finished event
12
+ )
13
+
6
14
  DEFAULT_TIMEOUT = 15 * 60 # 15m
7
15
 
8
16
  def initialize(
9
17
  image:,
10
18
  name:,
11
19
  command: nil,
12
- log: NullContainerLog.new,
20
+ listener: ContainerListener.new,
13
21
  timeout: DEFAULT_TIMEOUT
14
22
  )
15
23
  @image = image
16
24
  @name = name
17
25
  @command = command
18
- @log = log
26
+ @listener = listener
19
27
  @timeout = timeout
20
28
 
21
29
  @output_delimeter = "\n"
@@ -31,7 +39,8 @@ module CC
31
39
  end
32
40
 
33
41
  def run(options = [])
34
- @log.started(@image, @name)
42
+ started = Time.now
43
+ @listener.started(container_data)
35
44
 
36
45
  pid, _, out, err = POSIX::Spawn.popen4(*docker_run_command(options))
37
46
 
@@ -41,14 +50,15 @@ module CC
41
50
 
42
51
  _, status = Process.waitpid2(pid)
43
52
 
44
- @log.finished(@image, @name, status, @stderr_io.string)
53
+ duration = ((Time.now - started) * 1000).round
54
+ @listener.finished(container_data(duration: duration, status: status))
45
55
 
46
56
  t_timeout.kill
47
57
  ensure
48
58
  t_timeout.kill if t_timeout
49
59
 
50
60
  if @timed_out
51
- @log.timed_out(@image, @name, @timeout)
61
+ @listener.timed_out(container_data(duration: @timeout))
52
62
  t_out.kill if t_out
53
63
  t_err.kill if t_err
54
64
  else
@@ -93,6 +103,16 @@ module CC
93
103
  Process.kill("KILL", pid)
94
104
  end
95
105
  end
106
+
107
+ def container_data(duration: nil, status: nil)
108
+ ContainerData.new(
109
+ @image,
110
+ @name,
111
+ duration,
112
+ status,
113
+ @stderr_io.string
114
+ )
115
+ end
96
116
  end
97
117
  end
98
118
  end
@@ -0,0 +1,14 @@
1
+ module CC
2
+ module Analyzer
3
+ class ContainerListener
4
+ def started(_data)
5
+ end
6
+
7
+ def timed_out(_data)
8
+ end
9
+
10
+ def finished(_data)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -3,7 +3,8 @@ require "securerandom"
3
3
  module CC
4
4
  module Analyzer
5
5
  class Engine
6
- autoload :ContainerLog, "cc/analyzer/engine/container_log"
6
+ EngineFailure = Class.new(StandardError)
7
+ EngineTimeout = Class.new(StandardError)
7
8
 
8
9
  attr_reader :name
9
10
 
@@ -15,12 +16,19 @@ module CC
15
16
  @label = label.to_s
16
17
  end
17
18
 
18
- def run(stdout_io:, container_log: NullContainerLog.new)
19
+ def run(stdout_io, container_listener)
20
+ composite_listener = CompositeContainerListener.new(
21
+ container_listener,
22
+ LoggingContainerListener.new(name, Analyzer.logger),
23
+ StatsdContainerListener.new(name, Analyzer.statsd),
24
+ RaisingContainerListener.new(name, EngineFailure, EngineTimeout),
25
+ )
26
+
19
27
  container = Container.new(
20
28
  image: @metadata["image"],
21
29
  command: @metadata["command"],
22
30
  name: container_name,
23
- log: ContainerLog.new(name, container_log)
31
+ listener: composite_listener,
24
32
  )
25
33
 
26
34
  container.on_output("\0") do |output|
@@ -14,14 +14,12 @@ module CC
14
14
  @container_label = container_label
15
15
  end
16
16
 
17
- def run(container_log = NullContainerLog.new)
17
+ def run(container_listener = ContainerListener.new)
18
18
  raise NoEnabledEngines if engines.empty?
19
19
 
20
- Analyzer.logger.info("running #{engines.size} engines")
21
-
22
20
  @formatter.started
23
21
 
24
- engines.each { |engine| run_engine(engine, container_log) }
22
+ engines.each { |engine| run_engine(engine, container_listener) }
25
23
 
26
24
  @formatter.finished
27
25
  ensure
@@ -30,21 +28,10 @@ module CC
30
28
 
31
29
  private
32
30
 
33
- def run_engine(engine, container_log)
34
- Analyzer.logger.info("starting engine #{engine.name}")
35
-
36
- Analyzer.statsd.time("engines.time") do
37
- Analyzer.statsd.time("engines.names.#{engine.name}.time") do
38
- @formatter.engine_running(engine) do
39
- engine.run(
40
- stdout_io: @formatter,
41
- container_log: container_log
42
- )
43
- end
44
- end
31
+ def run_engine(engine, container_listener)
32
+ @formatter.engine_running(engine) do
33
+ engine.run(@formatter, container_listener)
45
34
  end
46
-
47
- Analyzer.logger.info("finished engine #{engine.name}")
48
35
  end
49
36
 
50
37
  def engines
@@ -0,0 +1,22 @@
1
+ module CC
2
+ module Analyzer
3
+ class LoggingContainerListener < ContainerListener
4
+ def initialize(engine_name, logger)
5
+ @engine_name = engine_name
6
+ @logger = logger
7
+ end
8
+
9
+ def started(_data)
10
+ logger.info("starting engine #{engine_name}")
11
+ end
12
+
13
+ def finished(_data)
14
+ logger.info("finished engine #{engine_name}")
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :engine_name, :logger
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ module CC
2
+ module Analyzer
3
+ class RaisingContainerListener < ContainerListener
4
+ def initialize(engine_name, failure_ex, timeout_ex)
5
+ @engine_name = engine_name
6
+ @failure_ex = failure_ex
7
+ @timeout_ex = timeout_ex
8
+ end
9
+
10
+ def timed_out(data)
11
+ message = "engine #{engine_name} ran for #{data.duration} seconds"
12
+ message << " and was killed"
13
+
14
+ raise timeout_ex, message
15
+ end
16
+
17
+ def finished(data)
18
+ unless data.status.success?
19
+ message = "engine #{engine_name} failed"
20
+ message << " with status #{data.status.exitstatus}"
21
+ message << " and stderr \n#{data.stderr}"
22
+
23
+ raise failure_ex, message
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :engine_name, :failure_ex, :timeout_ex
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module CC
2
+ module Analyzer
3
+ class StatsdContainerListener < ContainerListener
4
+ def initialize(engine_name, statsd)
5
+ @engine_name = engine_name
6
+ @statsd = statsd
7
+ end
8
+
9
+ def started(_data)
10
+ increment("started")
11
+ end
12
+
13
+ def timed_out(data)
14
+ timing("time", data.duration)
15
+ increment("result.error")
16
+ increment("result.error.timeout")
17
+ end
18
+
19
+ def finished(data)
20
+ timing("time", data.duration)
21
+ increment("finished")
22
+
23
+ if data.status.success?
24
+ increment("result.success")
25
+ else
26
+ increment("result.error")
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :engine_name, :statsd
33
+
34
+ def increment(metric)
35
+ statsd.increment("engines.#{metric}")
36
+ statsd.increment("engines.names.#{engine_name}.#{metric}")
37
+ end
38
+
39
+ def timing(metric, ms)
40
+ statsd.timing("engines.#{metric}", ms)
41
+ statsd.timing("engines.names.#{engine_name}.#{metric}", ms)
42
+ end
43
+ end
44
+ end
45
+ 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.2.9
4
+ version: 0.2.11
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-08-14 00:00:00.000000000 Z
11
+ date: 2015-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -188,12 +188,14 @@ extra_rdoc_files: []
188
188
  files:
189
189
  - bin/check
190
190
  - bin/codeclimate
191
+ - bin/release
191
192
  - config/engines.yml
192
193
  - lib/cc/analyzer.rb
194
+ - lib/cc/analyzer/composite_container_listener.rb
193
195
  - lib/cc/analyzer/config.rb
194
196
  - lib/cc/analyzer/container.rb
197
+ - lib/cc/analyzer/container_listener.rb
195
198
  - lib/cc/analyzer/engine.rb
196
- - lib/cc/analyzer/engine/container_log.rb
197
199
  - lib/cc/analyzer/engine_output_filter.rb
198
200
  - lib/cc/analyzer/engine_registry.rb
199
201
  - lib/cc/analyzer/engines_runner.rb
@@ -205,11 +207,11 @@ files:
205
207
  - lib/cc/analyzer/formatters/spinner.rb
206
208
  - lib/cc/analyzer/issue_sorter.rb
207
209
  - lib/cc/analyzer/location_description.rb
208
- - lib/cc/analyzer/null_config.rb
209
- - lib/cc/analyzer/null_container_log.rb
210
+ - lib/cc/analyzer/logging_container_listener.rb
210
211
  - lib/cc/analyzer/path_patterns.rb
212
+ - lib/cc/analyzer/raising_container_listener.rb
211
213
  - lib/cc/analyzer/source_buffer.rb
212
- - lib/cc/analyzer/unit_name.rb
214
+ - lib/cc/analyzer/statsd_container_listener.rb
213
215
  - lib/cc/cli.rb
214
216
  - lib/cc/cli/analyze.rb
215
217
  - lib/cc/cli/command.rb
@@ -1,48 +0,0 @@
1
- module CC
2
- module Analyzer
3
- class Engine
4
- EngineFailure = Class.new(StandardError)
5
- EngineTimeout = Class.new(StandardError)
6
-
7
- class ContainerLog
8
- def initialize(name, inner_log)
9
- @name = name
10
- @inner_log = inner_log
11
- end
12
-
13
- def started(image, name)
14
- @inner_log.started(image, name)
15
-
16
- Analyzer.statsd.increment("cli.engines.started")
17
- end
18
-
19
- def timed_out(image, name, timeout)
20
- @inner_log.timed_out(image, name, timeout)
21
-
22
- Analyzer.statsd.increment("cli.engines.result.error")
23
- Analyzer.statsd.increment("cli.engines.result.error.timeout")
24
- Analyzer.statsd.increment("cli.engines.names.#{@name}.result.error")
25
- Analyzer.statsd.increment("cli.engines.names.#{@name}.result.error.timeout")
26
-
27
- raise EngineTimeout, "engine #{@name} ran past #{timeout} seconds and was killed"
28
- end
29
-
30
- def finished(image, name, status, stderr)
31
- @inner_log.finished(image, name, status, stderr)
32
-
33
- Analyzer.statsd.increment("cli.engines.finished")
34
-
35
- if status.success?
36
- Analyzer.statsd.increment("cli.engines.result.success")
37
- Analyzer.statsd.increment("cli.engines.names.#{@name}.result.success")
38
- else
39
- Analyzer.statsd.increment("cli.engines.result.error")
40
- Analyzer.statsd.increment("cli.engines.names.#{@name}.result.error")
41
-
42
- raise EngineFailure, "engine #{@name} failed with status #{status.exitstatus} and stderr \n#{stderr}"
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,9 +0,0 @@
1
- module CC
2
- module Analyzer
3
- class NullConfig < Config
4
- def initialize(*)
5
- @config = { "engines" => {} }
6
- end
7
- end
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- module CC
2
- module Analyzer
3
- class NullContainerLog
4
- def started(_image, _name)
5
- end
6
-
7
- def timed_out(_image, _name, _seconds)
8
- end
9
-
10
- def finished(_image, _name, _status, _stderr)
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module CC
2
- module Analyzer
3
- class UnitName
4
- attr_reader :full_name
5
- attr_reader :local_name
6
-
7
- def initialize(full_name, local_name)
8
- @full_name = full_name
9
- @local_name = local_name
10
- end
11
-
12
- end
13
- end
14
- end