query_packwerk 0.1.0 → 0.1.24

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: 69878aa37cf34d0896f727625f444787cf166db630cf8334109eccbd61cc40a9
4
- data.tar.gz: ba722634ea12a50ea7473bb976567af174a40e14c5ba9aa0b12d782c8e92b49e
3
+ metadata.gz: 392d286b38084a21900d3cfe40e81f79f7e6eff5ca872327551589688b309d85
4
+ data.tar.gz: 5bc5556fbc5279b3d8056757067ec696e362ab2860251cc6cefc403223f89ce6
5
5
  SHA512:
6
- metadata.gz: ad07eb416e3993dbbe823dd2305afbb86fc52c0e0ec652482a58f0058f60330bc5a16ecb969f9356bcc13eb52a669e58ea094eaf4c9486097fbc7862fd8b671b
7
- data.tar.gz: 42115b541cc33e22658978aec000c83ce3d8db9385bcd7671e111c0629537be3dda33bcce9909a5b88d9e9c21a15ecce4af74d948aa2ea96d64583cefbd5c7b2
6
+ metadata.gz: 5f99589b97b415a4f98d404b5270e368b201353ce0b5107f70f3341b43c9f6590cae133a4cc0cdd6decc6eb1c0d67a373fbef15df439beed841653bcec6ac4a0
7
+ data.tar.gz: 9ede139265993386cbfbd3e5a9987b00d658865af3d4a3833f0bf41b0d723e84da51c91737b49175a37c52f1668b2671655030ee19a2628e910644416084b7e9
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ plugins:
3
3
  - rubocop-performance
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 3.1
6
+ TargetRubyVersion: 3.3
7
7
  SuggestExtensions: false
8
8
  NewCops: enable
9
9
  Exclude:
@@ -41,9 +41,6 @@ Style/Documentation:
41
41
  Style/SignalException:
42
42
  Enabled: false
43
43
 
44
- Style/FrozenStringLiteralComment:
45
- Enabled: false
46
-
47
44
  Style/MultilineBlockChain:
48
45
  Enabled: false
49
46
 
@@ -86,5 +83,5 @@ Style/SuperArguments:
86
83
  Style/ArgumentsForwarding:
87
84
  Enabled: false
88
85
 
89
- Style/BlockForwarding:
86
+ Naming/BlockForwarding:
90
87
  Enabled: false
data/AGENTS.md ADDED
@@ -0,0 +1,30 @@
1
+ This file provides guidance to AI coding agents when working with code in this repository.
2
+
3
+ ## What this project is
4
+
5
+ `query_packwerk` is a Ruby gem for querying and analyzing [packwerk](https://github.com/Shopify/packwerk) violations and dependencies. It provides a fluent API and an interactive console for exploring `package.yml` and `package_todo.yml` files.
6
+
7
+ ## Commands
8
+
9
+ ```bash
10
+ bundle install
11
+
12
+ # Run all tests (RSpec)
13
+ bundle exec rspec
14
+
15
+ # Run a single spec file
16
+ bundle exec rspec spec/path/to/spec.rb
17
+
18
+ # Lint
19
+ bundle exec rubocop
20
+ bundle exec rubocop -a # auto-correct
21
+
22
+ # Type checking (Sorbet)
23
+ bundle exec srb tc
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ - `lib/query_packwerk.rb` — entry point and public API
29
+ - `lib/query_packwerk/` — query classes for violations, packages, and dependency graphs; also includes an interactive console (REPL) interface
30
+ - `spec/` — RSpec tests
data/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ @AGENTS.md
data/README.md CHANGED
@@ -1,68 +1,87 @@
1
1
  # QueryPackwerk
2
2
 
3
- QueryPackwerk is a Ruby gem for querying and analyzing Packwerk violations in Ruby applications.
4
- It provides a friendly API for exploring package.yml and package_todo.yml files, making it easier to manage module boundaries and dependencies in your codebase.
3
+ QueryPackwerk is a Ruby gem for querying and analyzing [Packwerk](https://github.com/Shopify/packwerk) violations in Ruby applications.
4
+ It provides a friendly API for exploring `package.yml` and `package_todo.yml` files, making it easier to manage module boundaries and dependencies in your codebase.
5
5
 
6
6
  ## Installation
7
7
 
8
- Install the gem and add to the application's Gemfile by executing:
8
+ This gem provides a CLI interface that can be used independently from your application.
9
9
 
10
10
  ```bash
11
- bundle add query_packwerk
11
+ gem install query_packwerk
12
12
  ```
13
13
 
14
- If bundler is not being used to manage dependencies, install the gem by executing:
14
+ You can also make it available in a specific application by adding it to your Gemfile:
15
15
 
16
16
  ```bash
17
- gem install query_packwerk
17
+ bundle add query_packwerk --group=development
18
18
  ```
19
19
 
20
20
  ## Usage
21
21
 
22
22
  ### Console Interface
23
23
 
24
- The easiest way to use QueryPackwerk is through its interactive console:
24
+ The easiest way to use QueryPackwerk is through its interactive console. This will use the local directory Packwerk context and provide you with all QueryPackwerk methods.
25
25
 
26
26
  ```bash
27
27
  query_packwerk console
28
28
  ```
29
29
 
30
- This will load the Packwerk context from your current directory and provide you with an interactive Ruby console with QueryPackwerk methods available.
30
+ The CLI includes a welcome message with a list of commands. You can access it any time with `welcome`:
31
+
32
+ ```
33
+ query_packwerk:001:0> welcome
34
+ ```
35
+
36
+ Find packages to work with:
37
+
38
+ ```ruby
39
+ # Get a package
40
+ query_packwerk:001:0> package("pack_name")
41
+
42
+ # Get all packages
43
+ query_packwerk:001:0> Packages.all
44
+
45
+ # Find a package
46
+ query_packwerk:001:0> Packages.where(name: /service/)
47
+ ```
31
48
 
32
- Available commands in the console:
49
+ Explore violations:
33
50
 
34
51
  ```ruby
35
52
  # Get all violations for a pack
36
- violations_for("pack_name")
53
+ query_packwerk:001:0> violations_for("pack_name")
37
54
 
38
55
  # Get where violations occurred
39
- violation_sources_for("pack_name")
56
+ query_packwerk:001:0> violation_sources_for("pack_name")
40
57
 
41
58
  # Get how often violations occurred
42
- violation_counts_for("pack_name")
59
+ query_packwerk:001:0> violation_counts_for("pack_name")
43
60
 
44
61
  # Get the 'shape' of violations
45
- anonymous_violation_sources_for("pack_name")
62
+ query_packwerk:001:0> anonymous_violation_sources_for("pack_name")
46
63
 
47
64
  # Get how often each shape occurs
48
- anonymous_violation_counts_for("pack_name")
65
+ query_packwerk:001:0> anonymous_violation_counts_for("pack_name")
49
66
 
50
67
  # Get who consumes this pack
51
- consumers("pack_name")
52
-
53
- # Get all packages
54
- Packages.all
68
+ query_packwerk:001:0> consumers("pack_name")
55
69
 
56
70
  # Get all violations
57
- Violations.all
71
+ query_packwerk:001:0> Violations.all
58
72
 
73
+ ```
74
+
75
+ If you change any of the package.yml or package_todo.yml files, you can reload the running console:
76
+
77
+ ```ruby
59
78
  # Reset the cache
60
- reload!
79
+ query_packwerk:001:0> reload!
61
80
  ```
62
81
 
63
82
  ### Ruby API
64
83
 
65
- You can also use QueryPackwerk programmatically in your Ruby code:
84
+ QueryPackwerk can also be used programmatically from Ruby:
66
85
 
67
86
  ```ruby
68
87
  require 'query_packwerk'
@@ -97,11 +116,11 @@ QueryPackwerk.anonymous_violation_counts_for("my_pack", threshold: 3)
97
116
 
98
117
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
99
118
 
100
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
119
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, push a PR with the label for the version you want, like 'major', 'minor' or 'patch'. When the PR is merged, the version will be automatically released to RubyGems.
101
120
 
102
121
  ## Contributing
103
122
 
104
- Bug reports and pull requests are welcome on GitHub at https://github.com/martinemde/query_packwerk.
123
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rubyatscale/query_packwerk.
105
124
 
106
125
  ## License
107
126
 
@@ -1,4 +1,5 @@
1
1
  # typed: strict
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'thor'
4
5
 
@@ -1,144 +1,148 @@
1
1
  # typed: true
2
+ # frozen_string_literal: true
2
3
 
3
- module QueryPackwerk::ConsoleHelpers
4
- extend T::Sig
4
+ module QueryPackwerk
5
+ module ConsoleHelpers
6
+ extend T::Sig
7
+ include Kernel
5
8
 
6
- sig { returns(String) }
7
- def inspect
8
- 'query_packwerk console'
9
- end
10
-
11
- sig { returns(NilClass) } # returning nil is less ugly in the console.
12
- def welcome
13
- help_query_packwerk
14
- puts
15
- help_help
16
- end
9
+ sig { returns(String) }
10
+ def inspect
11
+ 'query_packwerk console'
12
+ end
17
13
 
18
- sig { params(type: T.nilable(T.any(String, Symbol))).returns(NilClass) }
19
- def help(type = nil)
20
- case type.to_s.downcase
21
- when 'violation'
22
- help_violation
23
- when 'violations'
24
- help_violations
25
- when 'package'
26
- help_package
27
- when 'packages'
28
- help_packages
29
- when '', 'help'
30
- help_help
31
- else
32
- puts "Unknown help topic: #{type}\n"
14
+ sig { returns(NilClass) } # returning nil is less ugly in the console.
15
+ def welcome
16
+ help_query_packwerk
17
+ puts
33
18
  help_help
34
19
  end
35
- end
36
20
 
37
- sig { returns(NilClass) }
38
- def help_help
39
- puts <<~HELP
40
- Available help topics:
41
- help # This help
42
- help_violation # Help for QueryPackwerk::Violation
43
- help_violations # Help for QueryPackwerk::Violations
44
- help_package # Help for QueryPackwerk::Package
45
- help_packages # Help for QueryPackwerk::Packages
46
- HELP
47
- end
21
+ sig { params(type: T.nilable(T.any(String, Symbol))).returns(NilClass) }
22
+ def help(type = nil)
23
+ case type.to_s.downcase
24
+ when 'violation'
25
+ help_violation
26
+ when 'violations'
27
+ help_violations
28
+ when 'package'
29
+ help_package
30
+ when 'packages'
31
+ help_packages
32
+ when '', 'help'
33
+ help_help
34
+ else
35
+ puts "Unknown help topic: #{type}\n"
36
+ help_help
37
+ end
38
+ end
48
39
 
49
- sig { returns(NilClass) }
50
- def help_violation
51
- puts <<~HELP
52
- QueryPackwerk::Violation (lib/query_packwerk/violation.rb)
53
- ------------------------------------------------
54
- .type # Returns the violation type ('privacy' or 'dependency')
55
- .class_name # Returns the violated constant name
56
- .files # Returns array of files containing the violation
57
- .producing_pack # Returns the Package that owns the violated constant
58
- .consuming_pack # Returns the Package that violated the constant
59
- .sources # Returns array of AST nodes representing the violation occurrences
60
- .sources_with_locations # Returns array of [file:line, source] pairs for each violation
61
- .source_counts # Returns hash of how often each violation source occurs
62
- .anonymous_sources # Returns array of violation sources with arguments anonymized
63
- .anonymous_sources_with_locations # Returns array of [file:line, source] pairs for each violation with arguments anonymized
64
- .count # Returns total number of violation occurrences
65
- HELP
66
- end
40
+ sig { returns(NilClass) }
41
+ def help_help
42
+ puts <<~HELP
43
+ Available help topics:
44
+ help # This help
45
+ help_violation # Help for QueryPackwerk::Violation
46
+ help_violations # Help for QueryPackwerk::Violations
47
+ help_package # Help for QueryPackwerk::Package
48
+ help_packages # Help for QueryPackwerk::Packages
49
+ HELP
50
+ end
67
51
 
68
- sig { returns(NilClass) }
69
- def help_violations
70
- puts <<~HELP
71
- QueryPackwerk::Violations (lib/query_packwerk/violations.rb)
72
- --------------------------------------------------
73
- .where(conditions) # Returns new Violations filtered by conditions
74
- .raw_sources # Returns hash of constant => AST nodes for all violations
75
- .sources # Returns hash of constant => source strings for all violations
76
- .sources_with_locations # Returns hash of constant => [file:line, source] pairs
77
- .source_counts # Returns hash of constant => {source => count} with occurrence counts
78
- .sources_with_contexts # Returns hash of constant => [file:line, source] pairs for each violation with context
79
- .anonymous_sources # Returns hash of constant => anonymized sources
80
- .anonymous_sources_with_locations # Returns array of [file:line, source] pairs for each violation with arguments anonymized
81
- .consumers(threshold) # Returns hash of consuming package names and violation counts
82
- .producers(threshold) # Returns hash of producing package names and violation counts
83
- .including_files(globs) # Returns new Violations filtered to include specific files
84
- .excluding_files(globs) # Returns new Violations filtered to exclude specific files
85
- HELP
86
- end
52
+ sig { returns(NilClass) }
53
+ def help_violation
54
+ puts <<~HELP
55
+ QueryPackwerk::Violation (lib/query_packwerk/violation.rb)
56
+ ------------------------------------------------
57
+ .type # Returns the violation type ('privacy' or 'dependency')
58
+ .class_name # Returns the violated constant name
59
+ .files # Returns array of files containing the violation
60
+ .producing_pack # Returns the Package that owns the violated constant
61
+ .consuming_pack # Returns the Package that violated the constant
62
+ .sources # Returns array of AST nodes representing the violation occurrences
63
+ .sources_with_locations # Returns array of [file:line, source] pairs for each violation
64
+ .source_counts # Returns hash of how often each violation source occurs
65
+ .anonymous_sources # Returns array of violation sources with arguments anonymized
66
+ .anonymous_sources_with_locations # Returns array of [file:line, source] pairs for each violation with arguments anonymized
67
+ .count # Returns total number of violation occurrences
68
+ HELP
69
+ end
87
70
 
88
- sig { returns(NilClass) }
89
- def help_package
90
- puts <<~HELP
91
- QueryPackwerk::Package (lib/query_packwerk/package.rb)
92
- ----------------------------------------------
93
- .name # Returns the package name
94
- .enforce_dependencies # Returns whether package enforces dependencies
95
- .enforce_privacy # Returns whether package enforces privacy
96
- .metadata # Returns the package metadata from package.yml
97
- .config # Returns the package configuration
98
- .dependencies # Returns Packages collection of dependencies
99
- .dependency_names # Returns array of dependency package names
100
- .owner # Returns the package owner or 'Unowned'
101
- .directory # Returns the package directory path
102
- .todos # Returns Violations where this package is the consumer
103
- .violations # Returns Violations where this package is the producer
104
- .consumers # Returns Packages that consume this package
105
- .consumer_names # Returns array of names of consuming packages
106
- .consumer_counts # Returns hash of consumer package names and counts
107
- HELP
108
- end
71
+ sig { returns(NilClass) }
72
+ def help_violations
73
+ puts <<~HELP
74
+ QueryPackwerk::Violations (lib/query_packwerk/violations.rb)
75
+ --------------------------------------------------
76
+ .where(conditions) # Returns new Violations filtered by conditions
77
+ .raw_sources # Returns hash of constant => AST nodes for all violations
78
+ .sources # Returns hash of constant => source strings for all violations
79
+ .sources_with_locations # Returns hash of constant => [file:line, source] pairs
80
+ .source_counts # Returns hash of constant => {source => count} with occurrence counts
81
+ .sources_with_contexts # Returns hash of constant => [file:line, source] pairs for each violation with context
82
+ .anonymous_sources # Returns hash of constant => anonymized sources
83
+ .anonymous_sources_with_locations # Returns array of [file:line, source] pairs for each violation with arguments anonymized
84
+ .consumers(threshold) # Returns hash of consuming package names and violation counts
85
+ .producers(threshold) # Returns hash of producing package names and violation counts
86
+ .including_files(globs) # Returns new Violations filtered to include specific files
87
+ .excluding_files(globs) # Returns new Violations filtered to exclude specific files
88
+ HELP
89
+ end
109
90
 
110
- sig { returns(NilClass) }
111
- def help_packages
112
- puts <<~HELP
113
- QueryPackwerk::Packages (lib/query_packwerk/packages.rb)
114
- ------------------------------------------------
115
- .all # Returns all packages in the application
116
- .where(conditions) # Returns new Packages filtered by conditions
117
- .violations # Returns Violations for all packages in collection
118
- HELP
119
- end
91
+ sig { returns(NilClass) }
92
+ def help_package
93
+ puts <<~HELP
94
+ QueryPackwerk::Package (lib/query_packwerk/package.rb)
95
+ ----------------------------------------------
96
+ .name # Returns the package name
97
+ .enforce_dependencies # Returns whether package enforces dependencies
98
+ .enforce_privacy # Returns whether package enforces privacy
99
+ .metadata # Returns the package metadata from package.yml
100
+ .config # Returns the package configuration
101
+ .dependencies # Returns Packages collection of dependencies
102
+ .dependency_names # Returns array of dependency package names
103
+ .owner # Returns the package owner or 'Unowned'
104
+ .directory # Returns the package directory path
105
+ .todos # Returns Violations where this package is the consumer
106
+ .violations # Returns Violations where this package is the producer
107
+ .consumers # Returns Packages that consume this package
108
+ .consumer_names # Returns array of names of consuming packages
109
+ .consumer_counts # Returns hash of consumer package names and counts
110
+ HELP
111
+ end
112
+
113
+ sig { returns(NilClass) }
114
+ def help_packages
115
+ puts <<~HELP
116
+ QueryPackwerk::Packages (lib/query_packwerk/packages.rb)
117
+ ------------------------------------------------
118
+ .all # Returns all packages in the application
119
+ .where(conditions) # Returns new Packages filtered by conditions
120
+ .violations # Returns Violations for all packages in collection
121
+ HELP
122
+ end
120
123
 
121
- sig { returns(NilClass) }
122
- def help_query_packwerk
123
- puts <<~HELP
124
- QueryPackwerk (lib/query_packwerk.rb)
125
- ------------------------------
126
- Available commands:
127
- package(pack_name) # Get a package by name
128
- Packages.all # Get all packages
124
+ sig { returns(NilClass) }
125
+ def help_query_packwerk
126
+ puts <<~HELP
127
+ QueryPackwerk (lib/query_packwerk.rb)
128
+ ------------------------------
129
+ Available commands:
130
+ package(pack_name) # Get a package by name
131
+ Packages.all # Get all packages
129
132
 
130
- Package Consumption (how others use this package):
131
- violations_for(pack_name) # Get all violations where others access this package
132
- violation_sources_for(pack_name) # Get where others access this package
133
- violation_counts_for(pack_name) # Get how often others access this package
134
- anonymous_violation_sources_for(pack_name) # Get the 'shape' of how others access this package
135
- anonymous_violation_counts_for(pack_name) # Get how often each access pattern occurs
136
- consumers(pack_name) # Get which packages consume this package
133
+ Package Consumption (how others use this package):
134
+ violations_for(pack_name) # Get all violations where others access this package
135
+ violation_sources_for(pack_name) # Get where others access this package
136
+ violation_counts_for(pack_name) # Get how often others access this package
137
+ anonymous_violation_sources_for(pack_name) # Get the 'shape' of how others access this package
138
+ anonymous_violation_counts_for(pack_name) # Get how often each access pattern occurs
139
+ consumers(pack_name) # Get which packages consume this package
137
140
 
138
- Package Dependencies (how this package uses others):
139
- todos_for(pack_name) # Get all todos where this package accesses others
141
+ Package Dependencies (how this package uses others):
142
+ todos_for(pack_name) # Get all todos where this package accesses others
140
143
 
141
- Violations.all # Get all violations
142
- HELP
144
+ Violations.all # Get all violations
145
+ HELP
146
+ end
143
147
  end
144
148
  end
@@ -74,7 +74,7 @@ module QueryPackwerk
74
74
  end
75
75
  end
76
76
 
77
- # Get all occurrencs of the violation's constant in a file
77
+ # Get all occurrences of the violation's constant in a file
78
78
  sig { params(file_name: String, class_name: String).returns(T::Array[RuboCop::AST::Node]) }
79
79
  def get_all_const_occurrences(file_name:, class_name:)
80
80
  const_key = [file_name, class_name]
@@ -139,8 +139,8 @@ module QueryPackwerk
139
139
  RuboCop::ProcessedSource.new(string, RUBY_VERSION.to_f).ast
140
140
  end
141
141
 
142
- # We can find a constant, but by going up its parents we can find out the full call chain
143
- # by checking if each parent is a receiver of the child, giving us method calls and
142
+ # We can find a constant, but by going up its parents we can find the full call chain.
143
+ # We check if each parent is a receiver of the child, giving us method calls and
144
144
  # arguments on a constant as well as where it occurred.
145
145
  sig { params(node: RuboCop::AST::Node).returns(RuboCop::AST::Node) }
146
146
  def get_full_receiver_chain(node)
@@ -21,13 +21,15 @@ module QueryPackwerk
21
21
  @original_package.name
22
22
  end
23
23
 
24
+ # Mirrors packwerk's public API naming, so it can't take a `?` suffix.
24
25
  sig { returns(T::Boolean) }
25
- def enforce_dependencies
26
+ def enforce_dependencies # rubocop:disable Naming/PredicateMethod
26
27
  !!@original_package.enforce_dependencies
27
28
  end
28
29
 
30
+ # Mirrors packwerk's public API naming, so it can't take a `?` suffix.
29
31
  sig { returns(T::Boolean) }
30
- def enforce_privacy
32
+ def enforce_privacy # rubocop:disable Naming/PredicateMethod
31
33
  !!@original_package.enforce_privacy
32
34
  end
33
35
 
@@ -56,6 +56,24 @@ module QueryPackwerk
56
56
  @original_collection = original_collection
57
57
  end
58
58
 
59
+ sig { returns(T::Boolean) }
60
+ def empty?
61
+ @original_collection.empty?
62
+ end
63
+
64
+ sig do
65
+ params(
66
+ blk: T.nilable(T.proc.params(arg0: QueryPackwerk::Package).returns(T::Boolean))
67
+ ).returns(T::Boolean)
68
+ end
69
+ def any?(&blk)
70
+ if blk.nil?
71
+ !empty?
72
+ else
73
+ @original_collection.any?(&blk)
74
+ end
75
+ end
76
+
59
77
  # You can query for packages rather than violations to get a broader view, and
60
78
  # the violations returned from this will be related to all packs in this class rather than just
61
79
  # one.
@@ -68,11 +86,12 @@ module QueryPackwerk
68
86
 
69
87
  sig { returns(String) }
70
88
  def inspect
71
- [
72
- "#<#{self.class.name} [",
73
- to_a.map(&:inspect).join("\n"),
74
- ']>'
75
- ].join("\n")
89
+ arr = to_a.map(&:inspect)
90
+ if arr.empty?
91
+ "#<#{self.class.name} []>"
92
+ else
93
+ "#<#{self.class.name} [\n#{arr.join("\n")}\n]>"
94
+ end
76
95
  end
77
96
  end
78
97
  end
@@ -36,8 +36,6 @@ module QueryPackwerk
36
36
  end
37
37
 
38
38
  # Should be overridden, the base of most of the queries.
39
- #
40
- # TODO: Consider refactoring to `abstract` interface
41
39
  sig { overridable.returns(T::Array[T.untyped]) }
42
40
  def original_collection
43
41
  []
@@ -127,7 +125,7 @@ module QueryPackwerk
127
125
  end
128
126
  end
129
127
  end
130
- # Similar to the above `original_collection` we want to override this by defining
128
+ # Similar to the above `original_collection`, we want to override this by defining
131
129
  # where the InheritingClass can find all of its raw data.
132
130
  #
133
131
  # Sorbet does not recognize `included(klass)`/`klass.extend(ClassMethods)` when
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module QueryPackwerk
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.24'
6
6
  end
@@ -88,7 +88,7 @@ module QueryPackwerk
88
88
 
89
89
  # Whether or not the files containing violations match any provided globs
90
90
  #
91
- # See also: https://ruby-doc.org/core-2.7.6/File.html#method-c-fnmatch
91
+ # See Ruby documentation for File.fnmatch for more details.
92
92
  sig { params(globs: T.any(String, Regexp)).returns(T::Boolean) }
93
93
  def includes_files?(*globs)
94
94
  globs.any? do |glob|
@@ -188,7 +188,7 @@ module QueryPackwerk
188
188
  end
189
189
  end
190
190
 
191
- # Like above frequency of sources, except by method "shape" rather than
191
+ # Like the above source frequency, except grouped by method "shape" rather than
192
192
  # exact arguments
193
193
  sig { returns(T::Hash[String, Integer]) }
194
194
  def anonymous_source_counts
@@ -272,9 +272,6 @@ module QueryPackwerk
272
272
  **runtime_keys(keys)
273
273
  }
