code-scanning-rubocop 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop-analysis.yml +34 -0
- data/.github/workflows/ruby.yml +23 -0
- data/.rubocop.yml +48 -0
- data/.rubocop_todo.yml +14 -0
- data/Dockerfile +0 -5
- data/Gemfile +3 -1
- data/Gemfile.lock +19 -16
- data/README.md +65 -17
- data/Rakefile +26 -1
- data/bin/console +2 -1
- data/code-scanning-rubocop.gemspec +9 -8
- data/entrypoint.sh +2 -3
- data/lib/code_scanning/rubocop/rule.rb +126 -0
- data/lib/code_scanning/rubocop/sarif_formatter.rb +46 -65
- data/lib/code_scanning/rubocop/version.rb +3 -1
- data/lib/code_scanning/rules_generator.rb +36 -0
- data/lib/code_scanning.rb +6 -1
- data/preview.png +0 -0
- data/rubocop-action/action.yml +1 -1
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aede2d4f861c011d78db9d9f6df567bdd94322ed40951f3d15613b844e3e48b5
|
4
|
+
data.tar.gz: d2fdb4fc5b34b560c5a9af454def6730d75c4ed80cbfd6865027175df10b393c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f44b470a1e45e04a535fb6becc9ee6348da281405ea14cd96f726894327bec3523ecd627ece9b2426ae409ca13f14d9eaca5110d4bd5b8ba9515d1ad60edd7bd
|
7
|
+
data.tar.gz: 5f790f1cdcfb47d202e7b4afb613450ebe108fa3cc3b301140ee14cf98b63f7b15b2ad694a7be6ec29968569905e4029cdbfea5fe3b7c353b3d7651785998286
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: "RuboCop"
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rubocop_job:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
name: Code Scanning job run
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
|
12
|
+
steps:
|
13
|
+
- name: Checkout repository
|
14
|
+
uses: actions/checkout@v2
|
15
|
+
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 2.6
|
20
|
+
|
21
|
+
- name: Install dependencies
|
22
|
+
run: bundle install
|
23
|
+
|
24
|
+
- name: RuboCop run
|
25
|
+
run: |
|
26
|
+
bash -c "
|
27
|
+
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
28
|
+
[[ $? -ne 2 ]]
|
29
|
+
"
|
30
|
+
|
31
|
+
- name: Upload Sarif output
|
32
|
+
uses: github/codeql-action/upload-sarif@v1
|
33
|
+
with:
|
34
|
+
sarif_file: rubocop.sarif
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- uses: actions/checkout@v2
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 2.6
|
20
|
+
- name: Install dependencies
|
21
|
+
run: bundle install
|
22
|
+
- name: Run tests
|
23
|
+
run: bundle exec rake
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
4
|
+
# configuration file. It makes it possible to enable/disable
|
5
|
+
# certain cops (checks) and to alter their behavior if they accept
|
6
|
+
# any parameters. The file can be placed either in your home
|
7
|
+
# directory or in some project directory.
|
8
|
+
#
|
9
|
+
# RuboCop will start looking for the configuration file in the directory
|
10
|
+
# where the inspected file is and continue its way up to the root directory.
|
11
|
+
#
|
12
|
+
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
|
13
|
+
AllCops:
|
14
|
+
NewCops: enable
|
15
|
+
|
16
|
+
Layout/LineLength:
|
17
|
+
Exclude:
|
18
|
+
- 'code-scanning-rubocop.gemspec'
|
19
|
+
Layout/SpaceAroundMethodCallOperator:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Lint/RaiseException:
|
23
|
+
Enabled: true
|
24
|
+
Lint/StructNewOverride:
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
Style/HashSyntax:
|
28
|
+
EnforcedStyle: ruby19
|
29
|
+
Style/StringLiterals:
|
30
|
+
EnforcedStyle: double_quotes
|
31
|
+
Style/ExponentialNotation:
|
32
|
+
Enabled: true
|
33
|
+
Style/HashEachMethods:
|
34
|
+
Enabled: true
|
35
|
+
Style/HashTransformKeys:
|
36
|
+
Enabled: true
|
37
|
+
Style/HashTransformValues:
|
38
|
+
Enabled: true
|
39
|
+
Style/ClassAndModuleChildren:
|
40
|
+
Exclude:
|
41
|
+
- 'test/**/*'
|
42
|
+
|
43
|
+
Metrics/MethodLength:
|
44
|
+
Enabled: false
|
45
|
+
Metrics/BlockLength:
|
46
|
+
Enabled: false
|
47
|
+
Metrics/AbcSize:
|
48
|
+
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-05-05 14:10:36 -0400 using RuboCop version 0.82.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
Style/Documentation:
|
10
|
+
Exclude:
|
11
|
+
- 'spec/**/*'
|
12
|
+
- 'test/**/*'
|
13
|
+
- 'lib/code_scanning.rb'
|
14
|
+
- 'lib/code_scanning/**/*'
|
data/Dockerfile
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,31 +1,34 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
code-scanning-rubocop (0.
|
5
|
-
rubocop (~>
|
4
|
+
code-scanning-rubocop (0.5.0)
|
5
|
+
rubocop (~> 1.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
ast (2.4.
|
11
|
-
jaro_winkler (1.5.4)
|
10
|
+
ast (2.4.2)
|
12
11
|
minitest (5.14.0)
|
13
|
-
parallel (1.
|
14
|
-
parser (
|
15
|
-
ast (~> 2.4.
|
16
|
-
rainbow (3.
|
12
|
+
parallel (1.21.0)
|
13
|
+
parser (3.1.0.0)
|
14
|
+
ast (~> 2.4.1)
|
15
|
+
rainbow (3.1.1)
|
17
16
|
rake (12.3.3)
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
regexp_parser (2.2.0)
|
18
|
+
rexml (3.2.5)
|
19
|
+
rubocop (1.24.1)
|
21
20
|
parallel (~> 1.10)
|
22
|
-
parser (>=
|
21
|
+
parser (>= 3.0.0.0)
|
23
22
|
rainbow (>= 2.2.2, < 4.0)
|
23
|
+
regexp_parser (>= 1.8, < 3.0)
|
24
24
|
rexml
|
25
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
25
26
|
ruby-progressbar (~> 1.7)
|
26
|
-
unicode-display_width (>= 1.4.0, <
|
27
|
-
|
28
|
-
|
27
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
28
|
+
rubocop-ast (1.15.1)
|
29
|
+
parser (>= 3.0.1.1)
|
30
|
+
ruby-progressbar (1.11.0)
|
31
|
+
unicode-display_width (2.1.0)
|
29
32
|
|
30
33
|
PLATFORMS
|
31
34
|
ruby
|
@@ -36,4 +39,4 @@ DEPENDENCIES
|
|
36
39
|
rake (~> 12.0)
|
37
40
|
|
38
41
|
BUNDLED WITH
|
39
|
-
2.
|
42
|
+
2.3.4
|
data/README.md
CHANGED
@@ -1,34 +1,82 @@
|
|
1
|
-
#
|
1
|
+
# CodeScanning::Rubocop
|
2
2
|
|
3
|
-
|
3
|
+
'code-scanning-rubocop' is a gem to integrate RuboCop and the GitHub's code scanning feature.
|
4
|
+
The repository is composed by two components. The gem which can be installed in any ruby application and a default GitHub action to ease the usage of it.
|
4
5
|
|
5
|
-
|
6
|
+
The rubygem adds a SARIF exporter to the rubocop runner. GitHub's code scanning feature accepts a SARIF file with the 'results' (alerts) generated by the tool.
|
7
|
+
The action, is what will run rubocop with the exporter. Note: you can only run the gem within your application, and have our own action that calls rubocop. See more in the Installation and Usage sections.
|
6
8
|
|
7
|
-
|
9
|
+
This is how it would look in your Security tab:
|
10
|
+
![preview](preview.png)
|
8
11
|
|
9
|
-
|
12
|
+
## Action Installation
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
```
|
14
|
+
The easiest way to install the integration, is this action template bellow. It will install the gem in your app and run it for you within the GitHub's action enviroment. To install the action create a file `.github/workflows/rubocop-analysis.yml` like the following:
|
15
|
+
|
16
|
+
```yaml
|
17
|
+
# .github/workflows/rubocop-analysis.yml
|
18
|
+
name: "RuboCop"
|
14
19
|
|
15
|
-
|
20
|
+
on: [push]
|
16
21
|
|
17
|
-
|
22
|
+
jobs:
|
23
|
+
rubocop:
|
24
|
+
runs-on: ubuntu-latest
|
25
|
+
strategy:
|
26
|
+
fail-fast: false
|
18
27
|
|
19
|
-
|
28
|
+
steps:
|
29
|
+
- name: Checkout repository
|
30
|
+
uses: actions/checkout@v2
|
20
31
|
|
21
|
-
|
32
|
+
- name: Set up Ruby
|
33
|
+
uses: ruby/setup-ruby@v1
|
34
|
+
with:
|
35
|
+
ruby-version: 2.6
|
22
36
|
|
23
|
-
|
37
|
+
# This step is not necessary if you add the gem to your Gemfile
|
38
|
+
- name: Install Code Scanning integration
|
39
|
+
run: bundle add code-scanning-rubocop --skip-install
|
40
|
+
|
41
|
+
- name: Install dependencies
|
42
|
+
run: bundle install
|
43
|
+
|
44
|
+
- name: RuboCop run
|
45
|
+
run: |
|
46
|
+
bash -c "
|
47
|
+
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
48
|
+
[[ $? -ne 2 ]]
|
49
|
+
"
|
50
|
+
|
51
|
+
- name: Upload Sarif output
|
52
|
+
uses: github/codeql-action/upload-sarif@v1
|
53
|
+
with:
|
54
|
+
sarif_file: rubocop.sarif
|
55
|
+
```
|
24
56
|
|
25
|
-
|
57
|
+
## Gem installation & usage in a custom action
|
58
|
+
Note: this is not necessary if you use the action above.
|
26
59
|
|
27
|
-
|
60
|
+
To install the gem add this line to your application's Gemfile:
|
28
61
|
|
29
|
-
|
62
|
+
```ruby
|
63
|
+
gem 'code-scanning-rubocop'
|
64
|
+
```
|
65
|
+
|
66
|
+
Then, in your custom GitHub's action, you need to run rubocop and make sure you give it the SarifFormatter:
|
67
|
+
```bash
|
68
|
+
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
69
|
+
```
|
70
|
+
|
71
|
+
As a last step, make sure you upload the `rubocop.sarif` file to the code-scan integration. That will create the Code Scanning alerts.
|
72
|
+
Thus, add this step to your custom rubocop workflow:
|
73
|
+
```yaml
|
74
|
+
- name: Upload Sarif output
|
75
|
+
uses: github/codeql-action/upload-sarif@v1
|
76
|
+
with:
|
77
|
+
sarif_file: rubocop.sarif
|
78
|
+
```
|
30
79
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
80
|
|
33
81
|
## Contributing
|
34
82
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler/gem_tasks"
|
2
4
|
require "rake/testtask"
|
3
5
|
|
@@ -7,4 +9,27 @@ Rake::TestTask.new(:test) do |t|
|
|
7
9
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
10
|
end
|
9
11
|
|
10
|
-
task :
|
12
|
+
task :generate_rules do
|
13
|
+
require_relative "lib/code_scanning/rules_generator"
|
14
|
+
|
15
|
+
begin
|
16
|
+
output_file = "#{Time.now.strftime('%Y%m%d')}.sarif"
|
17
|
+
puts "Cloning rubocop repository to read manuals"
|
18
|
+
puts
|
19
|
+
|
20
|
+
sh "git clone git@github.com:rubocop-hq/rubocop.git _tmp"
|
21
|
+
|
22
|
+
gen = QHelpGenerator.new
|
23
|
+
Dir["_tmp/manual/cops_*.md"].each do |f|
|
24
|
+
gen.parse_file(f)
|
25
|
+
end
|
26
|
+
puts
|
27
|
+
puts "Writing rules help sarif to '#{output_file}' file"
|
28
|
+
puts
|
29
|
+
File.write(output_file, gen.sarif_json)
|
30
|
+
ensure
|
31
|
+
sh "rm -rf _tmp"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
task default: :test
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require "bundler/setup"
|
4
|
-
require "
|
5
|
+
require "code_scanning"
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
|
4
|
-
require_relative
|
6
|
+
require_relative "lib/code_scanning/rubocop/version"
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
9
|
spec.name = "code-scanning-rubocop"
|
@@ -9,25 +11,24 @@ Gem::Specification.new do |spec|
|
|
9
11
|
spec.authors = ["Arthur Neves"]
|
10
12
|
spec.email = ["arthurnn@gmail.com"]
|
11
13
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
+
spec.summary = "Extra formater to make rubocop compatible with GitHub's code-scanning feature."
|
15
|
+
spec.description = "This gem adds a SARIF formatter to rubocop, so we can export alerts to code-scanning inside GitHub."
|
14
16
|
spec.homepage = "https://github.com/arthurnn/code-scanning-rubocop"
|
15
17
|
spec.license = "MIT"
|
16
18
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
17
19
|
|
18
|
-
|
19
20
|
spec.metadata["homepage_uri"] = spec.homepage
|
20
21
|
spec.metadata["source_code_uri"] = "https://github.com/arthurnn/code-scanning-rubocop"
|
21
|
-
#spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
22
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
22
23
|
|
23
24
|
# Specify which files should be added to the gem when it is released.
|
24
25
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
-
spec.files
|
26
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
27
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
28
|
end
|
28
29
|
spec.bindir = "exe"
|
29
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
31
|
spec.require_paths = ["lib"]
|
31
32
|
|
32
|
-
spec.add_dependency
|
33
|
+
spec.add_dependency "rubocop", "~> 1.0"
|
33
34
|
end
|
data/entrypoint.sh
CHANGED
@@ -7,10 +7,9 @@ cd $GITHUB_WORKSPACE
|
|
7
7
|
# Install correct bundler version
|
8
8
|
gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)"
|
9
9
|
|
10
|
-
bundle install
|
11
|
-
|
12
|
-
bundle inject code-scanning-rubocop "$(gem list | grep code-scanning-rubocop | tr -cd '0-9.')"
|
10
|
+
bundle add code-scanning-rubocop --version 0.2.0 --skip-install
|
13
11
|
|
12
|
+
bundle install
|
14
13
|
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
15
14
|
|
16
15
|
if [ ! -f rubocop.sarif ]; then
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module CodeScanning
|
6
|
+
class Rule
|
7
|
+
def initialize(cop_name, severity = nil)
|
8
|
+
@cop_name = cop_name
|
9
|
+
@severity = severity.to_s
|
10
|
+
@cop = RuboCop::Cop::Cop.registry.find_by_cop_name(cop_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@cop_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def help(format)
|
18
|
+
case format
|
19
|
+
when :text
|
20
|
+
"More info: #{help_uri}"
|
21
|
+
when :markdown
|
22
|
+
"[More info](#{help_uri})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other)
|
27
|
+
badge.match?(other.badge)
|
28
|
+
end
|
29
|
+
alias eql? ==
|
30
|
+
|
31
|
+
def badge
|
32
|
+
@cop.badge
|
33
|
+
end
|
34
|
+
|
35
|
+
def sarif_severity
|
36
|
+
cop_severity = @cop.new.send(:find_severity, nil, @severity)
|
37
|
+
return cop_severity if %w[warning error].include?(cop_severity)
|
38
|
+
return "note" if %w[refactor convention].include?(cop_severity)
|
39
|
+
return "error" if cop_severity == "fatal"
|
40
|
+
|
41
|
+
"none"
|
42
|
+
end
|
43
|
+
|
44
|
+
def help_uri
|
45
|
+
return @cop.documentation_url if @cop.documentation_url
|
46
|
+
return nil unless department_uri
|
47
|
+
|
48
|
+
anchor = "#{badge.department}#{badge.cop_name}".downcase.tr("/", "")
|
49
|
+
"#{department_uri}##{anchor}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def department_uri
|
53
|
+
case badge.department
|
54
|
+
when :Performance
|
55
|
+
"https://docs.rubocop.org/rubocop-performance/index.html"
|
56
|
+
when :Packaging
|
57
|
+
"https://docs.rubocop.org/rubocop-packaging/cops_packaging.html"
|
58
|
+
when :Rails
|
59
|
+
"https://docs.rubocop.org/rubocop-rails/cops_rails.html"
|
60
|
+
when :Minitest
|
61
|
+
"https://docs.rubocop.org/rubocop-minitest/cops_minitest.html"
|
62
|
+
when :RSpec
|
63
|
+
"https://docs.rubocop.org/rubocop-rspec/cops_rspec.html"
|
64
|
+
when :"RSpec/Rails"
|
65
|
+
"https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html"
|
66
|
+
when :"RSpec/Capybara"
|
67
|
+
"https://docs.rubocop.org/rubocop-rspec/cops_rspec_capybara.html"
|
68
|
+
when :"RSpec/FactoryBot"
|
69
|
+
"https://docs.rubocop.org/rubocop-rspec/cops_rspec_factorybot.html"
|
70
|
+
else
|
71
|
+
STDERR.puts "WARNING: Unknown docs URI for department #{badge.department}"
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_json(opts = {})
|
77
|
+
to_h.to_json(opts)
|
78
|
+
end
|
79
|
+
|
80
|
+
def cop_config
|
81
|
+
@config ||= RuboCop::ConfigStore.new.for(Pathname.new(Dir.pwd))
|
82
|
+
@cop_config ||= @config.for_cop(@cop.department.to_s)
|
83
|
+
.merge(@config.for_cop(@cop))
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_h
|
87
|
+
properties = {
|
88
|
+
"precision" => "very-high"
|
89
|
+
}
|
90
|
+
|
91
|
+
h = {
|
92
|
+
"id" => @cop_name,
|
93
|
+
"name" => @cop_name.tr("/", "").gsub("RSpec", "Rspec"),
|
94
|
+
"defaultConfiguration" => {
|
95
|
+
"level" => sarif_severity
|
96
|
+
},
|
97
|
+
"properties" => properties
|
98
|
+
}
|
99
|
+
|
100
|
+
desc = cop_config["Description"]
|
101
|
+
unless desc.nil?
|
102
|
+
h["shortDescription"] = { "text" => desc }
|
103
|
+
h["fullDescription"] = { "text" => desc }
|
104
|
+
properties["description"] = desc
|
105
|
+
end
|
106
|
+
|
107
|
+
if badge.qualified?
|
108
|
+
kind = badge.department.to_s
|
109
|
+
properties["tags"] = [kind.downcase]
|
110
|
+
end
|
111
|
+
|
112
|
+
if help_uri
|
113
|
+
h.merge!(
|
114
|
+
"queryURI" => help_uri,
|
115
|
+
"helpUri" => help_uri,
|
116
|
+
"help" => {
|
117
|
+
"text" => help(:text),
|
118
|
+
"markdown" => help(:markdown)
|
119
|
+
}
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
h
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -1,100 +1,81 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'rubocop/formatter/base_formatter'
|
3
|
-
require 'json'
|
4
|
-
require 'pathname'
|
5
2
|
|
6
|
-
|
3
|
+
require "json"
|
4
|
+
require_relative "rule"
|
7
5
|
|
6
|
+
module CodeScanning
|
8
7
|
class SarifFormatter < RuboCop::Formatter::BaseFormatter
|
9
8
|
def initialize(output, options = {})
|
10
9
|
super
|
11
|
-
@sarif = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@sarif['$schema'] = 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json'
|
16
|
-
@sarif['version'] = '2.1.0'
|
10
|
+
@sarif = {
|
11
|
+
"$schema" => "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
12
|
+
"version" => "2.1.0"
|
13
|
+
}
|
17
14
|
@rules_map = {}
|
18
|
-
@results = []
|
19
15
|
@rules = []
|
20
|
-
@
|
21
|
-
|
22
|
-
|
16
|
+
@results = []
|
17
|
+
@sarif["runs"] = [
|
18
|
+
{
|
19
|
+
"tool" => {
|
20
|
+
"driver" => {
|
21
|
+
"name" => "RuboCop",
|
22
|
+
"version" => RuboCop::Version.version,
|
23
|
+
"informationUri" => "https://rubocop.org",
|
24
|
+
"rules" => @rules
|
25
|
+
}
|
23
26
|
},
|
24
|
-
|
27
|
+
"results" => @results
|
28
|
+
}
|
25
29
|
]
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
def get_rule(cop_name, severity)
|
33
|
+
r = @rules_map[cop_name]
|
34
|
+
if r.nil?
|
35
|
+
rule = Rule.new(cop_name, severity&.name)
|
36
|
+
r = @rules_map[cop_name] = [rule, @rules.size]
|
37
|
+
@rules << rule
|
33
38
|
end
|
34
39
|
|
35
|
-
|
36
|
-
h = {
|
37
|
-
'id' => cop_name, 'name' => cop_name,
|
38
|
-
'shortDescription' => {
|
39
|
-
'text' => desc
|
40
|
-
},
|
41
|
-
'fullDescription' => {
|
42
|
-
'text' => desc
|
43
|
-
},
|
44
|
-
'defaultConfiguration' => {
|
45
|
-
'level' => sarif_severity(severity)
|
46
|
-
},
|
47
|
-
'properties' => {}
|
48
|
-
}
|
49
|
-
@rules << h
|
50
|
-
@rules_map[cop_name] = Rule.new(cop_name, @rules.size - 1)
|
51
|
-
end
|
52
|
-
|
53
|
-
def sarif_severity(cop_severity)
|
54
|
-
return cop_severity if %w[warning error].include?(cop_severity)
|
55
|
-
return 'note' if %w[refactor convention].include?(cop_severity)
|
56
|
-
return 'error' if cop_severity == 'fatal'
|
57
|
-
'none'
|
40
|
+
r
|
58
41
|
end
|
59
42
|
|
60
43
|
def file_finished(file, offenses)
|
61
44
|
relative_path = RuboCop::PathUtil.relative_path(file)
|
62
45
|
|
63
46
|
offenses.each do |o|
|
64
|
-
rule =
|
65
|
-
|
47
|
+
rule, rule_index = get_rule(o.cop_name, o.severity)
|
66
48
|
@results << {
|
67
|
-
"ruleId" => rule.
|
68
|
-
|
69
|
-
|
70
|
-
|
49
|
+
"ruleId" => rule.id,
|
50
|
+
"ruleIndex" => rule_index,
|
51
|
+
"message" => {
|
52
|
+
"text" => o.message
|
71
53
|
},
|
72
|
-
|
54
|
+
"locations" => [
|
73
55
|
{
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
'index' => 0
|
56
|
+
"physicalLocation" => {
|
57
|
+
"artifactLocation" => {
|
58
|
+
"uri" => relative_path,
|
59
|
+
"uriBaseId" => "%SRCROOT%",
|
79
60
|
},
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
61
|
+
"region" => {
|
62
|
+
"startLine" => o.line,
|
63
|
+
"startColumn" => o.real_column,
|
64
|
+
"endColumn" => o.last_column.zero? ? o.real_column : o.last_column
|
84
65
|
}
|
85
66
|
}
|
86
67
|
}
|
87
|
-
]
|
88
|
-
'partialFingerprints' => {
|
89
|
-
# This will be computed by the upload action for now
|
90
|
-
}
|
68
|
+
]
|
91
69
|
}
|
92
70
|
end
|
93
71
|
end
|
94
72
|
|
95
73
|
def finished(_inspected_files)
|
96
|
-
|
97
|
-
|
74
|
+
output.print(sarif_json)
|
75
|
+
end
|
76
|
+
|
77
|
+
def sarif_json
|
78
|
+
JSON.pretty_generate(@sarif)
|
98
79
|
end
|
99
80
|
end
|
100
81
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../code_scanning"
|
4
|
+
|
5
|
+
class QHelpGenerator
|
6
|
+
def initialize
|
7
|
+
@formatter = CodeScanning::SarifFormatter.new(nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_file(path_to_file)
|
11
|
+
file = File.open(path_to_file)
|
12
|
+
current_rule = nil
|
13
|
+
file.each_with_index do |line, index|
|
14
|
+
# title: skip
|
15
|
+
next if index.zero?
|
16
|
+
|
17
|
+
if line[0..2] == "## "
|
18
|
+
current_cop = line[3..-2]
|
19
|
+
current_rule, _index = @formatter.get_rule(current_cop, nil)
|
20
|
+
next
|
21
|
+
end
|
22
|
+
|
23
|
+
next if current_rule.nil?
|
24
|
+
if line == "\n" && current_rule.help_empty?
|
25
|
+
# Don't start the help text with new lines
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
current_rule.append_help(line)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def sarif_json
|
34
|
+
@formatter.sarif_json
|
35
|
+
end
|
36
|
+
end
|
data/lib/code_scanning.rb
CHANGED
data/preview.png
ADDED
Binary file
|
data/rubocop-action/action.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code-scanning-rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arthur Neves
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '1.0'
|
27
27
|
description: This gem adds a SARIF formatter to rubocop, so we can export alerts to
|
28
28
|
code-scanning inside GitHub.
|
29
29
|
email:
|
@@ -32,7 +32,11 @@ executables: []
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
+
- ".github/workflows/rubocop-analysis.yml"
|
36
|
+
- ".github/workflows/ruby.yml"
|
35
37
|
- ".gitignore"
|
38
|
+
- ".rubocop.yml"
|
39
|
+
- ".rubocop_todo.yml"
|
36
40
|
- CODE_OF_CONDUCT.md
|
37
41
|
- Dockerfile
|
38
42
|
- Gemfile
|
@@ -45,8 +49,11 @@ files:
|
|
45
49
|
- code-scanning-rubocop.gemspec
|
46
50
|
- entrypoint.sh
|
47
51
|
- lib/code_scanning.rb
|
52
|
+
- lib/code_scanning/rubocop/rule.rb
|
48
53
|
- lib/code_scanning/rubocop/sarif_formatter.rb
|
49
54
|
- lib/code_scanning/rubocop/version.rb
|
55
|
+
- lib/code_scanning/rules_generator.rb
|
56
|
+
- preview.png
|
50
57
|
- rubocop-action/action.yml
|
51
58
|
homepage: https://github.com/arthurnn/code-scanning-rubocop
|
52
59
|
licenses:
|
@@ -69,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
76
|
- !ruby/object:Gem::Version
|
70
77
|
version: '0'
|
71
78
|
requirements: []
|
72
|
-
|
73
|
-
rubygems_version: 2.7.6
|
79
|
+
rubygems_version: 3.3.3
|
74
80
|
signing_key:
|
75
81
|
specification_version: 4
|
76
82
|
summary: Extra formater to make rubocop compatible with GitHub's code-scanning feature.
|