rubocop-sketchup 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +20 -21
- data/assets/output.html.erb +301 -301
- data/config/default.yml +379 -379
- data/lib/rubocop/sketchup/config.rb +63 -63
- data/lib/rubocop/sketchup/cop/bugs/material_name.rb +108 -108
- data/lib/rubocop/sketchup/cop/bugs/render_mode.rb +72 -72
- data/lib/rubocop/sketchup/cop/bugs/uniform_scaling.rb +36 -36
- data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +25 -25
- data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +30 -30
- data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +27 -27
- data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +26 -26
- data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +25 -25
- data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +30 -30
- data/lib/rubocop/sketchup/cop/performance/openssl.rb +41 -41
- data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +33 -33
- data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +79 -79
- data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -63
- data/lib/rubocop/sketchup/cop/performance/typename.rb +24 -24
- data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +30 -30
- data/lib/rubocop/sketchup/cop/requirements/exit.rb +33 -33
- data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +125 -125
- data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +97 -97
- data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -45
- data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -95
- data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +38 -38
- data/lib/rubocop/sketchup/cop/requirements/global_include.rb +42 -42
- data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +65 -65
- data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +95 -95
- data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +46 -46
- data/lib/rubocop/sketchup/cop/requirements/load_path.rb +83 -83
- data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +73 -73
- data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +161 -161
- data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +45 -45
- data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +291 -291
- data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +634 -634
- data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +61 -61
- data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +119 -119
- data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +150 -149
- data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -49
- data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +128 -128
- data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +34 -34
- data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +78 -78
- data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +58 -58
- data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +45 -45
- data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +137 -137
- data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +39 -39
- data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +45 -45
- data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +68 -68
- data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -41
- data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -65
- data/lib/rubocop/sketchup/cop.rb +110 -110
- data/lib/rubocop/sketchup/dc_globals.rb +24 -24
- data/lib/rubocop/sketchup/dc_methods.rb +130 -130
- data/lib/rubocop/sketchup/extension_project.rb +65 -65
- data/lib/rubocop/sketchup/features.rb +1477 -1420
- data/lib/rubocop/sketchup/formatter/extension_review.rb +269 -269
- data/lib/rubocop/sketchup/inject.rb +19 -19
- data/lib/rubocop/sketchup/namespace.rb +49 -49
- data/lib/rubocop/sketchup/namespace_checker.rb +103 -103
- data/lib/rubocop/sketchup/no_comment_disable.rb +17 -17
- data/lib/rubocop/sketchup/range_help.rb +52 -52
- data/lib/rubocop/sketchup/sketchup_target_range.rb +75 -75
- data/lib/rubocop/sketchup/sketchup_version.rb +129 -128
- data/lib/rubocop/sketchup/tool_checker.rb +41 -43
- data/lib/rubocop/sketchup/version.rb +7 -7
- data/lib/rubocop/sketchup.rb +14 -14
- data/lib/rubocop-sketchup.rb +53 -53
- data/rubocop-sketchup.gemspec +29 -29
- metadata +8 -8
@@ -1,24 +1,24 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupPerformance
|
6
|
-
# `.typename` is very slow, prefer `.is_a?` instead.
|
7
|
-
#
|
8
|
-
# `entity.typename == 'Face'` is slow because it performs a string
|
9
|
-
# comparison. `is_a?` is much faster because it's a simple type check.
|
10
|
-
class Typename < SketchUp::Cop
|
11
|
-
MSG = '`.typename` is very slow, prefer `.is_a?` instead.'
|
12
|
-
|
13
|
-
def on_send(node)
|
14
|
-
_, method_name = *node
|
15
|
-
return unless method_name == :typename
|
16
|
-
|
17
|
-
# TODO(thomthom): Should we try to detect use of #typename
|
18
|
-
# in context of comparing against a string?
|
19
|
-
add_offense(node, location: :selector)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupPerformance
|
6
|
+
# `.typename` is very slow, prefer `.is_a?` instead.
|
7
|
+
#
|
8
|
+
# `entity.typename == 'Face'` is slow because it performs a string
|
9
|
+
# comparison. `is_a?` is much faster because it's a simple type check.
|
10
|
+
class Typename < SketchUp::Cop
|
11
|
+
MSG = '`.typename` is very slow, prefer `.is_a?` instead.'
|
12
|
+
|
13
|
+
def on_send(node)
|
14
|
+
_, method_name = *node
|
15
|
+
return unless method_name == :typename
|
16
|
+
|
17
|
+
# TODO(thomthom): Should we try to detect use of #typename
|
18
|
+
# in context of comparing against a string?
|
19
|
+
add_offense(node, location: :selector)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,30 +1,30 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupRequirements
|
6
|
-
# Do not modify the Sketch API. This will affect other extensions and
|
7
|
-
# very likely cause them to fail.
|
8
|
-
#
|
9
|
-
# This requirement also include adding things into the SketchUp API
|
10
|
-
# namespace. The API namespace is reserved for future additions to the
|
11
|
-
# API.
|
12
|
-
class ApiNamespace < SketchUp::Cop
|
13
|
-
|
14
|
-
include SketchUp::NoCommentDisable
|
15
|
-
include SketchUp::NamespaceChecker
|
16
|
-
|
17
|
-
MSG = 'Do not modify the SketchUp API.'
|
18
|
-
|
19
|
-
NAMESPACES = %w[
|
20
|
-
Geom Layout Sketchup SketchupExtension UI
|
21
|
-
].freeze
|
22
|
-
|
23
|
-
def namespaces
|
24
|
-
NAMESPACES
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
# Do not modify the Sketch API. This will affect other extensions and
|
7
|
+
# very likely cause them to fail.
|
8
|
+
#
|
9
|
+
# This requirement also include adding things into the SketchUp API
|
10
|
+
# namespace. The API namespace is reserved for future additions to the
|
11
|
+
# API.
|
12
|
+
class ApiNamespace < SketchUp::Cop
|
13
|
+
|
14
|
+
include SketchUp::NoCommentDisable
|
15
|
+
include SketchUp::NamespaceChecker
|
16
|
+
|
17
|
+
MSG = 'Do not modify the SketchUp API.'
|
18
|
+
|
19
|
+
NAMESPACES = %w[
|
20
|
+
Geom Layout Sketchup SketchupExtension UI
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
def namespaces
|
24
|
+
NAMESPACES
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,33 +1,33 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupRequirements
|
6
|
-
# Don't attempt to kill the Ruby interpreter by calling `exit` or `exit!`.
|
7
|
-
# SketchUp will trap `exit` and prevent that, with a message in the
|
8
|
-
# console. But `exit!` is not trapped and will terminate SketchUp without
|
9
|
-
# shutting down cleanly.
|
10
|
-
#
|
11
|
-
# Use `return`, `next`, `break` or `raise` instead.
|
12
|
-
class Exit < SketchUp::Cop
|
13
|
-
|
14
|
-
include SketchUp::NoCommentDisable
|
15
|
-
|
16
|
-
MSG = '`%s` attempts to kill the Ruby interpreter. Use `return`, '\
|
17
|
-
'`next`, `break` or `raise` instead.'
|
18
|
-
|
19
|
-
# Reference: http://rubocop.readthedocs.io/en/latest/development/
|
20
|
-
def_node_matcher :exit?, <<-PATTERN
|
21
|
-
(send {(const nil? :Kernel) nil?} {:abort :exit :exit!} ...)
|
22
|
-
PATTERN
|
23
|
-
|
24
|
-
def on_send(node)
|
25
|
-
return unless exit?(node)
|
26
|
-
|
27
|
-
message = format(MSG, node.method_name)
|
28
|
-
add_offense(node, location: :selector, message: message)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
# Don't attempt to kill the Ruby interpreter by calling `exit` or `exit!`.
|
7
|
+
# SketchUp will trap `exit` and prevent that, with a message in the
|
8
|
+
# console. But `exit!` is not trapped and will terminate SketchUp without
|
9
|
+
# shutting down cleanly.
|
10
|
+
#
|
11
|
+
# Use `return`, `next`, `break` or `raise` instead.
|
12
|
+
class Exit < SketchUp::Cop
|
13
|
+
|
14
|
+
include SketchUp::NoCommentDisable
|
15
|
+
|
16
|
+
MSG = '`%s` attempts to kill the Ruby interpreter. Use `return`, ' \
|
17
|
+
'`next`, `break` or `raise` instead.'
|
18
|
+
|
19
|
+
# Reference: http://rubocop.readthedocs.io/en/latest/development/
|
20
|
+
def_node_matcher :exit?, <<-PATTERN
|
21
|
+
(send {(const nil? :Kernel) nil?} {:abort :exit :exit!} ...)
|
22
|
+
PATTERN
|
23
|
+
|
24
|
+
def on_send(node)
|
25
|
+
return unless exit?(node)
|
26
|
+
|
27
|
+
message = format(MSG, node.method_name)
|
28
|
+
add_offense(node, location: :selector, message: message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,125 +1,125 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop/sketchup/cop/requirements/api_namespace'
|
4
|
-
require 'rubocop/sketchup/cop/requirements/ruby_core_namespace'
|
5
|
-
require 'rubocop/sketchup/cop/requirements/ruby_stdlib_namespace'
|
6
|
-
|
7
|
-
module RuboCop
|
8
|
-
module Cop
|
9
|
-
module SketchupRequirements
|
10
|
-
# Extensions in SketchUp all share the same Ruby environment on the user's
|
11
|
-
# machine. Because of this it's important that each extension isolate
|
12
|
-
# itself to avoid clashing with other extensions.
|
13
|
-
#
|
14
|
-
# Extensions submitted to Extension Warehouse is expected to use only one
|
15
|
-
# root module.
|
16
|
-
#
|
17
|
-
# @example Good - this contains everything in the extension.
|
18
|
-
# module MyExtension
|
19
|
-
# class Foo
|
20
|
-
# end
|
21
|
-
# class Bar
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# @example Better - this further reduce chance of clashing.
|
26
|
-
# module MyCompany
|
27
|
-
# module MyExtension
|
28
|
-
# class Foo
|
29
|
-
# end
|
30
|
-
# class Bar
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
class ExtensionNamespace < SketchUp::Cop
|
35
|
-
|
36
|
-
include SketchUp::NoCommentDisable
|
37
|
-
include SketchUp
|
38
|
-
|
39
|
-
def on_class(node)
|
40
|
-
check_class_or_module(node)
|
41
|
-
end
|
42
|
-
|
43
|
-
def on_module(node)
|
44
|
-
check_class_or_module(node)
|
45
|
-
end
|
46
|
-
|
47
|
-
def check_class_or_module(node)
|
48
|
-
name = node.defined_module_name
|
49
|
-
|
50
|
-
if node.parent_module_name
|
51
|
-
parent = Namespace.new(node.parent_module_name)
|
52
|
-
else
|
53
|
-
# This is somewhat of an educated guess. We might end up here with
|
54
|
-
# code like this:
|
55
|
-
#
|
56
|
-
# Example.generate do
|
57
|
-
# module HelloWorld
|
58
|
-
# end
|
59
|
-
# end
|
60
|
-
#
|
61
|
-
# It might be that the module is evaluated in a different context.
|
62
|
-
# But we'll accept the possible false positive and let the user
|
63
|
-
# config exceptions if needed.
|
64
|
-
parent = Namespace.new('Object')
|
65
|
-
end
|
66
|
-
namespace = parent.join(name)
|
67
|
-
|
68
|
-
# Don't want to process anything that aren't top level namespaces.
|
69
|
-
return unless parent.top_level?
|
70
|
-
# Don't check excluded namespaces.
|
71
|
-
return if exempted?(namespace)
|
72
|
-
|
73
|
-
check_namespace(node, namespace)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Class variables are normally frowned upon since they leak through all
|
77
|
-
# instances. However, in this case this is exactly what we want.
|
78
|
-
# The Cop picks up the first top level namespace it encounters and then
|
79
|
-
# keep track of whether it detects more top level namespaces.
|
80
|
-
@@namespace = nil
|
81
|
-
def check_namespace(node, namespace)
|
82
|
-
# Make sure the namespace isn't part of reserved namespaces that other
|
83
|
-
# cops are checking.
|
84
|
-
return if reserved?(namespace)
|
85
|
-
|
86
|
-
# Remember the first namespace encountered and log an offence if
|
87
|
-
# more top level namespaces are registered.
|
88
|
-
top = namespace.first
|
89
|
-
@@namespace ||= top
|
90
|
-
return if @@namespace == top
|
91
|
-
|
92
|
-
add_offense(node, location: :name)
|
93
|
-
end
|
94
|
-
|
95
|
-
def reserved?(namespace)
|
96
|
-
top = namespace.first
|
97
|
-
return true if RubyCoreNamespace::NAMESPACES.include?(top)
|
98
|
-
return true if RubyStdLibNamespace::NAMESPACES.include?(top)
|
99
|
-
return true if ApiNamespace::NAMESPACES.include?(top)
|
100
|
-
|
101
|
-
false
|
102
|
-
end
|
103
|
-
|
104
|
-
def message(node)
|
105
|
-
namespace = Namespace.new(node.defined_module_name).from_root
|
106
|
-
format('Use a single root namespace. '\
|
107
|
-
'(Found `%<found>s`; Previously found `%<expected>s`)',
|
108
|
-
found: namespace, expected: @@namespace)
|
109
|
-
end
|
110
|
-
|
111
|
-
def exempted?(namespace)
|
112
|
-
namespace_exceptions.include?(namespace.first)
|
113
|
-
end
|
114
|
-
|
115
|
-
def namespace_exceptions
|
116
|
-
exceptions = cop_config['Exceptions'] || []
|
117
|
-
return exceptions if exceptions.is_a?(Array)
|
118
|
-
|
119
|
-
raise 'exceptions needs to be an array of strings!'
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop/sketchup/cop/requirements/api_namespace'
|
4
|
+
require 'rubocop/sketchup/cop/requirements/ruby_core_namespace'
|
5
|
+
require 'rubocop/sketchup/cop/requirements/ruby_stdlib_namespace'
|
6
|
+
|
7
|
+
module RuboCop
|
8
|
+
module Cop
|
9
|
+
module SketchupRequirements
|
10
|
+
# Extensions in SketchUp all share the same Ruby environment on the user's
|
11
|
+
# machine. Because of this it's important that each extension isolate
|
12
|
+
# itself to avoid clashing with other extensions.
|
13
|
+
#
|
14
|
+
# Extensions submitted to Extension Warehouse is expected to use only one
|
15
|
+
# root module.
|
16
|
+
#
|
17
|
+
# @example Good - this contains everything in the extension.
|
18
|
+
# module MyExtension
|
19
|
+
# class Foo
|
20
|
+
# end
|
21
|
+
# class Bar
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @example Better - this further reduce chance of clashing.
|
26
|
+
# module MyCompany
|
27
|
+
# module MyExtension
|
28
|
+
# class Foo
|
29
|
+
# end
|
30
|
+
# class Bar
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
class ExtensionNamespace < SketchUp::Cop
|
35
|
+
|
36
|
+
include SketchUp::NoCommentDisable
|
37
|
+
include SketchUp
|
38
|
+
|
39
|
+
def on_class(node)
|
40
|
+
check_class_or_module(node)
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_module(node)
|
44
|
+
check_class_or_module(node)
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_class_or_module(node)
|
48
|
+
name = node.defined_module_name
|
49
|
+
|
50
|
+
if node.parent_module_name
|
51
|
+
parent = Namespace.new(node.parent_module_name)
|
52
|
+
else
|
53
|
+
# This is somewhat of an educated guess. We might end up here with
|
54
|
+
# code like this:
|
55
|
+
#
|
56
|
+
# Example.generate do
|
57
|
+
# module HelloWorld
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# It might be that the module is evaluated in a different context.
|
62
|
+
# But we'll accept the possible false positive and let the user
|
63
|
+
# config exceptions if needed.
|
64
|
+
parent = Namespace.new('Object')
|
65
|
+
end
|
66
|
+
namespace = parent.join(name)
|
67
|
+
|
68
|
+
# Don't want to process anything that aren't top level namespaces.
|
69
|
+
return unless parent.top_level?
|
70
|
+
# Don't check excluded namespaces.
|
71
|
+
return if exempted?(namespace)
|
72
|
+
|
73
|
+
check_namespace(node, namespace)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Class variables are normally frowned upon since they leak through all
|
77
|
+
# instances. However, in this case this is exactly what we want.
|
78
|
+
# The Cop picks up the first top level namespace it encounters and then
|
79
|
+
# keep track of whether it detects more top level namespaces.
|
80
|
+
@@namespace = nil
|
81
|
+
def check_namespace(node, namespace)
|
82
|
+
# Make sure the namespace isn't part of reserved namespaces that other
|
83
|
+
# cops are checking.
|
84
|
+
return if reserved?(namespace)
|
85
|
+
|
86
|
+
# Remember the first namespace encountered and log an offence if
|
87
|
+
# more top level namespaces are registered.
|
88
|
+
top = namespace.first
|
89
|
+
@@namespace ||= top
|
90
|
+
return if @@namespace == top
|
91
|
+
|
92
|
+
add_offense(node, location: :name)
|
93
|
+
end
|
94
|
+
|
95
|
+
def reserved?(namespace)
|
96
|
+
top = namespace.first
|
97
|
+
return true if RubyCoreNamespace::NAMESPACES.include?(top)
|
98
|
+
return true if RubyStdLibNamespace::NAMESPACES.include?(top)
|
99
|
+
return true if ApiNamespace::NAMESPACES.include?(top)
|
100
|
+
|
101
|
+
false
|
102
|
+
end
|
103
|
+
|
104
|
+
def message(node)
|
105
|
+
namespace = Namespace.new(node.defined_module_name).from_root
|
106
|
+
format('Use a single root namespace. ' \
|
107
|
+
'(Found `%<found>s`; Previously found `%<expected>s`)',
|
108
|
+
found: namespace, expected: @@namespace)
|
109
|
+
end
|
110
|
+
|
111
|
+
def exempted?(namespace)
|
112
|
+
namespace_exceptions.include?(namespace.first)
|
113
|
+
end
|
114
|
+
|
115
|
+
def namespace_exceptions
|
116
|
+
exceptions = cop_config['Exceptions'] || []
|
117
|
+
return exceptions if exceptions.is_a?(Array)
|
118
|
+
|
119
|
+
raise 'exceptions needs to be an array of strings!'
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -1,97 +1,97 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupRequirements
|
6
|
-
# Check that the extension conform to expected file structure with a
|
7
|
-
# single root .rb file and a support folder with matching name.
|
8
|
-
#
|
9
|
-
# Make sure to match upper and lower case characters between the root .rb
|
10
|
-
# file and the support folder.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# SketchUp/Plugins
|
14
|
-
# + ex_hello_world.rb
|
15
|
-
# + ex_hello_world
|
16
|
-
# + main.rb
|
17
|
-
# + ...
|
18
|
-
class FileStructure < SketchUp::Cop
|
19
|
-
|
20
|
-
include SketchUp::NoCommentDisable
|
21
|
-
include SketchUp::ExtensionProject
|
22
|
-
include RangeHelp
|
23
|
-
|
24
|
-
IGNORED_DIRECTORIES = %w[
|
25
|
-
__MACOSX
|
26
|
-
].freeze
|
27
|
-
|
28
|
-
def investigate(processed_source)
|
29
|
-
return if already_run?
|
30
|
-
|
31
|
-
# Using range similar to RuboCop::Cop::Naming::Filename (file_name.rb)
|
32
|
-
range = source_range(processed_source.buffer, 1, 0)
|
33
|
-
|
34
|
-
# Find all root Ruby files in the source directory.
|
35
|
-
pattern = "#{source_path}/*.rb"
|
36
|
-
root_ruby_files = Dir.glob(pattern)
|
37
|
-
|
38
|
-
# Ensure there is only one root Ruby file.
|
39
|
-
if root_ruby_files.size != 1
|
40
|
-
msg = 'Extensions must have exactly one root Ruby (.rb) file. '\
|
41
|
-
'Found: %d'
|
42
|
-
add_offense(nil,
|
43
|
-
location: range,
|
44
|
-
message: format(msg, root_ruby_files.size))
|
45
|
-
return
|
46
|
-
end
|
47
|
-
|
48
|
-
# Find the root file and collect the sub-directories.
|
49
|
-
root_file = root_ruby_files.first
|
50
|
-
extension_basename = File.basename(root_file, '.*')
|
51
|
-
sub_folders = source_path.children.select(&:directory?)
|
52
|
-
sub_folders.reject! { |folder|
|
53
|
-
IGNORED_DIRECTORIES.include?(folder.basename.to_s)
|
54
|
-
}
|
55
|
-
|
56
|
-
# Ensure there is only one sub-directory.
|
57
|
-
if sub_folders.size != 1
|
58
|
-
msg = 'Extensions must have exactly one support directory. Found %d'
|
59
|
-
add_offense(nil,
|
60
|
-
location: range,
|
61
|
-
message: format(msg, sub_folders.size))
|
62
|
-
return
|
63
|
-
end
|
64
|
-
|
65
|
-
# Ensure support directory's name match the root Ruby file.
|
66
|
-
support_directory = sub_folders.first
|
67
|
-
unless support_directory.basename.to_s == extension_basename
|
68
|
-
msg = 'Extensions must have a support directory matching the
|
69
|
-
'of the root Ruby file. Expected %s, found %s'
|
70
|
-
msg = format(msg, extension_basename, support_directory.basename)
|
71
|
-
add_offense(nil,
|
72
|
-
location: range,
|
73
|
-
message: msg)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
@@already_run = false
|
80
|
-
|
81
|
-
def already_run?
|
82
|
-
return true if @@already_run
|
83
|
-
|
84
|
-
@@already_run = true
|
85
|
-
false
|
86
|
-
end
|
87
|
-
|
88
|
-
# rubocop:disable Lint/IneffectiveAccessModifier
|
89
|
-
def self.reset
|
90
|
-
@@already_run = false
|
91
|
-
end
|
92
|
-
# rubocop:enable Lint/IneffectiveAccessModifier
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
# Check that the extension conform to expected file structure with a
|
7
|
+
# single root .rb file and a support folder with matching name.
|
8
|
+
#
|
9
|
+
# Make sure to match upper and lower case characters between the root .rb
|
10
|
+
# file and the support folder.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# SketchUp/Plugins
|
14
|
+
# + ex_hello_world.rb
|
15
|
+
# + ex_hello_world
|
16
|
+
# + main.rb
|
17
|
+
# + ...
|
18
|
+
class FileStructure < SketchUp::Cop
|
19
|
+
|
20
|
+
include SketchUp::NoCommentDisable
|
21
|
+
include SketchUp::ExtensionProject
|
22
|
+
include RangeHelp
|
23
|
+
|
24
|
+
IGNORED_DIRECTORIES = %w[
|
25
|
+
__MACOSX
|
26
|
+
].freeze
|
27
|
+
|
28
|
+
def investigate(processed_source)
|
29
|
+
return if already_run?
|
30
|
+
|
31
|
+
# Using range similar to RuboCop::Cop::Naming::Filename (file_name.rb)
|
32
|
+
range = source_range(processed_source.buffer, 1, 0)
|
33
|
+
|
34
|
+
# Find all root Ruby files in the source directory.
|
35
|
+
pattern = "#{source_path}/*.rb"
|
36
|
+
root_ruby_files = Dir.glob(pattern)
|
37
|
+
|
38
|
+
# Ensure there is only one root Ruby file.
|
39
|
+
if root_ruby_files.size != 1
|
40
|
+
msg = 'Extensions must have exactly one root Ruby (.rb) file. ' \
|
41
|
+
'Found: %d'
|
42
|
+
add_offense(nil,
|
43
|
+
location: range,
|
44
|
+
message: format(msg, root_ruby_files.size))
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
48
|
+
# Find the root file and collect the sub-directories.
|
49
|
+
root_file = root_ruby_files.first
|
50
|
+
extension_basename = File.basename(root_file, '.*')
|
51
|
+
sub_folders = source_path.children.select(&:directory?)
|
52
|
+
sub_folders.reject! { |folder|
|
53
|
+
IGNORED_DIRECTORIES.include?(folder.basename.to_s)
|
54
|
+
}
|
55
|
+
|
56
|
+
# Ensure there is only one sub-directory.
|
57
|
+
if sub_folders.size != 1
|
58
|
+
msg = 'Extensions must have exactly one support directory. Found %d'
|
59
|
+
add_offense(nil,
|
60
|
+
location: range,
|
61
|
+
message: format(msg, sub_folders.size))
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
# Ensure support directory's name match the root Ruby file.
|
66
|
+
support_directory = sub_folders.first
|
67
|
+
unless support_directory.basename.to_s == extension_basename
|
68
|
+
msg = 'Extensions must have a support directory matching the ' \
|
69
|
+
'name of the root Ruby file. Expected %s, found %s'
|
70
|
+
msg = format(msg, extension_basename, support_directory.basename)
|
71
|
+
add_offense(nil,
|
72
|
+
location: range,
|
73
|
+
message: msg)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
@@already_run = false
|
80
|
+
|
81
|
+
def already_run?
|
82
|
+
return true if @@already_run
|
83
|
+
|
84
|
+
@@already_run = true
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
88
|
+
# rubocop:disable Lint/IneffectiveAccessModifier
|
89
|
+
def self.reset
|
90
|
+
@@already_run = false
|
91
|
+
end
|
92
|
+
# rubocop:enable Lint/IneffectiveAccessModifier
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|