274
274
 
275
- # all_values[:is_active_record] = active_record? if !keys || keys.include?(:is_active_record)
276
- # all_values[:is_constant] = active_record? if !keys || keys.include?(:is_constant)
277
-
278
275
  keys.nil? ? all_values : all_values.slice(*T.unsafe(keys))
279
276
  end
280
277
 
@@ -121,6 +121,16 @@ module QueryPackwerk
121
121
  @original_collection.sum(&:file_count)
122
122
  end
123
123
 
124
+ sig { returns(T::Boolean) }
125
+ def empty?
126
+ @original_collection.empty?
127
+ end
128
+
129
+ sig { returns(T::Boolean) }
130
+ def any?
131
+ !empty?
132
+ end
133
+
124
134
  # Gets all sources and their receiving chains grouped by the constant they've violated.
125
135
  sig { returns(T.untyped) }
126
136
  def raw_sources
@@ -148,8 +158,8 @@ module QueryPackwerk
148
158
  deep_merge_groups(@original_collection) { |v| [v.class_name, v.sources_with_locations] }
149
159
  end
150
160
 
151
- # Instead of getting all instances of the source, count how often each occurs, with the option to
152
- # provide a threshold to remove lower-occuring items.
161
+ # Instead of returning all instances of the source, count how often each occurs, with the option to
162
+ # provide a threshold to remove lower-occurring items.
153
163
  sig { params(threshold: Integer).returns(T::Hash[String, T::Hash[String, Integer]]) }
