Class: RuboCop::Cop::SketchupRequirements::ExtensionNamespace

Inherits:
SketchUp::Cop
  • Object
show all
Includes:
SketchUp, SketchUp::NoCommentDisable
Defined in:
lib/rubocop/sketchup/cop/requirements/extension_namespace.rb

Overview

Extensions in SketchUp all share the same Ruby environment on the user’s machine. Because of this it’s important that each extension isolate itself to avoid clashing with other extensions.

Extensions submitted to Extension Warehouse is expected to use only one root module.

Examples:

Good - this contains everything in the extension.

module MyExtension
  class Foo
  end
  class Bar
  end
end

Better - this further reduce chance of clashing.

module MyCompany
  module MyExtension
    class Foo
    end
    class Bar
    end
  end
end

Constant Summary collapse

@@namespace =

Class variables are normally frowned upon since they leak through all instances. However, in this case this is exactly what we want. The Cop picks up the first top level namespace it encounters and then keep track of whether it detects more top level namespaces.

nil

Constants included from SketchUp

SketchUp::CONFIG, SketchUp::VERSION

Constants included from SketchUp::Config

SketchUp::Config::DEFAULT_CONFIGURATION

Instance Method Summary collapse

Methods inherited from SketchUp::Cop

inherited, #relevant_file?

Instance Method Details

#check_class_or_module(node) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 47

def check_class_or_module(node)
  name = node.defined_module_name
  parent = Namespace.new(node.parent_module_name)
  namespace = parent.join(name)
  # Don't want to process anything that aren't top level namespaces.
  return unless parent.top_level?
  # Don't check excluded namespaces.
  return if exempted?(namespace)

  check_namespace(node, namespace)
end

#check_namespace(node, namespace) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 64

def check_namespace(node, namespace)
  # Make sure the namespace isn't part of reserved namespaces that other
  # cops are checking.
  return if reserved?(namespace)

  # Remember the first namespace encountered and log an offence if
  # more top level namespaces are registered.
  top = namespace.first
  @@namespace ||= top
  return if @@namespace == top

  add_offense(node, location: :name)
end

#exempted?(namespace) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 94

def exempted?(namespace)
  namespace_exceptions.include?(namespace.first)
end

#message(node) ⇒ Object



87
88
89
90
91
92
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 87

def message(node)
  namespace = Namespace.new(node.defined_module_name).from_root
  format('Use a single root namespace. '\
         '(Found `%<found>s`; Previously found `%<expected>s`)',
      found: namespace, expected: @@namespace)
end

#namespace_exceptionsObject



98
99
100
101
102
103
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 98

def namespace_exceptions
  exceptions = cop_config['Exceptions'] || []
  return exceptions if exceptions.is_a?(Array)

  raise 'exceptions needs to be an array of strings!'
end

#on_class(node) ⇒ Object



39
40
41
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 39

def on_class(node)
  check_class_or_module(node)
end

#on_module(node) ⇒ Object



43
44
45
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 43

def on_module(node)
  check_class_or_module(node)
end

#reserved?(namespace) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
83
84
85
# File 'lib/rubocop/sketchup/cop/requirements/extension_namespace.rb', line 78

def reserved?(namespace)
  top = namespace.first
  return true if RubyCoreNamespace::NAMESPACES.include?(top)
  return true if RubyStdLibNamespace::NAMESPACES.include?(top)
  return true if ApiNamespace::NAMESPACES.include?(top)

  false
end