rubocop_challenger 0.5.2 → 1.0.0.pre

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
  SHA256:
3
- metadata.gz: 37ec8fd817642a69fe7bb68c99b6517f0058d7e8bc869b92f102e8b9e0ea1212
4
- data.tar.gz: 04caf2ba5be3f8b41b27dc7fcaf7fb69eea7cbc466e9be1521c614dfe79dffb5
3
+ metadata.gz: be161f42b0b71a8b844def77b8bf6804e509b2031e8c36414cca774e7a2c9d52
4
+ data.tar.gz: d25cc54a5fe1b7c790a777be33f588ee077c5e2e7bdda3859036b0cfdb6f8f09
5
5
  SHA512:
6
- metadata.gz: 750395303ee97a2cd991531a64ed837635537e85a3cbefa6e43efda0a0e970bdc37e74b11f632a74079f4afa1b3f245cbfc71910b0e09992365ba9117918f6eb
7
- data.tar.gz: f6a587358270e6f32233014a931b62d4df600a22e9931af220553f6765c674859ddf80c485a3f6819ac95da18421de8ad5e8fb10e5d7c10b78d3d8e285db517a
6
+ metadata.gz: cc662bd2602a49e01778f9d7cce01a1c9b1355ce34d0a787bb2069bbb047b91dfd781831991eb7948aa767a74466ccb33cab46954ae67eb723e6347d24347b43
7
+ data.tar.gz: 6ba85d28bd29051e39398edb5ef81737bf3181fc99d05140b541d13d92e299a4964822f25c9e72536958d357c6c8170f3e080760c4800c40786782a4fb630163
data/.rubocop.yml CHANGED
@@ -8,3 +8,8 @@ AllCops:
8
8
  Metrics/BlockLength:
9
9
  Exclude:
10
10
  - 'spec/**/*'
11
+
12
+ # For integration testing
13
+ RSpec/MultipleExpectations:
14
+ Exclude:
15
+ - 'spec/rubocop_challenger/cli_spec.rb'
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-11-04 14:59:09 +0900 using RuboCop version 0.60.0.
3
+ # on 2018-11-13 10:11:54 +0900 using RuboCop version 0.60.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop_challenger (0.5.2)
5
- pr-daikou (~> 0.2.0)
4
+ rubocop_challenger (1.0.0.pre)
5
+ octokit
6
6
  rubocop
7
7
  rubocop-rspec
8
8
  thor
@@ -11,16 +11,23 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
+ addressable (2.5.2)
15
+ public_suffix (>= 2.0.2, < 4.0)
14
16
  ast (2.4.0)
15
17
  diff-lcs (1.3)
16
18
  docile (1.3.1)
19
+ faraday (0.15.3)
20
+ multipart-post (>= 1.2, < 3)
17
21
  jaro_winkler (1.5.1)
18
22
  json (2.1.0)
23
+ multipart-post (2.0.0)
24
+ octokit (4.13.0)
25
+ sawyer (~> 0.8.0, >= 0.5.3)
19
26
  parallel (1.12.1)
20
27
  parser (2.5.3.0)
21
28
  ast (~> 2.4.0)
22
29
  powerpack (0.1.2)
23
- pr-daikou (0.2.0)
30
+ public_suffix (3.0.3)
24
31
  rainbow (3.0.0)
25
32
  rake (10.5.0)
26
33
  rspec (3.8.0)
@@ -49,12 +56,15 @@ GEM
49
56
  rubocop-rspec (1.30.1)
50
57
  rubocop (>= 0.60.0)
51
58
  ruby-progressbar (1.10.0)
59
+ sawyer (0.8.1)
60
+ addressable (>= 2.3.5, < 2.6)
61
+ faraday (~> 0.8, < 1.0)
52
62
  simplecov (0.16.1)
53
63
  docile (~> 1.1)
54
64
  json (>= 1.8, < 3)
55
65
  simplecov-html (~> 0.10.0)
56
66
  simplecov-html (0.10.2)
57
- thor (0.20.0)
67
+ thor (0.20.3)
58
68
  unicode-display_width (1.4.0)
59
69
  yard (0.9.16)
60
70
 
data/README.md CHANGED
@@ -55,8 +55,8 @@ jobs:
55
55
  command: |
56
56
  bundle install
57
57
  bundle exec rubocop_challenger go \
58
- --email=rubocop-challenge@example.com \
59
- --name="'Rubocop Challenge'"
58
+ --email=rubocop-challenger@example.com \
59
+ --name="'Rubocop Challenger'"
60
60
 
