Skip to content

Commit

Permalink
feat: update output for clean dry run
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Nov 29, 2020
1 parent 0617e9d commit 681a5dd
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 22 deletions.
154 changes: 132 additions & 22 deletions lib/pact_broker/db/clean_incremental.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,20 @@ def version_ids_to_delete
end

def version_ids_to_keep
@version_ids_to_keep ||= keep.collect do | selector |
@version_ids_to_keep ||= selected_versions_to_keep.reduce(&:union)
end

def selected_versions_to_keep
keep.collect do | selector |
PactBroker::Domain::Version.select(:id).for_selector(selector)
end.reduce(&:union)
end
end

def call
require 'pact_broker/db/models'

if dry_run?
to_delete = PactBroker::Domain::Version
.where(id: version_ids_to_delete.select(:id))
.all
.group_by{ | v | v.pacticipant_id }
.each_with_object({}) do | (pacticipant_id, versions), thing |
thing[versions.first.pacticipant.name] = {
count: versions.count,
from_version: {
number: versions.first.number,
created: DateHelper.distance_of_time_in_words(versions.first.created_at, DateTime.now) + " ago",
tags: versions.first.tags.collect(&:name)
},
to_version: {
number: versions.last.number,
created: DateHelper.distance_of_time_in_words(versions.last.created_at, DateTime.now) + " ago",
tags: versions.last.tags.collect(&:name)
}
}
end
{ "to_delete" => to_delete }
dry_run_results
else
before_counts = current_counts
result = PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete
Expand Down Expand Up @@ -102,6 +87,131 @@ def delete_orphan_pact_versions
referenced_pact_version_ids = db[:pact_publications].select(:pact_version_id).union(db[:verifications].select(:pact_version_id))
db[:pact_versions].where(id: referenced_pact_version_ids).invert.delete
end

def version_info(version)
{
"number" => version.number,
"created" => DateHelper.distance_of_time_in_words(version.created_at, DateTime.now) + " ago",
"tags" => version.tags.collect(&:name)
}
end

def dry_run_results
to_delete = dry_run_to_delete
to_keep = dry_run_to_keep

kept_per_selector = keep.collect do | selector |
{
selector: selector.to_hash,
count: PactBroker::Domain::Version.for_selector(selector).count
}
end

pacticipant_results = pacticipants.each_with_object({}) do | pacticipant, results |
results[pacticipant.name] = {
"toDelete" => to_delete[pacticipant.name] || { "count" => 0 },
"toKeep" => to_keep[pacticipant.id]
}
end

total_versions_count = PactBroker::Domain::Version.count
versions_to_keep_count = version_ids_to_keep.count
versions_to_delete_count = version_ids_to_delete.count

{
"counts" => {
"totalVersions" => total_versions_count,
"versionsToDelete" => versions_to_delete_count,
"versionsNotToKeep" => total_versions_count - versions_to_keep_count,
"versionsToKeep" => versions_to_keep_count,
"versionsToKeepBySelector" => kept_per_selector,
},
"versionSummary" => pacticipant_results
}
end

def dry_run_latest_versions_to_keep
latest_undeleted_versions_by_order = PactBroker::Domain::Version.where(id: version_ids_to_delete.select(:id))
.invert
.select_group(:pacticipant_id)
.select_append{ max(order).as(latest_order) }

lv_versions_join = {
Sequel[:lv][:latest_order] => Sequel[:versions][:order],
Sequel[:lv][:pacticipant_id] => Sequel[:versions][:pacticipant_id]
}

PactBroker::Domain::Version
.select_all_qualified
.join(latest_undeleted_versions_by_order, lv_versions_join, { table_alias: :lv })
end

def dry_run_earliest_versions_to_keep
earliest_undeleted_versions_by_order = PactBroker::Domain::Version.where(id: version_ids_to_delete.select(:id))
.invert
.select_group(:pacticipant_id)
.select_append{ min(order).as(first_order) }

ev_versions_join = {
Sequel[:lv][:first_order] => Sequel[:versions][:order],
Sequel[:lv][:pacticipant_id] => Sequel[:versions][:pacticipant_id]
}

PactBroker::Domain::Version
.select_all_qualified
.join(earliest_undeleted_versions_by_order, ev_versions_join, { table_alias: :lv })
end

def dry_run_to_delete
PactBroker::Domain::Version
.where(id: version_ids_to_delete.select(:id))
.all
.group_by{ | v | v.pacticipant_id }
.each_with_object({}) do | (pacticipant_id, versions), thing |
thing[versions.first.pacticipant.name] = {
"count" => versions.count,
"fromVersion" => version_info(versions.first),
"toVersion" => version_info(versions.last)
}
end
end

def dry_run_to_keep
latest_to_keep = dry_run_latest_versions_to_keep.eager(:tags).each_with_object({}) do | version, r |
r[version.pacticipant_id] = {
"firstVersion" => version_info(version)
}
end

earliest_to_keep = dry_run_earliest_versions_to_keep.eager(:tags).each_with_object({}) do | version, r |
r[version.pacticipant_id] = {
"latestVersion" => version_info(version)
}
end

counts = counts_to_keep

pacticipants.collect(&:id).each_with_object({}) do | pacticipant_id, results |
results[pacticipant_id] = { "count" => counts[pacticipant_id] || 0 }
.merge(earliest_to_keep[pacticipant_id] || {})
.merge(latest_to_keep[pacticipant_id] || {})
end
end

def counts_to_keep
db[:versions].where(id: version_ids_to_delete.select(:id))
.invert
.select_group(:pacticipant_id)
.select_append{ count(1).as(count) }
.all
.each_with_object({}) do | row, counts |
counts[row[:pacticipant_id]] = row[:count]
end
end

def pacticipants
@pacticipants ||= PactBroker::Domain::Pacticipant.order_ignore_case(:name).all
end
end
end
end
24 changes: 24 additions & 0 deletions lib/pact_broker/domain/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ class Tag < Sequel::Model
dataset_module do
include PactBroker::Repositories::Helpers

def latest_tags
tags_versions_join = {
Sequel[:tags][:version_id] => Sequel[:versions][:id],
}

latest_tags_versions_join = {
Sequel[:latest_tags][:name] => Sequel[:tags][:name],
Sequel[:latest_tags][:latest_order] => Sequel[:versions][:order],
Sequel[:latest_tags][:pacticipant_id] => Sequel[:versions][:pacticipant_id],
}

latest_tags = PactBroker::Domain::Tag
.select_group(Sequel[:tags][:name], Sequel[:versions][:pacticipant_id])
.select_append{ max(order).as(latest_order) }
.join(:versions, tags_versions_join)

PactBroker::Domain::Tag
.select_all_qualified
.join(:versions,
{ Sequel[:tags][:version_id] => Sequel[:versions][:id] }
)
.join(latest_tags, latest_tags_versions_join, { table_alias: :latest_tags })
end

# Does NOT care about whether or not there is a pact publication
# for the version
def latest_tags_for_pacticipant_ids(pacticipant_ids)
Expand Down
100 changes: 100 additions & 0 deletions spec/fixtures/approvals/clean_incremental_dry_run.approved.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"counts": {
"totalVersions": 9,
"versionsToDelete": 3,
"versionsNotToKeep": 6,
"versionsToKeep": 3,
"versionsToKeepBySelector": [
{
"selector": {
"tag": "prod"
},
"count": 2
},
{
"selector": {
"tag": "dev",
"latest": true
},
"count": 1
}
]
},
"versionSummary": {
"Bar": {
"toDelete": {
"count": 0
},
"toKeep": {
"count": 0
}
},
"Foo": {
"toDelete": {
"count": 3,
"fromVersion": {
"number": "2",
"created": "1 day ago",
"tags": [

]
},
"toVersion": {
"number": "6",
"created": "5 days ago",
"tags": [
"foo"
]
}
},
"toKeep": {
"count": 4,
"latestVersion": {
"number": "1",
"created": "less than a minute ago",
"tags": [
"dev",
"prod"
]
},
"firstVersion": {
"number": "7",
"created": "6 days ago",
"tags": [

]
}
}
},
"Meep": {
"toDelete": {
"count": 0
},
"toKeep": {
"count": 2,
"latestVersion": {
"number": "2",
"created": "6 days ago",
"tags": [
"foop"
]
},
"firstVersion": {
"number": "3",
"created": "6 days ago",
"tags": [
"blah"
]
}
}
},
"Moop": {
"toDelete": {
"count": 0
},
"toKeep": {
"count": 0
}
}
}
}
8 changes: 8 additions & 0 deletions spec/lib/pact_broker/db/clean_incremental_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,20 @@ def pact_publication_count_for(consumer_name, version_number)
context "when dry_run: true" do
before do
td.create_pact_with_hierarchy("Meep", "2", "Moop")
.create_consumer_version_tag("foop")
.create_consumer_version("3")
.create_consumer_version_tag("blah")
end

let(:dry_run) { true }

it "doesn't delete anything" do
expect { subject }.to_not change { PactBroker::Domain::Version.count }
end

it "returns info on what will be deleted" do
Approvals.verify(subject, :name => 'clean_incremental_dry_run', format: :json)
end
end
end

Expand Down

0 comments on commit 681a5dd

Please sign in to comment.