pack_stats 0.0.2 → 0.0.4

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: da5c8a0753cdd0e4b878fc2fb2c2732fc5ca3664b1e53dc55f9c16e3b7f43fef
4
- data.tar.gz: a57f443a4572e99c7bd8c187d5b963ff9fdecebf71cf5d1339518ea3f89d5852
3
+ metadata.gz: 43fc659730748dbbe47795bd71e3b421b746b8a76b1f8fe4c8d058161c3175b6
4
+ data.tar.gz: f5ad0c0e321f701bd7f426a67faaca0988a00ac5b47c44995139818918e4c540
5
5
  SHA512:
6
- metadata.gz: 5c1bed7cbd4c71fe9937b9ea9ceb47a9784b7852f3a788f0f69c240848dd1d106e5be56a0005a2f6785f5e948c3419b2c9d7094bca559112e3289fe4334ea3ed
7
- data.tar.gz: 06c0b6fd7a7af65934ad6c6f346bb0fafa61874742c12f4d752b8437e5f6024c34153a079c0666004d68eac8c693fbd5354a62d2fc7d45e8bdb6615ded6d0569
6
+ metadata.gz: 2d4d160bc1584c09a97c271a1f45a38b56183730f65c8a9235b85add2eb45e30a2e403ea19a13364b2a5e06fba41bbad4a36fb4e42adab96b205cadb61e117d4
7
+ data.tar.gz: 99d1de19334442e788ff48e27a3c980891e0cdfffb6327667dd3338e62b45499762e5d55580244fcac6771c87e3c05a93fe3589445c9ed9a09b22072d040a9ba
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  This gem is used to report opinionated statistics about modularization to DataDog and other observability systems.
4
4
 
5
+ # Configuring Packs
6
+ This gem assumes you've correctly configured the [`packs`](https://github.com/rubyatscale/packs#configuration) gem so that `pack_stats` knows where to find your code's packs.
7
+
5
8
  # Configuring Ownership
6
9
  The gem reports metrics per-team, where each team is configured based on metadata included in Packwerk package.yml files.
7
10
 
@@ -38,13 +41,6 @@ PackStats.report_to_datadog!(
38
41
  # Example: [Pathname.new("./gems")]
39
42
  #
40
43
  componentized_source_code_locations: componentized_source_code_locations,
41
- #
42
- # A file is determined to be packaged if it exists in any of these directories.
43
- # This is an array of `Pathname`. `Pathname` can be relative or absolute paths.
44
- #
45
- # Example: [Pathname.new("./packs")]
46
- #
47
- packaged_source_code_locations: packaged_source_code_locations,
48
44
  )
