From 2252dc1a3146d38abbc821978860ec8cc101d297 Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Thu, 18 Aug 2022 21:09:44 +0900 Subject: [PATCH 01/20] Format .github/workflows/ci.yml This PR is indentation adjusted. --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a950db5..c694d568 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,12 +10,12 @@ jobs: ruby_version: ["2.7", "3.0", "3.1"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby_version }} - - name: Install dependencies - run: bundle install --jobs 4 --retry 3 - - name: Run tests - run: bundle exec rake + - uses: actions/checkout@v2 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + - name: Install dependencies + run: bundle install --jobs 4 --retry 3 + - name: Run tests + run: bundle exec rake From af77d72f2ee4aac1b610ee2a551b7e98c7b4c329 Mon Sep 17 00:00:00 2001 From: Mike Griffin Date: Thu, 22 Sep 2022 15:21:53 +0100 Subject: [PATCH 02/20] Add autocorrect to RailsViewRenderShorthand The text is already provided in the error message, this reuses it to allow the problem to be auto corrected --- lib/rubocop/cop/github/rails_view_render_shorthand.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/rubocop/cop/github/rails_view_render_shorthand.rb b/lib/rubocop/cop/github/rails_view_render_shorthand.rb index e465d8d3..05952425 100644 --- a/lib/rubocop/cop/github/rails_view_render_shorthand.rb +++ b/lib/rubocop/cop/github/rails_view_render_shorthand.rb @@ -6,6 +6,8 @@ module RuboCop module Cop module GitHub class RailsViewRenderShorthand < Base + extend AutoCorrector + MSG = "Prefer `render` partial shorthand" def_node_matcher :render_with_options?, <<-PATTERN @@ -26,9 +28,13 @@ def on_send(node) locals_key = option_pairs.map { |pair| locals_key?(pair) }.compact.first if option_pairs.length == 1 && partial_key - add_offense(node, message: "Use `render #{partial_key.source}` instead") + add_offense(node, message: "Use `render #{partial_key.source}` instead") do |corrector| + corrector.replace(node.source_range, "render #{partial_key.source}") + end elsif option_pairs.length == 2 && partial_key && locals_key - add_offense(node, message: "Use `render #{partial_key.source}, #{locals_key.source}` instead") + add_offense(node, message: "Use `render #{partial_key.source}, #{locals_key.source}` instead") do |corrector| + corrector.replace(node.source_range, "render #{partial_key.source}, #{locals_key.source}") + end end end end From d97b12c16427c2e2e3be173fd51e608a352cd578 Mon Sep 17 00:00:00 2001 From: "Ben Sheldon [he/him]" Date: Thu, 13 Oct 2022 08:44:48 -0700 Subject: [PATCH 03/20] Create CONTRIBUTING.md --- CONTRIBUTING.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..d1804811 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing + +## Releasing a new version + +1. Update `rubocop-github.gemspec` with the next version number +2. Update the `CHANGELOG` with changes and contributor +3. Run `bundle` to update gem version contained in the lockfile +4. Make a commit: `Release v{VERSION}` +5. Tag the commit : `git tag v{VERSION}` +6. Create the package: `gem build rubocop-github.gemspec` +7. Push to GitHub: `git push origin && git push origin --tags` +8. Push to Rubygems: `gem push rubocop-github-{VERSION}.gem` +9. Publish a new release on GitHub: https://github.com/github/rubocop-github/releases/new From ce23317087c8e93ed628deebab828722eb9f9446 Mon Sep 17 00:00:00 2001 From: Ben Sheldon Date: Thu, 13 Oct 2022 13:41:13 -0700 Subject: [PATCH 04/20] Replace custom `RailsApplicationRecord` and `RailsRenderInline` cops with their upstream equivalent --- config/rails.yml | 10 +-- config/rails_cops.yml | 12 ---- guides/rails-render-inline.md | 27 -------- .../cop/github/rails_application_record.rb | 29 --------- lib/rubocop/cop/github/rails_render_inline.rb | 29 --------- test/test_rails_application_record.rb | 39 ------------ test/test_rails_render_inline.rb | 62 ------------------- 7 files changed, 2 insertions(+), 206 deletions(-) delete mode 100644 guides/rails-render-inline.md delete mode 100644 lib/rubocop/cop/github/rails_application_record.rb delete mode 100644 lib/rubocop/cop/github/rails_render_inline.rb delete mode 100644 test/test_rails_application_record.rb delete mode 100644 test/test_rails_render_inline.rb diff --git a/config/rails.yml b/config/rails.yml index e414a00a..afe402cc 100644 --- a/config/rails.yml +++ b/config/rails.yml @@ -2,9 +2,6 @@ require: - rubocop-github-rails - rubocop-rails -GitHub/RailsApplicationRecord: - Enabled: true - GitHub/RailsControllerRenderActionSymbol: Enabled: true @@ -17,9 +14,6 @@ GitHub/RailsControllerRenderPathsExist: GitHub/RailsControllerRenderShorthand: Enabled: true -GitHub/RailsRenderInline: - Enabled: true - GitHub/RailsRenderObjectCollection: Enabled: false @@ -94,7 +88,7 @@ Rails/ApplicationMailer: Enabled: false Rails/ApplicationRecord: - Enabled: false + Enabled: true Rails/ArelStar: Enabled: false @@ -307,7 +301,7 @@ Rails/RelativeDateConstant: Enabled: false Rails/RenderInline: - Enabled: false + Enabled: true Rails/RenderPlainText: Enabled: false diff --git a/config/rails_cops.yml b/config/rails_cops.yml index ef3d9a4f..87363fbc 100644 --- a/config/rails_cops.yml +++ b/config/rails_cops.yml @@ -1,6 +1,3 @@ -GitHub/RailsApplicationRecord: - Enabled: pending - GitHub/RailsControllerRenderActionSymbol: Enabled: pending Include: @@ -25,15 +22,6 @@ GitHub/RailsControllerRenderShorthand: Include: - 'app/controllers/**/*.rb' -GitHub/RailsRenderInline: - Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-inline.md - Include: - - 'app/controllers/**/*.rb' - - 'app/helpers/**/*.rb' - - 'app/view_models/**/*.rb' - - 'app/views/**/*.erb' - GitHub/RailsRenderObjectCollection: Enabled: pending diff --git a/guides/rails-render-inline.md b/guides/rails-render-inline.md deleted file mode 100644 index 8b5fa9b9..00000000 --- a/guides/rails-render-inline.md +++ /dev/null @@ -1,27 +0,0 @@ -# GitHub/RailsRenderInline - -tldr; Do not use `render inline:`. - -## Rendering plain text - -``` ruby -render inline: "Just plain text" # bad -``` - -The `inline:` option is often misused when plain text is being returned. Instead use `render plain: "Just plain text"`. - -## Rendering a dynamic ERB string - -String `#{}` interpolation is often misused with `render inline:` instead of using `<%= %>` interpolation. This will lead to a memory leak where an ERB method will be compiled and cached for each invocation of `render inline:`. - -``` ruby -render inline: "Hello #{@name}" # bad -``` - -## Rendering static ERB strings - -``` ruby -render inline: "Hello <%= @name %>" # bad -``` - -If you are passing a static ERB string to `render inline:`, this string is best moved to a `.erb` template under `app/views`. Template files are able to be precompiled at boot time. diff --git a/lib/rubocop/cop/github/rails_application_record.rb b/lib/rubocop/cop/github/rails_application_record.rb deleted file mode 100644 index 1ec30cf9..00000000 --- a/lib/rubocop/cop/github/rails_application_record.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "rubocop" - -module RuboCop - module Cop - module GitHub - class RailsApplicationRecord < Base - MSG = "Models should subclass from ApplicationRecord" - - def_node_matcher :active_record_base_const?, <<-PATTERN - (const (const nil? :ActiveRecord) :Base) - PATTERN - - def_node_matcher :application_record_const?, <<-PATTERN - (const nil? :ApplicationRecord) - PATTERN - - def on_class(node) - klass, superclass, _ = *node - - if active_record_base_const?(superclass) && !(application_record_const?(klass)) - add_offense(superclass) - end - end - end - end - end -end diff --git a/lib/rubocop/cop/github/rails_render_inline.rb b/lib/rubocop/cop/github/rails_render_inline.rb deleted file mode 100644 index 8f76fb2f..00000000 --- a/lib/rubocop/cop/github/rails_render_inline.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "rubocop" - -module RuboCop - module Cop - module GitHub - class RailsRenderInline < Base - MSG = "Avoid `render inline:`" - - def_node_matcher :render_with_options?, <<-PATTERN - (send nil? {:render :render_to_string} (hash $...)) - PATTERN - - def_node_matcher :inline_key?, <<-PATTERN - (pair (sym :inline) $_) - PATTERN - - def on_send(node) - if option_pairs = render_with_options?(node) - if option_pairs.detect { |pair| inline_key?(pair) } - add_offense(node) - end - end - end - end - end - end -end diff --git a/test/test_rails_application_record.rb b/test/test_rails_application_record.rb deleted file mode 100644 index 7ac77945..00000000 --- a/test/test_rails_application_record.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require_relative "./cop_test" -require "minitest/autorun" -require "rubocop/cop/github/rails_application_record" - -class TestRailsApplicationRecord < CopTest - def cop_class - RuboCop::Cop::GitHub::RailsApplicationRecord - end - - def test_good_model - offenses = investigate(cop, <<-RUBY) - class Repository < ApplicationRecord - end - RUBY - - assert_empty offenses.map(&:message) - end - - def test_application_record_model - offenses = investigate(cop, <<-RUBY) - class ApplicationRecord < ActiveRecord::Base - end - RUBY - - assert_empty offenses.map(&:message) - end - - def test_bad_model - offenses = investigate(cop, <<-RUBY) - class Repository < ActiveRecord::Base - end - RUBY - - assert_equal 1, offenses.count - assert_equal "Models should subclass from ApplicationRecord", offenses.first.message - end -end diff --git a/test/test_rails_render_inline.rb b/test/test_rails_render_inline.rb deleted file mode 100644 index 53d5cadd..00000000 --- a/test/test_rails_render_inline.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require_relative "./cop_test" -require "minitest/autorun" -require "rubocop/cop/github/rails_render_inline" - -class TestRailsRenderInline < CopTest - def cop_class - RuboCop::Cop::GitHub::RailsRenderInline - end - - def test_render_string_no_offense - offenses = investigate cop, <<-RUBY, "app/controllers/foo_controller.rb" - class FooController < ActionController::Base - def index - render template: "index" - end - - def show - render template: "show.html.erb", locals: { foo: @foo } - end - end - RUBY - - assert_equal 0, offenses.count - end - - def test_render_inline_offense - offenses = investigate cop, <<-RUBY, "app/controllers/products_controller.rb" - class ProductsController < ActionController::Base - def index - render inline: "<% products.each do |p| %>