61
61
  workflows:
62
62
  version: 2
@@ -79,7 +79,7 @@ workflows:
79
79
  $ rubocop_challenger help
80
80
 
81
81
  Commands:
82
- rubocop_challenger go --email=EMAIL --name=NAME # Run `$ rubocop --auto-correct` and create PR to your GitHub repository
82
+ rubocop_challenger go --email=EMAIL --name=NAME # Run `$ rubocop --auto-correct` and create PR to GitHub repo
83
83
  rubocop_challenger help [COMMAND] # Describe available commands or one specific command
84
84
  rubocop_challenger version # Show current version
85
85
  ```
@@ -105,9 +105,10 @@ Options:
105
105
  l, [--labels=one two three] # Label to give to Pull Request
106
106
  # Default: ["rubocop challenge"]
107
107
  [--regenerate-rubocop-todo], [--no-regenerate-rubocop-todo] # Rerun `$ rubocop --auto-gen-config` after autocorrect
108
+ # Default: true
108
109
  [--no-commit] # No commit after autocorrect
109
110
 
110
- Run `$ rubocop --auto-correct` and create PR to your GitHub repository
111
+ Run `$ rubocop --auto-correct` and create PR to GitHub repo
111
112
  ```
112
113
 
113
114
  ## Requirement
@@ -11,42 +11,39 @@ def exit_process(error_message)
11
11
  exit!
12
12
  end
13
13
 
14
- def exist_uncommitted_modify?
15
- `git add -n .; git diff --name-only` != ''
16
- end
17
-
18
- VERSION_FORMAT = /\A\d+\.\d+\.\d+\z/.freeze
14
+ VERSION_FORMAT = /\A\d+\.\d+\.\d+(\.(pre|beta|rc)\d?)?\z/.freeze
19
15
  version = ARGV[0]
16
+ rubocop = RubocopChallenger::Rubocop::Command.new
17
+ pr_creater =
18
+ RubocopChallenger::Github::PrCreater.new(
19
+ access_token: ENV['GITHUB_ACCESS_TOKEN'],
20
+ branch: "update/v#{version}"
21
+ )
20
22
 
21
23
  # Verifying
22
24
  exit_process 'usage: bin/create_release_pr VERSION' if version.nil?
23
25
  exit_process 'A version must be like a `1.2.3`' unless version =~ VERSION_FORMAT
24
- exit_process 'There are uncommitted modify' if exist_uncommitted_modify?
25
26
 
26
27
  # Modify a version file
27
- File.write('lib/rubocop_challenger/version.rb', <<~VERSION)
28
- # frozen_string_literal: true
29
-
30
- module RubocopChallenger
31
- VERSION = '#{version}'
32
- end
33
- VERSION
28
+ pr_creater.commit 'Update version' do
29
+ File.write('lib/rubocop_challenger/version.rb', <<~VERSION)
30
+ # frozen_string_literal: true
31
+
32
+ module RubocopChallenger
33
+ VERSION = '#{version}'
34
+ end
35
+ VERSION
36
+ end
34
37
 
35
38
  # Bundle Update
36
- `bundle update`
39
+ pr_creater.commit 'Run $ bundle update' do
40
+ `bundle update`
41
+ end
37
42
 
38
43
  # Regenerate .rubocop_todo.yml
39
- `bundle exec rubocop --auto-gen-config`
44
+ pr_creater.commit 'Regenerate .rubocop_todo.yml' do
45
+ rubocop.auto_gen_config
46
+ end
40
47
 
41
48
  # Create PR
42
- PRDaikou.exec(
43
- {
44
- email: `git config user.email`,
45
- name: `git config user.name`,
46
- base: 'master',
47
- title: "Update v#{version}",
48
- labels: '',
49
- topic: "update/v#{version}",
50
- commit: "Update v#{version}"
51
- }, nil
52
- )
49
+ pr_creater.create_pr(title: "Update v#{version}", body: '', base: 'master')
data/challenger.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_runtime_dependency 'pr-daikou', '~> 0.2.0'
25
+ spec.add_runtime_dependency 'octokit'
26
26
  spec.add_runtime_dependency 'rubocop'
27
27
  spec.add_runtime_dependency 'rubocop-rspec'
28
28
  spec.add_runtime_dependency 'thor'
@@ -2,8 +2,12 @@
2
2
 
3
3
  require 'erb'
4
4
  require 'yard'
