codemonitor 0.3.3 → 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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +36 -1
- data/README.md +128 -3
- data/codemonitor.gemspec +1 -0
- data/engines/custom/extractor.rb +35 -0
- data/engines/debug/extractor.rb +2 -4
- data/engines/eslint/extractor.rb +4 -8
- data/engines/git/extractor.rb +4 -6
- data/engines/github/extractor.rb +72 -0
- data/engines/npm/extractor.rb +2 -4
- data/engines/packwerk/extractor.rb +2 -4
- data/engines/rubocop/extractor.rb +4 -7
- data/engines/scc/extractor.rb +59 -0
- data/engines/semgrep/extractor.rb +4 -7
- data/engines/sorbet/extractor.rb +2 -5
- data/exe/codemonitor +9 -1
- data/lib/codemonitor/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67bdedaed6063ea891d58825204d5dd31d60498325ee9b4b217d5981947282d7
|
4
|
+
data.tar.gz: 2cdf8289ed5be0af4dfbd1acbb0d7d6d77964b81427ae22edf3f4aff1b081d19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fc80f0a516df374fa081ead8d3de1d3a9a58cd320b36ad867e106aa13c123fb9aed0bafa07f9958df4ce1a3a7c78c6451c49cd56fe9dcb225e1635eb61c5c86
|
7
|
+
data.tar.gz: 6bc644578c63a242697bea5d17949c610e2ca1b3d1ccda0fcf62999cd3dd77f6d15b44f4dc1dce0cbcd07620dde3bf49e3032f390bb47b91031291017f04b19b
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,25 +1,56 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
codemonitor (0.
|
4
|
+
codemonitor (0.4.0)
|
5
5
|
dogapi (~> 1.45)
|
6
|
+
octokit (~> 4.0)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
addressable (2.8.0)
|
12
|
+
public_suffix (>= 2.0.2, < 5.0)
|
10
13
|
ast (2.4.2)
|
11
14
|
coderay (1.1.3)
|
12
15
|
diff-lcs (1.3)
|
13
16
|
dogapi (1.45.0)
|
14
17
|
multi_json
|
18
|
+
faraday (1.9.3)
|
19
|
+
faraday-em_http (~> 1.0)
|
20
|
+
faraday-em_synchrony (~> 1.0)
|
21
|
+
faraday-excon (~> 1.1)
|
22
|
+
faraday-httpclient (~> 1.0)
|
23
|
+
faraday-multipart (~> 1.0)
|
24
|
+
faraday-net_http (~> 1.0)
|
25
|
+
faraday-net_http_persistent (~> 1.0)
|
26
|
+
faraday-patron (~> 1.0)
|
27
|
+
faraday-rack (~> 1.0)
|
28
|
+
faraday-retry (~> 1.0)
|
29
|
+
ruby2_keywords (>= 0.0.4)
|
30
|
+
faraday-em_http (1.0.0)
|
31
|
+
faraday-em_synchrony (1.0.0)
|
32
|
+
faraday-excon (1.1.0)
|
33
|
+
faraday-httpclient (1.0.1)
|
34
|
+
faraday-multipart (1.0.3)
|
35
|
+
multipart-post (>= 1.2, < 3)
|
36
|
+
faraday-net_http (1.0.1)
|
37
|
+
faraday-net_http_persistent (1.2.0)
|
38
|
+
faraday-patron (1.0.0)
|
39
|
+
faraday-rack (1.0.0)
|
40
|
+
faraday-retry (1.0.3)
|
15
41
|
method_source (1.0.0)
|
16
42
|
multi_json (1.15.0)
|
43
|
+
multipart-post (2.1.1)
|
44
|
+
octokit (4.22.0)
|
45
|
+
faraday (>= 0.9)
|
46
|
+
sawyer (~> 0.8.0, >= 0.5.3)
|
17
47
|
parallel (1.20.1)
|
18
48
|
parser (3.0.1.1)
|
19
49
|
ast (~> 2.4.1)
|
20
50
|
pry (0.13.1)
|
21
51
|
coderay (~> 1.1)
|
22
52
|
method_source (~> 1.0)
|
53
|
+
public_suffix (4.0.6)
|
23
54
|
rainbow (3.0.0)
|
24
55
|
rake (13.0.3)
|
25
56
|
regexp_parser (2.1.1)
|
@@ -49,6 +80,10 @@ GEM
|
|
49
80
|
rubocop-ast (1.5.0)
|
50
81
|
parser (>= 3.0.1.1)
|
51
82
|
ruby-progressbar (1.11.0)
|
83
|
+
ruby2_keywords (0.0.5)
|
84
|
+
sawyer (0.8.2)
|
85
|
+
addressable (>= 2.3.5)
|
86
|
+
faraday (> 0.8, < 2.0)
|
52
87
|
unicode-display_width (1.7.0)
|
53
88
|
|
54
89
|
PLATFORMS
|
data/README.md
CHANGED
@@ -1,9 +1,134 @@
|
|
1
|
-
# CodeMonitor
|
1
|
+
# 🖥️ CodeMonitor
|
2
2
|
|
3
3
|
A engine to collect multiple metrics from your repository and push them to a
|
4
4
|
time series provider.
|
5
5
|
|
6
6
|
|
7
|
-
#
|
7
|
+
# Engines
|
8
8
|
|
9
|
-
|
9
|
+
## Git
|
10
|
+
|
11
|
+
Collect multiple metrics from the a Git repository.
|
12
|
+
|
13
|
+
**Requirements / Setup**:
|
14
|
+
|
15
|
+
You need a `.git` folder present in the current folder:
|
16
|
+
|
17
|
+
**Options**:
|
18
|
+
|
19
|
+
`CODEMONITOR_GIT_FILES_THRESHOLD`: Don't emit metrics about number of files, from those that are above of this threshold. (Default: `0`)
|
20
|
+
|
21
|
+
## Eslint
|
22
|
+
|
23
|
+
Collect multiple metrics from the a project with [Eslint](https://eslint.org/) configured.
|
24
|
+
|
25
|
+
**Requirements / Setup**:
|
26
|
+
|
27
|
+
You need a `.eslintrc.js` and a `eslint.output.json` file present in the current folder.
|
28
|
+
|
29
|
+
You can generate the `eslint.output.json` file with this example command:
|
30
|
+
|
31
|
+
```
|
32
|
+
eslint -f json -o eslint.output.json
|
33
|
+
```
|
34
|
+
**Options**:
|
35
|
+
|
36
|
+
`CODEMONITOR_ESLINT_THRESHOLD`: Don't emit metrics about eslint rules that are above of this threshold. (Default: `10`)
|
37
|
+
|
38
|
+
|
39
|
+
## Npm
|
40
|
+
|
41
|
+
Collect multiple metrics from the a NodeJS.
|
42
|
+
|
43
|
+
**Requirements / Setup**:
|
44
|
+
|
45
|
+
You need a `package.json` file present in the current folder.
|
46
|
+
|
47
|
+
## Packwerk
|
48
|
+
|
49
|
+
Collect multiple metrics from the a Ruby project with [Packwerk](https://github.com/Shopify/packwerk) configured.
|
50
|
+
|
51
|
+
**Requirements / Setup**:
|
52
|
+
|
53
|
+
You need a `deprecated_references.yml` files present in the current project.
|
54
|
+
|
55
|
+
## Rubocop
|
56
|
+
|
57
|
+
Collect multiple metrics from the a Ruby project with [Rubocop](https://github.com/rubocop/rubocop) configured.
|
58
|
+
|
59
|
+
**Requirements / Setup**:
|
60
|
+
|
61
|
+
You need a `.rubocop.yml` and a `rubocop.output.json` file present in the current folder.
|
62
|
+
|
63
|
+
You can generate the `rubocop.output.json` file with this example command:
|
64
|
+
|
65
|
+
```
|
66
|
+
bundle exec srb tc --metrics-prefix 'codemetrics' --metrics-file sorbet.output.json
|
67
|
+
```
|
68
|
+
|
69
|
+
**Options**:
|
70
|
+
|
71
|
+
`CODEMONITOR_RUBOCOP_THRESHOLD`: Don't emit metrics about rubocop cops that are above of this threshold. (Default: `50`)
|
72
|
+
|
73
|
+
|
74
|
+
## Semgrep
|
75
|
+
|
76
|
+
Collect multiple metrics from the a with [Semgrep](https://semgrep.dev/) configured.
|
77
|
+
|
78
|
+
**Requirements / Setup**:
|
79
|
+
|
80
|
+
You need a `.semgrep.yml` and a `semgrep.output.json` file present in the current folder.
|
81
|
+
|
82
|
+
You can generate the `semgrep.output.json` file with this example command:
|
83
|
+
|
84
|
+
```
|
85
|
+
semgrep --json -o semgrep.output.json
|
86
|
+
```
|
87
|
+
|
88
|
+
**Options**:
|
89
|
+
|
90
|
+
`CODEMONITOR_SEMGREP_THRESHOLD`: Don't emit metrics about rubocop cops that are above of this threshold. (Default: `50`)
|
91
|
+
|
92
|
+
## Sorbet
|
93
|
+
|
94
|
+
Collect multiple metrics from the a with [Sorbet](https://sorbet.org/) configured.
|
95
|
+
|
96
|
+
**Requirements / Setup**:
|
97
|
+
|
98
|
+
You need a `sorbet.output.json` file present in the current folder.
|
99
|
+
|
100
|
+
You can generate the `sorbet.output.json` file with this example command:
|
101
|
+
|
102
|
+
```
|
103
|
+
bundle exec srb tc --metrics-prefix 'codemetrics' --metrics-file sorbet.output.json
|
104
|
+
```
|
105
|
+
|
106
|
+
## SCC
|
107
|
+
|
108
|
+
Collect multiple metrics from [SCC](https://github.com/boyter/scc) configured.
|
109
|
+
|
110
|
+
**Requirements / Setup**:
|
111
|
+
|
112
|
+
You need a `scc.output.json` file present in the current folder.
|
113
|
+
|
114
|
+
You can generate the `scc.output.json` file with this example command:
|
115
|
+
|
116
|
+
```
|
117
|
+
scc -f json scc.output.json
|
118
|
+
```
|
119
|
+
|
120
|
+
# Providers
|
121
|
+
|
122
|
+
## Console
|
123
|
+
|
124
|
+
TODO
|
125
|
+
|
126
|
+
## Datadog
|
127
|
+
|
128
|
+
TODO
|
129
|
+
|
130
|
+
# Contribute
|
131
|
+
|
132
|
+
This project started as a side project, so I'm sure that is full
|
133
|
+
of mistakes and areas to be improve. If you think you can tweak the code to
|
134
|
+
make it better, I'll really appreciate a pull request. ;)
|
data/codemonitor.gemspec
CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.require_paths = ['lib']
|
38
38
|
|
39
39
|
spec.add_runtime_dependency 'dogapi', '~> 1.45'
|
40
|
+
spec.add_runtime_dependency 'octokit', '~> 4.0'
|
40
41
|
|
41
42
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
42
43
|
spec.add_development_dependency 'pry', '~> 0.13.1'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Engines
|
4
|
+
module Custom
|
5
|
+
class Extractor
|
6
|
+
def call(provider)
|
7
|
+
provider.emit(metrics)
|
8
|
+
end
|
9
|
+
|
10
|
+
def requirements?
|
11
|
+
custom_files.length.positive?
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def custom_files
|
17
|
+
Dir.glob('./.codemonitor/*.rb')
|
18
|
+
end
|
19
|
+
|
20
|
+
def metrics
|
21
|
+
custom_files.map do |file|
|
22
|
+
values = begin
|
23
|
+
eval File.read(file)
|
24
|
+
rescue SyntaxError => e
|
25
|
+
raise "Unable to execute the custom codemonitor script `#{file}` file"
|
26
|
+
end
|
27
|
+
|
28
|
+
raise "Malformed return value from `#{file}` file. It must be a hash of metrics" unless values.is_a?(Hash)
|
29
|
+
|
30
|
+
values
|
31
|
+
end.reduce({}, :merge)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/engines/debug/extractor.rb
CHANGED
@@ -8,8 +8,6 @@ module Engines
|
|
8
8
|
].freeze
|
9
9
|
|
10
10
|
def call(provider)
|
11
|
-
return unless requirements?
|
12
|
-
|
13
11
|
metrics = METRICS.map do |metric|
|
14
12
|
[metric, send(metric) || 0]
|
15
13
|
end.to_h
|
@@ -17,12 +15,12 @@ module Engines
|
|
17
15
|
provider.emit(metrics)
|
18
16
|
end
|
19
17
|
|
20
|
-
private
|
21
|
-
|
22
18
|
def requirements?
|
23
19
|
true
|
24
20
|
end
|
25
21
|
|
22
|
+
private
|
23
|
+
|
26
24
|
def debug_random
|
27
25
|
rand(0..100)
|
28
26
|
end
|
data/engines/eslint/extractor.rb
CHANGED
@@ -16,8 +16,6 @@ module Engines
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def call(provider)
|
19
|
-
return unless requirements?
|
20
|
-
|
21
19
|
metrics = METRICS.map do |metric|
|
22
20
|
[metric, send(metric)]
|
23
21
|
end.to_h
|
@@ -29,16 +27,14 @@ module Engines
|
|
29
27
|
provider.emit(metrics)
|
30
28
|
end
|
31
29
|
|
30
|
+
def requirements?
|
31
|
+
File.exist?('eslint.output.json')
|
32
|
+
end
|
33
|
+
|
32
34
|
private
|
33
35
|
|
34
36
|
attr_reader :threshold
|
35
37
|
|
36
|
-
def requirements?
|
37
|
-
# FIXME: Review if this is the only check we can do or there are more.
|
38
|
-
File.exist?('.eslintrc.js')
|
39
|
-
end
|
40
|
-
|
41
|
-
# NOTE: This output file must be created by an external command
|
42
38
|
def eslint
|
43
39
|
@eslint ||= JSON.parse(File.read('eslint.output.json'))
|
44
40
|
end
|
data/engines/git/extractor.rb
CHANGED
@@ -20,8 +20,6 @@ module Engines
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def call(provider)
|
23
|
-
return unless requirements?
|
24
|
-
|
25
23
|
metrics = METRICS.map do |metric|
|
26
24
|
[metric, send(metric)]
|
27
25
|
end.to_h
|
@@ -32,14 +30,14 @@ module Engines
|
|
32
30
|
provider.emit(metrics)
|
33
31
|
end
|
34
32
|
|
35
|
-
private
|
36
|
-
|
37
|
-
attr_reader :threshold
|
38
|
-
|
39
33
|
def requirements?
|
40
34
|
File.exist?('.git')
|
41
35
|
end
|
42
36
|
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :threshold
|
40
|
+
|
43
41
|
def git_number_of_commits
|
44
42
|
Shell.run("git log --format='%h'").lines.count
|
45
43
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'octokit'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
Octokit.configure do |c|
|
7
|
+
c.auto_paginate = true
|
8
|
+
end
|
9
|
+
|
10
|
+
module Engines
|
11
|
+
module Github
|
12
|
+
class Extractor
|
13
|
+
METRICS = %i[
|
14
|
+
github_number_of_open_pull_requests
|
15
|
+
github_number_of_lead_time_in_days
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@access_token = ENV['GITHUB_TOKEN']
|
20
|
+
@repository = ENV['GITHUB_REPOSITORY']
|
21
|
+
@since_days = ENV['GITHUB_SINCE_DAYS'] || 30
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(provider)
|
25
|
+
metrics = METRICS.map do |metric|
|
26
|
+
[metric, send(metric)]
|
27
|
+
end.to_h
|
28
|
+
|
29
|
+
provider.emit(metrics)
|
30
|
+
end
|
31
|
+
|
32
|
+
def requirements?
|
33
|
+
!access_token.nil? && !repository.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :access_token, :repository, :since_days
|
39
|
+
|
40
|
+
def github
|
41
|
+
@github ||= Octokit::Client.new(access_token: access_token)
|
42
|
+
end
|
43
|
+
|
44
|
+
def since
|
45
|
+
(Date.today - since_days).to_time.iso8601
|
46
|
+
end
|
47
|
+
|
48
|
+
def github_number_of_open_pull_requests
|
49
|
+
github.issues(repository, state: 'open').length
|
50
|
+
end
|
51
|
+
|
52
|
+
def github_number_of_lead_time_in_days
|
53
|
+
diffs = github
|
54
|
+
.issues(repository, since: since, state: 'closed')
|
55
|
+
.map do |issue|
|
56
|
+
next nil if issue[:pull_request][:merged_at].nil? || issue[:created_at].nil?
|
57
|
+
|
58
|
+
merged_at = Time.at(issue[:pull_request][:merged_at])
|
59
|
+
created_at = Time.at(issue[:created_at])
|
60
|
+
|
61
|
+
merged_at - created_at
|
62
|
+
end.reject do |diff|
|
63
|
+
diff.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
value = (diffs.reduce(:+) / diffs.size.to_f / (24 * 60 * 60))
|
67
|
+
|
68
|
+
value.round(2)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/engines/npm/extractor.rb
CHANGED
@@ -18,8 +18,6 @@ module Engines
|
|
18
18
|
].freeze
|
19
19
|
|
20
20
|
def call(provider)
|
21
|
-
return unless requirements?
|
22
|
-
|
23
21
|
metrics = METRICS.map do |metric|
|
24
22
|
[metric, send(metric) || 0]
|
25
23
|
end.to_h
|
@@ -27,12 +25,12 @@ module Engines
|
|
27
25
|
provider.emit(metrics)
|
28
26
|
end
|
29
27
|
|
30
|
-
private
|
31
|
-
|
32
28
|
def requirements?
|
33
29
|
File.exist?('package.json')
|
34
30
|
end
|
35
31
|
|
32
|
+
private
|
33
|
+
|
36
34
|
def npm_number_of_dependencies
|
37
35
|
npm_package['dependencies'].keys.length
|
38
36
|
end
|
@@ -13,8 +13,6 @@ module Engines
|
|
13
13
|
def initialize; end
|
14
14
|
|
15
15
|
def call(provider)
|
16
|
-
return unless requirements?
|
17
|
-
|
18
16
|
metrics = METRICS.map do |metric|
|
19
17
|
[metric, send(metric)]
|
20
18
|
end.to_h
|
@@ -22,12 +20,12 @@ module Engines
|
|
22
20
|
provider.emit(metrics)
|
23
21
|
end
|
24
22
|
|
25
|
-
private
|
26
|
-
|
27
23
|
def requirements?
|
28
24
|
packwerk_files.length.positive?
|
29
25
|
end
|
30
26
|
|
27
|
+
private
|
28
|
+
|
31
29
|
# NOTE: This output file must be created by an external command
|
32
30
|
def packwerk_files
|
33
31
|
Dir.glob('./**/deprecated_references.yml')
|
@@ -15,8 +15,6 @@ module Engines
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call(provider)
|
18
|
-
return unless requirements?
|
19
|
-
|
20
18
|
metrics = METRICS.map do |metric|
|
21
19
|
[metric, send(metric)]
|
22
20
|
end.to_h
|
@@ -28,15 +26,14 @@ module Engines
|
|
28
26
|
provider.emit(metrics)
|
29
27
|
end
|
30
28
|
|
29
|
+
def requirements?
|
30
|
+
File.exist?('rubocop.output.json')
|
31
|
+
end
|
32
|
+
|
31
33
|
private
|
32
34
|
|
33
35
|
attr_reader :threshold
|
34
36
|
|
35
|
-
def requirements?
|
36
|
-
File.exist?('.rubocop.yml')
|
37
|
-
end
|
38
|
-
|
39
|
-
# NOTE: This output file must be created by an external command
|
40
37
|
def rubocop
|
41
38
|
@rubocop ||= JSON.parse(File.read('rubocop.output.json'))
|
42
39
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Engines
|
6
|
+
module Scc
|
7
|
+
class Extractor
|
8
|
+
METRICS = %i[].freeze
|
9
|
+
FIELDS = %w[Bytes Lines Code Comment Blank Complexity Count WeightedComplexity]
|
10
|
+
|
11
|
+
def initialize; end
|
12
|
+
|
13
|
+
def call(provider)
|
14
|
+
metrics = METRICS.map do |metric|
|
15
|
+
[metric, send(metric)]
|
16
|
+
end.to_h
|
17
|
+
|
18
|
+
metrics
|
19
|
+
.merge!(scc_totals)
|
20
|
+
.merge!(scc_by_file_type)
|
21
|
+
|
22
|
+
provider.emit(metrics)
|
23
|
+
end
|
24
|
+
|
25
|
+
def requirements?
|
26
|
+
File.exist?('scc.output.json')
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def scc
|
32
|
+
@scc ||= JSON.parse(File.read('scc.output.json'))
|
33
|
+
end
|
34
|
+
|
35
|
+
def scc_totals
|
36
|
+
scc.each_with_object({}) do |type, totals|
|
37
|
+
FIELDS.each do |field|
|
38
|
+
key = "scc_total_#{clean(field)}"
|
39
|
+
totals[key] = 0 unless totals.key?(key)
|
40
|
+
|
41
|
+
totals[key] += type[field]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def scc_by_file_type
|
47
|
+
scc.map do |type|
|
48
|
+
FIELDS.map do |field|
|
49
|
+
["scc_type_#{clean(type['Name'])}_#{clean(field)}", type[field]]
|
50
|
+
end.to_h
|
51
|
+
end.inject(&:merge)
|
52
|
+
end
|
53
|
+
|
54
|
+
def clean(key)
|
55
|
+
key.gsub(%r{[-,./ ]}, '_').downcase
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -15,8 +15,6 @@ module Engines
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call(provider)
|
18
|
-
return unless requirements?
|
19
|
-
|
20
18
|
metrics = METRICS.map do |metric|
|
21
19
|
[metric, send(metric)]
|
22
20
|
end.to_h
|
@@ -26,15 +24,14 @@ module Engines
|
|
26
24
|
provider.emit(metrics)
|
27
25
|
end
|
28
26
|
|
27
|
+
def requirements?
|
28
|
+
File.exist?('semgrep.output.json')
|
29
|
+
end
|
30
|
+
|
29
31
|
private
|
30
32
|
|
31
33
|
attr_reader :threshold
|
32
34
|
|
33
|
-
def requirements?
|
34
|
-
File.exist?('.semgrep.yml')
|
35
|
-
end
|
36
|
-
|
37
|
-
# NOTE: This output file must be created by an external command
|
38
35
|
def semgrep
|
39
36
|
@semgrep ||= JSON.parse(File.read('semgrep.output.json'))
|
40
37
|
end
|
data/engines/sorbet/extractor.rb
CHANGED
@@ -24,8 +24,6 @@ module Engines
|
|
24
24
|
def initialize; end
|
25
25
|
|
26
26
|
def call(provider)
|
27
|
-
return unless requirements?
|
28
|
-
|
29
27
|
metrics = METRICS.map do |metric|
|
30
28
|
[metric, send(metric)]
|
31
29
|
end.to_h
|
@@ -33,13 +31,12 @@ module Engines
|
|
33
31
|
provider.emit(metrics)
|
34
32
|
end
|
35
33
|
|
36
|
-
private
|
37
|
-
|
38
34
|
def requirements?
|
39
35
|
File.exist?('sorbet.output.json')
|
40
36
|
end
|
41
37
|
|
42
|
-
|
38
|
+
private
|
39
|
+
|
43
40
|
def sorbet
|
44
41
|
@sorbet ||= JSON.parse(File.read('sorbet.output.json'))
|
45
42
|
end
|
data/exe/codemonitor
CHANGED
@@ -7,11 +7,14 @@ require_relative '../providers/datadog'
|
|
7
7
|
require_relative '../engines/eslint/extractor'
|
8
8
|
require_relative '../engines/debug/extractor'
|
9
9
|
require_relative '../engines/git/extractor'
|
10
|
+
require_relative '../engines/github/extractor'
|
10
11
|
require_relative '../engines/npm/extractor'
|
11
12
|
require_relative '../engines/packwerk/extractor'
|
12
13
|
require_relative '../engines/rubocop/extractor'
|
13
14
|
require_relative '../engines/semgrep/extractor'
|
14
15
|
require_relative '../engines/sorbet/extractor'
|
16
|
+
require_relative '../engines/scc/extractor'
|
17
|
+
require_relative '../engines/custom/extractor'
|
15
18
|
|
16
19
|
PROVIDERS = {
|
17
20
|
console: Providers::Console,
|
@@ -22,11 +25,14 @@ EXTRACTORS = {
|
|
22
25
|
eslint: Engines::Eslint::Extractor,
|
23
26
|
debug: Engines::Debug::Extractor,
|
24
27
|
git: Engines::Git::Extractor,
|
28
|
+
github: Engines::Github::Extractor,
|
25
29
|
npm: Engines::Npm::Extractor,
|
26
30
|
packwerk: Engines::Packwerk::Extractor,
|
27
31
|
rubocop: Engines::Rubocop::Extractor,
|
28
32
|
semgrep: Engines::Semgrep::Extractor,
|
29
|
-
sorbet: Engines::Sorbet::Extractor
|
33
|
+
sorbet: Engines::Sorbet::Extractor,
|
34
|
+
scc: Engines::Scc::Extractor,
|
35
|
+
custom: Engines::Custom::Extractor
|
30
36
|
}.freeze
|
31
37
|
|
32
38
|
config_provider = ENV['CODEMONITOR_PROVIDER'] || 'console'
|
@@ -45,6 +51,8 @@ puts '# process start'
|
|
45
51
|
extractors
|
46
52
|
.map(&:new)
|
47
53
|
.map do |extractor|
|
54
|
+
raise "Requirements not fullfiled in #{extractor.class.name}" unless extractor.requirements?
|
55
|
+
|
48
56
|
extractor.call(provider)
|
49
57
|
end
|
50
58
|
|
data/lib/codemonitor/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codemonitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ferran Basora
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dogapi
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.45'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: octokit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,12 +129,15 @@ files:
|
|
115
129
|
- bin/console
|
116
130
|
- bin/setup
|
117
131
|
- codemonitor.gemspec
|
132
|
+
- engines/custom/extractor.rb
|
118
133
|
- engines/debug/extractor.rb
|
119
134
|
- engines/eslint/extractor.rb
|
120
135
|
- engines/git/extractor.rb
|
136
|
+
- engines/github/extractor.rb
|
121
137
|
- engines/npm/extractor.rb
|
122
138
|
- engines/packwerk/extractor.rb
|
123
139
|
- engines/rubocop/extractor.rb
|
140
|
+
- engines/scc/extractor.rb
|
124
141
|
- engines/semgrep/extractor.rb
|
125
142
|
- engines/sorbet/extractor.rb
|
126
143
|
- exe/codemonitor
|