visualize_packwerk 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e1857563c4bf2c40025fbf771b4e5d0ee3d3b1a7623015097274ae1198a6ab6
4
- data.tar.gz: b917ec146a3e97aec95effe57ae0ab5905ec5456549a6bbd2d65dd5ed6a6fd2d
3
+ metadata.gz: dbd24c4c7be488fb37b173c00512196884dafe06e1788bbfb9fd3161988f395b
4
+ data.tar.gz: 0c4da79eef14eba7759074636a556d03f2e74a1b964b485bba0d7e090c83471b
5
5
  SHA512:
6
- metadata.gz: d4f389a11294cbd70ba330e6f7888e03f1dd1666aa80f15214d40914f3fdfe6d711103fc02b364ee5caf4c2344c7bdc343e3be32693bf99801decf94b031860e
7
- data.tar.gz: 2a500bb635dc10ac6785d648be7cc1e8dd8396d2dfd48a45059ee1ba924a8fe26d1b782bebeea1c43f94721eca08ef0ada4c41f1918d484f3eaa3380c6d11d1c
6
+ metadata.gz: 38855ce47c28b248a67de636f9e530e850425b5b7823ccc3bd1f13bde14c6bacd5aa32b68b68f54244325b6c75f8050586b36e98d5c5f0f2e90265728594f854
7
+ data.tar.gz: 68c24d06b1f0c9ae4d109806d0459b38a58e6d6827a07bc745fe6dafaddf17a15c359f80a9b21e495c386eac8ceeba5e8e66d40162d3ee572544c01b5fc35e10
@@ -27,7 +27,7 @@ module VisualizePackwerk
27
27
  # We would also need to ignore it when parsing PackageNodes.
28
28
  # next if p.name == ParsePackwerk::ROOT_PACKAGE_NAME
29
29
  owner = CodeOwnership.for_package(p)
30
- violations_by_package = PackageProtections::ProtectedPackage.from(p).violations.group_by(&:to_package_name).transform_values(&:count)
30
+ violations_by_package = p.violations.group_by(&:to_package_name).transform_values(&:count)
31
31
 
