rubocop-packs 0.0.45 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/config/default.yml +12 -0
- data/lib/rubocop/cop/packs/class_methods_as_public_apis.rb +4 -11
- data/lib/rubocop/cop/packs/documented_public_apis.rb +14 -8
- data/lib/rubocop/cop/packs/root_namespace_is_pack_name/desired_zeitwerk_api.rb +2 -2
- data/lib/rubocop/cop/packs/root_namespace_is_pack_name.rb +15 -14
- data/lib/rubocop/cop/packwerk_lite/constant_resolver.rb +8 -6
- data/lib/rubocop/cop/packwerk_lite/dependency_checker.rb +2 -9
- data/lib/rubocop/cop/packwerk_lite/privacy_checker.rb +4 -11
- data/lib/rubocop/packs/plugin.rb +37 -0
- data/lib/rubocop/packs/version.rb +8 -0
- data/lib/rubocop/packs.rb +0 -5
- data/lib/rubocop-packs.rb +2 -3
- metadata +71 -16
- data/lib/rubocop/packs/inject.rb +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8dd71f6422be7332808603d1237a03e40a919fd9a49e7f5cc0e2e70ef1543f83
|
|
4
|
+
data.tar.gz: f7ec591736305bbe8e8acff73c3abda3efdbf2afd53bfb9b9363182e2b8473bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9502ccc3746e1ae9f6ee3801fe78330ece03aad0934729ab33c560c73a4ce226cb7f8e3e0726e8da9509b9495e7e06be991cd927d6709a15601c89dc47178fec
|
|
7
|
+
data.tar.gz: e917ea12928f8cf3e8ab20496261fbb0f9672708b4114b0254fb3df96eb0735f6893d7413f19aaf6d181ae0089040e1356d5e6a49fb3190dd9cda7730599edd5
|
data/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Just install the `rubocop-packs` gem
|
|
|
9
9
|
```sh
|
|
10
10
|
gem install rubocop-packs
|
|
11
11
|
```
|
|
12
|
-
or, if you use `Bundler`, add this line your application's `Gemfile`:
|
|
12
|
+
or, if you use `Bundler`, add this line to your application's `Gemfile`:
|
|
13
13
|
|
|
14
14
|
```ruby
|
|
15
15
|
gem 'rubocop-packs', require: false
|
|
@@ -24,13 +24,17 @@ You need to tell RuboCop to load the Packs extension. There are three ways to do
|
|
|
24
24
|
Put this into your `.rubocop.yml`:
|
|
25
25
|
|
|
26
26
|
```yaml
|
|
27
|
-
|
|
27
|
+
plugins:
|
|
28
28
|
- rubocop-packs
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
Now you can run `rubocop` and it will automatically load the RuboCop Packs cops together with the standard cops.
|
|
32
32
|
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.
|
|
35
|
+
|
|
33
36
|
## The Cops
|
|
37
|
+
|
|
34
38
|
All cops are located under [`lib/rubocop/cop/packs`](lib/rubocop/cop/packs), and contain examples/documentation.
|
|
35
39
|
|
|
36
40
|
In your `.rubocop.yml`, you may treat the Packs cops just like any other cop. For example:
|
data/config/default.yml
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Packs/ClassMethodsAsPublicApis:
|
|
2
|
+
Description: 'Requires public API methods (in `app/public`) to be defined as class methods, which are more easily statically analyzable and typically hold less state.'
|
|
2
3
|
Enabled: false
|
|
4
|
+
VersionAdded: '0.0.2'
|
|
3
5
|
AcceptableParentClasses:
|
|
4
6
|
- T::Enum
|
|
5
7
|
- T::Struct
|
|
@@ -8,18 +10,28 @@ Packs/ClassMethodsAsPublicApis:
|
|
|
8
10
|
AcceptableMixins: []
|
|
9
11
|
|
|
10
12
|
Packs/RootNamespaceIsPackName:
|
|
13
|
+
Description: 'Requires that each file is namespaced under its pack name, so that each pack exposes exactly one root namespace.'
|
|
11
14
|
Enabled: false
|
|
15
|
+
VersionAdded: '0.0.2'
|
|
12
16
|
|
|
13
17
|
Packs/TypedPublicApis:
|
|
18
|
+
Description: "Requires that each pack's public API (in `app/public`) is `typed: strict`."
|
|
14
19
|
Enabled: false
|
|
20
|
+
VersionAdded: '0.0.2'
|
|
15
21
|
|
|
16
22
|
Packs/DocumentedPublicApis:
|
|
23
|
+
Description: 'Requires that each public API method (in `app/public`) has a documentation comment.'
|
|
17
24
|
Enabled: false
|
|
25
|
+
VersionAdded: '0.0.2'
|
|
18
26
|
|
|
19
27
|
PackwerkLite/Privacy:
|
|
28
|
+
Description: 'Detects references to the private implementation of another pack instead of its public API.'
|
|
20
29
|
# It is recommended to use packwerk
|
|
21
30
|
Enabled: false
|
|
31
|
+
VersionAdded: '0.0.12'
|
|
22
32
|
|
|
23
33
|
PackwerkLite/Dependency:
|
|
34
|
+
Description: 'Detects references to a pack that is not listed as an explicit dependency.'
|
|
24
35
|
# It is recommended to use packwerk
|
|
25
36
|
Enabled: false
|
|
37
|
+
VersionAdded: '0.0.12'
|
|
@@ -31,17 +31,12 @@ module RuboCop
|
|
|
31
31
|
class ClassMethodsAsPublicApis < Base
|
|
32
32
|
extend T::Sig
|
|
33
33
|
|
|
34
|
-
sig { returns(T::Boolean) }
|
|
35
|
-
def support_autocorrect?
|
|
36
|
-
false
|
|
37
|
-
end
|
|
38
|
-
|
|
39
34
|
sig { params(node: T.untyped).void }
|
|
40
35
|
def on_def(node)
|
|
41
36
|
# This cop only applies for ruby files in `app/public`
|
|
42
37
|
return if !processed_source.file_path.include?('app/public/')
|
|
43
38
|
|
|
44
|
-
# Looked at https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Lint/MissingSuper source code as inspiration for
|
|
39
|
+
# Looked at https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Lint/MissingSuper source code as inspiration for this part.
|
|
45
40
|
class_node = node.each_ancestor(:class).first
|
|
46
41
|
module_node = node.each_ancestor(:module).first
|
|
47
42
|
parent_class = class_node&.parent_class || module_node&.parent
|
|
@@ -52,15 +47,13 @@ module RuboCop
|
|
|
52
47
|
class_is_allowed_to_have_instance_methods = acceptable_parent_classes.include?(parent_class&.const_name)
|
|
53
48
|
return if uses_implicit_static_methods || class_is_allowed_to_have_instance_methods
|
|
54
49
|
|
|
55
|
-
is_sorbet_interface_or_abstract_class = !module_node.nil? && module_node.descendants.any? { |d| d.is_a?(RuboCop::AST::SendNode) && (
|
|
50
|
+
is_sorbet_interface_or_abstract_class = !module_node.nil? && module_node.descendants.any? { |d| d.is_a?(RuboCop::AST::SendNode) && %i(interface! abstract!).include?(d.method_name) }
|
|
56
51
|
return if is_sorbet_interface_or_abstract_class
|
|
57
52
|
return if node_includes_acceptable_mixin?(class_node || module_node)
|
|
58
53
|
|
|
59
54
|
add_offense(
|
|
60
55
|
node.source_range,
|
|
61
|
-
message:
|
|
62
|
-
"Public API method must be a class method (e.g. `self.#{node.method_name}(...)`)"
|
|
63
|
-
)
|
|
56
|
+
message: "Public API method must be a class method (e.g. `self.#{node.method_name}(...)`)"
|
|
64
57
|
)
|
|
65
58
|
end
|
|
66
59
|
|
|
@@ -74,7 +67,7 @@ module RuboCop
|
|
|
74
67
|
node.descendants.any? do |d|
|
|
75
68
|
d.is_a?(RuboCop::AST::SendNode) &&
|
|
76
69
|
d.method_name == :include &&
|
|
77
|
-
d.arguments.
|
|
70
|
+
d.arguments.one? &&
|
|
78
71
|
d.arguments.first.is_a?(RuboCop::AST::ConstNode) &&
|
|
79
72
|
acceptable_mixins.include?(d.arguments.first.const_name)
|
|
80
73
|
end
|
|
@@ -42,20 +42,17 @@ module RuboCop
|
|
|
42
42
|
# support this for some packs.
|
|
43
43
|
extend T::Sig
|
|
44
44
|
|
|
45
|
-
sig { returns(T::Boolean) }
|
|
46
|
-
def support_autocorrect?
|
|
47
|
-
false
|
|
48
|
-
end
|
|
49
|
-
|
|
50
45
|
sig { params(node: T.untyped).void }
|
|
51
46
|
def check(node)
|
|
52
47
|
# This cop only applies for ruby files in `app/public`
|
|
53
48
|
return if !processed_source.file_path.include?('app/public')
|
|
54
|
-
return if non_public?(node) && !require_for_non_public_methods?
|
|
55
49
|
|
|
56
50
|
left_sibling = node.left_sibling
|
|
57
51
|
|
|
58
|
-
|
|
52
|
+
# A `Symbol` sibling means the definition was passed to a modifier, as in
|
|
53
|
+
# `private def foo` or `private_class_method def self.foo`, so both the sig and the
|
|
54
|
+
# documentation comment sit above the enclosing send rather than above the definition.
|
|
55
|
+
if left_sibling.is_a?(Symbol)
|
|
59
56
|
if node_is_sorbet_signature?(node.parent.left_sibling)
|
|
60
57
|
return if documentation_comment?(node.parent.left_sibling)
|
|
61
58
|
elsif documentation_comment?(node.parent)
|
|
@@ -72,8 +69,17 @@ module RuboCop
|
|
|
72
69
|
|
|
73
70
|
sig { params(node: T.untyped).returns(T::Boolean) }
|
|
74
71
|
def node_is_sorbet_signature?(node)
|
|
72
|
+
# A sibling is not necessarily an AST node. It is a `Symbol` when a method definition is
|
|
73
|
+
# passed to a modifier, such as the `:private` in `private def foo`.
|
|
74
|
+
return false if !node.is_a?(RuboCop::AST::Node)
|
|
75
|
+
|
|
76
|
+
# A node's `source` is `nil` when it has no source range. That is the case for the empty
|
|
77
|
+
# `args` node of a block written without parameters, as in `Struct.new(:a) do ... end`,
|
|
78
|
+
# which is the left sibling of a method defined as the block's only statement.
|
|
79
|
+
node_source = node.source
|
|
80
|
+
|
|
75
81
|
# Is there a better way to check if a node is a sorbet signature? Probably!
|
|
76
|
-
!!(
|
|
82
|
+
!!(node_source && (node_source.include?('sig do') || node_source.include?('sig {')))
|
|
77
83
|
end
|
|
78
84
|
end
|
|
79
85
|
end
|
|
@@ -48,14 +48,14 @@ module RuboCop
|
|
|
48
48
|
# Therefore, for our implementation, we substitute out the non-namespace producing portions of the filename to count the number of namespaces.
|
|
49
49
|
# Note this will *not work* properly in applications that have different assumptions about autoloading.
|
|
50
50
|
|
|
51
|
-
path_without_package_base = relative_filename.gsub(%r
|
|
51
|
+
path_without_package_base = relative_filename.gsub(%r(#{package_name}/app/), '')
|
|
52
52
|
if path_without_package_base.include?('/concerns/')
|
|
53
53
|
autoload_folder_name = path_without_package_base.split('/').first(2).join('/')
|
|
54
54
|
else
|
|
55
55
|
autoload_folder_name = path_without_package_base.split('/').first
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
remaining_file_path = path_without_package_base.gsub(%r
|
|
58
|
+
remaining_file_path = path_without_package_base.gsub(%r(\A#{autoload_folder_name}/), '')
|
|
59
59
|
actual_namespace = get_actual_namespace(remaining_file_path, package_name)
|
|
60
60
|
|
|
61
61
|
if relative_filename.include?('app/')
|
|
@@ -44,12 +44,16 @@ module RuboCop
|
|
|
44
44
|
return if package_for_path.nil?
|
|
45
45
|
|
|
46
46
|
namespace_context = desired_zeitwerk_api.for_file(relative_filename, package_for_path)
|
|
47
|
+
# :nocov: defensive: for_file always returns a context for the `app/` paths that reach here
|
|
47
48
|
return if namespace_context.nil?
|
|
49
|
+
# :nocov:
|
|
48
50
|
|
|
49
|
-
allowed_global_namespaces = Set.new(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
allowed_global_namespaces = Set.new(
|
|
52
|
+
[
|
|
53
|
+
namespace_context.expected_namespace,
|
|
54
|
+
*RuboCop::Packs.config.globally_permitted_namespaces,
|
|
55
|
+
]
|
|
56
|
+
)
|
|
53
57
|
|
|
54
58
|
package_name = package_for_path.name
|
|
55
59
|
actual_namespace = namespace_context.current_namespace
|
|
@@ -63,22 +67,19 @@ module RuboCop
|
|
|
63
67
|
add_offense(
|
|
64
68
|
source_range(processed_source.buffer, 1, 0),
|
|
65
69
|
message: format(
|
|
66
|
-
'Based on the filepath, this file defines
|
|
67
|
-
package_name
|
|
68
|
-
expected_namespace
|
|
70
|
+
'Based on the filepath, this file defines `%{current_fully_qualified_constant}`, but it should be namespaced as `%{expected_namespace}::%{current_fully_qualified_constant}` with path `%{expected_path}`.',
|
|
71
|
+
package_name:,
|
|
72
|
+
expected_namespace:,
|
|
69
73
|
expected_path: relative_desired_path,
|
|
70
|
-
current_fully_qualified_constant:
|
|
74
|
+
current_fully_qualified_constant:
|
|
71
75
|
)
|
|
72
76
|
)
|
|
73
77
|
end
|
|
74
78
|
end
|
|
75
79
|
|
|
76
|
-
# In the future, we'd love this to support auto-correct
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
def support_autocorrect?
|
|
80
|
-
false
|
|
81
|
-
end
|
|
80
|
+
# In the future, we'd love this to support auto-correct,
|
|
81
|
+
# perhaps by automatically renamespacing the file and changing its location.
|
|
82
|
+
# That would mean extending `AutoCorrector` and implementing the correction.
|
|
82
83
|
|
|
83
84
|
private
|
|
84
85
|
|
|
@@ -28,8 +28,8 @@ module RuboCop
|
|
|
28
28
|
sig { returns(T::Boolean) }
|
|
29
29
|
def public_api?
|
|
30
30
|
# PackwerkExtensions should have a method to take in a path and determine if the file is public.
|
|
31
|
-
# For now we put it here and only support the public folder (and not specific private constants).
|
|
32
|
-
# However if we declare that dependency we may want to extract this into `rubocop-packwerk_lite` or something
|
|
31
|
+
# For now, we put it here and only support the public folder (and not specific private constants).
|
|
32
|
+
# However, if we declare that dependency we may want to extract this into `rubocop-packwerk_lite` or something like that!
|
|
33
33
|
constant_definition_location.to_s.include?('/public/')
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -46,21 +46,23 @@ module RuboCop
|
|
|
46
46
|
expected_containing_pack = ParsePackwerk.all.find { |p| p.name.include?("/#{expected_containing_pack_last_name}") }
|
|
47
47
|
return if expected_containing_pack.nil?
|
|
48
48
|
|
|
49
|
-
if namespaces.
|
|
49
|
+
if namespaces.one?
|
|
50
50
|
found_files = expected_containing_pack.directory.glob("app/*/#{expected_containing_pack_last_name}.rb")
|
|
51
51
|
else
|
|
52
52
|
expected_location_in_pack = namespaces[1..].map(&:underscore).join('/')
|
|
53
53
|
found_files = expected_containing_pack.directory.glob("app/*/#{expected_containing_pack_last_name}/#{expected_location_in_pack}.rb")
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
# Because of how
|
|
56
|
+
# Because of how Zeitwerk works, we know two things:
|
|
57
57
|
# 1) Since namespaces map one to one with files, Zeitwerk does not permit multiple files to define the same fully-qualified class/module.
|
|
58
58
|
# (Note it does permit multiple files to open up portions of other namespaces)
|
|
59
59
|
# 2) If a file *could* define a fully qualified constant, then it *must* define that constant!
|
|
60
60
|
#
|
|
61
61
|
# Therefore when we've found possible files, we can sanity check there is only one,
|
|
62
62
|
# and then assume the found pack defines the constant!
|
|
63
|
+
# :nocov: defensive invariant: Zeitwerk guarantees a constant maps to at most one file
|
|
63
64
|
raise if found_files.count > 1
|
|
65
|
+
# :nocov:
|
|
64
66
|
|
|
65
67
|
expected_pack_contains_constant = found_files.any?
|
|
66
68
|
|
|
@@ -69,8 +71,8 @@ module RuboCop
|
|
|
69
71
|
found_file = found_files.first
|
|
70
72
|
|
|
71
73
|
ConstantReference.new(
|
|
72
|
-
constant_name
|
|
73
|
-
global_namespace
|
|
74
|
+
constant_name:,
|
|
75
|
+
global_namespace:,
|
|
74
76
|
source_package: expected_containing_pack,
|
|
75
77
|
constant_definition_location: T.must(found_file),
|
|
76
78
|
referencing_file: Pathname.new(processed_source.path).relative_path_from(Pathname.pwd)
|
|
@@ -39,11 +39,6 @@ module RuboCop
|
|
|
39
39
|
class Dependency < Base
|
|
40
40
|
extend T::Sig
|
|
41
41
|
|
|
42
|
-
sig { returns(T::Boolean) }
|
|
43
|
-
def support_autocorrect?
|
|
44
|
-
false
|
|
45
|
-
end
|
|
46
|
-
|
|
47
42
|
sig { params(node: RuboCop::AST::ConstNode).void }
|
|
48
43
|
def on_const(node)
|
|
49
44
|
return if Private.partial_const_reference?(node)
|
|
@@ -59,15 +54,13 @@ module RuboCop
|
|
|
59
54
|
is_new_violation = [
|
|
60
55
|
!constant_reference.referencing_package.dependencies.include?(constant_reference.source_package.name),
|
|
61
56
|
constant_reference.referencing_package.enforces_dependencies?,
|
|
62
|
-
!Private.violation_in_package_todo_yml?(constant_reference, type: 'dependency')
|
|
57
|
+
!Private.violation_in_package_todo_yml?(constant_reference, type: 'dependency'),
|
|
63
58
|
].all?
|
|
64
59
|
|
|
65
60
|
if is_new_violation
|
|
66
61
|
add_offense(
|
|
67
62
|
node.source_range,
|
|
68
|
-
message:
|
|
69
|
-
'Dependency violation detected. See https://github.com/Shopify/packwerk/blob/main/RESOLVING_VIOLATIONS.md for help'
|
|
70
|
-
)
|
|
63
|
+
message: 'Dependency violation detected. See https://github.com/Shopify/packwerk/blob/main/RESOLVING_VIOLATIONS.md for help'
|
|
71
64
|
)
|
|
72
65
|
end
|
|
73
66
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module PackwerkLite
|
|
6
|
-
# This cop helps ensure that packs are using public API of other systems
|
|
6
|
+
# This cop helps ensure that packs are using the public API of other systems
|
|
7
7
|
# The following examples assume this basic setup.
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
@@ -40,11 +40,6 @@ module RuboCop
|
|
|
40
40
|
class Privacy < Base
|
|
41
41
|
extend T::Sig
|
|
42
42
|
|
|
43
|
-
sig { returns(T::Boolean) }
|
|
44
|
-
def support_autocorrect?
|
|
45
|
-
false
|
|
46
|
-
end
|
|
47
|
-
|
|
48
43
|
sig { params(node: RuboCop::AST::ConstNode).void }
|
|
49
44
|
def on_const(node)
|
|
50
45
|
# See https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/lint/constant_resolution.rb source code as an example
|
|
@@ -52,7 +47,7 @@ module RuboCop
|
|
|
52
47
|
|
|
53
48
|
constant_reference = ConstantResolver::ConstantReference.resolve(node, processed_source)
|
|
54
49
|
|
|
55
|
-
# If we can't determine a constant reference, we can just early return. This could be
|
|
50
|
+
# If we can't determine a constant reference, we can just early return. This could be because the constant is defined
|
|
56
51
|
# in a gem OR because it's not abiding by the namespace convention we've established.
|
|
57
52
|
return if constant_reference.nil?
|
|
58
53
|
return if constant_reference.referencing_package.name == constant_reference.source_package.name
|
|
@@ -60,15 +55,13 @@ module RuboCop
|
|
|
60
55
|
is_new_violation = [
|
|
61
56
|
!constant_reference.public_api?,
|
|
62
57
|
constant_reference.source_package.enforces_privacy?,
|
|
63
|
-
!Private.violation_in_package_todo_yml?(constant_reference)
|
|
58
|
+
!Private.violation_in_package_todo_yml?(constant_reference),
|
|
64
59
|
].all?
|
|
65
60
|
|
|
66
61
|
if is_new_violation
|
|
67
62
|
add_offense(
|
|
68
63
|
node.source_range,
|
|
69
|
-
message:
|
|
70
|
-
'Privacy violation detected. See https://github.com/Shopify/packwerk/blob/main/RESOLVING_VIOLATIONS.md for help'
|
|
71
|
-
)
|
|
64
|
+
message: 'Privacy violation detected. See https://github.com/Shopify/packwerk/blob/main/RESOLVING_VIOLATIONS.md for help'
|
|
72
65
|
)
|
|
73
66
|
end
|
|
74
67
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'lint_roller'
|
|
5
|
+
|
|
6
|
+
module RuboCop
|
|
7
|
+
module Packs
|
|
8
|
+
# A plugin that integrates rubocop-packs with RuboCop's plugin system.
|
|
9
|
+
class Plugin < LintRoller::Plugin
|
|
10
|
+
extend T::Sig
|
|
11
|
+
|
|
12
|
+
sig { returns(LintRoller::About) }
|
|
13
|
+
def about
|
|
14
|
+
LintRoller::About.new(
|
|
15
|
+
name: 'rubocop-packs',
|
|
16
|
+
version: VERSION,
|
|
17
|
+
homepage: 'https://github.com/rubyatscale/rubocop-packs',
|
|
18
|
+
description: 'A collection of Rubocop rules for gradually modularizing a ruby codebase'
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
sig { params(context: LintRoller::Context).returns(T::Boolean) }
|
|
23
|
+
def supported?(context)
|
|
24
|
+
context.engine == :rubocop
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sig { params(_context: LintRoller::Context).returns(LintRoller::Rules) }
|
|
28
|
+
def rules(_context)
|
|
29
|
+
LintRoller::Rules.new(
|
|
30
|
+
type: :path,
|
|
31
|
+
config_format: :rubocop,
|
|
32
|
+
value: Pathname.new(__dir__).join('../../../config/default.yml')
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/rubocop/packs.rb
CHANGED
|
@@ -7,11 +7,6 @@ module RuboCop
|
|
|
7
7
|
module Packs
|
|
8
8
|
extend T::Sig
|
|
9
9
|
|
|
10
|
-
PROJECT_ROOT = T.let(Pathname.new(__dir__).parent.parent.expand_path.freeze, Pathname)
|
|
11
|
-
CONFIG_DEFAULT = T.let(PROJECT_ROOT.join('config', 'default.yml').freeze, Pathname)
|
|
12
|
-
|
|
13
|
-
private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
|
|
14
|
-
|
|
15
10
|
sig { void }
|
|
16
11
|
def self.bust_cache!
|
|
17
12
|
config.bust_cache!
|
data/lib/rubocop-packs.rb
CHANGED
|
@@ -5,12 +5,11 @@ require 'rubocop'
|
|
|
5
5
|
require 'packs-specification'
|
|
6
6
|
|
|
7
7
|
require_relative 'rubocop/packs'
|
|
8
|
-
require_relative 'rubocop/packs/
|
|
8
|
+
require_relative 'rubocop/packs/version'
|
|
9
|
+
require_relative 'rubocop/packs/plugin'
|
|
9
10
|
require_relative 'rubocop/packwerk_lite'
|
|
10
11
|
|
|
11
12
|
require 'rubocop/cop/packs/root_namespace_is_pack_name'
|
|
12
13
|
require 'rubocop/cop/packs/typed_public_apis'
|
|
13
14
|
require 'rubocop/cop/packs/class_methods_as_public_apis'
|
|
14
15
|
require 'rubocop/cop/packs/documented_public_apis'
|
|
15
|
-
|
|
16
|
-
RuboCop::Packs::Inject.defaults!
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-packs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gusto Engineers
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activesupport
|
|
@@ -52,6 +51,20 @@ dependencies:
|
|
|
52
51
|
- - ">="
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: lint_roller
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.1'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '1.1'
|
|
55
68
|
- !ruby/object:Gem::Dependency
|
|
56
69
|
name: packs-specification
|
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -86,28 +99,28 @@ dependencies:
|
|
|
86
99
|
requirements:
|
|
87
100
|
- - "~>"
|
|
88
101
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.
|
|
102
|
+
version: '1.72'
|
|
90
103
|
type: :runtime
|
|
91
104
|
prerelease: false
|
|
92
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
106
|
requirements:
|
|
94
107
|
- - "~>"
|
|
95
108
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '1.
|
|
109
|
+
version: '1.72'
|
|
97
110
|
- !ruby/object:Gem::Dependency
|
|
98
111
|
name: rubocop-sorbet
|
|
99
112
|
requirement: !ruby/object:Gem::Requirement
|
|
100
113
|
requirements:
|
|
101
114
|
- - ">="
|
|
102
115
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 0.
|
|
116
|
+
version: 0.9.0
|
|
104
117
|
type: :runtime
|
|
105
118
|
prerelease: false
|
|
106
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
120
|
requirements:
|
|
108
121
|
- - ">="
|
|
109
122
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 0.
|
|
123
|
+
version: 0.9.0
|
|
111
124
|
- !ruby/object:Gem::Dependency
|
|
112
125
|
name: sorbet-runtime
|
|
113
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -126,16 +139,16 @@ dependencies:
|
|
|
126
139
|
name: bundler
|
|
127
140
|
requirement: !ruby/object:Gem::Requirement
|
|
128
141
|
requirements:
|
|
129
|
-
- - "
|
|
142
|
+
- - ">="
|
|
130
143
|
- !ruby/object:Gem::Version
|
|
131
|
-
version:
|
|
144
|
+
version: '0'
|
|
132
145
|
type: :development
|
|
133
146
|
prerelease: false
|
|
134
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
148
|
requirements:
|
|
136
|
-
- - "
|
|
149
|
+
- - ">="
|
|
137
150
|
- !ruby/object:Gem::Version
|
|
138
|
-
version:
|
|
151
|
+
version: '0'
|
|
139
152
|
- !ruby/object:Gem::Dependency
|
|
140
153
|
name: parser
|
|
141
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -192,6 +205,34 @@ dependencies:
|
|
|
192
205
|
- - ">="
|
|
193
206
|
- !ruby/object:Gem::Version
|
|
194
207
|
version: '0'
|
|
208
|
+
- !ruby/object:Gem::Dependency
|
|
209
|
+
name: rubocop-gusto
|
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0'
|
|
215
|
+
type: :development
|
|
216
|
+
prerelease: false
|
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
222
|
+
- !ruby/object:Gem::Dependency
|
|
223
|
+
name: simplecov
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - ">="
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '0'
|
|
229
|
+
type: :development
|
|
230
|
+
prerelease: false
|
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
232
|
+
requirements:
|
|
233
|
+
- - ">="
|
|
234
|
+
- !ruby/object:Gem::Version
|
|
235
|
+
version: '0'
|
|
195
236
|
- !ruby/object:Gem::Dependency
|
|
196
237
|
name: sorbet
|
|
197
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -220,6 +261,20 @@ dependencies:
|
|
|
220
261
|
- - ">="
|
|
221
262
|
- !ruby/object:Gem::Version
|
|
222
263
|
version: '0'
|
|
264
|
+
- !ruby/object:Gem::Dependency
|
|
265
|
+
name: yard
|
|
266
|
+
requirement: !ruby/object:Gem::Requirement
|
|
267
|
+
requirements:
|
|
268
|
+
- - ">="
|
|
269
|
+
- !ruby/object:Gem::Version
|
|
270
|
+
version: '0'
|
|
271
|
+
type: :development
|
|
272
|
+
prerelease: false
|
|
273
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
274
|
+
requirements:
|
|
275
|
+
- - ">="
|
|
276
|
+
- !ruby/object:Gem::Version
|
|
277
|
+
version: '0'
|
|
223
278
|
description: A collection of Rubocop rules for gradually modularizing a ruby codebase
|
|
224
279
|
email:
|
|
225
280
|
- dev@gusto.com
|
|
@@ -240,10 +295,11 @@ files:
|
|
|
240
295
|
- lib/rubocop/cop/packwerk_lite/privacy_checker.rb
|
|
241
296
|
- lib/rubocop/cop/packwerk_lite/private.rb
|
|
242
297
|
- lib/rubocop/packs.rb
|
|
243
|
-
- lib/rubocop/packs/
|
|
298
|
+
- lib/rubocop/packs/plugin.rb
|
|
244
299
|
- lib/rubocop/packs/private.rb
|
|
245
300
|
- lib/rubocop/packs/private/configuration.rb
|
|
246
301
|
- lib/rubocop/packs/private/offense.rb
|
|
302
|
+
- lib/rubocop/packs/version.rb
|
|
247
303
|
- lib/rubocop/packwerk_lite.rb
|
|
248
304
|
homepage: https://github.com/rubyatscale/rubocop-packs
|
|
249
305
|
licenses:
|
|
@@ -253,7 +309,7 @@ metadata:
|
|
|
253
309
|
source_code_uri: https://github.com/rubyatscale/rubocop-packs
|
|
254
310
|
changelog_uri: https://github.com/rubyatscale/rubocop-packs/releases
|
|
255
311
|
allowed_push_host: https://rubygems.org
|
|
256
|
-
|
|
312
|
+
default_lint_roller_plugin: RuboCop::Packs::Plugin
|
|
257
313
|
rdoc_options: []
|
|
258
314
|
require_paths:
|
|
259
315
|
- lib
|
|
@@ -261,15 +317,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
261
317
|
requirements:
|
|
262
318
|
- - ">="
|
|
263
319
|
- !ruby/object:Gem::Version
|
|
264
|
-
version: '
|
|
320
|
+
version: '3.3'
|
|
265
321
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
322
|
requirements:
|
|
267
323
|
- - ">="
|
|
268
324
|
- !ruby/object:Gem::Version
|
|
269
325
|
version: '0'
|
|
270
326
|
requirements: []
|
|
271
|
-
rubygems_version: 3.
|
|
272
|
-
signing_key:
|
|
327
|
+
rubygems_version: 3.6.9
|
|
273
328
|
specification_version: 4
|
|
274
329
|
summary: A collection of Rubocop rules for gradually modularizing a ruby codebase
|
|
275
330
|
test_files: []
|
data/lib/rubocop/packs/inject.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# typed: strict
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# The original code is from https://github.com/rubocop/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
|
|
5
|
-
# See https://github.com/rubocop/rubocop-rspec/blob/master/MIT-LICENSE.md
|
|
6
|
-
module RuboCop
|
|
7
|
-
module Packs
|
|
8
|
-
# Because RuboCop doesn't yet support plugins, we have to monkey patch in a
|
|
9
|
-
# bit of our configuration.
|
|
10
|
-
module Inject
|
|
11
|
-
extend T::Sig
|
|
12
|
-
|
|
13
|
-
sig { void }
|
|
14
|
-
def self.defaults!
|
|
15
|
-
path = CONFIG_DEFAULT.to_s
|
|
16
|
-
hash = ConfigLoader.send(:load_yaml_configuration, path)
|
|
17
|
-
config = Config.new(hash, path).tap(&:make_excludes_absolute)
|
|
18
|
-
puts "configuration from #{path}" if ConfigLoader.debug?
|
|
19
|
-
config = ConfigLoader.merge_with_default(config, path)
|
|
20
|
-
ConfigLoader.instance_variable_set(:@default_configuration, config)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|