Rubocop with rubocop-sketchup

This is for @tt_su and @ene_su or others who are familiar with rubocop.

In our September Developer MeetUp, I brought up having some issues integrating rubocop-sketchup with standard rubocop. Created this topic to discuss some of the issues I’ve encountered when trying to use rubocop-sketchup.

First, I have version 1.2.0 of RuboCop…
rubocop -v
1.2.0

And, in the Github page for rubocop-sketchup the installation specify to use rubocop version 0.93. Does this means I have to uninstall version 1.2.0 for rubocop?

gem install rubocop -v 0.93
gem install rubocop-sketchup

The last time I installed gem files was when developing ruby on rails apps using a gem file and running bundle install after. But, not sure how to make this work outside of rails app. However, I ran the commands on the terminal and they seem to have been installed.

Ok so here is the error I get when running rubocop from the terminal while having require: rubocop-sketchup on my .rubocop.yml file.

◯ src % rubocop
/Users/rafaelrivera/Dropbox/GIT/compo-guides/.rubocop.yml:5: `Metrics/MethodLength` is concealed by line 134
Unable to activate rubocop-sketchup-0.19.0, because rubocop-1.2.0 conflicts with rubocop (>= 0.82, <= 0.93)
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/specification.rb:2243:in `raise_if_conflicts'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/specification.rb:1371:in `activate'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems.rb:215:in `rescue in try_activate'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems.rb:208:in `try_activate'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:161:in `rescue in require'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:156:in `require'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader_resolver.rb:17:in `block (2 levels) in resolve_requires'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader_resolver.rb:13:in `each'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader_resolver.rb:13:in `block in resolve_requires'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader_resolver.rb:12:in `tap'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader_resolver.rb:12:in `resolve_requires'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader.rb:43:in `load_file'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_loader.rb:104:in `configuration_from_file'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_store.rb:58:in `for_dir'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/config_store.rb:37:in `for_pwd'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/cli.rb:124:in `apply_default_formatter'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/lib/rubocop/cli.rb:40:in `run'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/exe/rubocop:13:in `block in <top (required)>'
/Users/rafaelrivera/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/benchmark.rb:308:in `realtime'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/gems/rubocop-1.2.0/exe/rubocop:12:in `<top (required)>'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/bin/rubocop:23:in `load'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/bin/rubocop:23:in `<main>'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/bin/ruby_executable_hooks:24:in `eval'
/Users/rafaelrivera/.rvm/gems/ruby-2.7.0/bin/ruby_executable_hooks:24:in `<main>'

I personally use rubocop with Sublime by installing rubocop Package Control.
https://packagecontrol.io/packages/RuboCop

Everything works without rubocop-sketchup being required.
Here is my .rubocop.yml file just in case (most was copied from eneroth y thomthom).

# The line below if uncommented makes rubocop not work.
#require: rubocop-sketchup

# Aim for 10 lines or less but accept longer ones when things can't be extracted
# to sensible methods.
Metrics/MethodLength:
  Max: 20

Naming/MethodName:
  IgnoredPatterns:
    # Tool
    - '^\s*enableVCB\?(\(.*\))?$'
    - '^\s*getExtents(\(.*\))?$'
    - '^\s*getInstructorContentDirectory(\(.*\))?$'
    - '^\s*getMenu(\(.*\))?$'
    - '^\s*onCancel(\(.*\))?$'
    - '^\s*onKeyDown(\(.*\))?$'
    - '^\s*onKeyUp(\(.*\))?$'
    - '^\s*onLButtonDoubleClick(\(.*\))?$'
    - '^\s*onLButtonDown(\(.*\))?$'
    - '^\s*onLButtonUp(\(.*\))?$'
    - '^\s*onMButtonDoubleClick(\(.*\))?$'
    - '^\s*onMButtonDown(\(.*\))?$'
    - '^\s*onMButtonUp(\(.*\))?$'
    - '^\s*onMouseEnter(\(.*\))?$'
    - '^\s*onMouseLeave(\(.*\))?$'
    - '^\s*onMouseMove(\(.*\))?$'
    - '^\s*onMouseWheel(\(.*\))?$'
    - '^\s*onRButtonDown(\(.*\))?$'
    - '^\s*onRButtonUp(\(.*\))?$'
    - '^\s*onReturn(\(.*\))?$'
    - '^\s*onSetCursor(\(.*\))?$'
    - '^\s*onUserText(\(.*\))?$'
    # AppObserver
    - '^\s*expectsStartupModelNotifications(\(.*\))?$'
    - '^\s*onActivateModel(\(.*\))?$'
    - '^\s*onNewModel(\(.*\))?$'
    - '^\s*onOpenModel(\(.*\))?$'
    - '^\s*onQuit(\(.*\))?$'
    - '^\s*onUnloadExtension(\(.*\))?$'
    # DefinitionObserver
    - '^\s*onComponentInstanceAdded(\(.*\))?$'
    - '^\s*onComponentInstanceRemoved(\(.*\))?$'
    # DefinitionsObserver
    - '^\s*onComponentAdded(\(.*\))?$'
    - '^\s*onComponentPropertiesChanged(\(.*\))?$'
    - '^\s*onComponentRemoved(\(.*\))?$'
    - '^\s*onComponentTypeChanged(\(.*\))?$'
    # DimensionsObserver
    - '^\s*onTextChanged(\(.*\))?$'
    # EntitiesObserver
    - '^\s*onActiveSectionPlaneChanged(\(.*\))?$'
    - '^\s*onElementAdded(\(.*\))?$'
    - '^\s*onElementModified(\(.*\))?$'
    - '^\s*onElementRemoved(\(.*\))?$'
    - '^\s*onEraseEntities(\(.*\))?$'
    # EntityObserver
    - '^\s*onChangeEntity(\(.*\))?$'
    - '^\s*onEraseEntity(\(.*\))?$'
    # FrameChangeObserver
    - '^\s*frameChange(\(.*\))?$'
    # InstanceObserver
    - '^\s*onClose(\(.*\))?$'
    - '^\s*onOpen(\(.*\))?$'
    # LayersObserver
    - '^\s*onCurrentLayerChangedS(\(.*\))?$'
    - '^\s*onLayerAdded(\(.*\))?$'
    - '^\s*onLayerChanged(\(.*\))?$'
    - '^\s*onLayerRemoved(\(.*\))?$'
    - '^\s*onRemoveAllLayers(\(.*\))?$'
    # MaterialsObserver
    - '^\s*onMaterialAdd(\(.*\))?$'
    - '^\s*onMaterialChange(\(.*\))?$'
    - '^\s*onMaterialRefChange(\(.*\))?$'
    - '^\s*onMaterialRemove(\(.*\))?$'
    - '^\s*onMaterialSetCurrent(\(.*\))?$'
    - '^\s*onMaterialUndoRedo(\(.*\))?$'
    # ModelObserver
    - '^\s*onActivePathChanged(\(.*\))?$'
    - '^\s*onAfterComponentSaveAs(\(.*\))?$'
    - '^\s*onBeforeComponentSaveAs(\(.*\))?$'
    - '^\s*onDeleteModel(\(.*\))?$'
    - '^\s*onEraseAll(\(.*\))?$'
    - '^\s*onExplode(\(.*\))?$'
    - '^\s*onPidChanged(\(.*\))?$'
    - '^\s*onPlaceComponent(\(.*\))?$'
    - '^\s*onPostSaveModel(\(.*\))?$'
    - '^\s*onPreSaveModel(\(.*\))?$'
    - '^\s*onSaveModel(\(.*\))?$'
    - '^\s*onTransactionAbort(\(.*\))?$'
    - '^\s*onTransactionCommit(\(.*\))?$'
    - '^\s*onTransactionEmpty(\(.*\))?$'
    - '^\s*onTransactionRedo(\(.*\))?$'
    - '^\s*onTransactionStart(\(.*\))?$'
    - '^\s*onTransactionUndo(\(.*\))?$'
    # OptionsproviderObserver
    - '^\s*onOptionsProviderChanged(\(.*\))?$'
    # PagesObserver
    - '^\s*onContentsModified(\(.*\))?$'
    - '^\s*onElementAdded(\(.*\))?$'
    - '^\s*onElementRemoved(\(.*\))?$'
    # RenderingOptionsObserver
    - '^\s*onRenderingOptionsChanged(\(.*\))?$'
    # SelectionObserver
    - '^\s*onSelectionAdded(\(.*\))?$'
    - '^\s*onSelectionBulkChange(\(.*\))?$'
    - '^\s*onSelectionCleared(\(.*\))?$'
    - '^\s*onSelectionRemoved(\(.*\))?$'
    - '^\s*onSelectedRemoved(\(.*\))?$'
    # ShadowInfoObserver
    - '^\s*onShadowInfoChanged(\(.*\))?$'
    # ToolsObserver
    - '^\s*onActiveToolChanged(\(.*\))?$'
    - '^\s*onToolStateChanged(\(.*\))?$'
    # ViewObserver
    - '^\s*onViewChanged(\(.*\))?$'

# Allow common names in SketchUp 3d modeling.
Naming/MethodParameterName:
  AllowedNames:
    - 'x'
    - 'y'
    - 'z'
    - 'u'
    - 'v'
    - 'uv'
    - 'ip'

# Ideal length should be 80. But some times it reads better to let the line
# bleed over by a little. In this project there are enough of these cases that
# the RuboCop max is set to 100.
Metrics/LineLength:
  Max: 100

Metrics/MethodLength:
  Max: 30

Ok, I’ll stop here for now.
Hopefully, I was able to express what is going on.

Try something like following with the version you have installed (run gem list) :

rubocop _0.93.1_

Does this means I have to uninstall version 1.2.0 for rubocop?

No

1 Like

I ran gem list on the terminal and I got the following rubocop gems…

...
rubocop (1.2.0, 0.93.0)

rubocop-ast (1.1.1)

rubocop-sketchup (0.19.0)
...

I then ran the following and it worked…:smiley:

rubocop _0.93_

But, the problem is that I normally do not use rubocop from the terminal. :frowning:
I use Sublime text editor with rubocop Package Control. This makes it much more practical and easy to spot rubocop alerts.

Here is a Screenshot… Notice rubocop highlights the alert with a red square beside the line number and gives feedback on the bottom.

Question:
If I want to use rubocop-sketchup and Sublime rubocop what should I do?
Delete ruboco version 1.2.0 and only keep 0.93.0?
Or is there I way to make version 0.93.0 of rubocop the default?

Thanks in advance! :smiley:

1 Like

Quick update…

I uninstalled rubocop version 1.2.0 by running the following on the terminal…

gem uninstall rubocop --version 1.2.0

And now I can run rubocop on the terminal without specifying the version.

And most importantly rubocop work in Sublime text while having require: rubocop-sketchup on my .rubocop.yml file.

Thanks @MSP_Greg for helping out!

Still wondering if I could have accomplished this without removing the newer version of rubocop.

gem install rubocop -v 0.93
gem install rubocop-sketchup

That is the global installation version. It’s simplest to get started, but you might run into issues when you start working with multiple projects that might depend on different versions of rubocop.

RuboCop is updates extremely frequently. One of the reasons rubocop-sketchup isn’t up to date yet. Their compatibility has become better, but before minor version updates usually broke rubocop-sketchup. This should be better with 1.x branch. It’s on our list to get updated to that.

The more stable way of working with rubocop with your projects is to use Bundler and a Gemfile to manage the dependencies for your project: Installation - RuboCop SketchUp: SketchUp Extension Best Practices

In this case you’d add a Gemfile to your project root with the content:

source 'https://rubygems.org'

gem 'rubocop', '>= 0.82', '<= 0.93'
gem 'rubocop-sketchup', '~> 0.19.0'

Then, to get started you do bundle update and Bundler will install the gems required for this projects.

From then on, instead of invoking rubocop by rubocop you instead invoke it via bundler: bundle exec rubocop. Bundler ensures that you run the rubocop version required by that project instead of the latest version on your machine.

You can see examples of how this is set up in the VSCode Extension Example Project:

The project also is set up to display rubocop warnings within VSCode, so you don’t have to manually run it. It’s doing so by using the Solargraph VSCode extension. (Related config found in https://github.com/SketchUp/sketchup-extension-vscode-project/blob/main/.solargraph.yml and https://github.com/SketchUp/sketchup-extension-vscode-project/blob/main/.vscode/settings.json)

2 Likes

Do you have an example on how to setup rubocop with Sublime? Would be nice to add a section in our docs for various popular editors.

1 Like

First, we need to make sure Package Control is installed in Sublime.
Here is a more detailed explanation: Installation - Package Control

Summary:

  1. Install & open Sublime text (https://www.sublimetext.com/)
  2. Open the command palette with the following keyboard shortcuts in Sublime.
    Win/Linux: ctrl+shift+p, Mac: cmd+shift+p
  3. Type Install Package Control, press enter
  4. Be sure to restart Sublime Text after installation.

Install Rubocop :robot:

To use rubocop and rubocop-sketchup make sure to install the right version specified in the following Github page. https://github.com/SketchUp/rubocop-sketchup

Summary:
Below you will see what to install through the terminal window.

gem install rubocop -v 0.93
gem install rubocop-sketchup

Install Rubocop in Sublime Text

For a more detailed explanation here are a couple of links.
RuboCop - Package Control
Install RuboCop in Sublime Text

Sumary:

  1. Once Package Control is installed, go back into Sublime Text and open the Command Palette. Win/Linux: ctrl+shift+p, Mac: cmd+shift+p
  2. Type install and click Package Control: Install Packages in the menu that appears
  3. Type RuboCop into the new box and choose RuboCop in the menu.

Here is how to see all your installed packages in Sublime Text.
Sublime TextPreferencesPackage ControlList Packages


Hope this explains the process of installing RuboCop inside Sublime Text. :smiley:

2 Likes

Adding a Gemfile to my project was easier than I thought. :+1:

I wonder if using Docker will be a possible solution when having to use different versions of gems depending on the project. I personally know very little about Docker or Kubernetes but might look into it in the future. Right now I do not have a problem uninstalling the newer version of rubocop though.

I may try VSCode and rubocop in the near future so thanks for the info!

Thanks @tt_su

1 Like

Awesome! I logged an issue to add that info to the Integration page.

I mentioned VSCode only because that’s what I most often use. Though, if you try to use the debugger you might run into issues with Sublime, I wasn’t able to find a way to to that. In that case you might be forced to try a different editor.

2 Likes