Skip to content

Commit

Permalink
Use packs to determine packaged paths and for testing (#28)
Browse files Browse the repository at this point in the history
* Use Packs to determine packaged file locations

* use packs/rspec/support
  • Loading branch information
Alex Evanczuk committed Dec 29, 2022
1 parent 5a1921a commit c790934
Show file tree
Hide file tree
Showing 14 changed files with 693 additions and 425 deletions.
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

0 comments on commit c790934

Please sign in to comment.