codeclimate 0.2.9 → 0.2.11

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