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

Fix method definition cop #44

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

kuahyeow
Copy link

Fixes #42

Fixes ClassDefinitionInTask, and MethodDefinitionInTask to allow classes, modules and methods to defined inside tasks

@kuahyeow
Copy link
Author

@koic Is the configured Circle CI still working. Am getting the error below:

 CircleCI Pipeline — Could not find a usable config.yml, you may have revoked the CircleCI OAuth app. 

Copy link

@pboling pboling left a comment

Choose a reason for hiding this comment

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

This is correct. The difference between which definition of a method or class wins is according to lexical order. The only one that works properly, without polluting the global Ruby Object namespace is inside a task, (whether or not it is inside a namespace is irrelevant).

# because it is defined to the top level.
# It is confusing because the scope looks in the task or namespace,
# It is confusing because the scope looks in the namespace,
Copy link

Choose a reason for hiding this comment

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

Suggested change
# It is confusing because the scope looks in the namespace,
# It is confusing because the scope appears as if it is in the namespace,

@@ -33,7 +33,7 @@ class ClassDefinitionInTask < Base

def on_class(node)
return if Helper::ClassDefinition.in_class_definition?(node)
return unless Helper::TaskDefinition.in_task_or_namespace?(node)
return unless Helper::TaskDefinition.in_namespace?(node)
Copy link

@pboling pboling Feb 26, 2023

Choose a reason for hiding this comment

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

Actually this is the wrong test. It should be "in task". If not in task then it is using the Global Ruby Object namespace. It makes no difference if it is in a namespace or not.

Copy link

@pboling pboling Feb 26, 2023

Choose a reason for hiding this comment

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

Testing if in a namespace here may have been allowing you to avoid a test for the Global Object Space, but that's really what you want. According to this Cop's intention:

- Class, Module and Method definitions are OK iff defined at the top-level OR inside a task.

  • Class, Module, and Method definitions are not OK if defined inside a namespace without also being inside a task.

I don't think it can accurately capture that intent without a test for the definitions at the top level of the file.

Copy link
Author

@kuahyeow kuahyeow Nov 10, 2023

Choose a reason for hiding this comment

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

@pboling Sorry, I dropped this completely. Must have slipped through the cracks

I don't think it can accurately capture that intent without a test for the definitions at the top level of the file.

There are such tests, which were pre-existing, please refer to:

  • "does not register an offense to def at the top level"
  • "allows class definition outside task"

Given this cop's intention is to only highlight "surprising" behavior, I will leave this logic as is.

Though I also see that the name of this cop is in-correct. Not sure how this is normally handled (is it breaking?) but I will push a rename for now.

@pboling
Copy link

pboling commented Nov 9, 2023

Ping! Just ran into this false positive again, and came looking to see if any activity here.

@kuahyeow kuahyeow force-pushed the fix_method_definition_cop branch 2 times, most recently from bac9816 to e116f67 Compare November 10, 2023 08:19
Copy link

@pboling pboling left a comment

Choose a reason for hiding this comment

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

LGTM! ❤️

Thong Kuah added 5 commits November 11, 2023 21:54
As methods defined in task do not pollute top level

For example, this rakefile below will show that `do_something` does not
appear in top level methods

```
task :a do
  def do_something
    puts 'a'
  end

  do_something
end

task :b do
  def do_something
    puts 'b'
  end

  do_something
end

puts methods.include?(:do_something)
```
As classes defined in task do not pollute top level.

For example, this Rakefile shows class C in task
does not pollute top level

```
task :a do
  class C
    def do_something
      puts 'a'
    end
  end

  C.new.do_something
end

task :b do
  class C
    def do_something
      puts 'b'
    end
  end

  C.new.do_something
end

puts Object.const_defined?('C')
```
Since the cop is now fixed to warn against class in namespaces, update
the cop name accordingly.
Since the cop is now fixed to warn against method in namespaces, update
the cop name accordingly.
@kuahyeow kuahyeow force-pushed the fix_method_definition_cop branch from e116f67 to 2915482 Compare November 11, 2023 09:01
@q3aiml
Copy link

q3aiml commented Dec 22, 2023

Is this correctly handling when a task is nested inside a namespace? I believe that should be allowed, but the spec doesn't seem to cover it and it looks like it is disallowed.

For example this test fails:

  it 'does not register an offense to `def` in a task when wrapped in a namespace' do
    expect_no_offenses(<<~RUBY)
      namespace :bar do
        task :foo do
          def helper_method
            do_something
          end
        end
      end
    RUBY
  end

@kuahyeow
Copy link
Author

That's true. I have now pushed a fix for this.

Is this correctly handling when a task is nested inside a namespace? I believe that should be allowed, but the spec doesn't seem to cover it and it looks like it is disallowed.

For example this test fails:

  it 'does not register an offense to `def` in a task when wrapped in a namespace' do
    expect_no_offenses(<<~RUBY)
      namespace :bar do
        task :foo do
          def helper_method
            do_something
          end
        end
      end
    RUBY
  end

Copy link

@pboling pboling left a comment

Choose a reason for hiding this comment

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

LGTM

@pboling
Copy link

pboling commented May 10, 2024

@kuahyeow The build passed before your last fix, but now it failing on Ruby >= 2.7. Any ideas?

This is similar to definitions within a task (without a namespace).
@kuahyeow kuahyeow force-pushed the fix_method_definition_cop branch from 000d0e2 to 0fd68b2 Compare May 11, 2024 05:23
@kuahyeow
Copy link
Author

Looks like it's failing on unrelated rubocop errors....

rubocop
Inspecting 25 files
............C.......C....

Offenses:

lib/rubocop/cop/rake/helper/task_name.rb:11:30: C: [Correctable] InternalAffairs/NodeFirstOrLastArgument: Use #first_argument instead of #arguments[0].
            first_arg = node.arguments[0]
                             ^^^^^^^^^^^^
spec/rubocop/cop/rake/desc_spec.rb:4:6: C: [Correctable] InternalAffairs/ExampleDescription: Description does not match use of expect_offense.
  it 'register an offense for task on the top level' do
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
spec/rubocop/cop/rake/desc_spec.rb:16:6: C: [Correctable] InternalAffairs/ExampleDescription: Description does not match use of expect_offense.
  it 'register an offense for task with block in a block' do
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
spec/rubocop/cop/rake/desc_spec.rb:33:6: C: [Correctable] InternalAffairs/ExampleDescription: Description does not match use of expect_offense.
  it 'register an offense for task in kwbegin' do
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

25 files inspected, 4 offenses detected, 4 offenses autocorrectable
rake aborted!
Command failed with status (1): [rubocop...]
/home/circleci/project/Rakefile:36:in `block in <top (required)>'
/home/circleci/.rubygems/gems/rake-12.3.3/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => default => rubocop
(See full trace by running task with --trace)

Exited with code exit status 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rake/MethodDefinitionInTask is 66.6% incorrect
3 participants