32
32
  package_nodes << PackageNode.new(
33
33
  name: p.name,
@@ -6,25 +6,6 @@ module VisualizePackwerk
6
6
 
7
7
  OUTPUT_FILENAME = T.let('packwerk.png'.freeze, String)
8
8
 
9
- sig { void }
10
- def initialize
11
- @colors_by_team = T.let({}, T::Hash[String, String])
12
- @remaining_colors = T.let(
13
- [
14
- # Found using https://htmlcolorcodes.com/color-picker/
15
- '#77EE77', # green
16
- '#DFEE77', # yellow
17
- '#77EEE6', # teal
18
- '#EEC077', # orange
19
- '#EE77BF', # pink
20
- '#EE6F6F', # red
21
- '#ED6EDE', # magenta
22
- '#8E8CFE', # blue
23
- '#EEA877', # red-orange
24
- ], T::Array[String]
25
- )
26
- end
27
-
28
9
  sig { params(teams: T::Array[CodeTeams::Team]).void }
29
10
  def create_package_graph_for_teams!(teams)
30
11
  packages = ParsePackwerk.all.select do |package|
@@ -38,27 +19,27 @@ module VisualizePackwerk
38
19
  def create_team_graph!(teams, show_all_teams: false)
39
20
  package_graph = PackageGraph.construct
40
21
  team_graph = TeamGraph.from_package_graph(package_graph)
41
- highlighted_node_names = teams.map(&:name)
22
+ node_names = teams.map(&:name)
42
23
 
43
- draw_graph!(team_graph, highlighted_node_names, show_all_nodes: show_all_teams)
24
+ draw_graph!(team_graph, node_names, show_all_nodes: show_all_teams)
44
25
  end
45
26
 
46
- sig { params(packages: T::Array[ParsePackwerk::Package], show_all_packs: T::Boolean).void }
47
- def create_package_graph!(packages, show_all_packs: false)
27
+ sig { params(packages: T::Array[ParsePackwerk::Package]).void }
28
+ def create_package_graph!(packages)
48
29
  graph = PackageGraph.construct
49
- highlighted_node_names = packages.map(&:name)
50
- draw_graph!(graph, highlighted_node_names, show_all_nodes: show_all_packs)
30
+ node_names = packages.map(&:name)
31
+ draw_graph!(graph, node_names)
51
32
  end
52
33
 
53
34
  sig { params(packages: T::Array[ParsePackwerk::Package], show_all_nodes: T::Boolean).void }
54
35
  def create_graph!(packages, show_all_nodes: false)
55
36
  graph = PackageGraph.construct
56
- highlighted_node_names = packages.map(&:name)
57
- draw_graph!(graph, highlighted_node_names, show_all_nodes: show_all_nodes)
37
+ node_names = packages.map(&:name)
38
+ draw_graph!(graph, node_names, show_all_nodes: show_all_nodes)
58
39
  end
59
40
 
60
- sig { params(graph: GraphInterface, highlighted_node_names: T::Array[String], show_all_nodes: T::Boolean).void }
61
- def draw_graph!(graph, highlighted_node_names, show_all_nodes: false)
41
+ sig { params(graph: GraphInterface, node_names: T::Array[String], show_all_nodes: T::Boolean).void }
42
+ def draw_graph!(graph, node_names, show_all_nodes: false)
62
43
  # SFDP looks better than dot in some cases, but less good in other cases.
63
44
  # If your visualization looks bad, change the layout to other_layout!
64
45
  # https://graphviz.org/docs/layouts/
@@ -69,13 +50,10 @@ module VisualizePackwerk
69
50
  # Create graph nodes
70
51
  graphviz_nodes = T.let({}, T::Hash[String, GraphViz::Node])
71
52
 
72
- nodes_to_draw = graph.nodes
53
+ nodes_to_draw = graph.nodes.select{|n| node_names.include?(n.name) }
73
54
 
74
55
  nodes_to_draw.each do |node|
75
- next unless highlighted_node_names.any? { |highlighted_node_name| node.depends_on?(highlighted_node_name) } || highlighted_node_names.include?(node.name)
76
-
77
- highlight_node = highlighted_node_names.include?(node.name) && !show_all_nodes
78
- graphviz_nodes[node.name] = add_node(node, graphviz_graph, highlight_node)
56
+ graphviz_nodes[node.name] = add_node(node, graphviz_graph)
79
57
  end
80
58
 
81
59
  max_edge_width = 10
@@ -83,7 +61,7 @@ module VisualizePackwerk
83
61
  # Draw all edges
84
62
  nodes_to_draw.each do |node|
85
63
  node.dependencies.each do |to_node|
86
- next unless highlighted_node_names.include?(to_node)
64
+ next unless node_names.include?(to_node)
87
65
 
88
66
  graphviz_graph.add_edges(
89
67
  graphviz_nodes[node.name],
@@ -93,7 +71,7 @@ module VisualizePackwerk
93
71
  end
94
72
 
95
73
  node.violations_by_node_name.each do |to_node_name, violation_count|
96
- next unless highlighted_node_names.include?(to_node_name)
74
+ next unless node_names.include?(to_node_name)
97
75
 
98
76
  edge_width = [
99
77
  [(violation_count / 5).to_i, 1].max, # rubocop:disable Lint/NumberConversion
@@ -114,44 +92,20 @@ module VisualizePackwerk
114
92
  puts 'Finished!'
115
93
  end
116
94
 
117
- sig { params(node: NodeInterface, graph: GraphViz, highlight_node: T::Boolean).returns(GraphViz::Node) }
118
- def add_node(node, graph, highlight_node)
119
- default_node_options = {
95
+ sig { params(node: NodeInterface, graph: GraphViz).returns(GraphViz::Node) }
96
+ def add_node(node, graph)
97
+ node_options = {
120
98
  fontsize: 26.0,
121
- fontcolor: 'white',
122
- fillcolor: 'black',
99
+ fontcolor: 'black',
100
+ fillcolor: 'white',
123
101
  color: 'black',
124
102
  height: 1.0,
125
103
  style: 'filled, rounded',
126
104
  shape: 'box',
127
105
  }
128
106
 
129
- node_options = if highlight_node
130
- default_node_options.merge(
131
- fillcolor: highlight_by_group(node),
132
- color: highlight_by_group(node),
133
- fontcolor: 'black'
134
- )
135
- else
136
- default_node_options
137
- end
138
-
139
107
  graph.add_nodes(node.name, **node_options)
140
108
  end
141
-
142
- sig { params(node: NodeInterface).returns(String) }
143
- def highlight_by_group(node)
144
- highlighted_package_color = @colors_by_team[node.group_name]
145
- if !highlighted_package_color
146
- highlighted_package_color = @remaining_colors.first
147
- raise 'Can only color nodes a max of 5 unique colors for now' if highlighted_package_color.nil?
148
-
149
- @remaining_colors.delete(highlighted_package_color)
150
- @colors_by_team[node.group_name] = highlighted_package_color
151
- end
152
-
153
- highlighted_package_color
154
- end
155
109
  end
156
110
 
157
111
  private_constant :PackageRelationships
@@ -27,7 +27,7 @@ module VisualizePackwerk
27
27
  end
28
28
  end
29
29
 
30
- PackageRelationships.new.create_package_graph!(packages, show_all_packs: show_all_packs)
30
+ PackageRelationships.new.create_package_graph!(packages)
31
31
  end
32
32
 
33
33
  # This creates the array of symbols that are needed to declare an argument to a rake task
@@ -4,7 +4,6 @@ module VisualizePackwerk
4
4
  require 'visualize_packwerk/railtie' if defined?(Rails)
5
5
  require 'parse_packwerk'
6
6
  require 'code_ownership'
7
- require 'package_protections'
8
7
  require 'graphviz'
9
8
 
10
9
  require 'visualize_packwerk/node_interface'
data/sorbet/config CHANGED
@@ -1,2 +1,3 @@
1
1
  --dir
2
2
  .
3
+ --ignore=/vendor/bundle
@@ -4,20 +4,30 @@
4
4
  # This is an autogenerated file for types exported from the `parse_packwerk` gem.
5
5
  # Please instead update this file by running `bin/tapioca gem parse_packwerk`.
6
6
 
7
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:3
7
8
  module ParsePackwerk
8
9
  class << self
10
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:28
9
11
  sig { returns(T::Array[::ParsePackwerk::Package]) }
10
12
  def all; end
11
13
 
14
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:112
15
+ sig { void }
16
+ def bust_cache!; end
17
+
18
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:33
12
19
  sig { params(name: ::String).returns(T.nilable(::ParsePackwerk::Package)) }
13
20
  def find(name); end
14
21
 
15
- sig { params(file_path: T.any(::Pathname, ::String)).returns(T.nilable(::ParsePackwerk::Package)) }
22
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:43
23
+ sig { params(file_path: T.any(::Pathname, ::String)).returns(::ParsePackwerk::Package) }
16
24
  def package_from_path(file_path); end
17
25
 
26
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:54
18
27
  sig { params(package: ::ParsePackwerk::Package).void }
19
28
  def write_package_yml!(package); end
20
29
 
30
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:38
21
31
  sig { returns(::ParsePackwerk::Configuration) }
22
32
  def yml; end
23
33
 
@@ -25,94 +35,148 @@ module ParsePackwerk
25
35
 
26
36
  # We memoize packages_by_name for fast lookup.
27
37
  # Since Graph is an immutable value object, we can create indexes and general caching mechanisms safely.
38
+ #
39
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:100
28
40
  sig { returns(T::Hash[::String, ::ParsePackwerk::Package]) }
29
41
  def packages_by_name; end
30
42
  end
31
43
  end
32
44
 
45
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/configuration.rb:4
33
46
  class ParsePackwerk::Configuration < ::T::Struct
34
47
  const :exclude, T::Array[::String]
35
48
  const :package_paths, T::Array[::String]
36
49
 
37
50
  class << self
51
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/configuration.rb:28
38
52
  sig { params(config_hash: T::Hash[T.untyped, T.untyped]).returns(T::Array[::String]) }
39
53
  def excludes(config_hash); end
40
54
 
55
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/configuration.rb:11
41
56
  sig { returns(::ParsePackwerk::Configuration) }
42
57
  def fetch; end
43
58
 
59
+ # source://sorbet-runtime-0.5.10323/lib/types/struct.rb:13
44
60
  def inherited(s); end
45
61
 
62
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/configuration.rb:40
46
63
  sig { params(config_hash: T::Hash[T.untyped, T.untyped]).returns(T::Array[::String]) }
47
64
  def package_paths(config_hash); end
48
65
  end
49
66
  end
50
67
 
68
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:20
51
69
  ParsePackwerk::DEFAULT_EXCLUDE_GLOBS = T.let(T.unsafe(nil), Array)
70
+
71
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:21
52
72
  ParsePackwerk::DEFAULT_PACKAGE_PATHS = T.let(T.unsafe(nil), Array)
73
+
74
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:22
75
+ ParsePackwerk::DEFAULT_PUBLIC_PATH = T.let(T.unsafe(nil), String)
76
+
77
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:12
53
78
  ParsePackwerk::DEPENDENCIES = T.let(T.unsafe(nil), String)
79
+
80
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:7
54
81
  ParsePackwerk::DEPRECATED_REFERENCES_YML_NAME = T.let(T.unsafe(nil), String)
55
82
 
83
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/deprecated_references.rb:4
56
84
  class ParsePackwerk::DeprecatedReferences < ::T::Struct
57
85
  const :pathname, ::Pathname
58
86
  const :violations, T::Array[::ParsePackwerk::Violation]
59
87
 
60
88
  class << self
89
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/deprecated_references.rb:11
61
90
  sig { params(package: ::ParsePackwerk::Package).returns(::ParsePackwerk::DeprecatedReferences) }
62
91
  def for(package); end
63
92
 
93
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/deprecated_references.rb:17
64
94
  sig { params(pathname: ::Pathname).returns(::ParsePackwerk::DeprecatedReferences) }
65
95
  def from(pathname); end
66
96
 
97
+ # source://sorbet-runtime-0.5.10323/lib/types/struct.rb:13
67
98
  def inherited(s); end
68
99
  end
69
100
  end
70
101
 
102
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:8
71
103
  ParsePackwerk::ENFORCE_DEPENDENCIES = T.let(T.unsafe(nil), String)
104
+
105
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:9
72
106
  ParsePackwerk::ENFORCE_PRIVACY = T.let(T.unsafe(nil), String)
107
+
108
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:11
73
109
  ParsePackwerk::METADATA = T.let(T.unsafe(nil), String)
74
110
 
75
111
  # Since this metadata is unstructured YAML, it could be any type. We leave it to clients of `ParsePackwerk::Package`
76
112
  # to add types based on their known usage of metadata.
113
+ #
114
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:16
77
115
  ParsePackwerk::MetadataYmlType = T.type_alias { T::Hash[T.untyped, T.untyped] }
78
116
 
117
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:14
79
118
  class ParsePackwerk::MissingConfiguration < ::StandardError
119
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk.rb:18
80
120
  sig { params(packwerk_file_name: ::Pathname).void }
81
121
  def initialize(packwerk_file_name); end
82
122
  end
83
123
 
124
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:5
84
125
  ParsePackwerk::PACKAGE_YML_NAME = T.let(T.unsafe(nil), String)
126
+
127
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:6
85
128
  ParsePackwerk::PACKWERK_YML_NAME = T.let(T.unsafe(nil), String)
86
129
 
130
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:10
131
+ ParsePackwerk::PUBLIC_PATH = T.let(T.unsafe(nil), String)
132
+
133
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:4
87
134
  class ParsePackwerk::Package < ::T::Struct
88
135
  const :dependencies, T::Array[::String]
89
136
  const :enforce_dependencies, T::Boolean
90
137
  const :enforce_privacy, T::Boolean
91
138
  const :metadata, T::Hash[T.untyped, T.untyped]
92
139
  const :name, ::String
140
+ const :public_path, ::String, default: T.unsafe(nil)
93
141
 
142
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:35
94
143
  sig { returns(::Pathname) }
95
144
  def directory; end
96
145
 
146
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:45
97
147
  sig { returns(T::Boolean) }
98
148
  def enforces_dependencies?; end
99
149
 
150
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:50
100
151
  sig { returns(T::Boolean) }
101
152
  def enforces_privacy?; end
102
153
 
154
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:40
155
+ sig { returns(::Pathname) }
156
+ def public_directory; end
157
+
158
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:55
159
+ sig { returns(T::Array[::ParsePackwerk::Violation]) }
160
+ def violations; end
161
+
162
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:30
103
163
  sig { returns(::Pathname) }
104
164
  def yml; end
105
165
 
106
166
  class << self
167
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package.rb:15
107
168
  sig { params(pathname: ::Pathname).returns(::ParsePackwerk::Package) }
108
169
  def from(pathname); end
109
170
 
171
+ # source://sorbet-runtime-0.5.10323/lib/types/struct.rb:13
110
172
  def inherited(s); end
111
173
  end
112
174
  end
113
175
 
176
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package_set.rb:8
114
177
  class ParsePackwerk::PackageSet
115
178
  class << self
179
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package_set.rb:12
116
180
  sig do
117
181
  params(
118
182
  package_pathspec: T::Array[::String],
@@ -123,26 +187,32 @@ class ParsePackwerk::PackageSet
123
187
 
124
188
  private
125
189
 
190
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/package_set.rb:28
126
191
  sig { params(globs: T::Array[::String], path: ::Pathname).returns(T::Boolean) }
127
192
  def exclude_path?(globs, path); end
128
193
  end
129
194
  end
130
195
 
196
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/constants.rb:4
131
197
  ParsePackwerk::ROOT_PACKAGE_NAME = T.let(T.unsafe(nil), String)
132
198
 
199
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/violation.rb:4
133
200
  class ParsePackwerk::Violation < ::T::Struct
134
201
  const :class_name, ::String
135
202
  const :files, T::Array[::String]
136
203
  const :to_package_name, ::String
137
204
  const :type, ::String
138
205
 
206
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/violation.rb:13
139
207
  sig { returns(T::Boolean) }
140
208
  def dependency?; end
141
209
 
210
+ # source://parse_packwerk-0.14.0/lib/parse_packwerk/violation.rb:18
142
211
  sig { returns(T::Boolean) }
143
212
  def privacy?; end
144
213
 
145
214
  class << self
215
+ # source://sorbet-runtime-0.5.10323/lib/types/struct.rb:13
146
216
  def inherited(s); end
147
217
  end
148
218
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visualize_packwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
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-08-12 00:00:00.000000000 Z
11
+ date: 2022-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: package_protections
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: code_ownership
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -180,9 +166,8 @@ files:
180
166
  - sorbet/rbi/gems/json@2.6.2.rbi
181
167
  - sorbet/rbi/gems/method_source@1.0.0.rbi
182
168
  - sorbet/rbi/gems/minitest@5.16.2.rbi
183
- - sorbet/rbi/gems/package_protections@1.3.0.rbi
184
169
  - sorbet/rbi/gems/parallel@1.22.1.rbi
185
- - sorbet/rbi/gems/parse_packwerk@0.11.0.rbi
170
+ - sorbet/rbi/gems/parse_packwerk@0.14.0.rbi
186
171
  - sorbet/rbi/gems/parser@3.1.2.0.rbi
187
172
  - sorbet/rbi/gems/pry@0.14.1.rbi
188
173
  - sorbet/rbi/gems/rainbow@3.1.1.rbi
@@ -234,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
219
  - !ruby/object:Gem::Version
235
220
  version: '0'
236
221
  requirements: []
237
- rubygems_version: 3.3.7
222
+ rubygems_version: 3.1.6
238
223
  signing_key:
239
224
  specification_version: 4
240
225
  summary: A gem to visualize connections in a Rails app that uses Packwerk
@@ -1,654 +0,0 @@
1
- # typed: true
2
-
3
- # DO NOT EDIT MANUALLY
4
- # This is an autogenerated file for types exported from the `package_protections` gem.
5
- # Please instead update this file by running `bin/tapioca gem package_protections`.
6
-
7
- # Welcome to PackageProtections!
8
- # See https://github.com/rubyatscale/package_protections#readme for more info
9
- #
10
- # This file is a reference for the available API to `package_protections`, but all implementation details are private
11
- # (which is why we delegate to `Private` for the actual implementation).
12
- module PackageProtections
13
- class << self
14
- sig { returns(T::Array[::PackageProtections::ProtectionInterface]) }
15
- def all; end
16
-
17
- sig { void }
18
- def bust_cache!; end
19
-
20
- # @yield [Private.config]
21
- sig { params(blk: T.proc.params(arg0: ::PackageProtections::Private::Configuration).void).void }
22
- def configure(&blk); end
23
-
24
- # This returns an array of a `Offense` which is how we represent the outcome of attempting to protect one or more packages,
25
- # each of which is configured with different violation behaviors for each protection.
26
- sig do
27
- params(
28
- packages: T::Array[::ParsePackwerk::Package],
29
- new_violations: T::Array[::PackageProtections::PerFileViolation]
30
- ).returns(T::Array[::PackageProtections::Offense])
31
- end
32
- def get_offenses(packages:, new_violations:); end
33
-
34
- sig do
35
- params(
36
- package_names: T::Array[::String],
37
- all_packages: T::Array[::ParsePackwerk::Package]
38
- ).returns(T::Array[::ParsePackwerk::Package])
39
- end
40
- def packages_for_names(package_names, all_packages); end
41
-
42
- # Do not use this method -- it's meant to be used by Rubocop cops to get directory-specific
43
- # parameters without needing to have directory-specific .rubocop.yml files.
44
- sig { params(identifier: ::String).returns(T::Hash[T.untyped, T.untyped]) }
45
- def private_cop_config(identifier); end
46
-
47
- # Why do we use Bundler.root here?
48
- # The reason is that this function is evaluated in `.client_rubocop.yml`, so when rubocop evaluates the
49
- # YML and parses the ERB, the working directory is inside this gem. We need to make sure it's at the root of the
50
- # application so that we can find all of the packwerk packages.
51
- # We use Bundler.root to get the root because:
52
- # A) We expect it to be reliable
53
- # B) We expect the client to be running bundle exec rubocop, which is typically done at the root, and also means
54
- # the client already has this dependency.
55
- sig { params(root_pathname: ::Pathname).returns(::String) }
56
- def rubocop_yml(root_pathname: T.unsafe(nil)); end
57
-
58
- # PackageProtections.set_defaults! sets any unset protections to their default enforcement
59
- sig do
60
- params(
61
- packages: T::Array[::ParsePackwerk::Package],
62
- protection_identifiers: T::Array[::String],
63
- verbose: T::Boolean
64
- ).void
65
- end
66
- def set_defaults!(packages, protection_identifiers: T.unsafe(nil), verbose: T.unsafe(nil)); end
67
-
68
- # This is a fast way to get a protection given an identifier
69
- sig { params(identifier: ::String).returns(::PackageProtections::ProtectionInterface) }
70
- def with_identifier(identifier); end
71
- end
72
- end
73
-
74
- PackageProtections::EXPECTED_PACK_DIRECTORIES = T.let(T.unsafe(nil), Array)
75
-
76
- # A protection identifier is just a string that identifies the name of the protection within a `package.yml`
77
- PackageProtections::Identifier = T.type_alias { ::String }
78
-
79
- # This is currently the only handled exception that `PackageProtections` will throw.
80
- class PackageProtections::IncorrectPublicApiUsageError < ::StandardError; end
81
-
82
- class PackageProtections::Offense < ::T::Struct
83
- const :file, ::String
84
- const :message, ::String
85
- const :package, ::ParsePackwerk::Package
86
- const :violation_type, ::String
87
-
88
- sig { returns(::String) }
89
- def package_name; end
90
-
91
- class << self
92
- def inherited(s); end
93
- end
94
- end
95
-
96
- PackageProtections::PROTECTIONS_TODO_YML = T.let(T.unsafe(nil), String)
97
-
98
- # Perhaps this should be in ParsePackwerk. For now, this is here to help us break down violations per file.
99
- # This is analogous to `Packwerk::ReferenceOffense`
100
- class PackageProtections::PerFileViolation < ::T::Struct
101
- const :class_name, ::String
102
- const :constant_source_package, ::String
103
- const :filepath, ::String
104
- const :reference_source_package, ::ParsePackwerk::Package
105
- const :type, ::String
106
-
107
- sig { returns(T::Boolean) }
108
- def dependency?; end
109
-
110
- sig { returns(T::Boolean) }
111
- def privacy?; end
112
-
113
- class << self
114
- sig do
115
- params(
116
- violation: ::ParsePackwerk::Violation,
117
- reference_source_package: ::ParsePackwerk::Package
118
- ).returns(T::Array[::PackageProtections::PerFileViolation])
119
- end
120
- def from(violation, reference_source_package); end
121
-
122
- def inherited(s); end
123
- end
124
- end
125
-
126
- # This module cannot be accessed by clients of `PackageProtections` -- only within the `PackageProtections` module itself.
127
- # All implementation details are in here to keep the main `PackageProtections` module easily scannable and to keep the private things private.
128
- module PackageProtections::Private
129
- class << self
130
- sig { returns(T::Array[::PackageProtections::ProtectedPackage]) }
131
- def all_protected_packages; end
132
-
133
- sig { void }
134
- def bust_cache!; end
135
-
136
- sig { returns(::PackageProtections::Private::Configuration) }
137
- def config; end
138
-
139
- sig do
140
- params(
141
- packages: T::Array[::ParsePackwerk::Package],
142
- new_violations: T::Array[::PackageProtections::PerFileViolation]
143
- ).returns(T::Array[::PackageProtections::Offense])
144
- end
145
- def get_offenses(packages:, new_violations:); end
146
-
147
- sig { params(name: ::String).returns(::PackageProtections::ProtectedPackage) }
148
- def get_package_with_name(name); end
149
-
150
- sig do
151
- params(
152
- package_names: T::Array[::String],
153
- all_packages: T::Array[::ParsePackwerk::Package]
154
- ).returns(T::Array[::ParsePackwerk::Package])
155
- end
156
- def packages_for_names(package_names, all_packages); end
157
-
158
- sig { params(identifier: ::String).returns(T::Hash[T.untyped, T.untyped]) }
159
- def private_cop_config(identifier); end
160
-
161
- sig { params(root_pathname: ::Pathname).returns(::String) }
162
- def rubocop_yml(root_pathname:); end
163
-
164
- sig do
165
- params(
166
- packages: T::Array[::ParsePackwerk::Package],
167
- protection_identifiers: T::Array[::String],
168
- verbose: T::Boolean
169
- ).void
170
- end
171
- def set_defaults!(packages, protection_identifiers:, verbose:); end
172
- end
173
- end
174
-
175
- class PackageProtections::Private::ColorizedString
176
- sig { params(original_string: ::String, color: ::PackageProtections::Private::ColorizedString::Color).void }
177
- def initialize(original_string, color = T.unsafe(nil)); end
178
-
179
- sig { returns(::PackageProtections::Private::ColorizedString) }
180
- def blue; end
181
-
182
- sig { returns(::String) }
183
- def colorized_to_s; end
184
-
185
- sig { returns(::PackageProtections::Private::ColorizedString) }
186
- def green; end
187
-
188
- sig { returns(::PackageProtections::Private::ColorizedString) }
189
- def light_blue; end
190
-
191
- sig { returns(::PackageProtections::Private::ColorizedString) }
192
- def pink; end
193
-
194
- sig { returns(::PackageProtections::Private::ColorizedString) }
195
- def red; end
196
-
197
- sig { returns(::String) }
198
- def to_s; end
199
-
200
- sig { returns(::PackageProtections::Private::ColorizedString) }
201
- def white; end
202
-
203
- sig { returns(::PackageProtections::Private::ColorizedString) }
204
- def yellow; end
205
-
206
- private
207
-
208
- sig { returns(::Integer) }
209
- def color_code; end
210
-
211
- sig do
212
- params(
213
- color: ::PackageProtections::Private::ColorizedString::Color
214
- ).returns(::PackageProtections::Private::ColorizedString)
215
- end
216
- def colorize(color); end
217
- end
218
-
219
- class PackageProtections::Private::ColorizedString::Color < ::T::Enum
220
- enums do
221
- Black = new
222
- Red = new
223
- Green = new
224
- Yellow = new
225
- Blue = new
226
- Pink = new
227
- LightBlue = new
228
- White = new
229
- end
230
- end
231
-
232
- class PackageProtections::Private::Configuration
233
- sig { void }
234
- def initialize; end
235
-
236
- sig { void }
237
- def bust_cache!; end
238
-
239
- sig { returns(T::Array[::PackageProtections::ProtectionInterface]) }
240
- def default_protections; end
241
-
242
- sig { returns(T::Array[::PackageProtections::ProtectionInterface]) }
243
- def protections; end
244
-
245
- sig { params(protections: T::Array[::PackageProtections::ProtectionInterface]).void }
246
- def protections=(protections); end
247
- end
248
-
249
- class PackageProtections::Private::IncomingPrivacyProtection
250
- include ::PackageProtections::ProtectionInterface
251
-
252
- sig do
253
- override
254
- .params(
255
- protected_packages: T::Array[::PackageProtections::ProtectedPackage]
256
- ).returns(T::Array[::PackageProtections::Offense])
257
- end
258
- def get_offenses_for_existing_violations(protected_packages); end
259
-
260
- sig do
261
- override
262
- .params(
263
- new_violations: T::Array[::PackageProtections::PerFileViolation]
264
- ).returns(T::Array[::PackageProtections::Offense])
265
- end
266
- def get_offenses_for_new_violations(new_violations); end
267
-
268
- sig { override.returns(::String) }
269
- def humanized_protection_description; end
270
-
271
- sig { override.returns(::String) }
272
- def humanized_protection_name; end
273
-
274
- sig { override.returns(::String) }
275
- def identifier; end
276
-
277
- sig do
278
- override
279
- .params(
280
- behavior: ::PackageProtections::ViolationBehavior,
281
- package: ::ParsePackwerk::Package
282
- ).returns(T.nilable(::String))
283
- end
284
- def unmet_preconditions_for_behavior(behavior, package); end
285
-
286
- private
287
-
288
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
289
- def message_for_fail_on_any(per_file_violation); end
290
-
291
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
292
- def message_for_fail_on_new(per_file_violation); end
293
- end
294
-
295
- PackageProtections::Private::IncomingPrivacyProtection::IDENTIFIER = T.let(T.unsafe(nil), String)
296
-
297
- class PackageProtections::Private::MetadataModifiers
298
- class << self
299
- sig do
300
- params(
301
- package: ::ParsePackwerk::Package,
302
- protection_identifier: ::String,
303
- violation_behavior: ::PackageProtections::ViolationBehavior
304
- ).returns(::ParsePackwerk::Package)
305
- end
306
- def package_with_modified_protection(package, protection_identifier, violation_behavior); end
307
- end
308
- end
309
-
310
- class PackageProtections::Private::OutgoingDependencyProtection
311
- include ::PackageProtections::ProtectionInterface
312
-
313
- sig do
314
- override
315
- .params(
316
- protected_packages: T::Array[::PackageProtections::ProtectedPackage]
317
- ).returns(T::Array[::PackageProtections::Offense])
318
- end
319
- def get_offenses_for_existing_violations(protected_packages); end
320
-
321
- sig do
322
- override
323
- .params(
324
- new_violations: T::Array[::PackageProtections::PerFileViolation]
325
- ).returns(T::Array[::PackageProtections::Offense])
326
- end
327
- def get_offenses_for_new_violations(new_violations); end
328
-
329
- sig { override.returns(::String) }
330
- def humanized_protection_description; end
331
-
332
- sig { override.returns(::String) }
333
- def humanized_protection_name; end
334
-
335
- sig { override.returns(::String) }
336
- def identifier; end
337
-
338
- sig do
339
- override
340
- .params(
341
- behavior: ::PackageProtections::ViolationBehavior,
342
- package: ::ParsePackwerk::Package
343
- ).returns(T.nilable(::String))
344
- end
345
- def unmet_preconditions_for_behavior(behavior, package); end
346
-
347
- private
348
-
349
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
350
- def message_for_fail_on_any(per_file_violation); end
351
-
352
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
353
- def message_for_fail_on_new(per_file_violation); end
354
- end
355
-
356
- PackageProtections::Private::OutgoingDependencyProtection::IDENTIFIER = T.let(T.unsafe(nil), String)
357
-
358
- class PackageProtections::Private::Output
359
- class << self
360
- sig { params(str: ::String).void }
361
- def p(str); end
362
-
363
- sig { params(str: ::PackageProtections::Private::ColorizedString, colorized: T::Boolean).void }
364
- def p_colorized(str, colorized:); end
365
- end
366
- end
367
-
368
- class PackageProtections::Private::VisibilityProtection
369
- include ::PackageProtections::ProtectionInterface
370
-
371
- # By default, this protection does not show up when creating a new package, and its default behavior is FailNever
372
- # A package that uses this protection is not considered strictly better -- in general, we want to design packages that
373
- # are consumable by all packages. Therefore, a package that is consumable by all packages is the happy path.
374
- #
375
- # If a user wants to turn on package visibility, they must do it explicitly.
376
- sig { returns(::PackageProtections::ViolationBehavior) }
377
- def default_behavior; end
378
-
379
- sig do
380
- override
381
- .params(
382
- protected_packages: T::Array[::PackageProtections::ProtectedPackage]
383
- ).returns(T::Array[::PackageProtections::Offense])
384
- end
385
- def get_offenses_for_existing_violations(protected_packages); end
386
-
387
- sig do
388
- override
389
- .params(
390
- new_violations: T::Array[::PackageProtections::PerFileViolation]
391
- ).returns(T::Array[::PackageProtections::Offense])
392
- end
393
- def get_offenses_for_new_violations(new_violations); end
394
-
395
- sig { override.returns(::String) }
396
- def humanized_protection_description; end
397
-
398
- sig { override.returns(::String) }
399
- def humanized_protection_name; end
400
-
401
- sig { override.returns(::String) }
402
- def identifier; end
403
-
404
- sig do
405
- override
406
- .params(
407
- behavior: ::PackageProtections::ViolationBehavior,
408
- package: ::ParsePackwerk::Package
409
- ).returns(T.nilable(::String))
410
- end
411
- def unmet_preconditions_for_behavior(behavior, package); end
412
-
413
- private
414
-
415
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
416
- def message_for_fail_on_any(per_file_violation); end
417
-
418
- sig { params(per_file_violation: ::PackageProtections::PerFileViolation).returns(::String) }
419
- def message_for_fail_on_new(per_file_violation); end
420
- end
421
-
422
- PackageProtections::Private::VisibilityProtection::IDENTIFIER = T.let(T.unsafe(nil), String)
423
-
424
- class PackageProtections::ProtectedPackage < ::T::Struct
425
- const :deprecated_references, ::ParsePackwerk::DeprecatedReferences
426
- const :original_package, ::ParsePackwerk::Package
427
- const :protections, T::Hash[::String, ::PackageProtections::ViolationBehavior]
428
-
429
- sig { returns(T::Array[::String]) }
430
- def dependencies; end
431
-
432
- sig { returns(T::Hash[T.untyped, T.untyped]) }
433
- def metadata; end
434
-
435
- sig { returns(::String) }
436
- def name; end
437
-
438
- sig { params(key: ::String).returns(::PackageProtections::ViolationBehavior) }
439
- def violation_behavior_for(key); end
440
-
441
- sig { returns(T::Array[::ParsePackwerk::Violation]) }
442
- def violations; end
443
-
444
- sig { returns(T::Set[::String]) }
445
- def visible_to; end
446
-
447
- sig { returns(::Pathname) }
448
- def yml; end
449
-
450
- class << self
451
- sig { params(original_package: ::ParsePackwerk::Package).returns(::PackageProtections::ProtectedPackage) }
452
- def from(original_package); end
453
-
454
- sig do
455
- params(
456
- protection: ::PackageProtections::ProtectionInterface,
457
- metadata: T::Hash[T.untyped, T.untyped],
458
- package: ::ParsePackwerk::Package
459
- ).returns(::PackageProtections::ViolationBehavior)
460
- end
461
- def get_violation_behavior(protection, metadata, package); end
462
-
463
- def inherited(s); end
464
- end
465
- end
466
-
467
- # @abstract Subclasses must implement the `abstract` methods below.
468
- module PackageProtections::ProtectionInterface
469
- requires_ancestor { Kernel }
470
-
471
- abstract!
472
-
473
- sig { returns(::PackageProtections::ViolationBehavior) }
474
- def default_behavior; end
475
-
476
- sig do
477
- params(
478
- protected_packages: T::Array[::PackageProtections::ProtectedPackage],
479
- new_violations: T::Array[::PackageProtections::PerFileViolation]
480
- ).returns(T::Array[::PackageProtections::Offense])
481
- end
482
- def get_offenses(protected_packages, new_violations); end
483
-
484
- # @abstract
485
- sig do
486
- abstract
487
- .params(
488
- protected_packages: T::Array[::PackageProtections::ProtectedPackage]
489
- ).returns(T::Array[::PackageProtections::Offense])
490
- end
491
- def get_offenses_for_existing_violations(protected_packages); end
492
-
493
- # @abstract
494
- sig do
495
- abstract
496
- .params(
497
- new_violations: T::Array[::PackageProtections::PerFileViolation]
498
- ).returns(T::Array[::PackageProtections::Offense])
499
- end
500
- def get_offenses_for_new_violations(new_violations); end
501
-
502
- # @abstract
503
- sig { abstract.returns(::String) }
504
- def humanized_protection_description; end
505
-
506
- # @abstract
507
- sig { abstract.returns(::String) }
508
- def humanized_protection_name; end
509
-
510
- # @abstract
511
- sig { abstract.returns(::String) }
512
- def identifier; end
513
-
514
- sig do
515
- params(
516
- behavior: ::PackageProtections::ViolationBehavior,
517
- package: ::ParsePackwerk::Package
518
- ).returns(T::Boolean)
519
- end
520
- def supports_violation_behavior?(behavior, package); end
521
-
522
- # @abstract
523
- sig do
524
- abstract
525
- .params(
526
- behavior: ::PackageProtections::ViolationBehavior,
527
- package: ::ParsePackwerk::Package
528
- ).returns(T.nilable(::String))
529
- end
530
- def unmet_preconditions_for_behavior(behavior, package); end
531
- end
532
-
533
- # @abstract Subclasses must implement the `abstract` methods below.
534
- module PackageProtections::RubocopProtectionInterface
535
- include ::PackageProtections::ProtectionInterface
536
-
537
- abstract!
538
-
539
- sig do
540
- params(
541
- packages: T::Array[::PackageProtections::ProtectedPackage]
542
- ).returns(T::Array[::PackageProtections::RubocopProtectionInterface::CopConfig])
543
- end
544
- def cop_configs(packages); end
545
-
546
- # Abstract Methods: These are methods that the client needs to implement
547
- #
548
- # @abstract
549
- sig { abstract.returns(::String) }
550
- def cop_name; end
551
-
552
- # Overriddable Methods: These are methods that the client can override,
553
- # but a default is provided.
554
- sig { params(package: ::PackageProtections::ProtectedPackage).returns(T::Hash[T.untyped, T.untyped]) }
555
- def custom_cop_config(package); end
556
-
557
- sig do
558
- override
559
- .params(
560
- protected_packages: T::Array[::PackageProtections::ProtectedPackage]
561
- ).returns(T::Array[::PackageProtections::Offense])
562
- end
563
- def get_offenses_for_existing_violations(protected_packages); end
564
-
565
- sig do
566
- override
567
- .params(
568
- new_violations: T::Array[::PackageProtections::PerFileViolation]
569
- ).returns(T::Array[::PackageProtections::Offense])
570
- end
571
- def get_offenses_for_new_violations(new_violations); end
572
-
573
- # @abstract
574
- sig { abstract.returns(T::Array[::String]) }
575
- def included_globs_for_pack; end
576
-
577
- # @abstract
578
- sig { abstract.params(file: ::String).returns(::String) }
579
- def message_for_fail_on_any(file); end
580
-
581
- sig do
582
- override
583
- .params(
584
- behavior: ::PackageProtections::ViolationBehavior,
585
- package: ::ParsePackwerk::Package
586
- ).returns(T.nilable(::String))
587
- end
588
- def unmet_preconditions_for_behavior(behavior, package); end
589
-
590
- private
591
-
592
- sig { params(rule: ::String).returns(T::Set[::String]) }
593
- def exclude_for_rule(rule); end
594
-
595
- class << self
596
- sig { void }
597
- def bust_rubocop_todo_yml_cache; end
598
-
599
- sig { returns(T.untyped) }
600
- def rubocop_todo_yml; end
601
- end
602
- end
603
-
604
- class PackageProtections::RubocopProtectionInterface::CopConfig < ::T::Struct
605
- const :enabled, T::Boolean, default: T.unsafe(nil)
606
- const :exclude_paths, T::Array[::String], default: T.unsafe(nil)
607
- const :include_paths, T::Array[::String], default: T.unsafe(nil)
608
- const :name, ::String
609
-
610
- sig { returns(::String) }
611
- def to_rubocop_yml_compatible_format; end
612
-
613
- class << self
614
- def inherited(s); end
615
- end
616
- end
617
-
618
- class PackageProtections::ViolationBehavior < ::T::Enum
619
- enums do
620
- FailOnAny = new
621
- FailOnNew = new
622
- FailNever = new
623
- end
624
-
625
- sig { returns(T::Boolean) }
626
- def enabled?; end
627
-
628
- sig { returns(T::Boolean) }
629
- def fail_never?; end
630
-
631
- sig { returns(T::Boolean) }
632
- def fail_on_any?; end
633
-
634
- sig { returns(T::Boolean) }
635
- def fail_on_new?; end
636
-
637
- class << self
638
- sig { params(value: T.untyped).returns(::PackageProtections::ViolationBehavior) }
639
- def from_raw_value(value); end
640
- end
641
- end
642
-
643
- RuboCop::Cop::PackageProtections::NamespacedUnderPackageName::IDENTIFIER = T.let(T.unsafe(nil), String)
644
-
645
- # This inherits from `Sorbet::StrictSigil` and doesn't change any behavior of it.
646
- # The only reason we do this is so that configuration for this cop can live under a different cop namespace.
647
- # This prevents this cop's configuration from clashing with other configurations for the same cop.
648
- # A concrete example of this would be if a user is using this package protection to make sure public APIs are typed,
649
- # and separately the application as a whole requiring strict typing in certain parts of the application.
650
- #
651
- # To prevent problems associated with needing to manage identical configurations for the same cop, we simply call it
652
- # something else in the context of this protection.
653
- #
654
- # We can apply this same pattern if we want to use other cops in the context of package protections and prevent clashing.