packwerk 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e1c2cdab1129d016428019597dc9f19dbf0836d0c545a13ce780486bf9fbba1
4
- data.tar.gz: d9556ef773c776283a30f8e22308f0068e4d1a4ea918e81af44a0e126c0ca62e
3
+ metadata.gz: 94a6e793dd2c071a7bfb9a739fb6aaf2e07b0d2183bf743afb38da5e3847f0e2
4
+ data.tar.gz: dd779094dad5572746476d25d63e26f29819cf0b57519f73a4f693610cfd238e
5
5
  SHA512:
6
- metadata.gz: 74cb6f2c95a7d51dc8e5199a47601b53897c29cfd6dde5d0c0ada40566d19bf0f9d0f0fcf9209dbe5b9e0ccbbcfcac9c1282fa74377af0b8e6cee63e75204948
7
- data.tar.gz: d03e35ab0975d457a9202d2df2f697372f22f5a4072880dc7d308b87581ffd5a30446b8b235b221da0655cd4b31be58552b0a3f658e15a8c48d78cdee23f9794
6
+ metadata.gz: 9ff4d2a2aa7b6cb34e59362321ea3fb22826d10430addeef1b6143408d1a1b510ff8915105f2e74e9173334dfcfbd0a76610ea00242a2720c6feb9c75b53556f
7
+ data.tar.gz: 7ed4cbe3376821d54a5a58e2bc25ac3baf1f03a84928e027c0e1e1f39d52a14df4e18cc8d9ecfa50de3756507f46c0e9687d04464d3ec149037a7fdecb8eed0e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- packwerk (2.2.2)
4
+ packwerk (2.3.0)
5
5
  activesupport (>= 5.2)
6
6
  ast
7
7
  better_html
@@ -3,27 +3,27 @@
3
3
  Violations can be [recorded as a deprecation](#recording-violations) or (better!) [eliminated](#eliminating-violations).
4
4
 
5
5
  ## Recording Violations
6
- 💡 New privacy and dependency violations are never hard-blocked. There are many very valid reasons to run `bin/packwerk update-deprecations`, adding new violations to `deprecated_references.yml` files. Even if you feel your reason might not be "valid," if your judgement says adding the violation and shipping your change will produce positive impact, trust your gut.
6
+ 💡 New privacy and dependency violations are never hard-blocked. There are many very valid reasons to run `bin/packwerk update-todo`, adding new violations to `package_todo.yml` files. Even if you feel your reason might not be "valid," if your judgement says adding the violation and shipping your change will produce positive impact, trust your gut.
7
7
 
8
8
  ### Emergency Fixes
9
9
  ❔ Is it a revert or is there a lot of urgency because you are fixing a production bug impacting customers?
10
10
 
11
- ➡️ Simply run `bin/packwerk update-deprecations`, and address the violation when the customer issue is resolved.
11
+ ➡️ Simply run `bin/packwerk update-todo`, and address the violation when the customer issue is resolved.
12
12
 
13
13
  ### Improving System Design
14
14
  ❔ Are you improving system boundaries by renaming or moving a file, class, constant,` or module?
15
15
 
16
- ➡️ Simply run `bin/packwerk update-deprecations`. We've improved how our system is organized, so the new violations are natural.
16
+ ➡️ Simply run `bin/packwerk update-todo`. We've improved how our system is organized, so the new violations are natural.
17
17
 
18
18
  ### Making Things Explicit
19
19
  ❔ Are you making something that was implicit (hidden to Packwerk) explicit, such as adding a Sorbet signature, using a class instead of a method call, or something similar?
20
20
 
21
- ➡️ Simply run `bin/packwerk update-deprecations`. Making something implicit explicit and capturing that as a new violation is a strict improvement.
21
+ ➡️ Simply run `bin/packwerk update-todo`. Making something implicit explicit and capturing that as a new violation is a strict improvement.
22
22
 
23
23
  ### Temporary State
24
24
  ❔ Is the violation temporary because you will soon delete the code or is it part of a refactor to improve system boundaries and reduce violations overall?
25
25
 
26
- ➡️ Simply run `bin/packwerk update-deprecations`. Sometimes things get "worse" before they get better.
26
+ ➡️ Simply run `bin/packwerk update-todo`. Sometimes things get "worse" before they get better.
27
27
 
28
28
  ### Delivering Features
29
29
  ❔ Are you in a rush to get a feature out and product, your manager, or an internal sense of urgency has made you feel like you can't resolve system design issues?
@@ -57,7 +57,7 @@ An explicit and implementation-hiding public API is a cornerstone of well-modula
57
57
 
58
58
  ➡️ Work together on a new public API and use that instead! If the thing we're using should be public, move it to the public folder to make it public!
59
59
 
60
- ⛈️ If working with the package's owner to improve the API is not possible, run `bin/packwerk update-deprecations`. Add some context to your PR about why it's not possible.
60
+ ⛈️ If working with the package's owner to improve the API is not possible, run `bin/packwerk update-todo`. Add some context to your PR about why it's not possible.
61
61
 
62
62
  ### Dependency Violations
63
63
  💡 Packwerk thinks something is a dependency violation if you're referencing a constant, class, module defined ANYWHERE but your package doesn't list it as an explicit dependency in its `package.yml`. We care about these because it allows us to be systematically intentional about what our code needs to run and helps us untangle and remove dependency cycles from our system.
@@ -78,4 +78,4 @@ Thoughtful dependency management is another cornerstone of well-modularized code
78
78
 
79
79
  ➡️ Work with the owners of the relevant packages, as well as your team, to think through a design that doesn't include the unwanted dependency.
80
80
 
81
- ⛈️ If this is not possible within the scope of your changes (think hard about this one!), run `bin/packwerk update-deprecations`. Add some context to your PR about why it's not possible, and any additional context you may have, such as a possible solution.
81
+ ⛈️ If this is not possible within the scope of your changes (think hard about this one!), run `bin/packwerk update-todo`. Add some context to your PR about why it's not possible, and any additional context you may have, such as a possible solution.
data/TROUBLESHOOT.md CHANGED
@@ -16,7 +16,7 @@ You can specify folders or packages in Packwerk commands for a shorter run time:
16
16
 
17
17
  bin/packwerk check components/your_package
18
18
 
19
- bin/packwerk update-deprecations components/your_package
19
+ bin/packwerk update-todo components/your_package
20
20
 
21
21
  _Note: You cannot specify folders or packages for `bin/packwerk validate` because the command runs for the entire application._
22
22
 
data/USAGE.md CHANGED
@@ -20,7 +20,7 @@
20
20
  * [Resolving new violations](#resolving-new-violations)
21
21
  * [Understanding how to respond to new violations](#understanding-how-to-respond-to-new-violations)
22
22
  * [Recording existing violations](#recording-existing-violations)
23
- * [Understanding the list of deprecated references](#understanding-the-list-of-deprecated-references)
23
+ * [Understanding the package todo file](#understanding-the-package-todo-file)
24
24
 
25
25
  ## What problem does Packwerk solve?
26
26
 
@@ -235,28 +235,28 @@ See: [RESOLVING_VIOLATIONS.md](RESOLVING_VIOLATIONS.md)
235
235
 
236
236
  For existing codebases, packages are likely to have existing boundary violations.
237
237
 
238
- If so, you will want to stop the bleeding and prevent more violations from occuring. The existing violations in the codebase can be recorded in a [deprecated references list](#Understanding_the_list_of_deprecated_references) by executing:
238
+ If so, you will want to stop the bleeding and prevent more violations from occuring. The existing violations in the codebase can be recorded in a [todo list](#understanding-the-package-todo-file) by executing:
239
239
 
240
- bin/packwerk update-deprecations
240
+ bin/packwerk update-todo
241
241
 
242
- Similar to `bin/packwerk check`, you may also run `bin/packwerk update-deprecations` on folders or packages:
242
+ Similar to `bin/packwerk check`, you may also run `bin/packwerk update-todo` on folders or packages:
243
243
 
244
- bin/packwerk update-deprecations components/your_package
244
+ bin/packwerk update-todo components/your_package
245
245
 
246
246
  ![](static/packwerk_update.gif)
247
247
 
248
248
  _Note: Changing dependencies or enabling dependencies will not require a full update of the codebase, only the package that changed. On the other hand, changing or enabling privacy will require a full update of the codebase._
249
249
 
250
- `bin/packwerk update-deprecations` should only be run to record existing violations and to remove deprecated references that have been worked off. Running `bin/packwerk update-deprecations` to resolve a violation should be the very last resort.
250
+ `bin/packwerk update-todo` should only be run to record existing violations and to remove violations that have been worked off. Running `bin/packwerk update-todo` to resolve a violation should be the very last resort.
251
251
 
252
252
  See: [TROUBLESHOOT.md - Troubleshooting violations](TROUBLESHOOT.md#Troubleshooting_violations)
253
253
 
254
254
 
255
- ### Understanding the list of deprecated references
255
+ ### Understanding the package todo file
256
256
 
257
- The deprecated references list is called `deprecated_references.yml` and can be found in the package folder. The list outlines the constant violations of the package, where the violation is located, and the file defining the violation.
257
+ The package TODO list is called `package_todo.yml` and can be found in the package folder. The list outlines the constant violations of the package, where the violation is located, and the file defining the violation.
258
258
 
259
- The deprecated references list should not be added to, but worked off over time.
259
+ The package TODO list should not be added to, but worked off over time.
260
260
 
261
261
  ```yaml
262
262
  components/merchant:
@@ -267,11 +267,11 @@ components/merchant:
267
267
  - components/merchant/app/public/merchant/generate_order.rb
268
268
  ```
269
269
 
270
- Above is an example of a constant violation entry in `deprecated_references.yml`.
270
+ Above is an example of a constant violation entry in `package_todo.yml`.
271
271
 
272
272
  * `components/merchant` - package where the constant violation is found
273
273
  * `::Checkouts::Core::CheckoutId` - violated constant in question
274
274
  * `dependency` - type of violation, either dependency or privacy
275
275
  * `components/merchant/app/public/merchant/generate_order.rb` - path to the file containing the violated constant
276
276
 
277
- Violations exist within the package that makes a violating reference. This means privacy violations of your package can be found listed in `deprecated_references.yml` files in the packages with the reference to a private constant.
277
+ Violations exist within the package that makes a violating reference. This means privacy violations of your package can be found listed in `package_todo.yml` files in the packages with the reference to a private constant.
data/lib/packwerk/cli.rb CHANGED
@@ -55,7 +55,17 @@ module Packwerk
55
55
  when "detect-stale-violations"
56
56
  output_result(parse_run(args).detect_stale_violations)
57
57
  when "update-deprecations"
58
- output_result(parse_run(args).update_deprecations)
58
+ warning = <<~WARNING.squish
59
+ DEPRECATION WARNING: `update-deprecations` is deprecated in favor of
60
+ `update-todo`.
61
+ WARNING
62
+
63
+ warn(warning)
64
+ output_result(parse_run(args).update_todo)
65
+ when "update-todo"
66
+ output_result(parse_run(args).update_todo)
67
+ when "update"
68
+ output_result(parse_run(args).update_todo)
59
69
  when "validate"
60
70
  validate(args)
61
71
  when nil, "help"
@@ -26,7 +26,7 @@ module Packwerk
26
26
  sig { override.params(offense_collection: Packwerk::OffenseCollection, fileset: T::Set[String]).returns(String) }
27
27
  def show_stale_violations(offense_collection, fileset)
28
28
  if offense_collection.stale_violations?(fileset)
29
- "There were stale violations found, please run `packwerk update-deprecations`"
29
+ "There were stale violations found, please run `packwerk update-todo`"
30
30
  else
31
31
  "No stale violations detected"
32
32
  end
@@ -1,6 +1,8 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "pathname"
5
+
4
6
  module Packwerk
5
7
  class OffenseCollection
6
8
  extend T::Sig
@@ -9,12 +11,12 @@ module Packwerk
9
11
  sig do
10
12
  params(
11
13
  root_path: String,
12
- deprecated_references: T::Hash[Packwerk::Package, Packwerk::DeprecatedReferences]
14
+ package_todo: T::Hash[Packwerk::Package, Packwerk::PackageTodo]
13
15
  ).void
14
16
  end
15
- def initialize(root_path, deprecated_references = {})
17
+ def initialize(root_path, package_todo = {})
16
18
  @root_path = root_path
17
- @deprecated_references = T.let(deprecated_references, T::Hash[Packwerk::Package, Packwerk::DeprecatedReferences])
19
+ @package_todo = T.let(package_todo, T::Hash[Packwerk::Package, Packwerk::PackageTodo])
18
20
  @new_violations = T.let([], T::Array[Packwerk::ReferenceOffense])
19
21
  @errors = T.let([], T::Array[Packwerk::Offense])
20
22
  end
@@ -33,7 +35,7 @@ module Packwerk
33
35
  return false unless offense.is_a?(ReferenceOffense)
34
36
 
35
37
  reference = offense.reference
36
- deprecated_references_for(reference.source_package).listed?(reference, violation_type: offense.violation_type)
38
+ package_todo_for(reference.source_package).listed?(reference, violation_type: offense.violation_type)
37
39
  end
38
40
 
39
41
  sig do
@@ -44,23 +46,23 @@ module Packwerk
44
46
  @errors << offense
45
47
  return
46
48
  end
47
- deprecated_references = deprecated_references_for(offense.reference.source_package)
48
- unless deprecated_references.add_entries(offense.reference, offense.violation_type)
49
+ package_todo = package_todo_for(offense.reference.source_package)
50
+ unless package_todo.add_entries(offense.reference, offense.violation_type)
49
51
  new_violations << offense
50
52
  end
51
53
  end
52
54
 
53
55
  sig { params(for_files: T::Set[String]).returns(T::Boolean) }
54
56
  def stale_violations?(for_files)
55
- @deprecated_references.values.any? do |deprecated_references|
56
- deprecated_references.stale_violations?(for_files)
57
+ @package_todo.values.any? do |package_todo|
58
+ package_todo.stale_violations?(for_files)
57
59
  end
58
60
  end
59
61
 
60
62
  sig { params(package_set: Packwerk::PackageSet).void }
61
- def persist_deprecated_references_files(package_set)
62
- dump_deprecated_references_files
63
- cleanup_extra_deprecated_references_files(package_set)
63
+ def persist_package_todo_files(package_set)
64
+ dump_package_todo_files
65
+ cleanup_extra_package_todo_files(package_set)
64
66
  end
65
67
 
66
68
  sig { returns(T::Array[Packwerk::Offense]) }
@@ -68,36 +70,46 @@ module Packwerk
68
70
  errors + new_violations
69
71
  end
70
72
 
73
+ sig { void }
74
+ def dump_package_todo_files
75
+ @package_todo.each_value(&:dump)
76
+ end
77
+
71
78
  private
72
79
 
73
80
  sig { params(package_set: Packwerk::PackageSet).void }
74
- def cleanup_extra_deprecated_references_files(package_set)
75
- packages_without_todos = (package_set.packages.values - @deprecated_references.keys)
81
+ def cleanup_extra_package_todo_files(package_set)
82
+ packages_without_todos = (package_set.packages.values - @package_todo.keys)
76
83
 
77
84
  packages_without_todos.each do |package|
78
- Packwerk::DeprecatedReferences.new(
85
+ Packwerk::PackageTodo.new(
79
86
  package,
80
- deprecated_references_file_for(package),
87
+ package_todo_file_for(package),
81
88
  ).delete_if_exists
82
89
  end
83
90
  end
84
91
 
85
- sig { void }
86
- def dump_deprecated_references_files
87
- @deprecated_references.each_value(&:dump)
88
- end
89
-
90
- sig { params(package: Packwerk::Package).returns(Packwerk::DeprecatedReferences) }
91
- def deprecated_references_for(package)
92
- @deprecated_references[package] ||= Packwerk::DeprecatedReferences.new(
92
+ sig { params(package: Packwerk::Package).returns(Packwerk::PackageTodo) }
93
+ def package_todo_for(package)
94
+ @package_todo[package] ||= Packwerk::PackageTodo.new(
93
95
  package,
94
- deprecated_references_file_for(package),
96
+ package_todo_file_for(package),
95
97
  )
96
98
  end
97
99
 
98
100
  sig { params(package: Packwerk::Package).returns(String) }
99
- def deprecated_references_file_for(package)
100
- File.join(@root_path, package.name, "deprecated_references.yml")
101
+ def package_todo_file_for(package)
102
+ if Pathname.new(@root_path).join(package.name, "deprecated_references.yml").exist?
103
+ warning = <<~WARNING.squish
104
+ DEPRECATION WARNING: `deprecated_references.yml` files have been renamed to `package_todo.yml`.
105
+ Run `packwerk update-todo` to rename files automatically.
106
+ WARNING
107
+
108
+ warn(warning)
109
+ File.join(@root_path, package.name, "deprecated_references.yml")
110
+ else
111
+ File.join(@root_path, package.name, "package_todo.yml")
112
+ end
101
113
  end
102
114
  end
103
115
  end
@@ -4,7 +4,7 @@
4
4
  require "yaml"
5
5
 
6
6
  module Packwerk
7
- class DeprecatedReferences
7
+ class PackageTodo
8
8
  extend T::Sig
9
9
 
10
10
  EntriesType = T.type_alias do
@@ -16,7 +16,7 @@ module Packwerk
16
16
  @package = package
17
17
  @filepath = filepath
18
18
  @new_entries = T.let({}, EntriesType)
19
- @deprecated_references = T.let(nil, T.nilable(EntriesType))
19
+ @todo_list = T.let(nil, T.nilable(EntriesType))
20
20
  end
21
21
 
22
22
  sig do
@@ -24,7 +24,7 @@ module Packwerk
24
24
  .returns(T::Boolean)
25
25
  end
26
26
  def listed?(reference, violation_type:)
27
- violated_constants_found = deprecated_references.dig(reference.constant.package.name, reference.constant.name)
27
+ violated_constants_found = todo_list.dig(reference.constant.package.name, reference.constant.name)
28
28
  return false unless violated_constants_found
29
29
 
30
30
  violated_constant_in_file = violated_constants_found.fetch("files", []).include?(reference.relative_path)
@@ -52,7 +52,7 @@ module Packwerk
52
52
  def stale_violations?(for_files)
53
53
  prepare_entries_for_dump
54
54
 
55
- deprecated_references.any? do |package, package_violations|
55
+ todo_list.any? do |package, package_violations|
56
56
  package_violations_for_files = {}
57
57
  package_violations.each do |constant_name, entries_for_constant|
58
58
  entries_for_files = for_files & entries_for_constant["files"]
@@ -83,6 +83,8 @@ module Packwerk
83
83
 
84
84
  sig { void }
85
85
  def dump
86
+ delete_old_deprecated_references
87
+
86
88
  if @new_entries.empty?
87
89
  delete_if_exists
88
90
  else
@@ -93,9 +95,11 @@ module Packwerk
93
95
  #
94
96
  # You can regenerate this file using the following command:
95
97
  #
96
- # bin/packwerk update-deprecations #{@package.name}
98
+ # bin/packwerk update-todo #{@package.name}
97
99
  MESSAGE
98
- File.open(@filepath, "w") do |f|
100
+ package_todo_filepath = File.join(File.dirname(@filepath), "package_todo.yml")
101
+
102
+ File.open(package_todo_filepath, "w") do |f|
99
103
  f.write(message)
100
104
  f.write(@new_entries.to_yaml)
101
105
  end
@@ -109,6 +113,12 @@ module Packwerk
109
113
 
110
114
  private
111
115
 
116
+ sig { void }
117
+ def delete_old_deprecated_references
118
+ deprecated_references_filepath = File.join(File.dirname(@filepath), "deprecated_references.yml")
119
+ File.delete(deprecated_references_filepath) if File.exist?(deprecated_references_filepath)
120
+ end
121
+
112
122
  sig { returns(EntriesType) }
113
123
  def prepare_entries_for_dump
114
124
  @new_entries.each do |package_name, package_violations|
@@ -123,8 +133,8 @@ module Packwerk
123
133
  end
124
134
 
125
135
  sig { returns(EntriesType) }
126
- def deprecated_references
127
- @deprecated_references ||= if File.exist?(@filepath)
136
+ def todo_list
137
+ @todo_list ||= if File.exist?(@filepath)
128
138
  load_yaml(@filepath)
129
139
  else
130
140
  {}
@@ -49,14 +49,14 @@ module Packwerk
49
49
  end
50
50
 
51
51
  sig { returns(Result) }
52
- def update_deprecations
52
+ def update_todo
53
53
  run_context = Packwerk::RunContext.from_configuration(@configuration)
54
54
  offense_collection = find_offenses(run_context)
55
- offense_collection.persist_deprecated_references_files(run_context.package_set)
55
+ offense_collection.persist_package_todo_files(run_context.package_set)
56
56
 
57
57
  message = <<~EOS
58
58
  #{@offenses_formatter.show_offenses(offense_collection.errors)}
59
- ✅ `deprecated_references.yml` has been updated.
59
+ ✅ `package_todo.yml` has been updated.
60
60
  EOS
61
61
 
62
62
  Result.new(message: message, status: offense_collection.errors.empty?)
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Packwerk
5
- VERSION = "2.2.2"
5
+ VERSION = "2.3.0"
6
6
  end
data/lib/packwerk.rb CHANGED
@@ -21,7 +21,7 @@ module Packwerk
21
21
  autoload :ConstantDiscovery
22
22
  autoload :ConstantNameInspector
23
23
  autoload :ConstNodeInspector
24
- autoload :DeprecatedReferences
24
+ autoload :PackageTodo
25
25
  autoload :FileProcessor
26
26
  autoload :FilesForProcessing
27
27
  autoload :Graph
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-15 00:00:00.000000000 Z
11
+ date: 2023-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -188,7 +188,6 @@ files:
188
188
  - lib/packwerk/const_node_inspector.rb
189
189
  - lib/packwerk/constant_discovery.rb
190
190
  - lib/packwerk/constant_name_inspector.rb
191
- - lib/packwerk/deprecated_references.rb
192
191
  - lib/packwerk/file_processor.rb
193
192
  - lib/packwerk/files_for_processing.rb
194
193
  - lib/packwerk/formatters/offenses_formatter.rb
@@ -211,6 +210,7 @@ files:
211
210
  - lib/packwerk/output_styles/plain.rb
212
211
  - lib/packwerk/package.rb
213
212
  - lib/packwerk/package_set.rb
213
+ - lib/packwerk/package_todo.rb
214
214
  - lib/packwerk/parse_run.rb
215
215
  - lib/packwerk/parsed_constant_definitions.rb
216
216
  - lib/packwerk/parsers.rb