49
45
  ```
50
46
 
@@ -69,13 +65,7 @@ namespace(:modularization) do
69
65
  # `enforce_dependencies` and `enforce_privacy` set to true, then update deprecations.
70
66
  old_packages = ParsePackwerk.all
71
67
  old_packages.each do |package|
72
- new_package = ParsePackwerk::Package.new(
73
- dependencies: package.dependencies,
74
- enforce_dependencies: true,
75
- enforce_privacy: true,
76
- metadata: package.metadata,
77
- name: package.name
78
- )
68
+ new_package = package.with(enforce_dependencies: true, enforce_privacy: true)
79
69
  ParsePackwerk.write_package_yml!(new_package)
80
70
  end
81
71
 
@@ -83,14 +73,7 @@ namespace(:modularization) do
83
73
 
84
74
  # Now we reset it back so that the protection values are the same as the native packwerk configuration
85
75
  old_packages.each do |package|
86
- new_package = ParsePackwerk::Package.new(
87
- dependencies: package.dependencies,
88
- enforce_dependencies: package.enforce_dependencies,
89
- enforce_privacy: package.enforce_privacy,
90
- metadata: package.metadata,
91
- name: package.name
92
- )
93
- ParsePackwerk.write_package_yml!(new_package)
76
+ ParsePackwerk.write_package_yml!(package)
94
77
  end
95
78
 
96
79
  PackStats.report_to_datadog!(
@@ -105,7 +88,7 @@ end
105
88
 
106
89
  # Using Other Observability Tools
107
90
 
108
- Right now this tool sends metrics to DataDog early. However, if you want to use this with other tools, you can call `PackStats.get_metrics(...)` to get generic metrics that you can then send to whatever observability provider you use.
91
+ Right now this tool sends metrics to DataDog only. However, if you want to use this with other tools, you can call `PackStats.get_metrics(...)` to get generic metrics that you can then send to whatever observability provider you use.
109
92
 
110
93
  # Setting Up Your Dashboards
111
94
 
@@ -63,7 +63,7 @@ module PackStats
63
63
  raise StandardError, "Could not find matching package #{to_package_name}"
64
64
  end
65
65
 
66
- tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(to_package_name))] + Metrics.tags_for_to_team(CodeOwnership.for_package(to_package)&.name)
66
+ tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(to_package_name))] + Metrics.tags_for_to_team(Private.package_owner(to_package))
67
67
  all_metrics << GaugeMetric.for('by_package.outbound_dependency_violations.per_package.count', Metrics.file_count(violations.select(&:dependency?)), tags)
68
68
  all_metrics << GaugeMetric.for('by_package.outbound_privacy_violations.per_package.count', Metrics.file_count(violations.select(&:privacy?)), tags)
69
69
  end
@@ -89,7 +89,8 @@ module PackStats
89
89
  raise StandardError, "Could not find matching package #{explicit_dependency}"
90
90
  end
91
91
 
92
- tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(explicit_dependency))] + Metrics.tags_for_to_team(CodeOwnership.for_package(to_package)&.name)
92
+ owner = Private.package_owner(to_package)
93
+ tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(explicit_dependency))] + Metrics.tags_for_to_team(owner)
93
94
  all_metrics << GaugeMetric.for('by_package.outbound_explicit_dependencies.per_package.count', 1, tags)
94
95
  end
95
96
 
@@ -17,7 +17,8 @@ module PackStats
17
17
  all_metrics = T.let([], T::Array[GaugeMetric])
18
18
  app_level_tag = Tag.for('app', app_name)
19
19
 
20
- all_packages.group_by { |package| CodeOwnership.for_package(package)&.name }.each do |team_name, packages_by_team|
20
+
21
+ all_packages.group_by { |package| Private.package_owner(package) }.each do |team_name, packages_by_team|
21
22
  # We look at `all_packages` because we care about ALL inbound violations across all teams
22
23
  inbound_violations_by_package = all_packages.flat_map(&:violations).group_by(&:to_package_name)
23
24
 
@@ -51,7 +52,7 @@ module PackStats
51
52
  raise StandardError, "Could not find matching package #{violation.to_package_name}"
52
53
  end
53
54
 
54
- CodeOwnership.for_package(to_package)&.name
55
+ Private.package_owner(to_package)
55
56
  end
56
57
 
57
58
  grouped_outbound_violations.each do |to_team_name, violations|
@@ -17,7 +17,7 @@ module PackStats
17
17
  [
18
18
  Tag.new(key: 'package', value: humanized_package_name(package.name)),
19
19
  Tag.new(key: 'app', value: app_name),
20
- *Metrics.tags_for_team(CodeOwnership.for_package(package)&.name),
20
+ *Metrics.tags_for_team(Private.package_owner(package)),
21
21
  ]
22
22
  end
23
23
 
@@ -48,6 +48,13 @@ module PackStats
48
48
  new_metric
49
49
  end
50
50
  end
51
+
52
+ sig { params(package: ParsePackwerk::Package).returns(T.nilable(String) )}
53
+ def self.package_owner(package)
54
+ pack = Packs.find(package.name)
55
+ return nil if pack.nil?
56
+ CodeOwnership.for_package(pack)&.name
57
+ end
51
58
  end
52
59
 
53
60
  private_constant :Private
data/lib/pack_stats.rb CHANGED
@@ -7,6 +7,7 @@ require 'benchmark'
7
7
  require 'code_teams'
8
8
  require 'code_ownership'
9
9
  require 'pathname'
10
+ require 'packs'
10
11
  require 'pack_stats/private'
11
12
  require 'pack_stats/private/source_code_file'
12
13
  require 'pack_stats/private/datadog_reporter'
@@ -27,23 +28,17 @@ module PackStats
27
28
  ].freeze, T::Array[Pathname]
28
29
  )
29
30
 
30
- DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS = T.let(
31
- [
32
- Pathname.new('packs'),
33
- Pathname.new('packages'),
34
- ].freeze, T::Array[Pathname]
35
- )
36
-
37
31
  sig do
38
32
  params(
39
33
  datadog_client: Dogapi::Client,
40
34
  app_name: String,
41
35
  source_code_pathnames: T::Array[Pathname],
42
36
  componentized_source_code_locations: T::Array[Pathname],
43
- packaged_source_code_locations: T::Array[Pathname],
44
37
  report_time: Time,
45
38
  verbose: T::Boolean,
46
39
  # See note on get_metrics
40
+ packaged_source_code_locations: T.nilable(T::Array[Pathname]),
41
+ # See note on get_metrics
47
42
  use_gusto_legacy_names: T::Boolean
48
43
  ).void
49
44
  end
@@ -52,16 +47,15 @@ module PackStats
52
47
  app_name:,
53
48
  source_code_pathnames:,
54
49
  componentized_source_code_locations: DEFAULT_COMPONENTIZED_SOURCE_CODE_LOCATIONS,
55
- packaged_source_code_locations: DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS,
56
50
  report_time: Time.now, # rubocop:disable Rails/TimeZone
57
51
  verbose: false,
52
+ packaged_source_code_locations: [],
58
53
  use_gusto_legacy_names: false
59
54
  )
60
55
 
61
56
  all_metrics = self.get_metrics(
62
57
  source_code_pathnames: source_code_pathnames,
63
58
  componentized_source_code_locations: componentized_source_code_locations,
64
- packaged_source_code_locations: packaged_source_code_locations,
65
59
  app_name: app_name,
66
60
  use_gusto_legacy_names: use_gusto_legacy_names,
67
61
  )
@@ -88,8 +82,9 @@ module PackStats
88
82
  params(
89
83
  source_code_pathnames: T::Array[Pathname],
90
84
  componentized_source_code_locations: T::Array[Pathname],
91
- packaged_source_code_locations: T::Array[Pathname],
92
85
  app_name: String,
86
+ # This field is deprecated
87
+ packaged_source_code_locations: T.nilable(T::Array[Pathname]),
93
88
  # It is not recommended to set this to true.
94
89
  # Gusto uses this to preserve historical trends in Dashboards as the names of
95
90
  # things changed, but new dashboards can use names that better match current tooling conventions.
@@ -100,15 +95,14 @@ module PackStats
100
95
  def self.get_metrics(
101
96
  source_code_pathnames:,
102
97
  componentized_source_code_locations:,
103
- packaged_source_code_locations:,
104
98
  app_name:,
99
+ packaged_source_code_locations: [],
105
100
  use_gusto_legacy_names: false
106
101
  )
107
102
  all_metrics = Private::DatadogReporter.get_metrics(
108
103
  source_code_files: source_code_files(
109
104
  source_code_pathnames: source_code_pathnames,
110
105
  componentized_source_code_locations: componentized_source_code_locations,
111
- packaged_source_code_locations: packaged_source_code_locations
112
106
  ),
113
107
  app_name: app_name
114
108
  )
@@ -124,18 +118,21 @@ module PackStats
124
118
  params(
125
119
  source_code_pathnames: T::Array[Pathname],
126
120
  componentized_source_code_locations: T::Array[Pathname],
127
- packaged_source_code_locations: T::Array[Pathname]
128
121
  ).returns(T::Array[Private::SourceCodeFile])
129
122
  end
130
123
  def self.source_code_files(
131
124
  source_code_pathnames:,
132
- componentized_source_code_locations:,
133
- packaged_source_code_locations:
125
+ componentized_source_code_locations:
134
126
  )
135
127
 
136
128
  # Sorbet has the wrong signatures for `Pathname#find`, whoops!
