Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace ActiveSupport inflections with Utils methods #14778

Merged
merged 19 commits into from Feb 28, 2023

Conversation

dduugg
Copy link
Sponsor Member

@dduugg dduugg commented Feb 23, 2023

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew typecheck with your changes locally?
  • Have you successfully run brew tests with your changes locally?

Based on @MikeMcQuaid's comment in #10508 (comment) I've put together a quick replacement candidate for ActiveSupport's String#pluralize monkey-patch, and ported the first five instances (based on git grep). There are ~50 instances of pluralize in the repo, so I want to confirm this approach before moving forward.

(Note that there are a handful of other String monkey-patches that I found when i remove them from the active-support rbi: five instances of demodulize, one of titleize, and one of first (which may be a type error). We will need to replace these before we can remove the active_support/core_ext/string/inflections dependency.)

(Also, after the breakages caused by #14502, I've preemptively checked homebrew-{cask,core} and found no instances of pluralize (but I didn't look for other ActiceSupport inflection methods)).

@BrewTestBot
Copy link
Member

Review period will end on 2023-02-24 at 05:35:32 UTC.

@BrewTestBot BrewTestBot added the waiting for feedback Merging is blocked until sufficient time has passed for review label Feb 23, 2023
@dduugg dduugg marked this pull request as draft February 23, 2023 05:56
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work so far! Implementation looks good, just have some naming thoughts.


# Combines `stem`` with the `singular`` or `plural` suffix based on `count`.
sig { params(count: Integer, stem: String, plural: String, singular: String).returns(String) }
def self.number(count, stem, plural = "s", singular = "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pluralise (or pluralize of you prefer `en_US) may be a nicer name here.

# Inflection utility methods, as a lightweight alternative to `ActiveSupport::Inflector``.
#
# @api private
module Inflection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this matches ActiveSupport but similarly perhaps making this just Utils.pluralize may be a nicer fit with the existing API.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do, though it feels materially different from the others at the top level:

irb(main):001:0> Utils.methods(false)
=> [:safe_popen_read, :git_commit_message, :popen, :git_short_head, :git_branch, :popen_read, :popen_write, :safe_popen_write, :git_head, :rewrite_child_error, :safe_fork]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dduugg Honestly I think those ones have just ended up there because we didn't use to separate into submodules. I think the benefit of having this just be Utils::pluralize or, probably overkill, even in or wrapped in utils.rb as pluralize is it makes invocations, usually interpolated, much shorter.


# Combines `stem`` with the `singular`` or `plural` suffix based on `count`.
sig { params(count: Integer, stem: String, plural: String, singular: String).returns(String) }
def self.number(count, stem, plural = "s", singular = "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on making plural and singular keyword rags? Could even abbreviate to pl and sg if line length is a concern. I think it will be much easier to use the methods this way since remembering the order won't be necessary.

Suggested change
def self.number(count, stem, plural = "s", singular = "")
def self.number(count, stem, plural: "s", singular: "")

I also like the pluralize naming, and if we go with that I think it makes sense to have the stem come first. So ultimately:

Suggested change
def self.number(count, stem, plural = "s", singular = "")
def self.pluralize(stem, count, plural: "s", singular: "")

@dduugg
Copy link
Sponsor Member Author

dduugg commented Feb 23, 2023

I'll go with the majority and call it pluralize, but will explain my original thinking here. Grammatical number is the concept we're implementing, so i chose number for that reason. (pluralize makes sense when it's acting on the singular noun, but this is starting in an undermined state).

I don't have a strong opinion about parameter ordering or kwarg vs positional, so i'll go with @Rylan12's recommendation there.

@dduugg
Copy link
Sponsor Member Author

dduugg commented Feb 23, 2023

I've changed the name to pluralize, used the method signature suggested by @Rylan12, ported a few more call sites, and added a non-monkey-patched demodulize. These methods remain under Utils::Inflection for now. There's some odd formatting due to brew style --fix that i'll clean up ahead of final review.

PTAL @Rylan12 @MikeMcQuaid

@BrewTestBot BrewTestBot removed the waiting for feedback Merging is blocked until sufficient time has passed for review label Feb 24, 2023
@BrewTestBot
Copy link
Member

Review period ended.

@dduugg dduugg force-pushed the inflection-util branch 5 times, most recently from a8b4a6f to 3420278 Compare February 24, 2023 17:53
@dduugg dduugg marked this pull request as ready for review February 24, 2023 18:11
@dduugg dduugg marked this pull request as draft February 24, 2023 18:18
@dduugg dduugg force-pushed the inflection-util branch 2 times, most recently from ec43833 to 4ab2f20 Compare February 28, 2023 04:52
@dduugg
Copy link
Sponsor Member Author

dduugg commented Feb 28, 2023

@MikeMcQuaid @Rylan12 PTAL

  • Changed the namespace from Utils::Inflections to Utils
  • Also ported demodulize and deconstantize from ActiveSupport::Inflections, and inlined an instance of titleize
  • Added tests

require "active_support/core_ext/string/inflections" remains in global.rb. I'd like to scope that to a separate PR in case we see downstream consequences (like we did in #14502 ) and wish to revert.

@dduugg dduugg marked this pull request as ready for review February 28, 2023 05:11
@@ -3415,56 +3415,6 @@ class Regexp::Token < ::Struct
end
end

class String
Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This serves as a type guard to avoid introducing monkey-patch dependencies into typed code while the deletion of require "active_support/core_ext/string/inflections" in global.rb is pending

@@ -76,7 +76,8 @@ def parse_api_response(limit = nil, last_package = "", repository:)
break if (limit && outdated_packages.size >= limit) || response.size <= 1
end

puts "#{outdated_packages.size} outdated #{package_term.pluralize(outdated_packages.size)} found"
package_term = package_term.chop if outdated_packages.size == 1
Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the only dynamic instance of pluralize. I took advantage of the fact that there's an easier path from plural to singular among {formulae, casks, packages} and reversed the logic here

@@ -103,7 +103,8 @@ def self.versions_from_tags(tags, regex = nil, &block)
tags.map do |tag|
if regex
# Use the first capture group (the version)
tag.scan(regex).first&.first
# This code is not typesafe unless the regex includes a capture group
T.unsafe(tag.scan(regex).first)&.first
Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a type error that appears when deleting String#first from the active support rbi below (but I don't think this code uses that path, looking at call sites).

@@ -46,7 +46,7 @@ def self.uninstall_casks(*casks, binaries: nil, force: false, verbose: false)
next if (versions = cask.versions).empty?

puts <<~EOS
#{cask} #{versions.to_sentence} #{"is".pluralize(versions.count)} still installed.
#{cask} #{versions.to_sentence} #{versions.count == 1 ? "is" : "are"} still installed.
Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's possible that versions.one? makes sense in substitutions like these, but there are some edge cases i didn't want to risk

@dduugg dduugg changed the title Draft implementation to replace ActiveSupport inflections Replace ActiveSupport inflections with Utils methods Feb 28, 2023
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, nice cleanup!

@MikeMcQuaid MikeMcQuaid merged commit 5ca4ab0 into Homebrew:master Feb 28, 2023
@MikeMcQuaid
Copy link
Member

Thanks again @dduugg!

carlocab added a commit to carlocab/homebrew-test-bot that referenced this pull request Mar 8, 2023
This was replaced by a method in `Utils`, but we don't really need that
here either.

See Homebrew/brew#14778.
@github-actions github-actions bot added the outdated PR was locked due to age label Apr 7, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants