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

rubocop: order uninstall/zap methods #16377

Merged

Conversation

razvanazamfirei
Copy link
Member

@razvanazamfirei razvanazamfirei commented Dec 21, 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?

This PR introduces a new RuboCop rule to ensure a standardized order of uninstall/zap methods. The changes involve updating the constants to include a predefined order for uninstall methods and adding a new cop (UninstallMethodsOrder) to enforce this order.

Note: Our documentation currently conflicts with this implementation. Our documentation recommends ordering methods alphabetically. This cop orders methods based on the order of execution. I think both are reasonable and I would be happy to change it to alphabetical.

This should work nicely with: #16365

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.

Makes sense to me! Rerequest review when no longer draft.

@razvanazamfirei razvanazamfirei force-pushed the rubocop-uninstall-methods-order branch 2 times, most recently from 49c51bf to 4e18311 Compare December 26, 2023 06:29
@razvanazamfirei
Copy link
Member Author

I'm having some issues writing tests for this. I would appreciate any help, but the rest of the PR should be ready.

@razvanazamfirei razvanazamfirei marked this pull request as ready for review December 26, 2023 06:31
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.

Code looks good but needs some tests. I'd suggest copy-pasting existing tests and trying to modify or asking @issyl0 for help in Slack.

@bevanjkay
Copy link
Member

@razvanazamfirei Below is an initial run through a test spec for this.

Note that these are currently failing due to some potential issues with how whitespace is taken into account in the auto-corrector.
This doesn't show up when you run brew style because each offense is then picked up by the white-space cop.

There's also a test that takes into account inline comments which is currently failing.

Expand for Code

`/Library/Homebrew/test/rubocops/cask/uninstall_methods_order_spec.rb`

# frozen_string_literal: true

require "rubocops/rubocop-cask"

describe RuboCop::Cop::Cask::UninstallMethodsOrder, :config do
  it "accepts when all stanzas are in order" do
    expect_no_offenses <<~RUBY
            cask 'foo' do
              uninstall early_script: {
                          executable: "foo.sh",
                          args:       ["--unattended"],
                        },
                        launchctl:    "com.example.foo",
                        quit:         "com.example.foo",
                        signal:       ["TERM", "com.example.foo"],
                        login_item:   "FooApp",
                        kext:         "com.example.foo",
                        script:       {
                          executable: "foo.sh",
                          args:       ["--unattended"],
                        },
                        pkgutil:      "com.example.foo",
                        delete:       "~/Library/Preferences/com.example.foo",
                        trash:        "~/Library/Preferences/com.example.foo",
                        rmdir:        "~/Library/Foo"

              zap early_script: {
                    executable: "foo.sh",
                    args:       ["--unattended"],
                  },
                  launchctl:    "com.example.foo",
                  quit:         "com.example.foo",
                  signal:       ["TERM", "com.example.foo"],
                  login_item:   "FooApp",
                  kext:         "com.example.foo",
                  script:       {
                    executable: "foo.sh",
                    args:       ["--unattended"],
                  },
                  pkgutil:      "com.example.foo",
                  delete:       "~/Library/Preferences/com.example.foo",
                  trash:        "~/Library/Preferences/com.example.foo",
                  rmdir:        "~/Library/Foo"
            end
    RUBY
  end

  it "reports an offense when uninstall methods are out of order" do
    expect_offense <<~CASK
      cask 'foo' do
        uninstall quit:      "com.example.foo",
                  ^^^^ `quit` method out of order
                  launchctl: "com.example.foo"
                  ^^^^^^^^^ `launchctl` method out of order
      end
    CASK

    expect_correction <<~CASK
      cask 'foo' do
        uninstall launchctl: "com.example.foo",
                  quit:      "com.example.foo"
      end
    CASK
  end

  it "reports an offense when zap methods are out of order" do
    expect_offense <<~CASK
      cask 'foo' do
        zap rmdir: "/Library/Foo",
            ^^^^^ `rmdir` method out of order
            trash: "com.example.foo"
            ^^^^^ `trash` method out of order
      end
    CASK

    expect_correction <<~CASK
      cask 'foo' do
        zap trash: "com.example.foo",
        rmdir: "/Library/Foo"
      end
    CASK
  end

  it "keeps associated comments when auto-correcting" do
    expect_offense <<~CASK
      cask 'foo' do
        uninstall quit:      "com.example.foo", # comment on same line
                  ^^^^ `quit` method out of order
                  launchctl: "com.example.foo"
                  ^^^^^^^^^ `launchctl` method out of order
      end
    CASK

    expect_correction <<~CASK
      cask 'foo' do
        uninstall launchctl: "com.example.foo",
                  quit:      "com.example.foo" # comment on same line
      end
    CASK
  end

  it "registers an offense when inside an `on_os` block" do
    expect_offense <<~CASK
      cask "foo" do
        on_catalina do
          uninstall trash:     "com.example.foo",
                    ^^^^^ `trash` method out of order
                    launchctl: "com.example.foo"
                    ^^^^^^^^^ `launchctl` method out of order
        end
        on_ventura do
          uninstall quit:      "com.example.foo",
                    ^^^^ `quit` method out of order
                    launchctl: "com.example.foo"
                    ^^^^^^^^^ `launchctl` method out of order
        end
      end
    CASK

    expect_correction <<~CASK
      cask "foo" do
        on_catalina do
          uninstall launchctl: "com.example.foo",
                    trash:     "com.example.foo"
        end
        on_ventura do
          uninstall launchctl: "com.example.foo",
                    quit:      "com.example.foo"
        end
      end
    CASK
  end
end

@razvanazamfirei
Copy link
Member Author

Thank you so much, @bevanjkay! Let me merge the tests and I'll fix the inline comments issue!

@razvanazamfirei razvanazamfirei force-pushed the rubocop-uninstall-methods-order branch 3 times, most recently from c92a877 to 898d8f0 Compare January 1, 2024 15:23
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.

Code looking good now (once CI failures addressed)!

Copy link

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale No recent activity label Jan 23, 2024
@razvanazamfirei razvanazamfirei removed the stale No recent activity label Jan 27, 2024
@bevanjkay
Copy link
Member

@razvanazamfirei I haven't checked for any occurrences in the repo, so this may not be a current issue. But what happens if there is a comment between two uninstall/zap keys.

uninstall quit:  "com.foo.bar",
          # comment here
          trash: "..."

@razvanazamfirei
Copy link
Member Author

@bevanjkay, this seems to be a problem only in one cask: jupyterlab. The comment will be overwritten. I'm not sure if the complexity of handling that case is worth it. It also has the potential to create confusing situations.

  uninstall signal:    [
              ["TERM", "com.every.thing.controller#{version.major}"],
              ["TERM", "com.every.thing.bin"],
            ],
            # Something about launchctl not relevant to anything else
            launchctl: "com.every.thing.agent",
            kext:      "com.every.thing.driver",
            delete:    "/Library/EverythingHelperTools"

would be corrected to:

  # Something about launchctl not relevant to anything else
  uninstall	launchctl: "com.every.thing.agent",
            signal:    [
              ["TERM", "com.every.thing.controller#{version.major}"],
              ["TERM", "com.every.thing.bin"],
            ],
            kext:      "com.every.thing.driver",
            delete:    "/Library/EverythingHelperTools"

Copy link
Member

@issyl0 issyl0 left a comment

Choose a reason for hiding this comment

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

Looks great, thanks for the perseverance here, the comments handling has a tendency to 🤯.

@razvanazamfirei
Copy link
Member Author

Thanks for the patience, @issyl0! :)

@MikeMcQuaid MikeMcQuaid merged commit 2cb8efc into Homebrew:master Jan 29, 2024
24 checks passed
@MikeMcQuaid
Copy link
Member

Thanks again @razvanazamfirei!

@razvanazamfirei razvanazamfirei deleted the rubocop-uninstall-methods-order branch January 29, 2024 16:43
@github-actions github-actions bot added the outdated PR was locked due to age label Feb 29, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 29, 2024
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