137
129
  componentized_file_set = Set.new(componentized_source_code_locations.select(&:exist?).flat_map { |pathname| T.unsafe(pathname).find.to_a })
138
- packaged_file_set = Set.new(packaged_source_code_locations.select(&:exist?).flat_map { |pathname| T.unsafe(pathname).find.to_a })
130
+
131
+ packaged_file_set = Packs.all.flat_map do |pack|
132
+ pack.relative_path.find.to_a
133
+ end
134
+
135
+ packaged_file_set = Set.new(packaged_file_set)
139
136
 
140
137
  source_code_pathnames.map do |pathname|
141
138
  componentized_file = componentized_file_set.include?(pathname)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pack_stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-14 00:00:00.000000000 Z
11
+ date: 2023-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_teams
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: packs
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: parse_packwerk
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -188,16 +202,6 @@ files:
188
202
  - lib/pack_stats/private/source_code_file.rb
189
203
  - lib/pack_stats/tag.rb
190
204
  - lib/pack_stats/tags.rb
191
- - sorbet/config
192
- - sorbet/rbi/gems/ast@2.4.2.rbi
193
- - sorbet/rbi/gems/code_ownership@1.28.0.rbi
194
- - sorbet/rbi/gems/code_teams@1.0.0.rbi
195
- - sorbet/rbi/gems/dogapi@1.45.0.rbi
196
- - sorbet/rbi/gems/manual.rbi
197
- - sorbet/rbi/gems/parse_packwerk@0.16.0.rbi
198
- - sorbet/rbi/gems/rspec@3.10.0.rbi
199
- - sorbet/rbi/gems/rubocop-packs@0.0.30.rbi
200
- - sorbet/rbi/todo.rbi
201
205
  homepage: https://github.com/rubyatscale/pack_stats
202
206
  licenses:
203
207
  - MIT
data/sorbet/config DELETED
@@ -1,4 +0,0 @@
1
- --dir
2
- .
3
- --ignore=/vendor/bundle
4
- --enable-experimental-requires-ancestor