5
+ require 'octokit'
5
6
  require 'rubocop'
6
7
  require 'rubocop-rspec'
8
+ require 'rubocop_challenger/errors'
9
+ require 'rubocop_challenger/version'
10
+ require 'rubocop_challenger/command_line'
7
11
  require 'rubocop_challenger/rubocop/rule'
8
12
  require 'rubocop_challenger/rubocop/todo_reader'
9
13
  require 'rubocop_challenger/rubocop/todo_writer'
@@ -11,6 +15,7 @@ require 'rubocop_challenger/rubocop/command'
11
15
  require 'rubocop_challenger/rubocop/challenge'
12
16
  require 'rubocop_challenger/rubocop/yardoc'
13
17
  require 'rubocop_challenger/cli'
14
- require 'rubocop_challenger/version'
15
- require 'rubocop_challenger/github/pr_template.rb'
16
- require 'pr-daikou'
18
+ require 'rubocop_challenger/git/command'
19
+ require 'rubocop_challenger/github/client'
20
+ require 'rubocop_challenger/github/pr_template'
21
+ require 'rubocop_challenger/github/pr_creater'
@@ -42,7 +42,7 @@ module RubocopChallenger
42
42
  desc: 'Label to give to Pull Request'
43
43
  option :'regenerate-rubocop-todo',
44
44
  type: :boolean,
45
- default: false,
45
+ default: true,
46
46
  desc: 'Rerun `$ rubocop --auto-gen-config` after autocorrect'
47
47
  option :'no-commit',
48
48
  type: :boolean,
@@ -72,48 +72,53 @@ module RubocopChallenger
72
72
 
73
73
  private
74
74
 
75
+ def pr_creater
76
+ @pr_creater ||= Github::PrCreater.new(
77
+ access_token: ENV['GITHUB_ACCESS_TOKEN'],
78
+ branch: "rubocop-challenge/#{timestamp}",
79
+ user_name: options[:name],
80
+ user_email: options[:email]
81
+ )
82
+ end
83
+
75
84
  def rubocop_challenge
76
- Rubocop::Challenge.exec(options[:file_path], options[:mode])
85
+ target_rule = Rubocop::Challenge.exec(options[:file_path], options[:mode])
86
+ pr_creater.commit ":robot: #{target_rule.title}"
87
+ target_rule
77
88
  end
78
89
 
79
90
  def regenerate_rubocop_todo
80
91
  return unless options[:'regenerate-rubocop-todo']
81
92
 
82
- Rubocop::Command.new.auto_gen_config
93
+ pr_creater.commit ':robot: regenerate rubocop todo' do
94
+ Rubocop::Command.new.auto_gen_config
95
+ end
83
96
  end
84
97
 
85
98
  def create_pull_request(rule)
86
- pr_daikou_options = generate_pr_daikou_options(rule)
99
+ pr_creater_options = generate_pr_creater_options(rule)
87
100
  return if options[:'no-commit']
88
101
 
89
- PRDaikou.exec(pr_daikou_options, nil)
102
+ pr_creater.create_pr(pr_creater_options)
90
103
  end
91
104
 
92
- def generate_pr_daikou_options(target_rule)
105
+ def generate_pr_creater_options(rule)
93
106
  {
94
- email: options[:email],
95
- name: options[:name],
107
+ title: "#{rule.title}-#{timestamp}",
108
+ body: generate_pr_body(rule),
96
109
  base: options[:base],
97
- title: target_rule.title,
98
- description: pr_template(target_rule),
99
- labels: options[:labels].join(','),
100
- topic: generate_topic(target_rule),
101
- commit: ":robot: #{target_rule.title}"
110
+ labels: options[:labels]
102
111
  }
103
112
  end
104
113
 
105
- def generate_topic(rule)
106
- "rubocop-challenge/#{rule.title.tr('/', '-')}-#{timestamp}"
107
- end
108
-
109
- def pr_template(rule)
114
+ def generate_pr_body(rule)
110
115
  Github::PrTemplate
111
116
  .new(rule, options[:template])
112
117
  .generate_pullrequest_markdown
113
118
  end
114
119
 
115
120
  def timestamp
116
- Time.now.strftime('%Y%m%d%H%M%S')
121
+ @timestamp ||= Time.now.strftime('%Y%m%d%H%M%S')
117
122
  end
118
123
  end
