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 +4 -4
- data/bin/check +1 -1
- data/bin/release +41 -0
- data/lib/cc/analyzer.rb +16 -16
- data/lib/cc/analyzer/composite_container_listener.rb +25 -0
- data/lib/cc/analyzer/container.rb +25 -5
- data/lib/cc/analyzer/container_listener.rb +14 -0
- data/lib/cc/analyzer/engine.rb +11 -3
- data/lib/cc/analyzer/engines_runner.rb +5 -18
- data/lib/cc/analyzer/logging_container_listener.rb +22 -0
- data/lib/cc/analyzer/raising_container_listener.rb +32 -0
- data/lib/cc/analyzer/statsd_container_listener.rb +45 -0
- metadata +8 -6
- data/lib/cc/analyzer/engine/container_log.rb +0 -48
- data/lib/cc/analyzer/null_config.rb +0 -9
- data/lib/cc/analyzer/null_container_log.rb +0 -14
- data/lib/cc/analyzer/unit_name.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32566ddd677d0f2659e3a463d78a2a41e78eee0e
|
4
|
+
data.tar.gz: 650ce0df21367faa2b8f94362a01ed46c9057620
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 -
|
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
|
data/bin/release
ADDED
@@ -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"
|
data/lib/cc/analyzer.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
module CC
|
2
2
|
module Analyzer
|
3
|
-
autoload :
|
4
|
-
autoload :Config,
|
5
|
-
autoload :Container,
|
6
|
-
autoload :
|
7
|
-
autoload :
|
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,
|
10
|
-
autoload :EnginesRunner,
|
11
|
-
autoload :Filesystem,
|
12
|
-
autoload :Formatters,
|
13
|
-
autoload :IssueSorter,
|
14
|
-
autoload :LocationDescription,"cc/analyzer/location_description"
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :SourceBuffer,
|
19
|
-
autoload :
|
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
|
-
|
20
|
+
listener: ContainerListener.new,
|
13
21
|
timeout: DEFAULT_TIMEOUT
|
14
22
|
)
|
15
23
|
@image = image
|
16
24
|
@name = name
|
17
25
|
@command = command
|
18
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
data/lib/cc/analyzer/engine.rb
CHANGED
@@ -3,7 +3,8 @@ require "securerandom"
|
|
3
3
|
module CC
|
4
4
|
module Analyzer
|
5
5
|
class Engine
|
6
|
-
|
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
|
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
|
-
|
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(
|
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,
|
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,
|
34
|
-
|
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.
|
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-
|
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/
|
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/
|
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
|