154
164
  def source_counts(threshold: 0)
155
165
  load_sources!
@@ -253,11 +263,12 @@ module QueryPackwerk
253
263
 
254
264
  sig { returns(String) }
255
265
  def inspect
256
- [
257
- "#<#{self.class.name} [",
258
- to_a.map(&:inspect).join("\n"),
259
- ']>'
260
- ].join("\n")
266
+ arr = to_a.map(&:inspect)
267
+ if arr.empty?
268
+ "#<#{self.class.name} []>"
269
+ else
270
+ "#<#{self.class.name} [\n#{arr.join("\n")}\n]>"
271
+ end
261
272
  end
262
273
 
263
274
  private
@@ -5,12 +5,12 @@ require 'sorbet-runtime'
5
5
  require 'parse_packwerk'
6
6
  require 'rubocop'
7
7
 
8
- #
9
8
  # QueryPackwerk is a tool for querying Packwerk violations.
10
9
  #
11
10
  # It is built on top of ParsePackwerk, and provides a Ruby-friendly API
12
11
  # for querying package.yml and package_todo.yml files.
13
12
  #
13
+ # See also: https://github.com/rubyatscale/parse_packwerk
14
14
  module QueryPackwerk
15
15
  autoload :Console, 'query_packwerk/console'
16
16
  autoload :ConsoleHelpers, 'query_packwerk/console_helpers'
@@ -24,8 +24,8 @@ module QueryPackwerk
24
24
  autoload :Version, 'query_packwerk/version'
25
25
 
26
26
  extend T::Sig
27
- # TODO: module_function isn't playing nicely with Sorbet
28
- extend self # rubocop:todo Style/ModuleFunction
27
+
28
+ module_function
29
29
 
30
30
  sig { params(name: String).returns(T.nilable(QueryPackwerk::Package)) }
31
31
  def package(name)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: query_packwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineering
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-27 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: coderay
@@ -103,7 +103,9 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - ".rspec"
105
105
  - ".rubocop.yml"
106
+ - AGENTS.md
106
107
  - CHANGELOG.md
108
+ - CLAUDE.md
107
109
  - CODE_OF_CONDUCT.md
108
110
  - LICENSE.txt
109
111
  - README.md
@@ -124,15 +126,14 @@ files:
124
126
  - lib/query_packwerk/version.rb
125
127
  - lib/query_packwerk/violation.rb
126
128
  - lib/query_packwerk/violations.rb
127
- - sig/query_packwerk.rbs
128
- homepage: https://github.com/gusto/query_packwerk
129
+ homepage: https://github.com/rubyatscale/query_packwerk
129
130
  licenses:
130
131
  - MIT
131
132
  metadata:
132
133
  allowed_push_host: https://rubygems.org
133
- homepage_uri: https://github.com/gusto/query_packwerk
134
- source_code_uri: https://github.com/gusto/query_packwerk
135
- changelog_uri: https://github.com/gusto/query_packwerk/blob/main/CHANGELOG.md
134
+ homepage_uri: https://github.com/rubyatscale/query_packwerk
135
+ source_code_uri: https://github.com/rubyatscale/query_packwerk
136
+ changelog_uri: https://github.com/rubyatscale/query_packwerk/blob/main/CHANGELOG.md
136
137
  rdoc_options: []
137
138
  require_paths:
138
139
  - lib
@@ -140,14 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
141
  requirements:
141
142
  - - ">="
142
143
  - !ruby/object:Gem::Version
143
- version: 3.1.0
144
+ version: '3.3'
144
145
  required_rubygems_version: !ruby/object:Gem::Requirement
145
146
  requirements:
146
147
  - - ">="
147
148
  - !ruby/object:Gem::Version
148
149
  version: '0'
149
150
  requirements: []
150
- rubygems_version: 3.6.2
151
+ rubygems_version: 3.6.9
151
152
  specification_version: 4
152
153
  summary: Query Packwerk
153
154
  test_files: []
@@ -1,4 +0,0 @@
1
- module QueryPackwerk
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end