119
124
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ # To execute command line. You should inherit this class to use.
5
+ class CommandLine
6
+ private
7
+
8
+ # Execute a command
9
+ #
10
+ # @param command [String] The command you want to execute
11
+ # @return [String] Execution result
12
+ def execute(command)
13
+ puts "$ #{command}"
14
+ `#{command}`.chomp
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ module Errors
5
+ class ExistUncommittedModify < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ module Git
5
+ # To execute git command
6
+ class Command < CommandLine
7
+ def initialize(user_name: nil, user_email: nil)
8
+ @user_name = user_name
9
+ @user_email = user_email
10
+ end
11
+
12
+ def user_name
13
+ @user_name ||= config('user.name')
14
+ end
15
+
16
+ def user_email
17
+ @user_email ||= config('user.email')
18
+ end
19
+
20
+ def exist_uncommitted_modify?
21
+ execute('git add -n .; git diff --name-only') != ''
22
+ end
23
+
24
+ def checkout(branch)
25
+ run('checkout', branch)
26
+ end
27
+
28
+ def checkout_with(new_branch)
29
+ run('checkout', '-b', new_branch)
30
+ end
31
+
32
+ def add(*files)
33
+ run('add', *files)
34
+ end
35
+
36
+ def commit(message)
37
+ run_with_environments('commit', '-m', "\"#{message}\"")
38
+ end
39
+
40
+ def push(remote, branch = current_branch)
41
+ run('push', remote, branch)
42
+ end
43
+
44
+ def current_sha1
45
+ run('rev-parse', 'HEAD')
46
+ end
47
+
48
+ def current_sha1?(sha1)
49
+ current_sha1 == sha1.to_s
50
+ end
51
+
52
+ def current_branch
53
+ run('rev-parse', '--abbrev-ref', 'HEAD')
54
+ end
55
+
56
+ def current_branch?(branch)
57
+ current_branch == branch.to_s
58
+ end
59
+
60
+ def remote_url(remote)
61
+ run('remote', 'get-url', '--push', remote)
62
+ end
63
+
64
+ private
65
+
66
+ def run(*subcommands)
67
+ command = "git #{subcommands.join(' ')}"
68
+ execute(command)
69
+ end
70
+
71
+ def run_with_environments(*subcommands)
72
+ command = "#{environments} git #{subcommands.join(' ')}"
73
+ execute(command)
74
+ end
75
+
76
+ def config(key)
77
+ run('config', key)
78
+ end
79
+
80
+ def environments
81
+ @environments ||= [
82
+ "GIT_AUTHOR_NAME=\"#{user_name}\"",
83
+ "GIT_AUTHOR_EMAIL=\"#{user_email}\"",
84
+ "GIT_COMMITTER_NAME=\"#{user_name}\"",
85
+ "GIT_COMMITTER_EMAIL=\"#{user_email}\""
86
+ ].join(' ')
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ module Github
5
+ # GitHub API Client
6
+ class Client
7
+ attr_reader :repository
8
+
9
+ def initialize(access_token, remote_url)
10
+ @client = Octokit::Client.new(access_token: access_token)
11
+ @repository = remote_url.match(REPOSITORY_MATCHER)[:repository]
12
+ end
13
+
14
+ # Create a pull request
15
+ #
16
+ # @param base [String] The branch you want your changes pulled into
17
+ # @param head [String] The branch where your changes are implemented
18
+ # @param title [String] Title for the pull request
19
+ # @param body [String] The body for the pull request
20
+ # @return [Integer] Created pull request number
21
+ def create_pull_request(base:, head:, title:, body:)
22
+ response =
23
+ client.create_pull_request(repository, base, head, title, body)
24
+ response.number
25
+ end
26
+
27
+ # Description of #add_labels
28
+ #
29
+ # @param issue_number [Integer] Number ID of the issue (or pull request)
30
+ # @param labels [Array<String>] An array of labels to apply to this Issue
31
+ def add_labels(issue_number, *labels)
32
+ client.add_labels_to_an_issue(repository, issue_number, labels)
33
+ end
34
+
35
+ private
36
+
37
+ REPOSITORY_MATCHER = %r{github\.com[:/](?<repository>.+)\.git}.freeze
38
+
39
+ attr_reader :client
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ module Github
5
+ # To create Pull Request
6
+ class PrCreater
7
+ # Returns a new instance of Github::PrCreater
8
+ #
9
+ # @param access_token [String] The GitHub access token
10
+ # @param branch [String] The branch where your changes are going to
11
+ # implement.
12
+ # @param user_name [String] The username to use for committer and author
13
+ # @param user_email [String] The email to use for committer and author
14
+ def initialize(access_token:, branch:, user_name: nil, user_email: nil)
15
+ @topic_branch = branch
16
+ @git = Git::Command.new(user_name: user_name, user_email: user_email)
17
+ @github = Github::Client.new(access_token, git.remote_url('origin'))
18
+ @initial_sha1 = git.current_sha1
19
+ end
20
+
21
+ # Add and commit local files to this branch
22
+ #
23
+ # @param message [String] The commit message
24
+ # @yield Some commands where modify local files
25
+ # @return [Object] Return result of yield if you use &block
26
+ # @raise [RubocopChallenger::Errors::ExistUncommittedModify]
27
+ # Raise error if you use &block and exists someuncommitted files
28
+ def commit(message, &block)
29
+ git.checkout_with(topic_branch) unless git.current_branch?(topic_branch)
30
+ result = modify_files(&block) if block_given?
31
+ git.add('.')
32
+ git.commit(message)
33
+ result
34
+ end
35
+
36
+ # Create a pull request
37
+ # You should call #commit before calling this method
38
+ #
39
+ # @param title [String] Title for the pull request
40
+ # @param body [String] The body for the pull request
41
+ # @param base [String] The branch you want your changes pulled into
42
+ # @param labels [Array<String>] An array of labels to apply to this PR
43
+ # @return [Boolean] Return true if its successed
44
+ def create_pr(title:, body:, base:, labels: nil)
45
+ return false unless git_condition_valid?
46
+
47
+ git.push('origin', topic_branch)
48
+ pr_number = github.create_pull_request(
49
+ base: base, head: topic_branch, title: title, body: body
50
+ )
51
+ github.add_labels(pr_number, labels) unless labels.nil?
52
+ true
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :git, :github, :topic_branch, :initial_sha1
58
+
59
+ def git_condition_valid?
60
+ !git.current_sha1?(initial_sha1) && git.current_branch?(topic_branch)
61
+ end
62
+
63
+ def modify_files
64
+ raise Errors::ExistUncommittedModify if git.exist_uncommitted_modify?
65
+
66
+ yield
67
+ end
68
+ end
69
+ end
70
+ end
@@ -3,13 +3,20 @@
3
3
  module RubocopChallenger
