rubocop-packs 0.0.7 → 0.0.9
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/config/default.yml +4 -4
- data/lib/rubocop/cop/packs/class_methods_as_public_apis.rb +4 -10
- data/lib/rubocop/cop/packs/{namespaced_under_package_name → namespace_convention}/desired_zeitwerk_api.rb +5 -3
- data/lib/rubocop/cop/packs/{namespaced_under_package_name.rb → namespace_convention.rb} +10 -5
- data/lib/rubocop/cop/packs/require_documented_public_apis.rb +28 -0
- data/lib/rubocop-packs.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e2e2567a37e676f5c1ebf7a890057a542e4a5bbd667ab537ab0f82b24151a38
|
4
|
+
data.tar.gz: d19311bdf95df46ce37b93fe7bb898791b0a63b7804e418d77b300206ca818ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35941a67c992fc6afa9959d11c1c9d4929d48cb110329bea2ad3810458a769aeedc295c4e96bc1314cbc5ab3d1619b033e2314b8559753ce28827cbf329ebeeb
|
7
|
+
data.tar.gz: 1240836b6a4e0dff104815f1b7871102a2224abb3c80b2e8efa616d2dd251124149bc8efa4fcad31f63d300715e5853472090daa097cbaaa756bc635166172c5
|
data/config/default.yml
CHANGED
@@ -6,11 +6,11 @@ Packs/ClassMethodsAsPublicApis:
|
|
6
6
|
- Struct
|
7
7
|
- OpenStruct
|
8
8
|
|
9
|
-
Packs/
|
10
|
-
Enabled:
|
9
|
+
Packs/NamespaceConvention:
|
10
|
+
Enabled: true
|
11
11
|
|
12
12
|
Packs/TypedPublicApi:
|
13
|
-
Enabled:
|
13
|
+
Enabled: true
|
14
14
|
|
15
15
|
Packs/RequireDocumentedPublicApis:
|
16
|
-
Enabled:
|
16
|
+
Enabled: true
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
7
7
|
# This cop states that public API should live on class methods, which are more easily statically analyzable,
|
8
8
|
# searchable, and typically hold less state.
|
9
9
|
#
|
10
|
+
# Options:
|
11
|
+
#
|
12
|
+
# * `AcceptableParentClasses`: A list of classes that, if inherited from, non-class methods are permitted (useful when value objects are a part of your public API)
|
13
|
+
#
|
10
14
|
# @example
|
11
15
|
#
|
12
16
|
# # bad
|
@@ -23,16 +27,6 @@ module RuboCop
|
|
23
27
|
# end
|
24
28
|
# end
|
25
29
|
#
|
26
|
-
# @example AcceptableParentClasses: [T::Enum, T::Struct, Struct, OpenStruct] (default)
|
27
|
-
# You can define `AcceptableParentClasses` which are a list of classes that, if inherited from, non-class methods are permitted.
|
28
|
-
# This is useful when value objects are a part of your public API.
|
29
|
-
#
|
30
|
-
# # good
|
31
|
-
# # packs/foo/app/public/foo.rb
|
32
|
-
# class Foo < T::Enum
|
33
|
-
# const :blah
|
34
|
-
# end
|
35
|
-
#
|
36
30
|
class ClassMethodsAsPublicApis < Base
|
37
31
|
extend T::Sig
|
38
32
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Packs
|
6
|
-
class
|
6
|
+
class NamespaceConvention < Base
|
7
7
|
#
|
8
8
|
# This is a private class that represents API that we would prefer to be available somehow in Zeitwerk.
|
9
9
|
#
|
@@ -12,6 +12,7 @@ module RuboCop
|
|
12
12
|
|
13
13
|
class NamespaceContext < T::Struct
|
14
14
|
const :current_namespace, String
|
15
|
+
const :current_fully_qualified_constant, String
|
15
16
|
const :expected_namespace, String
|
16
17
|
const :expected_filepath, String
|
17
18
|
end
|
@@ -72,7 +73,8 @@ module RuboCop
|
|
72
73
|
relative_desired_path = absolute_desired_path.relative_path_from(root_pathname)
|
73
74
|
|
74
75
|
NamespaceContext.new(
|
75
|
-
current_namespace: actual_namespace,
|
76
|
+
current_namespace: T.must(actual_namespace.split('::').first),
|
77
|
+
current_fully_qualified_constant: actual_namespace,
|
76
78
|
expected_namespace: get_pack_based_namespace(package_for_path),
|
77
79
|
expected_filepath: relative_desired_path.to_s
|
78
80
|
)
|
@@ -99,7 +101,7 @@ module RuboCop
|
|
99
101
|
def get_actual_namespace(remaining_file_path, package_name)
|
100
102
|
# If the remaining file path is a ruby file (not a directory), then it establishes a global namespace
|
101
103
|
# Otherwise, per Zeitwerk's conventions as listed above, its a directory that establishes another global namespace
|
102
|
-
|
104
|
+
remaining_file_path.split('/').map { |entry| entry.gsub('.rb', '').camelize }.join('::')
|
103
105
|
end
|
104
106
|
end
|
105
107
|
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
# For String#camelize
|
4
4
|
require 'active_support/core_ext/string/inflections'
|
5
|
-
require 'rubocop/cop/packs/
|
5
|
+
require 'rubocop/cop/packs/namespace_convention/desired_zeitwerk_api'
|
6
6
|
|
7
7
|
module RuboCop
|
8
8
|
module Cop
|
9
9
|
module Packs
|
10
10
|
# This cop helps ensure that each pack exposes one namespace.
|
11
|
+
# Note that this cop doesn't necessarily expect you to be using stimpack (https://github.com/rubyatscale/stimpack),
|
12
|
+
# but it does expect packs to live in the organizational structure as described in the README.md of that gem.
|
11
13
|
#
|
12
14
|
# @example
|
13
15
|
#
|
@@ -19,7 +21,7 @@ module RuboCop
|
|
19
21
|
# # packs/foo/app/services/foo/blah/bar.rb
|
20
22
|
# class Foo::Blah::Bar; end
|
21
23
|
#
|
22
|
-
class
|
24
|
+
class NamespaceConvention < Base
|
23
25
|
extend T::Sig
|
24
26
|
|
25
27
|
include RangeHelp
|
@@ -47,6 +49,7 @@ module RuboCop
|
|
47
49
|
|
48
50
|
package_name = package_for_path.name
|
49
51
|
actual_namespace = namespace_context.current_namespace
|
52
|
+
current_fully_qualified_constant = namespace_context.current_fully_qualified_constant
|
50
53
|
|
51
54
|
if allowed_global_namespaces.include?(actual_namespace)
|
52
55
|
# No problem!
|
@@ -60,21 +63,23 @@ module RuboCop
|
|
60
63
|
add_offense(
|
61
64
|
source_range(processed_source.buffer, 1, 0),
|
62
65
|
message: format(
|
63
|
-
'
|
66
|
+
'Based on the filepath, this file defines `%<current_fully_qualified_constant>s`, but it should be namespaced as `%<expected_namespace>s::%<current_fully_qualified_constant>s` with path `%<expected_path>s`.',
|
64
67
|
package_name: package_name,
|
65
68
|
expected_namespace: expected_namespace,
|
66
|
-
expected_path: relative_desired_path
|
69
|
+
expected_path: relative_desired_path,
|
70
|
+
current_fully_qualified_constant: current_fully_qualified_constant
|
67
71
|
)
|
68
72
|
)
|
69
73
|
elsif pack_owning_this_namespace
|
70
74
|
add_offense(
|
71
75
|
source_range(processed_source.buffer, 1, 0),
|
72
76
|
message: format(
|
73
|
-
'`%<pack_owning_this_namespace>s` prevents other packs from sitting in the `%<actual_namespace>s` namespace. This should be namespaced under `%<expected_namespace>s` with path `%<expected_path>s`.
|
77
|
+
'Based on the filepath, this file defines `%<current_fully_qualified_constant>s`. `%<pack_owning_this_namespace>s` prevents other packs from sitting in the `%<actual_namespace>s` namespace. This should be namespaced under `%<expected_namespace>s` with path `%<expected_path>s`.',
|
74
78
|
package_name: package_name,
|
75
79
|
pack_owning_this_namespace: pack_owning_this_namespace,
|
76
80
|
expected_namespace: expected_namespace,
|
77
81
|
actual_namespace: actual_namespace,
|
82
|
+
current_fully_qualified_constant: current_fully_qualified_constant,
|
78
83
|
expected_path: relative_desired_path
|
79
84
|
)
|
80
85
|
)
|
@@ -3,7 +3,35 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Packs
|
6
|
+
# This cop helps ensure that each pack has a documented public API
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# # packs/foo/app/public/foo.rb
|
12
|
+
# class Foo
|
13
|
+
# sig { void }
|
14
|
+
# def bar
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # packs/foo/app/public/foo.rb
|
18
|
+
# class Foo
|
19
|
+
# # This is a documentation comment.
|
20
|
+
# # It can live below or below a sorbet type signature.
|
21
|
+
# sig { void }
|
22
|
+
# def bar
|
23
|
+
# end
|
24
|
+
#
|
6
25
|
class RequireDocumentedPublicApis < Style::DocumentationMethod
|
26
|
+
# This cop does two things:
|
27
|
+
# 1) It only activates for things in the public folder
|
28
|
+
# 2) It allows `Style/DocumentationMethod` to work with sigs as expected.
|
29
|
+
#
|
30
|
+
# An alternate approach would be to monkey patch the existing cop, as `rubocop-sorbet` did here:
|
31
|
+
# https://github.com/Shopify/rubocop-sorbet/blob/6634f033611604cd76eeb73eae6d8728ec82d504/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb
|
32
|
+
# This monkey-patched cop could/should probably be upstreamed to `rubocop-sorbet`, and then `config/default.yml` could simply set `packs/*/app/public/**/*`
|
33
|
+
# in the default include paths. However, that strategy has the downside of resulting in more configuration for the consumer if they only want to
|
34
|
+
# support this for some packs.
|
7
35
|
extend T::Sig
|
8
36
|
|
9
37
|
sig { returns(T::Boolean) }
|
data/lib/rubocop-packs.rb
CHANGED
@@ -7,7 +7,7 @@ require 'parse_packwerk'
|
|
7
7
|
require_relative 'rubocop/packs'
|
8
8
|
require_relative 'rubocop/packs/inject'
|
9
9
|
|
10
|
-
require 'rubocop/cop/packs/
|
10
|
+
require 'rubocop/cop/packs/namespace_convention'
|
11
11
|
require 'rubocop/cop/packs/typed_public_api'
|
12
12
|
require 'rubocop/cop/packs/class_methods_as_public_apis'
|
13
13
|
require 'rubocop/cop/packs/require_documented_public_apis'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
@@ -189,8 +189,8 @@ files:
|
|
189
189
|
- config/default.yml
|
190
190
|
- lib/rubocop-packs.rb
|
191
191
|
- lib/rubocop/cop/packs/class_methods_as_public_apis.rb
|
192
|
-
- lib/rubocop/cop/packs/
|
193
|
-
- lib/rubocop/cop/packs/
|
192
|
+
- lib/rubocop/cop/packs/namespace_convention.rb
|
193
|
+
- lib/rubocop/cop/packs/namespace_convention/desired_zeitwerk_api.rb
|
194
194
|
- lib/rubocop/cop/packs/require_documented_public_apis.rb
|
195
195
|
- lib/rubocop/cop/packs/typed_public_api.rb
|
196
196
|
- lib/rubocop/packs.rb
|