<%= p.name %>

<% end %>" - end - end - RUBY - - assert_equal 1, offenses.count - assert_equal "Avoid `render inline:`", offenses[0].message - end - - def test_render_status_with_inline_offense - offenses = investigate cop, <<-RUBY, "app/controllers/products_controller.rb" - class ProductsController < ActionController::Base - def index - render status: 200, inline: "<% products.each do |p| %>

<%= p.name %>

<% end %>" - end - end - RUBY - - assert_equal 1, offenses.count - assert_equal "Avoid `render inline:`", offenses[0].message - end - - def test_erb_render_inline_offense - offenses = erb_investigate cop, <<-ERB, "app/views/products/index.html.erb" - <%= render inline: template %> - ERB - - assert_equal 1, offenses.count - assert_equal "Avoid `render inline:`", offenses[0].message - end -end From 15a6e783a40980e48da73468c95ab240b7ca48d5 Mon Sep 17 00:00:00 2001 From: Ben Sheldon Date: Thu, 13 Oct 2022 14:03:21 -0700 Subject: [PATCH 05/20] Add Contribution instructions, code of conduct, and codeowners --- CODEOWNERS | 1 + CODE_OF_CONDUCT.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 47 +++++++++++++++++++++++------ README.md | 2 +- 4 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 CODEOWNERS create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..6e12c3bc --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @github/ruby-archiecture-reviewers diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..2ef4f602 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at opensource+rubocop@github.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1804811..4f1f09da 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,42 @@ # Contributing -## Releasing a new version +We welcome your contributions to the project. Thank you! + +Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. + + +## What to contribute + +This repository, `rubocop-github` is part of a broader RuboCop ecosystem. + +If the Cop you would like to propose is **generally applicable outside of GitHub**: + +1. Propose the change upstream in the core open source project (e.g. [`rubocop`](https://github.com/rubocop/rubocop), or [`rubocop-rails`](https://github.com/rubocop/rubocop-rails)), where it will have maximal visibility and discussion/feedback. +1. Patch the change provisionally into GitHub's project(s), for immediate benefit; that can include this repository. +1. ...if the proposal is accepted, remove the patch and pull the updated upstream. +1. ...if the proposal is not accepted, we usually learn something about our proposal, and we then choose whether to maintain the patch ourselves, discard it, or identify a better open-source home for it. + +If the Cop is **only applicable for GitHub**, then this is the right place to propose it. + +## How to contribute a Pull Request + +1. Fork and clone the repository +1. [Build it and make sure the tests pass](README.md#Testing) on your machine +1. Create a new branch: `git checkout -b my-branch-name` +1. Make your change, add tests, and make sure the tests still pass +1. Push to your fork and submit a Pull Request +1. Pat yourself on the back and wait for your pull request to be reviewed and merged. + +## For Maintainers + +### Releasing a new version 1. Update `rubocop-github.gemspec` with the next version number -2. Update the `CHANGELOG` with changes and contributor -3. Run `bundle` to update gem version contained in the lockfile -4. Make a commit: `Release v{VERSION}` -5. Tag the commit : `git tag v{VERSION}` -6. Create the package: `gem build rubocop-github.gemspec` -7. Push to GitHub: `git push origin && git push origin --tags` -8. Push to Rubygems: `gem push rubocop-github-{VERSION}.gem` -9. Publish a new release on GitHub: https://github.com/github/rubocop-github/releases/new +1. Update the `CHANGELOG` with changes and contributor +1. Run `bundle` to update gem version contained in the lockfile +1. Make a commit: `Release v{VERSION}` +1. Tag the commit : `git tag v{VERSION}` +1. Create the package: `gem build rubocop-github.gemspec` +1. Push to GitHub: `git push origin && git push origin --tags` +1. Push to Rubygems: `gem push rubocop-github-{VERSION}.gem` +1. Publish a new release on GitHub: https://github.com/github/rubocop-github/releases/new diff --git a/README.md b/README.md index 8796a67d..16b7a152 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RuboCop GitHub ![CI](https://github.com/github/rubocop-github/workflows/CI/badge.svg?event=push) -This repository provides recommended RuboCop configuration and additional Cops for use on GitHub open source and internal Ruby projects. +This repository provides recommended RuboCop configuration and additional Cops for use on GitHub's open source and internal Ruby projects. ## Usage From 27c926dab95dc989da9e234f169a92142b33e270 Mon Sep 17 00:00:00 2001 From: "Ben Sheldon [he/him]" Date: Thu, 13 Oct 2022 14:04:25 -0700 Subject: [PATCH 06/20] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 6e12c3bc..fb48a77e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @github/ruby-archiecture-reviewers +* @github/ruby-architecture-reviewers From 60688936c81bc73440059e2934ba93560d54e58a Mon Sep 17 00:00:00 2001 From: Issy Long Date: Tue, 18 Oct 2022 17:39:44 +0000 Subject: [PATCH 07/20] config/rails_cops: Update styleguide links now `master` => `main` - GitHub will do the redirection for a bit (not sure exactly how long), but it's nice to make these a direct link rather than an onward hop. --- config/rails_cops.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/rails_cops.yml b/config/rails_cops.yml index ef3d9a4f..f8f817e1 100644 --- a/config/rails_cops.yml +++ b/config/rails_cops.yml @@ -8,7 +8,7 @@ GitHub/RailsControllerRenderActionSymbol: GitHub/RailsControllerRenderLiteral: Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md + StyleGuide: https://github.com/github/rubocop-github/blob/main/guides/rails-render-literal.md Include: - 'app/controllers/**/*.rb' @@ -21,13 +21,13 @@ GitHub/RailsControllerRenderPathsExist: GitHub/RailsControllerRenderShorthand: Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-shorthand.md + StyleGuide: https://github.com/github/rubocop-github/blob/main/guides/rails-controller-render-shorthand.md Include: - 'app/controllers/**/*.rb' GitHub/RailsRenderInline: Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-inline.md + StyleGuide: https://github.com/github/rubocop-github/blob/main/guides/rails-controller-render-inline.md Include: - 'app/controllers/**/*.rb' - 'app/helpers/**/*.rb' @@ -39,7 +39,7 @@ GitHub/RailsRenderObjectCollection: GitHub/RailsViewRenderLiteral: Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md + StyleGuide: https://github.com/github/rubocop-github/blob/main/guides/rails-render-literal.md Include: - 'app/helpers/**/*.rb' - 'app/view_models/**/*.rb' From 596f143a2bbd103b1914069671680502bb11efe5 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Tue, 18 Oct 2022 16:06:25 +0000 Subject: [PATCH 08/20] config/default: Link some rules to their styleguide justifications - "Some of", yes, since there are a lot. But I thought I'd get started since this is an important step towards being able to a) enable more RuboCop rules based on the evidence of our styleguide, b) realising how far adrift our RuboCop configs have potentially become from what's written in the Styleguide, c) encouraging honest adoption of these rules across GitHub because they're actually justified in text. --- config/default.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/config/default.yml b/config/default.yml index 52a0655e..d7883cef 100644 --- a/config/default.yml +++ b/config/default.yml @@ -65,8 +65,10 @@ Layout/BlockAlignment: Layout/BlockEndNewline: Enabled: true +# TODO: Enable this since it's in the styleguide. Layout/CaseIndentation: Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#indent-when-as-start-of-case Layout/ClassStructure: Enabled: false @@ -186,10 +188,12 @@ Layout/IndentationStyle: Enabled: true EnforcedStyle: spaces IndentationWidth: 2 + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#default-indentation Layout/IndentationWidth: Enabled: true Width: 2 + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#default-indentation Layout/InitialIndentation: Enabled: true @@ -259,9 +263,11 @@ Layout/SingleLineBlockChain: Layout/SpaceAfterColon: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAfterComma: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAfterMethodName: Enabled: true @@ -271,12 +277,14 @@ Layout/SpaceAfterNot: Layout/SpaceAfterSemicolon: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAroundBlockParameters: Enabled: true Layout/SpaceAroundEqualsInParameterDefault: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-around-equals Layout/SpaceAroundKeyword: Enabled: false @@ -311,6 +319,7 @@ Layout/SpaceInLambdaLiteral: Layout/SpaceInsideArrayLiteralBrackets: Enabled: true EnforcedStyle: no_space + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-spaces-braces Layout/SpaceInsideArrayPercentLiteral: Enabled: true @@ -341,6 +350,7 @@ Layout/TrailingEmptyLines: Layout/TrailingWhitespace: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#trailing-whitespace Lint/AmbiguousAssignment: Enabled: false @@ -678,8 +688,10 @@ Lint/UnreachableCode: Lint/UnreachableLoop: Enabled: false +# TODO: Enable this since it's in the styleguide. Lint/UnusedBlockArgument: Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-around-equals Lint/UnusedMethodArgument: Enabled: false @@ -976,8 +988,10 @@ Style/AccessorGrouping: Style/Alias: Enabled: false +# TODO: Enable this since it's in the styleguide. Style/AndOr: Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-and-or-or Style/ArgumentsForwarding: Enabled: false @@ -1077,6 +1091,7 @@ Style/DateTime: Style/DefWithParentheses: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#method-parens-when-arguments Style/Dir: Enabled: false @@ -1164,6 +1179,7 @@ Style/FloatDivision: Style/For: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#avoid-for Style/FormatString: Enabled: false @@ -1201,6 +1217,7 @@ Style/HashLikeCase: Style/HashSyntax: Enabled: true EnforcedStyle: ruby19_no_mixed_keys + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#symbols-as-keys Style/HashTransformKeys: Enabled: false @@ -1300,6 +1317,7 @@ Style/MultilineIfModifier: Style/MultilineIfThen: Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-then-for-multi-line-if-unless Style/MultilineInPatternThen: Enabled: false @@ -1475,8 +1493,10 @@ Style/RedundantRegexpCharacterClass: Style/RedundantRegexpEscape: Enabled: false +# TODO: Enable this since it's in the styleguide. Style/RedundantReturn: Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#avoid-return Style/RedundantSelf: Enabled: false @@ -1626,8 +1646,10 @@ Style/TrailingUnderscoreVariable: Style/TrivialAccessors: Enabled: false +# TODO: Enable this since it's in the styleguide. Style/UnlessElse: Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-else-with-unless Style/UnlessLogicalOperators: Enabled: false From 5631e22dd165a9be2d77a6566a7ae1e7c3a2fb94 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Tue, 18 Oct 2022 17:47:06 +0000 Subject: [PATCH 09/20] config/rails: Broader ERB exclude paths - Yes, by default Rails has `app/views/**/*.erb`, but ERB can also be elsewhere in the codebase. - This avoids users (of the Rails configs of this gem) from having to manually add other ERB exclusions, since these cops don't reliably play nicely with any ERB regardless of where it lives. --- config/rails.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/config/rails.yml b/config/rails.yml index e414a00a..3114c3cf 100644 --- a/config/rails.yml +++ b/config/rails.yml @@ -34,27 +34,27 @@ GitHub/RailsViewRenderShorthand: Layout/BlockAlignment: Exclude: - - app/views/**/*.erb + - "**/*.erb" Layout/IndentationWidth: Exclude: - - app/views/**/*.erb + - "**/*.erb" Layout/InitialIndentation: Exclude: - - app/views/**/*.erb + - "**/*.erb" Layout/SpaceInsideParens: Exclude: - - app/views/**/*.erb + - "**/*.erb" Layout/TrailingEmptyLines: Exclude: - - app/views/**/*.erb + - "**/*.erb" Layout/TrailingWhitespace: Exclude: - - app/views/**/*.erb + - "**/*.erb" Lint/UselessAccessModifier: ContextCreatingMethods: @@ -399,16 +399,16 @@ Rails/WhereNot: Style/For: Exclude: - - app/views/**/*.erb + - "**/*.erb" Style/OneLineConditional: Exclude: - - app/views/**/*.erb + - "**/*.erb" Style/Semicolon: Exclude: - - app/views/**/*.erb + - "**/*.erb" Style/StringLiterals: Exclude: - - app/views/**/*.erb + - "**/*.erb" From 5428bd25892707bab2f3cb1c1a3ed6da7acc1219 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Fri, 21 Oct 2022 12:03:13 +0000 Subject: [PATCH 10/20] config/default: Upstream cop disables since this is the central place - In `github/github` when we bumped this gem and bumped the version of RuboCop and turned off `DisabledByDefault`, there were some cops that RuboCop had detected offenses for that weren't declared in here as explicitly disabled. - Let's set `Enabled: false` for the new cops, so that this gem's config is the source of truth and downstream consumers don't diverge too much. --- config/default.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/config/default.yml b/config/default.yml index d7883cef..7aef6c8d 100644 --- a/config/default.yml +++ b/config/default.yml @@ -454,6 +454,15 @@ Lint/EmptyConditionalBody: Lint/EmptyEnsure: Enabled: true +Lint/EmptyExpression: + Enabled: false + +Lint/EmptyFile: + Enabled: false + +Lint/EmptyWhen: + Enabled: false + Lint/EmptyInterpolation: Enabled: true @@ -607,6 +616,9 @@ Lint/RegexpAsCondition: Lint/RequireParentheses: Enabled: true +Lint/RequireRangeParentheses: + Enabled: false + Lint/RequireRelativeSelfPath: Enabled: false @@ -1129,6 +1141,9 @@ Style/EmptyCaseCondition: Style/EmptyElse: Enabled: false +Style/EmptyHeredoc: + Enabled: false + Style/EmptyLambdaParameter: Enabled: false @@ -1273,6 +1288,9 @@ Style/LambdaCall: Style/LineEndConcatenation: Enabled: false +Style/MagicCommentFormat: + Enabled: false + Style/MapCompactWithConditionalBlock: Enabled: false From 25a3a08f7ac3aed0216a755e104e9fdbadd9bac5 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Fri, 21 Oct 2022 14:19:04 +0000 Subject: [PATCH 11/20] config/default: Remove some redundant `Enabled: true` for cops - For cops with a styleguide link, where there's evidence that we want the rule to apply, we don't need to also explicitly declare `Enabled: true` for each of them. Since we removed `DisabledByDefault`, the enablements here for cops that are *enabled by default in RuboCop itself** are redundant. - I could have gone further and removed the rules that RuboCop has enabled by default that _didn't_ have a styleguide link, but I feel like we need some evidence for why a rule is in place first for when people come looking at this gem's config to figure out why new rules are suddenly failing or not. --- config/default.yml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/config/default.yml b/config/default.yml index d7883cef..6ae30545 100644 --- a/config/default.yml +++ b/config/default.yml @@ -182,16 +182,14 @@ Layout/HeredocIndentation: Enabled: false Layout/IndentationConsistency: - Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#indentation Layout/IndentationStyle: - Enabled: true EnforcedStyle: spaces IndentationWidth: 2 StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#default-indentation Layout/IndentationWidth: - Enabled: true Width: 2 StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#default-indentation @@ -262,11 +260,9 @@ Layout/SingleLineBlockChain: Enabled: false Layout/SpaceAfterColon: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAfterComma: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAfterMethodName: @@ -276,18 +272,16 @@ Layout/SpaceAfterNot: Enabled: true Layout/SpaceAfterSemicolon: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAroundBlockParameters: Enabled: true Layout/SpaceAroundEqualsInParameterDefault: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-around-equals Layout/SpaceAroundKeyword: - Enabled: false + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-operators Layout/SpaceAroundMethodCallOperator: Enabled: false @@ -317,7 +311,6 @@ Layout/SpaceInLambdaLiteral: Enabled: false Layout/SpaceInsideArrayLiteralBrackets: - Enabled: true EnforcedStyle: no_space StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-spaces-braces @@ -349,7 +342,6 @@ Layout/TrailingEmptyLines: Enabled: true Layout/TrailingWhitespace: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#trailing-whitespace Lint/AmbiguousAssignment: @@ -1090,7 +1082,6 @@ Style/DateTime: Enabled: false Style/DefWithParentheses: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#method-parens-when-arguments Style/Dir: @@ -1178,7 +1169,6 @@ Style/FloatDivision: Enabled: false Style/For: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#avoid-for Style/FormatString: @@ -1215,7 +1205,6 @@ Style/HashLikeCase: Enabled: false Style/HashSyntax: - Enabled: true EnforcedStyle: ruby19_no_mixed_keys StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#symbols-as-keys @@ -1316,7 +1305,6 @@ Style/MultilineIfModifier: Enabled: false Style/MultilineIfThen: - Enabled: true StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#no-then-for-multi-line-if-unless Style/MultilineInPatternThen: @@ -1583,8 +1571,8 @@ Style/StringHashKeys: Enabled: false Style/StringLiterals: - Enabled: true EnforcedStyle: double_quotes + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#double-quotes Style/StringLiteralsInInterpolation: Enabled: false From 217b98638c7636652c1430a19d32c13f97eb7e27 Mon Sep 17 00:00:00 2001 From: Sam Partington Date: Fri, 21 Oct 2022 16:35:38 +0100 Subject: [PATCH 12/20] Fix Styleguide link in default.yml https://github.com/github/rubocop-github/pull/124/files#r1000474353 --- config/default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/default.yml b/config/default.yml index d7883cef..ad020013 100644 --- a/config/default.yml +++ b/config/default.yml @@ -691,7 +691,7 @@ Lint/UnreachableLoop: # TODO: Enable this since it's in the styleguide. Lint/UnusedBlockArgument: Enabled: false - StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#spaces-around-equals + StyleGuide: https://github.com/github/rubocop-github/blob/main/STYLEGUIDE.md#underscore-unused-vars Lint/UnusedMethodArgument: Enabled: false From 8e768057435f96782bb53fa91fc7c77f8d857a58 Mon Sep 17 00:00:00 2001 From: Sam Partington Date: Tue, 25 Oct 2022 13:52:40 +0100 Subject: [PATCH 13/20] Add link to Style Guide from README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8796a67d..7ba558fa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RuboCop GitHub ![CI](https://github.com/github/rubocop-github/workflows/CI/badge.svg?event=push) -This repository provides recommended RuboCop configuration and additional Cops for use on GitHub open source and internal Ruby projects. +This repository provides recommended RuboCop configuration and additional Cops for use on GitHub open source and internal Ruby projects, and is the home of [GitHub's Ruby Style Guide](./STYLEGUIDE.md). ## Usage From d24723ec59b2ceae6fd42f62746330841c35e058 Mon Sep 17 00:00:00 2001 From: Sam Partington Date: Tue, 25 Oct 2022 14:33:09 +0100 Subject: [PATCH 14/20] Add Rails recommendations to styleguide These were originally in our web-systems documentation --- STYLEGUIDE.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index 1e55a3be..56839237 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -27,6 +27,9 @@ This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide]. 1. [Conditional keywords](#conditional-keywords) 2. [Ternary operator](#ternary-operator) 17. [Syntax](#syntax) +18. [Rails](#rails) + 1. [content_for](#content_for) + 2. [Instance Variables in Views](#instance-variables-in-views) ## Layout @@ -893,4 +896,129 @@ result = hash.map { |_, v| v + 1 } Refactoring is even better. It's worth looking hard at any code that explicitly checks types. +## Rails + +### content_for + +Limit usage of `content_for` helper. The use of `content_for` is the same as setting an instance variable plus `capture`. + +``` erb +<% content_for :foo do %> + Hello +<% end %> +``` + +Is effectively the same as + +``` erb +<% @foo_content = capture do %> + Hello +<% end %> +``` + +See "Instance Variables in Views" below. + +#### Common Anti-patterns + +**Using `content_for` within the same template to capture data.** + +Instead, just use `capture`. + +``` erb + +<% content_for :page do %> + Hello +<% end %> +<% if foo? %> +
+ <%= yield :page %> +
+<% else %> + <%= yield :page %> +<% end %> +``` + +Simply capture and use a local variable since the result is only needed in this template. + +``` erb + +<% page = capture do %> + Hello +<% end %> +<% if foo? %> +
+ <%= page %> +
+<% else %> + <%= page %> +<% end %> +``` + +**Using `content_for` to pass content to a subtemplate.** + +Instead, `render layout:` with a block. + +``` erb + +<% content_for :page do %> + Hello +<% end %> +<%= render partial: "page" %> + +
+ <%= yield :page %> +
+``` + +Pass the content in a block directly to the `render` function. + +``` erb + +<%= render layout: "page" do %> + Hello +<% end %> + +
+ <%= yield %> +
+``` + +### Instance Variables in Views + +In general, passing data between templates with instance variables is discouraged. This even applies from controllers to templates, not just between partials. + +`:locals` can be used to pass data from a controller just like partials. + +``` ruby +def show + render "blob/show", locals: { + :repository => current_repository, + :commit => current_commit, + :blob => current_blob + } +end +``` + +Rails implicit renders are also discouraged. + +Always explicitly render templates with a full directory path. This makes template callers easier to trace. You can find all the callers of `"app/view/site/hompage.html.erb"` with a simple project search for `"site/homepage"`. + +``` ruby +def homepage + render "site/homepage" +end +``` + +#### Exceptions + +There are some known edge cases where you might be forced to use instance variables. In these cases, its okay to do so. + +##### Legacy templates + +If you need to call a subview that expects an instance variable be set. If possible consider refactoring the subview to accept a local instead. + +##### Layouts + +Unfortunately the only way to get data into a layout template is with instance variables. You can't explicitly pass locals to them. + [rubocop-guide]: https://github.com/rubocop-hq/ruby-style-guide From 9930c9050c0fd314ea291b8b08e7d7cd01dcef87 Mon Sep 17 00:00:00 2001 From: "Ben Sheldon [he/him]" Date: Wed, 26 Oct 2022 08:02:11 -0700 Subject: [PATCH 15/20] Update CONTRIBUTING.md Co-authored-by: Sam Partington --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4f1f09da..a69b7d28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Please note that this project is released with a [Contributor Code of Conduct](C ## What to contribute -This repository, `rubocop-github` is part of a broader RuboCop ecosystem. +This repository, `rubocop-github`, is part of a broader RuboCop ecosystem. If the Cop you would like to propose is **generally applicable outside of GitHub**: From ffeb9fbdc9003f0d125573d2fbb9079df50228c7 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Wed, 26 Oct 2022 15:30:43 +0000 Subject: [PATCH 16/20] STYLEGUIDE: For each styleguide recommendation, link to the RuboCop rule - This allows people who are reading the style guide to investigate the configuration of the RuboCop rules in their apps if they wish, without having to Google the words in our styleguide which might not match the RuboCop rule explanation, and guess as to what the cop is called. Co-authored-by: Issy Long Co-authored-by: Elena Tanasoiu --- STYLEGUIDE.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index 1e55a3be..476fcc02 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -34,9 +34,11 @@ This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide]. * Use soft-tabs with a two space indent. [[link](#default-indentation)] + * RuboCop rule: Layout/IndentationStyle * Indent `when` with the start of the `case` expression. [[link](#indent-when-as-start-of-case)] + * RuboCop rule: Layout/CaseIndentation ``` ruby # bad @@ -80,10 +82,18 @@ end * Never leave trailing whitespace. [[link](#trailing-whitespace)] + * RuboCop rule: Layout/TrailingWhitespace * Use spaces around operators, after commas, colons and semicolons, around `{` and before `}`. [[link](#spaces-operators)] + * RuboCop rule: Layout/SpaceAroundOperators + * RuboCop rule: Layout/SpaceAfterComma + * RuboCop rule: Layout/SpaceAfterColon + * RuboCop rule: Layout/SpaceBeforeBlockBraces + * RuboCop rule: Layout/SpaceInsideHashLiteralBraces + * RuboCop rule: Style/HashSyntax + * RuboCop rule: Layout/SpaceAroundOperators ``` ruby sum = 1 + 2 @@ -94,6 +104,8 @@ a, b = 1, 2 * No spaces after `(`, `[` or before `]`, `)`. [[link](#no-spaces-braces)] + * RuboCop rule: Layout/SpaceInsideParens + * RuboCop rule: Layout/SpaceInsideReferenceBrackets ``` ruby some(arg).other @@ -102,6 +114,7 @@ some(arg).other * No spaces after `!`. [[link](#no-spaces-bang)] + * RuboCop rule: Layout/SpaceAfterNot ``` ruby !array.include?(element) @@ -111,10 +124,12 @@ some(arg).other * End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof). [[link](#newline-eof)] + * RuboCop rule: Layout/TrailingEmptyLines * Use empty lines between `def`s and to break up a method into logical paragraphs. [[link](#empty-lines-def)] + * RuboCop rule: Layout/EmptyLineBetweenDefs ``` ruby def some_method @@ -134,12 +149,14 @@ end * Keep each line of code to a readable length. Unless you have a reason to, keep lines to a maximum of 118 characters. Why 118? That's the width at which the pull request diff UI needs horizontal scrolling (making pull requests harder to review). [[link](#line-length)] + * RuboCop rule: Layout/LineLength ## Classes * Avoid the usage of class (`@@`) variables due to their unusual behavior in inheritance. [[link](#class-variables)] + * RuboCop rule: Style/ClassVars ``` ruby class Parent @@ -164,6 +181,7 @@ Parent.print_class_var # => will print "child" * Use `def self.method` to define singleton methods. This makes the methods more resistant to refactoring changes. [[link](#singleton-methods)] + * RuboCop rule: Style/ClassMethodsDefinitions ``` ruby class TestClass @@ -181,6 +199,7 @@ class TestClass * Avoid `class << self` except when necessary, e.g. single accessors and aliased attributes. [[link](#class-method-definitions)] + * RuboCop rule: Style/ClassMethodsDefinitions ``` ruby class TestClass @@ -214,6 +233,8 @@ end * Indent the `public`, `protected`, and `private` methods as much the method definitions they apply to. Leave one blank line above them. [[link](#access-modifier-identation)] + * RuboCop rule: Layout/AccessModifierIndentation + * RuboCop rule: Layout/EmptyLinesAroundAccessModifier ``` ruby class SomeClass @@ -231,6 +252,7 @@ end * Avoid explicit use of `self` as the recipient of internal class or instance messages unless to specify a method shadowed by a variable. [[link](#self-messages)] + * RuboCop rule: Style/RedundantSelf ``` ruby class SomeClass @@ -248,6 +270,7 @@ end * Prefer `%w` to the literal array syntax when you need an array of strings. [[link](#percent-w)] + * RuboCop rule: Style/WordArray ``` ruby # bad @@ -265,6 +288,7 @@ STATES = %w(draft open closed) * Use symbols instead of strings as hash keys. [[link](#symbols-as-keys)] + * RuboCop rule: Style/StringHashKeys ``` ruby # bad @@ -300,9 +324,10 @@ end Avoid calling `send` and its cousins unless you really need it. Metaprogramming can be extremely powerful, but in most cases you can write code that captures your meaning by being explicit: [[link](#avoid-send)] + * RuboCop rule: Style/Send ``` ruby -# avoid +# avoid unless [:base, :head].include?(base_or_head) raise ArgumentError, "base_or_head must be either :base or :head" end @@ -366,6 +391,7 @@ end Use the Ruby 1.9 syntax for hash literals when all the keys are symbols: [[link](#symbols-as-hash-keys)] +* RuboCop rule: Style/StringHashKeys ``` ruby # bad @@ -396,6 +422,7 @@ link_to("Account", controller: "users", action: "show", id: user) If you have a hash with mixed key types, use the legacy hashrocket style to avoid mixing styles within the same hash: [[link](#consistent-hash-syntax)] +* RuboCop rule: Style/HashSyntax ``` ruby @@ -417,6 +444,7 @@ hsh = { [Keyword arguments](http://magazine.rubyist.net/?Ruby200SpecialEn-kwarg) are recommended but not required when a method's arguments may otherwise be opaque or non-obvious when called. Additionally, prefer them over the old "Hash as pseudo-named args" style from pre-2.0 ruby. [[link](#keyword-arguments)] +* RuboCop rule: Style/OptionalBooleanParameter So instead of this: @@ -444,21 +472,26 @@ remove_member(user, skip_membership_check: true) * Use `snake_case` for methods and variables. [[link](#snake-case-methods-vars)] + * RuboCop rule: Naming/SnakeCase + * RuboCop rule: Naming/VariableName * Use `CamelCase` for classes and modules. (Keep acronyms like HTTP, RFC, XML uppercase.) [[link](#camelcase-classes-modules)] + * RuboCop rule: Naming/ClassAndModuleCamelCase * Use `SCREAMING_SNAKE_CASE` for other constants. [[link](#screaming-snake-case-constants)] + * RuboCop rule: Naming/ConstantName * The names of predicate methods (methods that return a boolean value) should end in a question mark. (i.e. `Array#empty?`). [[link](#bool-methods-qmark)] + * RuboCop rule: Naming/PredicateName * The names of potentially "dangerous" methods (i.e. methods that modify `self` or the arguments, `exit!`, etc.) should end with an exclamation mark. Bang methods - should only exist if a non-bang counterpart (method name which does NOT end with !) + should only exist if a non-bang counterpart (method name which does NOT end with !) also exists. [[link](#dangerous-method-bang)] @@ -466,6 +499,7 @@ remove_member(user, skip_membership_check: true) * Use `%w` freely. [[link](#use-percent-w-freely)] + * RuboCop rule: Style/WordArray ``` ruby STATES = %w(draft open closed) @@ -474,6 +508,7 @@ STATES = %w(draft open closed) * Use `%()` for single-line strings which require both interpolation and embedded double-quotes. For multi-line strings, prefer heredocs. [[link](#percent-parens-single-line)] + * RuboCop rule: Style/BarePercentLiterals ``` ruby # bad (no interpolation needed) @@ -494,6 +529,7 @@ STATES = %w(draft open closed) * Use `%r` only for regular expressions matching *more than* one '/' character. [[link](#percent-r-regular-expressions)] + * RuboCop rule: Style/RegexpLiteral ``` ruby # bad @@ -512,7 +548,7 @@ STATES = %w(draft open closed) * Avoid using $1-9 as it can be hard to track what they contain. Named groups can be used instead. [[link](#capture-with-named-groups)] - + * RuboCop rule: Lint/MixedRegexpCaptureTypes ``` ruby # bad /(regexp)/ =~ string @@ -571,6 +607,7 @@ documentation about the libraries that the current file uses. * Prefer string interpolation instead of string concatenation: [[link](#string-interpolation)] + * RuboCop rule: Style/StringConcatenation ``` ruby # bad @@ -584,6 +621,7 @@ email_with_name = "#{user.name} <#{user.email}>" will always work without a delimiter change, and `'` is a lot more common than `"` in string literals. [[link](#double-quotes)] + * RuboCop rule: Style/StringLiterals ``` ruby # bad @@ -615,6 +653,7 @@ end * Use `def` with parentheses when there are arguments. Omit the parentheses when the method doesn't accept any arguments. [[link](#method-parens-when-arguments)] + * RuboCop rule: Style/DefWithParentheses ``` ruby def some_method @@ -632,9 +671,11 @@ end always use parentheses in the method invocation. For example, write `f((3 + 2) + 1)`. [[link](#parens-no-spaces)] + * RuboCop rule: Style/MethodCallWithArgsParentheses * Never put a space between a method name and the opening parenthesis. [[link](#no-spaces-method-parens)] + * RuboCop rule: Style/ParenthesesAsGroupedExpression ``` ruby # bad @@ -650,6 +691,7 @@ f(3 + 2) + 1 * Never use `then` for multi-line `if/unless`. [[link](#no-then-for-multi-line-if-unless)] + * RuboCop rule: Style/MultilineIfThen ``` ruby # bad @@ -665,10 +707,12 @@ end * The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead. [[link](#no-and-or-or)] + * RuboCop rule: Style/AndOr * Favor modifier `if/unless` usage when you have a single-line body. [[link](#favor-modifier-if-unless)] + * RuboCop rule: Style/MultilineTernaryOperator ``` ruby # bad @@ -682,6 +726,7 @@ do_something if some_condition * Never use `unless` with `else`. Rewrite these with the positive case first. [[link](#no-else-with-unless)] + * RuboCop rule: Style/UnlessElse ``` ruby # bad @@ -701,6 +746,7 @@ end * Don't use parentheses around the condition of an `if/unless/while`. [[link](#no-parens-if-unless-while)] + * RuboCop rule: Style/ParenthesesAroundCondition ``` ruby # bad @@ -720,6 +766,7 @@ end trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs for single line conditionals. [[link](#trivial-ternary)] + * RuboCop rule: Style/MultilineTernaryOperator ``` ruby # bad @@ -731,11 +778,13 @@ result = some_condition ? something : something_else * Avoid multi-line `?:` (the ternary operator), use `if/unless` instead. [[link](#no-multiline-ternary)] + * RuboCop rule: Style/MultilineTernaryOperator * Use one expression per branch in a ternary operator. This also means that ternary operators must not be nested. Prefer `if/else` constructs in these cases. [[link](#one-expression-per-branch)] + * RuboCop rule: Style/NestedTernaryOperator ``` ruby # bad @@ -757,6 +806,7 @@ end doesn't introduce a new scope (unlike `each`) and variables defined in its block will be visible outside it. [[link](#avoid-for)] + * RuboCop rule: Style/For ``` ruby arr = [1, 2, 3] @@ -776,6 +826,7 @@ arr.each { |elem| puts elem } definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end` when chaining. [[link](#squiggly-braces)] + * RuboCop rule: Style/BlockDelimiters ``` ruby names = ["Bozhidar", "Steve", "Sarah"] @@ -798,11 +849,12 @@ end.map { |name| name.upcase } ``` * Some will argue that multiline chaining would look OK with the use of `{...}`, - but they should ask themselves: is this code really readable and can't the block's + but they should ask themselves: is this code really readable and can't the block's contents be extracted into nifty methods? * Avoid `return` where not required. [[link](#avoid-return)] + * RuboCop rule: Style/RedundantReturn ``` ruby # bad @@ -818,6 +870,7 @@ end * Use spaces around the `=` operator when assigning default values to method parameters: [[link](#spaces-around-equals)] + * RuboCop rule: Style/SpaceAroundEqualsInParameterDefault ``` ruby # bad @@ -850,6 +903,7 @@ if (v = next_value) == "hello" ... * Use `||=` freely to initialize variables. [[link](#memoize-away)] + * RuboCop rule: Style/OrAssignment ``` ruby # set name to Bozhidar, only if it's nil or false @@ -859,6 +913,7 @@ name ||= "Bozhidar" * Don't use `||=` to initialize boolean variables. (Consider what would happen if the current value happened to be `false`.) [[link](#no-memoization-for-boolean)] + * RuboCop rule: Style/OrAssignment ``` ruby # bad - would set enabled to true even if it was false @@ -873,9 +928,11 @@ enabled = true if enabled.nil? one-liner scripts is discouraged. Prefer long form versions such as `$PROGRAM_NAME`. [[link](#no-cryptic-vars)] + * RuboCop rule: Style/SpecialGlobalVars * Use `_` for unused block parameters. [[link](#underscore-unused-vars)] + * RuboCop rule: Style/UnusedBlockArgument ``` ruby # bad @@ -890,6 +947,7 @@ result = hash.map { |_, v| v + 1 } For example, `String === "hi"` is true and `"hi" === String` is false. Instead, use `is_a?` or `kind_of?` if you must. [[link](#type-checking-is-a-kind-of)] + * RuboCop rule: Style/CaseEquality Refactoring is even better. It's worth looking hard at any code that explicitly checks types. From 90a607fbb26666eae11b8d2c4253edd85b3e8da8 Mon Sep 17 00:00:00 2001 From: Issy Long Date: Thu, 27 Oct 2022 12:16:15 +0100 Subject: [PATCH 17/20] STYLEGUIDE: `UnusedBlockArgument` is in `Lint` not `Style` --- STYLEGUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index b2940753..758651b6 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -935,7 +935,7 @@ enabled = true if enabled.nil? * Use `_` for unused block parameters. [[link](#underscore-unused-vars)] - * RuboCop rule: Style/UnusedBlockArgument + * RuboCop rule: Lint/UnusedBlockArgument ``` ruby # bad From 90e921a579f959eceded18791bdf87e813107620 Mon Sep 17 00:00:00 2001 From: Ben Sheldon Date: Fri, 28 Oct 2022 10:17:54 -0700 Subject: [PATCH 18/20] Pin versions, add Dependabot rules, update rubocop versions and create pending files --- .github/dependabot.yml | 7 +++++ .rubocop.yml | 1 + CONTRIBUTING.md | 19 ++++++++++++++ Gemfile.lock | 52 +++++++++++++++++++------------------ config/default.yml | 3 +++ config/default_pending.yml | 6 +++++ config/rails.yml | 3 +++ config/rails_cops.yml | 9 ------- config/rails_pending.yml | 20 ++++++++++++++ lib/rubocop-github-rails.rb | 2 -- rubocop-github.gemspec | 6 ++--- 11 files changed, 89 insertions(+), 39 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 config/default_pending.yml create mode 100644 config/rails_pending.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..bdb77e0f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: bundler + directory: '/' + versioning-strategy: increase + schedule: + interval: weekly diff --git a/.rubocop.yml b/.rubocop.yml index 9c49771d..afe2d021 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,6 @@ inherit_from: - ./config/default.yml + - ./config/rails.yml Naming/FileName: Enabled: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a69b7d28..fcab75d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,25 @@ If the Cop is **only applicable for GitHub**, then this is the right place to pr ## For Maintainers +### Updating Rubocop Dependencies + +Rubocop regularly releases new versions with new cops. We want to keep up to date with the latest Rubocop releases, and keep these rules and styleguide in sync to reduce burden on consumers of this gem. + +- Run `bundle update rubocop rubocop-performance rubocop-rails` to update the dependencies within this repository. Major updates will require updating the `.gemspec` file because of the pinned version constraints. +- Run `bundle exec rubocop`, and copy the output of newly introduced rules into `config/default_pending.yml` and `config/rails_pending.yml`. They should look like this: + + ```sh + Lint/DuplicateMagicComment: # new in 1.37 + Enabled: true + Style/OperatorMethodCall: # new in 1.37 + Enabled: true + Style/RedundantStringEscape: # new in 1.37 + Enabled: true + ``` + +- Run `bundle exec rubocop` again to ensure that it runs cleanly without any pending cops. Also run `bundle exec rake` to run the tests. +- Work through the pending cops, and copy them to `config/{default,rails}.yml` with an explicity `Enabled: true` or `Enabled: false` depending on your decision as to whether they should be part of our standard ruleset. + ### Releasing a new version 1. Update `rubocop-github.gemspec` with the next version number diff --git a/Gemfile.lock b/Gemfile.lock index e597b511..7395888c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,20 +2,20 @@ PATH remote: . specs: rubocop-github (0.19.0) - rubocop (>= 1.0.0) - rubocop-performance - rubocop-rails + rubocop (~> 1.37) + rubocop-performance (~> 1.15) + rubocop-rails (~> 2.17) GEM remote: https://rubygems.org/ specs: - actionview (7.0.3) - activesupport (= 7.0.3) + actionview (7.0.4) + activesupport (= 7.0.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activesupport (7.0.3) + activesupport (7.0.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -24,22 +24,23 @@ GEM builder (3.2.4) concurrent-ruby (1.1.10) crass (1.0.6) - erubi (1.10.0) - i18n (1.10.0) + erubi (1.11.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) - loofah (2.18.0) + json (2.6.2) + loofah (2.19.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) - minitest (5.16.1) - nokogiri (1.13.6-arm64-darwin) + minitest (5.16.3) + nokogiri (1.13.9-arm64-darwin) racc (~> 1.4) - nokogiri (1.13.6-x86_64-darwin) + nokogiri (1.13.9-x86_64-darwin) racc (~> 1.4) parallel (1.22.1) - parser (3.1.2.0) + parser (3.1.2.1) ast (~> 2.4.1) racc (1.6.0) - rack (2.2.3.1) + rack (3.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) @@ -47,30 +48,31 @@ GEM loofah (~> 2.3) rainbow (3.1.1) rake (13.0.6) - regexp_parser (2.5.0) + regexp_parser (2.6.0) rexml (3.2.5) - rubocop (1.31.0) + rubocop (1.37.1) + json (~> 2.3) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.1.2.1) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.18.0, < 2.0) + rubocop-ast (>= 1.23.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.18.0) + rubocop-ast (1.23.0) parser (>= 3.1.1.0) - rubocop-performance (1.14.2) + rubocop-performance (1.15.0) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.15.1) + rubocop-rails (2.17.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.7.0, < 2.0) + rubocop (>= 1.33.0, < 2.0) ruby-progressbar (1.11.0) - tzinfo (2.0.4) + tzinfo (2.0.5) concurrent-ruby (~> 1.0) - unicode-display_width (2.2.0) + unicode-display_width (2.3.0) PLATFORMS arm64-darwin-21 @@ -84,4 +86,4 @@ DEPENDENCIES rubocop-github! BUNDLED WITH - 2.2.33 + 2.3.24 diff --git a/config/default.yml b/config/default.yml index 6b46b224..0a3672c7 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1,3 +1,6 @@ +inherit_from: + - ./default_pending.yml + require: - rubocop-github - rubocop-performance diff --git a/config/default_pending.yml b/config/default_pending.yml new file mode 100644 index 00000000..ee85c603 --- /dev/null +++ b/config/default_pending.yml @@ -0,0 +1,6 @@ +Lint/DuplicateMagicComment: # new in 1.37 + Enabled: false +Style/OperatorMethodCall: # new in 1.37 + Enabled: false +Style/RedundantStringEscape: # new in 1.37 + Enabled: false diff --git a/config/rails.yml b/config/rails.yml index 81ef8a4c..b7b8d6ec 100644 --- a/config/rails.yml +++ b/config/rails.yml @@ -1,3 +1,6 @@ +inherit_from: + - ./rails_pending.yml + require: - rubocop-github-rails - rubocop-rails diff --git a/config/rails_cops.yml b/config/rails_cops.yml index 1443e4ba..d0d0a34c 100644 --- a/config/rails_cops.yml +++ b/config/rails_cops.yml @@ -22,15 +22,6 @@ GitHub/RailsControllerRenderShorthand: Include: - 'app/controllers/**/*.rb' -GitHub/RailsRenderInline: - Enabled: pending - StyleGuide: https://github.com/github/rubocop-github/blob/main/guides/rails-controller-render-inline.md - Include: - - 'app/controllers/**/*.rb' - - 'app/helpers/**/*.rb' - - 'app/view_models/**/*.rb' - - 'app/views/**/*.erb' - GitHub/RailsRenderObjectCollection: Enabled: pending diff --git a/config/rails_pending.yml b/config/rails_pending.yml new file mode 100644 index 00000000..b3abb0b5 --- /dev/null +++ b/config/rails_pending.yml @@ -0,0 +1,20 @@ +Rails/ActionControllerFlashBeforeRender: # new in 2.16 + Enabled: false +Rails/ActionOrder: # new in 2.17 + Enabled: false +Rails/ActiveSupportOnLoad: # new in 2.16 + Enabled: false +Rails/FreezeTime: # new in 2.16 + Enabled: false +Rails/IgnoredColumnsAssignment: # new in 2.17 + Enabled: false +Rails/RootPathnameMethods: # new in 2.16 + Enabled: false +Rails/ToSWithArgument: # new in 2.16 + Enabled: false +Rails/TopLevelHashWithIndifferentAccess: # new in 2.16 + Enabled: false +Rails/WhereMissing: # new in 2.16 + Enabled: false +Rails/WhereNotWithMultipleConditions: # new in 2.17 + Enabled: false diff --git a/lib/rubocop-github-rails.rb b/lib/rubocop-github-rails.rb index 02aa6adc..887b1df5 100644 --- a/lib/rubocop-github-rails.rb +++ b/lib/rubocop-github-rails.rb @@ -6,12 +6,10 @@ RuboCop::GitHub::Inject.rails_defaults! -require "rubocop/cop/github/rails_application_record" require "rubocop/cop/github/rails_controller_render_action_symbol" require "rubocop/cop/github/rails_controller_render_literal" require "rubocop/cop/github/rails_controller_render_paths_exist" require "rubocop/cop/github/rails_controller_render_shorthand" -require "rubocop/cop/github/rails_render_inline" require "rubocop/cop/github/rails_render_object_collection" require "rubocop/cop/github/rails_view_render_literal" require "rubocop/cop/github/rails_view_render_paths_exist" diff --git a/rubocop-github.gemspec b/rubocop-github.gemspec index 7b243dd4..c6d1e41c 100644 --- a/rubocop-github.gemspec +++ b/rubocop-github.gemspec @@ -10,9 +10,9 @@ Gem::Specification.new do |s| s.files = Dir["README.md", "STYLEGUIDE.md", "LICENSE", "config/*.yml", "lib/**/*.rb", "guides/*.md"] - s.add_dependency "rubocop", ">= 1.0.0" - s.add_dependency "rubocop-performance" - s.add_dependency "rubocop-rails" + s.add_dependency "rubocop", "~> 1.37" + s.add_dependency "rubocop-performance", "~> 1.15" + s.add_dependency "rubocop-rails", "~> 2.17" s.add_development_dependency "actionview" s.add_development_dependency "minitest" From d959dddf041812457cb93b0c42b2d087b6c35cc9 Mon Sep 17 00:00:00 2001 From: Ben Sheldon Date: Fri, 28 Oct 2022 11:04:20 -0700 Subject: [PATCH 19/20] Update version constraint from `~>` to `>=` --- Gemfile.lock | 6 +++--- rubocop-github.gemspec | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7395888c..ccf0bb2d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,9 +2,9 @@ PATH remote: . specs: rubocop-github (0.19.0) - rubocop (~> 1.37) - rubocop-performance (~> 1.15) - rubocop-rails (~> 2.17) + rubocop (>= 1.37) + rubocop-performance (>= 1.15) + rubocop-rails (>= 2.17) GEM remote: https://rubygems.org/ diff --git a/rubocop-github.gemspec b/rubocop-github.gemspec index c6d1e41c..d2896876 100644 --- a/rubocop-github.gemspec +++ b/rubocop-github.gemspec @@ -10,9 +10,9 @@ Gem::Specification.new do |s| s.files = Dir["README.md", "STYLEGUIDE.md", "LICENSE", "config/*.yml", "lib/**/*.rb", "guides/*.md"] - s.add_dependency "rubocop", "~> 1.37" - s.add_dependency "rubocop-performance", "~> 1.15" - s.add_dependency "rubocop-rails", "~> 2.17" + s.add_dependency "rubocop", ">= 1.37" + s.add_dependency "rubocop-performance", ">= 1.15" + s.add_dependency "rubocop-rails", ">= 2.17" s.add_development_dependency "actionview" s.add_development_dependency "minitest" From 7c4a43c3f38e33350d6aa4700204ccb2235d1766 Mon Sep 17 00:00:00 2001 From: Ben Sheldon Date: Fri, 28 Oct 2022 12:09:42 -0700 Subject: [PATCH 20/20] Release v0.20.0 --- CHANGELOG.md | 4 ++++ Gemfile.lock | 2 +- rubocop-github.gemspec | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b4ce534..08647f45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## v0.20.0 + +- Updated minimum dependencies for "rubocop" (`>= 1.37`), "rubocop-performance" (`>= 1.15`), and "rubocop-rails", (`>= 2.17`). + ## v0.19.0 - Unset `DisabledByDefault: true` in `config/default.yml`. Prevents confusing behaviour where users of the gem didn't realise that RuboCop's default cops weren't being applied (including potentially custom cops in their projects). We've explicitly set `Enabled: false` for all the cops that were previously default disabled. This has the effect that consumers of this gem won't be surprised by new linting violations when they use this new version in their projects. (https://github.com/github/rubocop-github/pull/119) diff --git a/Gemfile.lock b/Gemfile.lock index ccf0bb2d..37967364 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - rubocop-github (0.19.0) + rubocop-github (0.20.0) rubocop (>= 1.37) rubocop-performance (>= 1.15) rubocop-rails (>= 2.17) diff --git a/rubocop-github.gemspec b/rubocop-github.gemspec index d2896876..00242746 100644 --- a/rubocop-github.gemspec +++ b/rubocop-github.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = "rubocop-github" - s.version = "0.19.0" + s.version = "0.20.0" s.summary = "RuboCop GitHub" s.description = "Code style checking for GitHub Ruby repositories " s.homepage = "https://github.com/github/rubocop-github" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy