oss-gate / workshop

OSSの開発に未参加または参加したことはあるけどまだ自信がない人を後押しするワークショップ用のリポジトリー
124 stars 547 forks source link

OSS Gate Workshop: Freee: 2021-11-25: timtoronto634: rubocop: Work log #1515

Closed timtoronto634 closed 2 years ago

timtoronto634 commented 2 years ago

This is a work log of a "OSS Gate workshop". "OSS Gate workshop" is an activity to increase OSS developers. Here's been discussed in Japanese. Thanks.

作業ログ作成時の説明

以下のテンプレートを埋めてタイトルに設定します。埋め方例はスクロールすると見えてきます。

OSS Gate Workshop: ${LOCATION}: ${YEAR}-${MONTH}-${DAY}: ${ACCOUNT_NAME}: ${OSS_NAME}: Work log

タイトル例↓:

OSS Gate Workshop: Tokyo: 2017-01-16: kou: Rabbit: Work log

OSS Gateワークショップ関連情報

timtoronto634 commented 2 years ago

https://github.com/rubocop/rubocop

READMEのCOPYRIGHT (https://github.com/rubocop/rubocop#copyright) にあるLISCENCE.txtリンクをクリックすると、rubocop/rubocop is licensed under the MIT License と書いてある。

https://opensource.org/licenses/alphabetical のサイトに、MIT Liscence の名前があるので、 rubocopはOSSと判断できる

timtoronto634 commented 2 years ago

rubocopはlinterなので、動かすにあたって、rubyで書かれたレポじとりが必要。

以前にrails tutorialをやったレポジトリがあったので、それを題材につかうぞ https://github.com/timtoronto634/sample_app

tdtds commented 2 years ago

わいわい

teyamagu commented 2 years ago

いいねいいね

timtoronto634 commented 2 years ago

マシンのローカルのターミナルが開かないので再起動するぞ

timtoronto634 commented 2 years ago

再起動完了。問題なく動く。

まずはrails tutorial のレポジトリをクローンする git clone git@github.com:timtoronto634/sample_app.git

timtoronto634 commented 2 years ago

問題なくcloneされたので、 cd sample_app して、vscodeでレポじとりを開く。 code . これでファイルの編集がしやすくなる

timtoronto634 commented 2 years ago

vscode にDo you trust the authors of the files in this folder? と聞かれるので Yes

いよいよrobocupをみていく。

https://github.com/rubocop/rubocop トップページを上から見ていけば、installationなどがあるはず

timtoronto634 commented 2 years ago

あった https://github.com/rubocop/rubocop#installation

一つ目に gem install rubocop とする方法が書いてあり、次に 「bundlerを使う場合」と記述してある。 今回はrails tutorialのレポジトリで、bundleを使っており、今後もbundlerを使うことが多いと予想されるので、「bundlerを使う場合」の案内に従う。

If you'd rather install RuboCop using bundler, add a line for it in your Gemfile (but set the require option to false, as it is a standalone tool):

gem 'rubocop', require: false

上の1行をGemfileに追加する。Gemfileは一つしかない。

group :development のブロックに追加する。

timtoronto634 commented 2 years ago

bundle installをしろと書いておらず、quickstart につながっているが、そのままではパッケージの中身がなく、動かないと思うので、bundle installを叩く

> bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
dry-inflector-0.2.1 requires ruby version >= 2.6.0, which is incompatible with the current version, ruby 2.5.8p224

と出てbundle installに失敗する。 そもそもローカルにrailsの実行環境があるか怪しいので、実行環境があるはずの(このチュートリアルをやっていた環境)PCでやりたかったが、手元にない。

timtoronto634 commented 2 years ago

仕方がないので、さらにまた別の環境に入ってやり直す。

timtoronto634 commented 2 years ago

クラウド上のマシンでやろうとしたが、結局環境構築が必要になりそうだったので、ローカルにdocker-composeで環境を作ることにした

timtoronto634 commented 2 years ago

https://docs.docker.com/samples/rails/ を少し変えた自前の設定で環境構築完了

timtoronto634 commented 2 years ago

先ほど同様、

gem 'rubocop', require: false

上の1行をGemfileに追加する。 linterは開発時しか使わない想定なので、group :development のブロックに追加した

timtoronto634 commented 2 years ago
docker-compose exec web bundle install

webはrubyのコンテナなので、これでrubocopがインストールできるはず。 ログの一部を抜粋すると、インストールできてそう

Fetching rubocop-ast 1.13.0
Installing rubocop-ast 1.13.0
Fetching unicode-display_width 2.1.0
Installing unicode-display_width 2.1.0
Fetching rubocop 1.23.0
Installing rubocop 1.23.0
timtoronto634 commented 2 years ago

Quickstart に Just type rubocop in a Ruby project's folder and watch the magic happen. とあるので、

rubocop

とタイプする。ただし、docker-composeで動かしてるので、上のコマンドの代わりに、

docker-compose exec web rubocop

と打つ。 まっさらなrails tutorial立ち上げただけのレポジトリなので、警告が多くはでないはず

timtoronto634 commented 2 years ago

結果、以下のようにたくさん出た


 docker-compose exec web rubocop
Inspecting 38 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

Offenses:

Gemfile:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
source 'https://rubygems.org'
^
Gemfile:6:1: C: [Correctable] Layout/EmptyLines: Extra blank line detected.
Gemfile:9:1: C: [Correctable] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem rails-controller-testing should appear before sqlite3.
gem 'rails-controller-testing', '~> 1.0'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:10:1: C: [Correctable] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem minitest should appear before rails-controller-testing.
gem 'minitest',                 '~> 5.10'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:12:1: C: [Correctable] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem guard should appear before minitest-reporters.
gem 'guard',                    '~> 2.16'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:15:1: C: [Correctable] Layout/EmptyLines: Extra blank line detected.
Gemfile:51:28: C: [Correctable] Style/SymbolArray: Use %i or %I for an array of symbols.
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:58:3: C: [Correctable] Bundler/OrderedGems: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem listen should appear before web-console.
  gem 'listen', '>= 3.0.5', '< 3.2'
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Gemfile:73:31: C: [Correctable] Style/SymbolArray: Use %i or %I for an array of symbols.
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Rakefile:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Add your own tasks in files placed in lib/tasks ending in .rake,
^
app/channels/application_cable/channel.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
module ApplicationCable
^
app/channels/application_cable/connection.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
module ApplicationCable
^
app/controllers/application_controller.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
class ApplicationController < ActionController::Base
^
app/helpers/application_helper.rb:1:1: C: Style/Documentation: Missing top-level documentation comment for module ApplicationHelper.
module ApplicationHelper
^^^^^^^^^^^^^^^^^^^^^^^^
app/helpers/application_helper.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
module ApplicationHelper
^
app/jobs/application_job.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
class ApplicationJob < ActiveJob::Base
^
app/mailers/application_mailer.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
class ApplicationMailer < ActionMailer::Base
^
app/models/application_record.rb:1:1: C: Style/Documentation: Missing top-level documentation comment for class ApplicationRecord.
class ApplicationRecord < ActiveRecord::Base
^^^^^^^^^^^^^^^^^^^^^^^
app/models/application_record.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
class ApplicationRecord < ActiveRecord::Base
^
bin/bundle:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/rails:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/rails:3:13: C: [Correctable] Style/ExpandPathArguments: Use expand_path('spring', __dir__) instead of expand_path('../spring', __FILE__).
  load File.expand_path('../spring', __FILE__)
            ^^^^^^^^^^^
bin/rake:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/rake:3:13: C: [Correctable] Style/ExpandPathArguments: Use expand_path('spring', __dir__) instead of expand_path('../spring', __FILE__).
  load File.expand_path('../spring', __FILE__)
            ^^^^^^^^^^^
bin/setup:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/setup:3:1: C: Style/MixinUsage: include is used at the top level. Use inside class or module.
include FileUtils
^^^^^^^^^^^^^^^^^
bin/spring:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/update:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/update:3:1: C: Style/MixinUsage: include is used at the top level. Use inside class or module.
include FileUtils
^^^^^^^^^^^^^^^^^
bin/yarn:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
#!/usr/bin/env ruby
^
bin/yarn:4:3: C: [Correctable] Style/RedundantBegin: Redundant begin block detected.
  begin
  ^^^^^
bin/yarn:5:10: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    exec "yarnpkg", *ARGV
         ^^^^^^^^^
bin/yarn:7:5: C: [Correctable] Style/StderrPuts: Use warn instead of $stderr.puts to allow such output to be disabled.
    $stderr.puts "Yarn executable was not detected in the system."
    ^^^^^^^^^^^^
bin/yarn:7:18: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    $stderr.puts "Yarn executable was not detected in the system."
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
bin/yarn:8:5: C: [Correctable] Style/StderrPuts: Use warn instead of $stderr.puts to allow such output to be disabled.
    $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
    ^^^^^^^^^^^^
bin/yarn:8:18: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
config.ru:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# This file is used by Rack-based servers to start the application.
^
config/application.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
require_relative 'boot'
^
config/application.rb:10:3: C: Style/Documentation: Missing top-level documentation comment for class Myapp::Application.
  class Application < Rails::Application
  ^^^^^^^^^^^^^^^^^
config/boot.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
^
config/environment.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Load the Rails application.
^
config/environments/development.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
Rails.application.configure do
^
config/environments/production.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
Rails.application.configure do
^
config/environments/production.rb:57:22: C: [Correctable] Layout/SpaceInsideArrayLiteralBrackets: Do not use space inside array brackets.
  config.log_tags = [ :request_id ]
                     ^
config/environments/production.rb:57:34: C: Layout/SpaceInsideArrayLiteralBrackets: Do not use space inside array brackets.
  config.log_tags = [ :request_id ]
                                 ^
config/environments/production.rb:86:10: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
  if ENV["RAILS_LOG_TO_STDOUT"].present?
         ^^^^^^^^^^^^^^^^^^^^^
config/environments/production.rb:87:50: C: [Correctable] Style/GlobalStdStream: Use $stdout instead of STDOUT.
    logger           = ActiveSupport::Logger.new(STDOUT)
                                                 ^^^^^^
config/environments/test.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
Rails.application.configure do
^
config/initializers/application_controller_renderer.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/assets.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/backtrace_silencers.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/content_security_policy.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/cookies_serializer.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/filter_parameter_logging.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/inflections.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/mime_types.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/initializers/wrap_parameters.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Be sure to restart your server when you modify this file.
^
config/puma.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# Puma can serve each request in a thread from an internal thread pool.
^
config/puma.rb:7:21: C: [Correctable] Style/RedundantFetchBlock: Use fetch("RAILS_MAX_THREADS", 5) instead of fetch("RAILS_MAX_THREADS") { 5 }.
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
config/puma.rb:7:27: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
                          ^^^^^^^^^^^^^^^^^^^
config/puma.rb:12:17: C: [Correctable] Style/RedundantFetchBlock: Use fetch("PORT", 3000) instead of fetch("PORT") { 3000 }.
port        ENV.fetch("PORT") { 3000 }
                ^^^^^^^^^^^^^^^^^^^^^^
config/puma.rb:12:23: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
port        ENV.fetch("PORT") { 3000 }
                      ^^^^^^
config/puma.rb:16:23: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
environment ENV.fetch("RAILS_ENV") { "development" }
                      ^^^^^^^^^^^
config/puma.rb:16:38: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
environment ENV.fetch("RAILS_ENV") { "development" }
                                     ^^^^^^^^^^^^^
config/puma.rb:19:19: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
                  ^^^^^^^^^
config/puma.rb:19:32: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
                               ^^^^^^^^^^^^^^^^^^^^^
config/routes.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
Rails.application.routes.draw do
^
config/spring.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
%w[
^
db/seeds.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
# This file should contain all the record creation needed to seed the database with its default values.
^
test/application_system_test_case.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
require "test_helper"
^
test/application_system_test_case.rb:1:9: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
require "test_helper"
        ^^^^^^^^^^^^^
test/test_helper.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
ENV['RAILS_ENV'] ||= 'test'
^
test/test_helper.rb:5:7: C: [Correctable] Style/ClassAndModuleChildren: Use nested module/class definitions instead of compact style.
class ActiveSupport::TestCase
      ^^^^^^^^^^^^^^^^^^^^^^^

38 files inspected, 73 offenses detected, 67 offenses auto-correctable
timtoronto634 commented 2 years ago

次にできることはないか、深く入ってみる。

まずは公式docHPをよむ https://docs.rubocop.org/rubocop/1.23/index.html

rubocopがどんなもので、何かしたいときにどうすればいいかの導線が書いてあるはず。

timtoronto634 commented 2 years ago

rails tutorialとrubocopではメンテナーが違うので、差分が出るのは当たり前ではある。

提案の方向性として以下もあり得る

timtoronto634 commented 2 years ago

https://github.com/github/rubocop-github

rubocopの推奨設定がまとめてあるレポジトリ。こちらはあまりREADMEが親切ではないので、こちらをメインに考えてみる

timtoronto634 commented 2 years ago

LICENSEはMIT License

https://github.com/github/rubocop-github/blob/master/LICENSE

timtoronto634 commented 2 years ago

そもそも何がしたいレポジトリなのかわからなくなってきた、が、 まずはインストールしてみる。

Legacy usageに

gem "rubocop", "< 0.68"
gem "rubocop-github"

とある。rubocopを動かすときにいれたのが1.23.0 なので、一度rubocopをGemfileから消して、bundle installした

おそらくだが、パッケージは取り除かれていない

timtoronto634 commented 2 years ago

いったんLegacy usageの通りに書いてbundle installしてみる。bundlerがうまく機能すれば、rubocopの1系が取り除かれて、0.68がインストールされるはず

timtoronto634 commented 2 years ago

bundle install の結果、

Bundle complete! 27 Gemfile dependencies, 105 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Post-install message from rubocop:
Performance Cops will be removed from RuboCop 0.68. Use rubocop-performance gem instead.

Put this in your Gemfile.

  gem 'rubocop-performance'

And then execute:

  $ bundle install

Put this into your .rubocop.yml.

  require: rubocop-performance

More information: https://github.com/rubocop-hq/rubocop-performance

と出た

timtoronto634 commented 2 years ago

rubocopは0.67.2がインストールされてる。 上のメッセージの詳細は不明だが、いったん動かしてみる

> docker-compose exec web rubocop

(略)

38 files inspected, 76 offenses detected, 70 offenses auto-correctable

offenseが3個増えた

timtoronto634 commented 2 years ago

調べたら、実行されているrubocopのバージョンが1.23のままだった

> docker-compose exec web rubocop -v
1.23.0
timtoronto634 commented 2 years ago

既存のgemを消してrubocop0.67.2で動かそうとするものの、方法がよくわからず、手探りでいろいろやった結果、最終的にはrubyのバージョン違いで動かせないとエラーが出た

# bundle ex rubocop
[Warn] Performance Cops will be removed from RuboCop 0.68. Use rubocop-performance gem instead.
       https://github.com/rubocop-hq/rubocop/tree/master/manual/migrate_performance_cops.md

Warning: unrecognized cop Layout/TrailingEmptyLines found in vendor/bundle/ruby/2.7.0/gems/rubocop-github-0.14.0/config/_default_shared.yml
Warning: unrecognized cop Lint/DuplicateHashKey found in vendor/bundle/ruby/2.7.0/gems/rubocop-github-0.14.0/config/_default_shared.yml
Warning: unrecognized cop Lint/RedundantStringCoercion found in vendor/bundle/ruby/2.7.0/gems/rubocop-github-0.14.0/config/_default_shared.yml
Warning: unrecognized cop Lint/RedundantCopDisableDirective found in vendor/bundle/ruby/2.7.0/gems/rubocop-github-0.14.0/config/_default_shared.yml
Warning: unrecognized cop Lint/RedundantSplatExpansion found in vendor/bundle/ruby/2.7.0/gems/rubocop-github-0.14.0/config/_default_shared.yml
Error: Unknown Ruby version 2.7 found in `.ruby-version`.
Supported versions: 2.2, 2.3, 2.4, 2.5, 2.6

rubocopの最新が既に1系であることからも分かる通り、rubocop-githubは古いといえそう

timtoronto634 commented 2 years ago

新しくrubyの環境を作り直して、これまで同様、READMEの手順でrubocopをインストール。

# rubocop -v
1.23.0
timtoronto634 commented 2 years ago

https://docs.rubocop.org/rubocop/1.23/development.html

rubocopのcop(rule)を開発する手順を見て操作を進める

timtoronto634 commented 2 years ago

タスクを作成する

bundle exec rake 'new_cop_sample_tim'

実行結果

root@b4045bf06f80:/myapp# bundle exec rake 'new_cop_sample_tim'
rake aborted!
Don't know how to build task 'new_cop_sample_tim' (See the list of available tasks with `rake --tasks`)
/usr/local/bundle/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
(See full trace by running task with --trace)

rakeの引数がないため失敗してる?

timtoronto634 commented 2 years ago

もしかしたらdocの解釈が違ったのかもしれないので

bundle exec rake 'new_cop[Department/Name]'

にたいして、[ ]をのこす必要があったのかも。

/myapp# bundle exec rake 'new_cop[Department/Name]'
rake aborted!
Don't know how to build task 'new_cop' (See the list of available tasks with `rake --tasks`)
/usr/local/bundle/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
(See full trace by running task with --trace)

だめそう

timtoronto634 commented 2 years ago

rakeにそういうタスクがあるのかと思い rake new_cop でぐぐったところ、 https://github.com/rubocop/rubocop/issues/4599 このイシューが見つかった。2017年のイシューで、

The rake task is meant for internal use. When we add full support for project specific cops, it should most likely be handled through a generator. 🙂 E.g.: rubocop generate cop Project/CustomCop

のように返答されてる。 このrake taskは内部の人間が使うためのもの、と言っているようだが、現在はすでに公開されてページまで作られており、このtaskが使えるようになっていないとdocとしてはおかしそう あるいは、 rubocop generate cop Project/CustomCop の方がdocに書いてあるべき?

timtoronto634 commented 2 years ago

https://github.com/rubocop/rubocop/issues/10117 別のissueで、taskが使えているっぽい記述はある。

クオーテーションをつけなければいいのかと思ったがそうでもない

timtoronto634 commented 2 years ago

https://gitter.im/bbatsov/rubocop?at=5c3607a11d1c2c3f9ce7c23d

どうやら、rubocopのプロジェクトディレクトリ以外では動作しないタスクらしい

timtoronto634 commented 2 years ago

cop を作るのにgit cloneがないのは不親切かもなので、PRチャンス

timtoronto634 commented 2 years ago
git clone https://github.com/rubocop/rubocop.git
 cd rubocop/
# bundle install --path vendor/bundle
# bundle exec rake 'new_cop[Department/Name]'
[create] lib/rubocop/cop/department/name.rb
[create] spec/rubocop/cop/department/name_spec.rb
[modify] lib/rubocop.rb - `require_relative 'rubocop/cop/department/name'` was injected.
[modify] A configuration for the cop is added into config/default.yml.
Do 4 steps:
  1. Modify the description of Department/Name in config/default.yml
  2. Implement your new cop in the generated file!
  3. Commit your new cop with a message such as
     e.g. "Add new `Department/Name` cop"
  4. Run `bundle exec rake changelog:new` to generate a changelog entry
     for your new cop.

と実行されたので、git clone と bundle installの記述はあっても良さそう

timtoronto634 commented 2 years ago

PR 作成して昨晩mergeされた

timtoronto634 commented 2 years ago

https://github.com/rubocop/rubocop/pull/10267

timtoronto634 commented 2 years ago

rubocopの仕組みの理解も兼ねて カスタムのcopを試しに作ってみる

 bundle exec rake 'new_cop[timtoronto/sample]'

descriptionを記述。試験的に、class名が11文字以上ならalert (?) をだすようにしてみる

      # sample cop
      # alert when length of class name is over 10
timtoronto634 commented 2 years ago

公式docのdevelopmentのページにBasicsとして基本的な使い方が書いてあるので、理解に役立った https://docs.rubocop.org/rubocop/1.23/development.html#basics

parserのgemは既にinstallされていた

bundle info parser
bundle ex ruby-parse -e '1'
timtoronto634 commented 2 years ago

class名もうまくparseできるかを見てみる

>bundle ex ruby-parse -e 'class HelloWorld end'
warning: parser/current is loading parser/ruby25, which recognizes
warning: 2.5.9-compliant syntax, but you are running 2.5.8.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
(class
  (const nil :HelloWorld) nil nil)

parseの正確性は厳密には判断できないが、よさそう

timtoronto634 commented 2 years ago

手順にも書いてある通り、コンソールに入ってREPLをつかってみる

bin/console 
Traceback (most recent call last):
(略)
/rubocop/lib/rubocop/cop/timtoronto/sample.rb:5: class/module name must be CONSTANT (SyntaxError)
    module timtoronto
                     ^
/rubocop/lib/rubocop/cop/timtoronto/sample.rb:29: class/module name must be CONSTANT
      class sample < Base
                   ^
>bin/console
Traceback (most recent call last):
(略)
/rubocop/cop/timtoronto/sample.rb:29: class/module name must be CONSTANT (SyntaxError)
      class sample < Base
                   ^

最初のタスクを走らせるときに、Department/Name は最初が大文字の必要があった。 言われてみればテンプレートの様式はそうなっている(Department のDが大文字)が、taskを作成する際に様式に合ってなければエラーで止めてもよさそう

timtoronto634 commented 2 years ago

tasks/new_cop.rake には

desc 'Generate a new cop template'
task :new_cop, [:cop] do |_task, args|
  cop_name = args.fetch(:cop) do
    warn 'usage: bundle exec rake new_cop[Department/Name]'
    exit!
  end

  generator = RuboCop::Cop::Generator.new(cop_name)

  generator.write_source
  generator.write_spec
  generator.inject_require
  generator.inject_config

  puts generator.todo
end

とあって、

task :new_cop, [:cop] do |_task, args|

現状、この task が何をやってくれるのかは知らない。 task の中身をみるのと、RuboCop::Cop::Generator の方にエラーを加えた方がいいかもしれないので、それも視野に入れておく

timtoronto634 commented 2 years ago

https://docs.ruby-lang.org/en/2.2.0/Rake/Task.htmlTasks are not usually created directly using the new method, but rather use the file and task convenience methods. とあるので、task はrakeの組み込みメソッドでよさそう

timtoronto634 commented 2 years ago

task はこれ https://docs.ruby-lang.org/en/2.2.0/Rake/DSL.html#method-i-task

timtoronto634 commented 2 years ago

rake 'new_cop[timtoronto/sample]'

task task_name, argument[, argument ...], :needs: dependencies

と対応するのか不明。 'new_cop[timtoronto/sample]' が new_cop (これはtask_name)と [timetoronto/sample] (これはargs) と分解されるものなのか

timtoronto634 commented 2 years ago

task メソッドは

def task(*args, &block) # :doc:
  Rake::Task.define_task(*args, &block)
end

とdefine_taskを呼び出してるみたいなので、そちらをみる https://docs.ruby-lang.org/en/2.2.0/Rake/Task.html#method-c-define_task

timtoronto634 commented 2 years ago

途中から先が追えなくなり、ブログを参考に読んでいた https://kei-p3.hatenablog.com/entry/2016/08/21/145000

が、結局何がなんだかわからなくなってので、task の中で何が起きているのかをりかいするため、printすることにした

desc 'Generate a new cop template'
task :new_cop, [:cop] do |_task, args|
  p args.class
  p args
  cop_name = args.fetch(:cop) do
    warn 'usage: bundle exec rake new_cop[Department/Name]'
    exit!
  end
  p cop_name
...

実行結果

>  bundle exec rake 'new_cop[Tim/Sample]' 
Rake::TaskArguments
#<Rake::TaskArguments cop: Tim/Sample>
"Tim/Sample"
[create] lib/rubocop/cop/tim/sample.rb
[create] spec/rubocop/cop/tim/sample_spec.rb
[modify] lib/rubocop.rb - `require_relative 'rubocop/cop/tim/sample'` was injected.
[modify] A configuration for the cop is added into config/default.yml.
Do 4 steps:
  1. Modify the description of Tim/Sample in config/default.yml
  2. Implement your new cop in the generated file!
  3. Commit your new cop with a message such as
     e.g. "Add new `Tim/Sample` cop"
  4. Run `bundle exec rake changelog:new` to generate a changelog entry
     for your new cop.
timtoronto634 commented 2 years ago

ブロック内のargs はRake::TaskArgumentsクラスで、args.fetch(:cop) によって "Tim/Sample" が取得されたことがわかる

cop_name を split('/')して先頭が大文字かどうか判定 or 全体を正規表現でvalidation などの案がある

きになってるのは、Department/Nameを大文字にしてもファイルパスは小文字に修正されてるといこと。それができるならクラス名を大文字に修正するくらいわけないのでは?

timtoronto634 commented 2 years ago

そもそもファイルシステムが大文字小文字を区別しないのか。 a/ と A/ は共存できない