rubocop-packs 0.0.32 → 0.0.33
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/lib/rubocop/cop/packs/documented_public_apis.rb +10 -1
- data/lib/rubocop/cop/packs/root_namespace_is_pack_name/desired_zeitwerk_api.rb +4 -9
- data/lib/rubocop/cop/packs/root_namespace_is_pack_name.rb +1 -3
- data/lib/rubocop/cop/packwerk_lite/constant_resolver.rb +3 -2
- data/lib/rubocop/packs/private/offense.rb +2 -2
- data/lib/rubocop/packs/private.rb +10 -8
- data/lib/rubocop/packs.rb +14 -18
- data/lib/rubocop/packwerk_lite.rb +1 -0
- data/lib/rubocop-packs.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e56f9a941b630002bfb4af833716b2cc58a3d2a3f21fbb673f86b04cf0eab0eb
|
4
|
+
data.tar.gz: abd74e0ecf25630da93a7ddff425060373787e33c209e0ce850599675ee6b842
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c45aa69414bc48fe5e0874defaee69dee2ddfc5372f4683ce9644c70aace411e64c46ef3630513d4e6660868116116ef2dc4d03363865e7f39059ffa5630e007
|
7
|
+
data.tar.gz: 794ffd4ad403ca046bac4b22e21d419207fe9bb49215ef8b56f3b5f3b3ef7ced9e8cbd33c331a7b13f9d8e0aebb986d9c512d14b880af757bb6e52cc0ba8b1b0
|
@@ -14,10 +14,19 @@ module RuboCop
|
|
14
14
|
# def bar; end
|
15
15
|
# end
|
16
16
|
#
|
17
|
+
# # good
|
17
18
|
# # packs/foo/app/public/foo.rb
|
18
19
|
# class Foo
|
19
20
|
# # This is a documentation comment.
|
20
|
-
#
|
21
|
+
# def bar; end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# # packs/foo/app/public/foo.rb
|
26
|
+
# class Foo
|
27
|
+
# # This is a documentation comment.
|
28
|
+
# # It should appear above a sorbet type signature
|
29
|
+
# sig { void }
|
21
30
|
# def bar; end
|
22
31
|
# end
|
23
32
|
#
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
# Likely this means that our own cop should determine the desired namespace and pass that in
|
29
29
|
# and this can determine actual namespace and how to get to expected.
|
30
30
|
#
|
31
|
-
sig { params(relative_filename: String, package_for_path:
|
31
|
+
sig { params(relative_filename: String, package_for_path: ::Packs::Pack).returns(T.nilable(NamespaceContext)) }
|
32
32
|
def for_file(relative_filename, package_for_path)
|
33
33
|
package_name = package_for_path.name
|
34
34
|
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
package_name,
|
69
69
|
T.must(app_or_lib),
|
70
70
|
T.must(autoload_folder_name),
|
71
|
-
|
71
|
+
package_for_path.last_name,
|
72
72
|
remaining_file_path
|
73
73
|
)
|
74
74
|
|
@@ -82,9 +82,9 @@ module RuboCop
|
|
82
82
|
)
|
83
83
|
end
|
84
84
|
|
85
|
-
sig { params(pack:
|
85
|
+
sig { params(pack: ::Packs::Pack).returns(String) }
|
86
86
|
def get_pack_based_namespace(pack)
|
87
|
-
|
87
|
+
pack.last_name.camelize
|
88
88
|
end
|
89
89
|
|
90
90
|
private
|
@@ -94,11 +94,6 @@ module RuboCop
|
|
94
94
|
Pathname.pwd
|
95
95
|
end
|
96
96
|
|
97
|
-
sig { params(pack: ParsePackwerk::Package).returns(String) }
|
98
|
-
def get_package_last_name(pack)
|
99
|
-
T.must(pack.name.split('/').last)
|
100
|
-
end
|
101
|
-
|
102
97
|
sig { params(remaining_file_path: String, package_name: String).returns(String) }
|
103
98
|
def get_actual_namespace(remaining_file_path, package_name)
|
104
99
|
# If the remaining file path is a ruby file (not a directory), then it establishes a global namespace
|
@@ -38,9 +38,7 @@ module RuboCop
|
|
38
38
|
return if !relative_filename.include?('app/') || relative_filepath.extname != '.rb'
|
39
39
|
|
40
40
|
relative_filename = relative_filepath.to_s
|
41
|
-
package_for_path =
|
42
|
-
# If a pack is using automatic pack namespaces, this protection is a no-op since zeitwerk will enforce single namespaces in that case.
|
43
|
-
return if package_for_path.metadata['automatic_pack_namespace']
|
41
|
+
package_for_path = ::Packs.for_file(relative_filename)
|
44
42
|
|
45
43
|
return if package_for_path.nil?
|
46
44
|
|
@@ -27,8 +27,9 @@ module RuboCop
|
|
27
27
|
|
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
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 liek that!
|
32
33
|
constant_definition_location.to_s.include?('/public/')
|
33
34
|
end
|
34
35
|
|
@@ -40,7 +41,7 @@ module RuboCop
|
|
40
41
|
|
41
42
|
expected_containing_pack_last_name = global_namespace.underscore
|
42
43
|
|
43
|
-
# We don't use
|
44
|
+
# We don't use Packs.find(...) here because we want to look for nested packs, and this pack could be a child pack in a nested pack too.
|
44
45
|
# In the future, we might want `find` to be able to take a glob or a regex to look for packs with a specific name structure.
|
45
46
|
expected_containing_pack = ParsePackwerk.all.find { |p| p.name.include?("/#{expected_containing_pack_last_name}") }
|
46
47
|
return if expected_containing_pack.nil?
|
@@ -9,9 +9,9 @@ module RuboCop
|
|
9
9
|
const :cop_name, String
|
10
10
|
const :filepath, String
|
11
11
|
|
12
|
-
sig { returns(
|
12
|
+
sig { returns(T.nilable(::Packs::Pack)) }
|
13
13
|
def pack
|
14
|
-
|
14
|
+
::Packs.for_file(filepath)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -36,10 +36,10 @@ module RuboCop
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
sig { params(package:
|
39
|
+
sig { params(package: ::Packs::Pack).returns(T::Array[String]) }
|
40
40
|
def self.validate_rubocop_todo_yml(package)
|
41
41
|
errors = []
|
42
|
-
rubocop_todo = package.
|
42
|
+
rubocop_todo = package.relative_path.join(PACK_LEVEL_RUBOCOP_TODO_YML)
|
43
43
|
return errors unless rubocop_todo.exist?
|
44
44
|
|
45
45
|
loaded_rubocop_todo = YAML.load_file(rubocop_todo)
|
@@ -57,7 +57,8 @@ module RuboCop
|
|
57
57
|
ERROR_MESSAGE
|
58
58
|
else
|
59
59
|
loaded_rubocop_todo[key]['Exclude'].each do |filepath|
|
60
|
-
|
60
|
+
pack = ::Packs.for_file(filepath)
|
61
|
+
return [] unless pack && pack.name != package.name
|
61
62
|
|
62
63
|
errors << <<~ERROR_MESSAGE
|
63
64
|
#{rubocop_todo} contains invalid configuration for #{key}.
|
@@ -71,10 +72,10 @@ module RuboCop
|
|
71
72
|
errors
|
72
73
|
end
|
73
74
|
|
74
|
-
sig { params(package:
|
75
|
+
sig { params(package: ::Packs::Pack).returns(T::Array[String]) }
|
75
76
|
def self.validate_rubocop_yml(package)
|
76
77
|
errors = []
|
77
|
-
rubocop_yml = package.
|
78
|
+
rubocop_yml = package.relative_path.join(PACK_LEVEL_RUBOCOP_YML)
|
78
79
|
return errors unless rubocop_yml.exist?
|
79
80
|
|
80
81
|
loaded_rubocop_yml = YAML.load_file(rubocop_yml)
|
@@ -122,14 +123,14 @@ module RuboCop
|
|
122
123
|
excludes
|
123
124
|
end
|
124
125
|
|
125
|
-
sig { params(package:
|
126
|
+
sig { params(package: ::Packs::Pack).returns(T::Array[String]) }
|
126
127
|
def self.validate_failure_mode_strict(package)
|
127
128
|
errors = T.let([], T::Array[String])
|
128
129
|
|
129
130
|
Packs.config.permitted_pack_level_cops.each do |cop|
|
130
131
|
excludes = exclude_for_rule(cop)
|
131
132
|
|
132
|
-
rubocop_yml = package.
|
133
|
+
rubocop_yml = package.relative_path.join(PACK_LEVEL_RUBOCOP_YML)
|
133
134
|
|
134
135
|
next unless rubocop_yml.exist?
|
135
136
|
|
@@ -137,7 +138,8 @@ module RuboCop
|
|
137
138
|
next unless loaded_rubocop_yml[cop] && loaded_rubocop_yml[cop]['FailureMode'] == 'strict'
|
138
139
|
|
139
140
|
excludes_for_package = excludes.select do |exclude|
|
140
|
-
|
141
|
+
pack = ::Packs.for_file(exclude)
|
142
|
+
pack && pack.name == package.name
|
141
143
|
end
|
142
144
|
next if excludes_for_package.empty?
|
143
145
|
|
data/lib/rubocop/packs.rb
CHANGED
@@ -26,15 +26,15 @@ module RuboCop
|
|
26
26
|
# That is: the ability to preserve the location of `.rubocop_todo.yml` files and associate
|
27
27
|
# exclusions with the closest ancestor `.rubocop_todo.yml`
|
28
28
|
#
|
29
|
-
sig { params(packs: T::Array[
|
29
|
+
sig { params(packs: T::Array[::Packs::Pack], files: T::Array[String]).void }
|
30
30
|
def self.regenerate_todo(packs: [], files: [])
|
31
31
|
# Delete the old pack-level rubocop todo files so that we can regenerate the new one from scratch
|
32
32
|
packs.each do |pack|
|
33
|
-
rubocop_todo_yml = pack.
|
33
|
+
rubocop_todo_yml = pack.relative_path.join(PACK_LEVEL_RUBOCOP_TODO_YML)
|
34
34
|
rubocop_todo_yml.delete if rubocop_todo_yml.exist?
|
35
35
|
end
|
36
36
|
|
37
|
-
paths = packs.empty? ? files : packs.map(&:name)
|
37
|
+
paths = packs.empty? ? files : packs.map(&:name)
|
38
38
|
|
39
39
|
cop_names = config.permitted_pack_level_cops.select do |cop_name|
|
40
40
|
YAML.load_file('.rubocop.yml').fetch(cop_name, {})['Enabled']
|
@@ -46,10 +46,10 @@ module RuboCop
|
|
46
46
|
)
|
47
47
|
|
48
48
|
offenses.group_by(&:pack).each do |pack, offenses_for_pack|
|
49
|
-
next if pack.
|
50
|
-
next if !pack.
|
49
|
+
next if pack.nil?
|
50
|
+
next if !pack.relative_path.join(PACK_LEVEL_RUBOCOP_YML).exist?
|
51
51
|
|
52
|
-
rubocop_todo_yml = pack.
|
52
|
+
rubocop_todo_yml = pack.relative_path.join(PACK_LEVEL_RUBOCOP_TODO_YML)
|
53
53
|
if rubocop_todo_yml.exist?
|
54
54
|
rubocop_todo = YAML.load_file(rubocop_todo_yml)
|
55
55
|
else
|
@@ -74,10 +74,10 @@ module RuboCop
|
|
74
74
|
# That is: the ability to preserve the location of `.rubocop_todo.yml` files and associate
|
75
75
|
# exclusions with the closest ancestor `.rubocop_todo.yml`
|
76
76
|
#
|
77
|
-
sig { params(packs: T::Array[
|
77
|
+
sig { params(packs: T::Array[::Packs::Pack]).void }
|
78
78
|
def self.set_default_rubocop_yml(packs:)
|
79
79
|
packs.each do |pack|
|
80
|
-
rubocop_yml =
|
80
|
+
rubocop_yml = pack.relative_path.join(PACK_LEVEL_RUBOCOP_YML)
|
81
81
|
rubocop_yml_hash = {}
|
82
82
|
config.required_pack_level_cops.each do |cop|
|
83
83
|
rubocop_yml_hash[cop] = { 'Enabled' => true }
|
@@ -101,10 +101,8 @@ module RuboCop
|
|
101
101
|
# We do this because when the ERB is evaluated Dir.pwd is at the directory containing the YML.
|
102
102
|
# Ideally rubocop wouldn't change the PWD before invoking this method.
|
103
103
|
Dir.chdir(root_pathname) do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
rubocop_todo = package.directory.join(PACK_LEVEL_RUBOCOP_TODO_YML)
|
104
|
+
::Packs.all.each do |package|
|
105
|
+
rubocop_todo = package.relative_path.join(PACK_LEVEL_RUBOCOP_TODO_YML)
|
108
106
|
if rubocop_todo.exist?
|
109
107
|
loaded_rubocop_todo = YAML.load_file(rubocop_todo)
|
110
108
|
loaded_rubocop_todo.each do |cop_name, key_config|
|
@@ -114,7 +112,7 @@ module RuboCop
|
|
114
112
|
end
|
115
113
|
end
|
116
114
|
|
117
|
-
pack_rubocop = package.
|
115
|
+
pack_rubocop = package.relative_path.join(PACK_LEVEL_RUBOCOP_YML)
|
118
116
|
next unless pack_rubocop.exist?
|
119
117
|
|
120
118
|
loaded_pack_rubocop = YAML.load_file(pack_rubocop)
|
@@ -123,10 +121,10 @@ module RuboCop
|
|
123
121
|
|
124
122
|
if key_config['Enabled']
|
125
123
|
rubocop_config[cop_name]['Include'] ||= []
|
126
|
-
rubocop_config[cop_name]['Include'] << package.
|
124
|
+
rubocop_config[cop_name]['Include'] << package.relative_path.join('**/*').to_s
|
127
125
|
else
|
128
126
|
rubocop_config[cop_name]['Exclude'] ||= []
|
129
|
-
rubocop_config[cop_name]['Exclude'] << package.
|
127
|
+
rubocop_config[cop_name]['Exclude'] << package.relative_path.join('**/*').to_s
|
130
128
|
end
|
131
129
|
end
|
132
130
|
end
|
@@ -167,9 +165,7 @@ module RuboCop
|
|
167
165
|
sig { returns(T::Array[String]) }
|
168
166
|
def self.validate
|
169
167
|
errors = T.let([], T::Array[String])
|
170
|
-
|
171
|
-
next if package.name == ParsePackwerk::ROOT_PACKAGE_NAME
|
172
|
-
|
168
|
+
::Packs.all.each do |package|
|
173
169
|
errors += Private.validate_rubocop_todo_yml(package)
|
174
170
|
errors += Private.validate_rubocop_yml(package)
|
175
171
|
errors += Private.validate_failure_mode_strict(package)
|
data/lib/rubocop-packs.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.33
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: packs
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: parse_packwerk
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,7 +234,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
234
|
requirements:
|
221
235
|
- - ">="
|
222
236
|
- !ruby/object:Gem::Version
|
223
|
-
version: '2.
|
237
|
+
version: '2.7'
|
224
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
239
|
requirements:
|
226
240
|
- - ">="
|