4
4
  module Rubocop
5
5
  # To execute rubocop gem command (Mainly for mock when testing)
6
- class Command
6
+ class Command < CommandLine
7
7
  def auto_correct
8
- `bundle exec rubocop --auto-correct || true`
8
+ run('--auto-correct')
9
9
  end
10
10
 
11
11
  def auto_gen_config
12
- `bundle exec rubocop --auto-gen-config || true`
12
+ run('--auto-gen-config')
13
+ end
14
+
15
+ private
16
+
17
+ def run(*subcommands)
18
+ command = "bundle exec rubocop #{subcommands.join(' ')} || true"
19
+ execute(command)
13
20
  end
14
21
  end
15
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubocopChallenger
4
- VERSION = '0.5.2'
4
+ VERSION = '1.0.0.pre'
5
5
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop_challenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 1.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - ryosuke_sato
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-04 00:00:00.000000000 Z
11
+ date: 2018-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: pr-daikou
14
+ name: octokit
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.0
19
+ version: '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: 0.2.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -181,6 +181,11 @@ files:
181
181
  - images/rubocop_challenge.png
182
182
  - lib/rubocop_challenger.rb
183
183
  - lib/rubocop_challenger/cli.rb
184
+ - lib/rubocop_challenger/command_line.rb
185
+ - lib/rubocop_challenger/errors.rb
186
+ - lib/rubocop_challenger/git/command.rb
187
+ - lib/rubocop_challenger/github/client.rb
188
+ - lib/rubocop_challenger/github/pr_creater.rb
184
189
  - lib/rubocop_challenger/github/pr_template.rb
185
190
  - lib/rubocop_challenger/rubocop/challenge.rb
186
191
  - lib/rubocop_challenger/rubocop/command.rb
@@ -206,9 +211,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
211
  version: '0'
207
212
  required_rubygems_version: !ruby/object:Gem::Requirement
208
213
  requirements:
209
- - - ">="
214
+ - - ">"
210
215
  - !ruby/object:Gem::Version
211
- version: '0'
216
+ version: 1.3.1
212
217
  requirements: []
213
218
  rubyforge_project:
214
219
  rubygems_version: 2.7.8