Skip to content

Commit c790934

Browse files
author
Alex Evanczuk
authored
Use packs to determine packaged paths and for testing (#28)
* Use Packs to determine packaged file locations * use packs/rspec/support
1 parent 5a1921a commit c790934

14 files changed

Lines changed: 693 additions & 425 deletions

Gemfile.lock

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
PATH
22
remote: .
33
specs:
4-
pack_stats (0.0.2)
4+
pack_stats (0.0.3)
55
code_ownership
66
code_teams
77
dogapi
8+
packs
89
parse_packwerk
910
rubocop-packs
1011
sorbet-runtime
@@ -18,9 +19,9 @@ GEM
1819
minitest (>= 5.1)
1920
tzinfo (~> 2.0)
2021
ast (2.4.2)
21-
code_ownership (1.29.1)
22+
code_ownership (1.29.2)
2223
code_teams (~> 1.0)
23-
parse_packwerk
24+
packs
2425
sorbet-runtime
2526
code_teams (1.0.0)
2627
sorbet-runtime
@@ -36,8 +37,10 @@ GEM
3637
minitest (5.16.3)
3738
multi_json (1.15.0)
3839
netrc (0.11.0)
40+
packs (0.0.5)
41+
sorbet-runtime
3942
parallel (1.22.1)
40-
parse_packwerk (0.16.0)
43+
parse_packwerk (0.18.0)
4144
sorbet-runtime
4245
parser (3.1.1.0)
4346
ast (~> 2.4.1)
@@ -76,10 +79,11 @@ GEM
7679
rubocop-ast (>= 1.19.1, < 2.0)
7780
ruby-progressbar (~> 1.7)
7881
unicode-display_width (>= 1.4.0, < 3.0)
79-
rubocop-ast (1.24.0)
82+
rubocop-ast (1.24.1)
8083
parser (>= 3.1.1.0)
81-
rubocop-packs (0.0.30)
84+
rubocop-packs (0.0.33)
8285
activesupport
86+
packs
8387
parse_packwerk
8488
rubocop
8589
rubocop-sorbet

README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,6 @@ PackStats.report_to_datadog!(
3838
# Example: [Pathname.new("./gems")]
3939
#
4040
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,
4841
)
4942
```
5043

lib/pack_stats.rb

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require 'code_teams'
88
require 'code_ownership'
99
require 'pathname'
10+
require 'packs'
1011
require 'pack_stats/private'
1112
require 'pack_stats/private/source_code_file'
1213
require 'pack_stats/private/datadog_reporter'
@@ -27,23 +28,17 @@ module PackStats
2728
].freeze, T::Array[Pathname]
2829
)
2930

30-
DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS = T.let(
31-
[
32-
Pathname.new('packs'),
33-
Pathname.new('packages'),
34-
].freeze, T::Array[Pathname]
35-
)
36-
3731
sig do
3832
params(
3933
datadog_client: Dogapi::Client,
4034
app_name: String,
4135
source_code_pathnames: T::Array[Pathname],
4236
componentized_source_code_locations: T::Array[Pathname],
43-
packaged_source_code_locations: T::Array[Pathname],
4437
report_time: Time,
4538
verbose: T::Boolean,
4639
# See note on get_metrics
40+
packaged_source_code_locations: T.nilable(T::Array[Pathname]),
41+
# See note on get_metrics
4742
use_gusto_legacy_names: T::Boolean
4843
).void
4944
end
@@ -52,16 +47,15 @@ def self.report_to_datadog!(
5247
app_name:,
5348
source_code_pathnames:,
5449
componentized_source_code_locations: DEFAULT_COMPONENTIZED_SOURCE_CODE_LOCATIONS,
55-
packaged_source_code_locations: DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS,
5650
report_time: Time.now, # rubocop:disable Rails/TimeZone
5751
verbose: false,
52+
packaged_source_code_locations: [],
5853
use_gusto_legacy_names: false
5954
)
6055

6156
all_metrics = self.get_metrics(
6257
source_code_pathnames: source_code_pathnames,
6358
componentized_source_code_locations: componentized_source_code_locations,
64-
packaged_source_code_locations: packaged_source_code_locations,
6559
app_name: app_name,
6660
use_gusto_legacy_names: use_gusto_legacy_names,
6761
)
@@ -88,8 +82,9 @@ def self.report_to_datadog!(
8882
params(
8983
source_code_pathnames: T::Array[Pathname],
9084
componentized_source_code_locations: T::Array[Pathname],
91-
packaged_source_code_locations: T::Array[Pathname],
9285
app_name: String,
86+
# This field is deprecated
87+
packaged_source_code_locations: T.nilable(T::Array[Pathname]),
9388
# It is not recommended to set this to true.
9489
# Gusto uses this to preserve historical trends in Dashboards as the names of
9590
# things changed, but new dashboards can use names that better match current tooling conventions.
@@ -100,15 +95,14 @@ def self.report_to_datadog!(
10095
def self.get_metrics(
10196
source_code_pathnames:,
10297
componentized_source_code_locations:,
103-
packaged_source_code_locations:,
10498
app_name:,
99+
packaged_source_code_locations: [],
105100
use_gusto_legacy_names: false
106101
)
107102
all_metrics = Private::DatadogReporter.get_metrics(
108103
source_code_files: source_code_files(
109104
source_code_pathnames: source_code_pathnames,
110105
componentized_source_code_locations: componentized_source_code_locations,
111-
packaged_source_code_locations: packaged_source_code_locations
112106
),
113107
app_name: app_name
114108
)
@@ -124,18 +118,21 @@ def self.get_metrics(
124118
params(
125119
source_code_pathnames: T::Array[Pathname],
126120
componentized_source_code_locations: T::Array[Pathname],
127-
packaged_source_code_locations: T::Array[Pathname]
128121
).returns(T::Array[Private::SourceCodeFile])
129122
end
130123
def self.source_code_files(
131124
source_code_pathnames:,
132-
componentized_source_code_locations:,
133-
packaged_source_code_locations:
125+
componentized_source_code_locations:
134126
)
135127

136128
# Sorbet has the wrong signatures for `Pathname#find`, whoops!
137129
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)
139136

140137
source_code_pathnames.map do |pathname|
141138
componentized_file = componentized_file_set.include?(pathname)

lib/pack_stats/private.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ def self.convert_metrics_to_legacy(metrics)
4848
new_metric
4949
end
5050
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
5158
end
5259

5360
private_constant :Private

lib/pack_stats/private/metrics.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def self.tags_for_package(package, app_name)
1717
[
1818
Tag.new(key: 'package', value: humanized_package_name(package.name)),
1919
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)),
2121
]
2222
end
2323

lib/pack_stats/private/metrics/packages.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def self.get_package_metrics(packages, app_name)
6363
raise StandardError, "Could not find matching package #{to_package_name}"
6464
end
6565

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))
6767
all_metrics << GaugeMetric.for('by_package.outbound_dependency_violations.per_package.count', Metrics.file_count(violations.select(&:dependency?)), tags)
6868
all_metrics << GaugeMetric.for('by_package.outbound_privacy_violations.per_package.count', Metrics.file_count(violations.select(&:privacy?)), tags)
6969
end
@@ -89,7 +89,8 @@ def self.get_package_metrics(packages, app_name)
8989
raise StandardError, "Could not find matching package #{explicit_dependency}"
9090
end
9191

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)
9394
all_metrics << GaugeMetric.for('by_package.outbound_explicit_dependencies.per_package.count', 1, tags)
9495
end
9596

lib/pack_stats/private/metrics/packages_by_team.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def self.get_package_metrics_by_team(all_packages, app_name)
1717
all_metrics = T.let([], T::Array[GaugeMetric])
1818
app_level_tag = Tag.for('app', app_name)
1919

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|
2122
# We look at `all_packages` because we care about ALL inbound violations across all teams
2223
inbound_violations_by_package = all_packages.flat_map(&:violations).group_by(&:to_package_name)
2324

@@ -51,7 +52,7 @@ def self.get_package_metrics_by_team(all_packages, app_name)
5152
raise StandardError, "Could not find matching package #{violation.to_package_name}"
5253
end
5354

54-
CodeOwnership.for_package(to_package)&.name
55+
Private.package_owner(to_package)
5556
end
5657

5758
grouped_outbound_violations.each do |to_team_name, violations|

pack_stats.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |spec|
22
spec.name = 'pack_stats'
3-
spec.version = '0.0.2'
3+
spec.version = '0.0.3'
44
spec.authors = ['Gusto Engineers']
55
spec.email = ['dev@gusto.com']
66

@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
2929
spec.add_dependency 'code_teams'
3030
spec.add_dependency 'code_ownership'
3131
spec.add_dependency 'dogapi'
32+
spec.add_dependency 'packs'
3233
spec.add_dependency 'parse_packwerk'
3334
spec.add_dependency 'sorbet-runtime'
3435
spec.add_dependency 'rubocop-packs'

0 commit comments

Comments
 (0)