Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
PATH
remote: .
specs:
pack_stats (0.0.2)
pack_stats (0.0.3)
code_ownership
code_teams
dogapi
packs
parse_packwerk
rubocop-packs
sorbet-runtime
Expand All @@ -18,9 +19,9 @@ GEM
minitest (>= 5.1)
tzinfo (~> 2.0)
ast (2.4.2)
code_ownership (1.29.1)
code_ownership (1.29.2)
code_teams (~> 1.0)
parse_packwerk
packs
sorbet-runtime
code_teams (1.0.0)
sorbet-runtime
Expand All @@ -36,8 +37,10 @@ GEM
minitest (5.16.3)
multi_json (1.15.0)
netrc (0.11.0)
packs (0.0.5)
sorbet-runtime
parallel (1.22.1)
parse_packwerk (0.16.0)
parse_packwerk (0.18.0)
sorbet-runtime
parser (3.1.1.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -76,10 +79,11 @@ GEM
rubocop-ast (>= 1.19.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.24.0)
rubocop-ast (1.24.1)
parser (>= 3.1.1.0)
rubocop-packs (0.0.30)
rubocop-packs (0.0.33)
activesupport
packs
parse_packwerk
rubocop
rubocop-sorbet
Expand Down
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ PackStats.report_to_datadog!(
# Example: [Pathname.new("./gems")]
#
componentized_source_code_locations: componentized_source_code_locations,
#
# A file is determined to be packaged if it exists in any of these directories.
# This is an array of `Pathname`. `Pathname` can be relative or absolute paths.
#
# Example: [Pathname.new("./packs")]
#
packaged_source_code_locations: packaged_source_code_locations,
)
```

Expand Down
31 changes: 14 additions & 17 deletions lib/pack_stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'code_teams'
require 'code_ownership'
require 'pathname'
require 'packs'
require 'pack_stats/private'
require 'pack_stats/private/source_code_file'
require 'pack_stats/private/datadog_reporter'
Expand All @@ -27,23 +28,17 @@ module PackStats
].freeze, T::Array[Pathname]
)

DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS = T.let(
[
Pathname.new('packs'),
Pathname.new('packages'),
].freeze, T::Array[Pathname]
)

sig do
params(
datadog_client: Dogapi::Client,
app_name: String,
source_code_pathnames: T::Array[Pathname],
componentized_source_code_locations: T::Array[Pathname],
packaged_source_code_locations: T::Array[Pathname],
report_time: Time,
verbose: T::Boolean,
# See note on get_metrics
packaged_source_code_locations: T.nilable(T::Array[Pathname]),
# See note on get_metrics
use_gusto_legacy_names: T::Boolean
).void
end
Expand All @@ -52,16 +47,15 @@ def self.report_to_datadog!(
app_name:,
source_code_pathnames:,
componentized_source_code_locations: DEFAULT_COMPONENTIZED_SOURCE_CODE_LOCATIONS,
packaged_source_code_locations: DEFAULT_PACKAGED_SOURCE_CODE_LOCATIONS,
report_time: Time.now, # rubocop:disable Rails/TimeZone
verbose: false,
packaged_source_code_locations: [],
use_gusto_legacy_names: false
)

all_metrics = self.get_metrics(
source_code_pathnames: source_code_pathnames,
componentized_source_code_locations: componentized_source_code_locations,
packaged_source_code_locations: packaged_source_code_locations,
app_name: app_name,
use_gusto_legacy_names: use_gusto_legacy_names,
)
Expand All @@ -88,8 +82,9 @@ def self.report_to_datadog!(
params(
source_code_pathnames: T::Array[Pathname],
componentized_source_code_locations: T::Array[Pathname],
packaged_source_code_locations: T::Array[Pathname],
app_name: String,
# This field is deprecated
packaged_source_code_locations: T.nilable(T::Array[Pathname]),
# It is not recommended to set this to true.
# Gusto uses this to preserve historical trends in Dashboards as the names of
# things changed, but new dashboards can use names that better match current tooling conventions.
Expand All @@ -100,15 +95,14 @@ def self.report_to_datadog!(
def self.get_metrics(
source_code_pathnames:,
componentized_source_code_locations:,
packaged_source_code_locations:,
app_name:,
packaged_source_code_locations: [],
use_gusto_legacy_names: false
)
all_metrics = Private::DatadogReporter.get_metrics(
source_code_files: source_code_files(
source_code_pathnames: source_code_pathnames,
componentized_source_code_locations: componentized_source_code_locations,
packaged_source_code_locations: packaged_source_code_locations
),
app_name: app_name
)
Expand All @@ -124,18 +118,21 @@ def self.get_metrics(
params(
source_code_pathnames: T::Array[Pathname],
componentized_source_code_locations: T::Array[Pathname],
packaged_source_code_locations: T::Array[Pathname]
).returns(T::Array[Private::SourceCodeFile])
end
def self.source_code_files(
source_code_pathnames:,
componentized_source_code_locations:,
packaged_source_code_locations:
componentized_source_code_locations:
)

# Sorbet has the wrong signatures for `Pathname#find`, whoops!
componentized_file_set = Set.new(componentized_source_code_locations.select(&:exist?).flat_map { |pathname| T.unsafe(pathname).find.to_a })
packaged_file_set = Set.new(packaged_source_code_locations.select(&:exist?).flat_map { |pathname| T.unsafe(pathname).find.to_a })

packaged_file_set = Packs.all.flat_map do |pack|
pack.relative_path.find.to_a
end

packaged_file_set = Set.new(packaged_file_set)

source_code_pathnames.map do |pathname|
componentized_file = componentized_file_set.include?(pathname)
Expand Down
7 changes: 7 additions & 0 deletions lib/pack_stats/private.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ def self.convert_metrics_to_legacy(metrics)
new_metric
end
end

sig { params(package: ParsePackwerk::Package).returns(T.nilable(String) )}
def self.package_owner(package)
pack = Packs.find(package.name)
return nil if pack.nil?
CodeOwnership.for_package(pack)&.name
end
end

private_constant :Private
Expand Down
2 changes: 1 addition & 1 deletion lib/pack_stats/private/metrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def self.tags_for_package(package, app_name)
[
Tag.new(key: 'package', value: humanized_package_name(package.name)),
Tag.new(key: 'app', value: app_name),
*Metrics.tags_for_team(CodeOwnership.for_package(package)&.name),
*Metrics.tags_for_team(Private.package_owner(package)),
]
end

Expand Down
5 changes: 3 additions & 2 deletions lib/pack_stats/private/metrics/packages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def self.get_package_metrics(packages, app_name)
raise StandardError, "Could not find matching package #{to_package_name}"
end

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)
tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(to_package_name))] + Metrics.tags_for_to_team(Private.package_owner(to_package))
all_metrics << GaugeMetric.for('by_package.outbound_dependency_violations.per_package.count', Metrics.file_count(violations.select(&:dependency?)), tags)
all_metrics << GaugeMetric.for('by_package.outbound_privacy_violations.per_package.count', Metrics.file_count(violations.select(&:privacy?)), tags)
end
Expand All @@ -89,7 +89,8 @@ def self.get_package_metrics(packages, app_name)
raise StandardError, "Could not find matching package #{explicit_dependency}"
end

tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(explicit_dependency))] + Metrics.tags_for_to_team(CodeOwnership.for_package(to_package)&.name)
owner = Private.package_owner(to_package)
tags = package_tags + [Tag.for('to_package', Metrics.humanized_package_name(explicit_dependency))] + Metrics.tags_for_to_team(owner)
all_metrics << GaugeMetric.for('by_package.outbound_explicit_dependencies.per_package.count', 1, tags)
end

Expand Down
5 changes: 3 additions & 2 deletions lib/pack_stats/private/metrics/packages_by_team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def self.get_package_metrics_by_team(all_packages, app_name)
all_metrics = T.let([], T::Array[GaugeMetric])
app_level_tag = Tag.for('app', app_name)

all_packages.group_by { |package| CodeOwnership.for_package(package)&.name }.each do |team_name, packages_by_team|

all_packages.group_by { |package| Private.package_owner(package) }.each do |team_name, packages_by_team|
# We look at `all_packages` because we care about ALL inbound violations across all teams
inbound_violations_by_package = all_packages.flat_map(&:violations).group_by(&:to_package_name)

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

CodeOwnership.for_package(to_package)&.name
Private.package_owner(to_package)
end

grouped_outbound_violations.each do |to_team_name, violations|
Expand Down
3 changes: 2 additions & 1 deletion pack_stats.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = 'pack_stats'
spec.version = '0.0.2'
spec.version = '0.0.3'
spec.authors = ['Gusto Engineers']
spec.email = ['dev@gusto.com']

Expand Down Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'code_teams'
spec.add_dependency 'code_ownership'
spec.add_dependency 'dogapi'
spec.add_dependency 'packs'
spec.add_dependency 'parse_packwerk'
spec.add_dependency 'sorbet-runtime'
spec.add_dependency 'rubocop-packs'
Expand Down
Loading