diff --git a/lib/pact_broker/db/clean_incremental.rb b/lib/pact_broker/db/clean_incremental.rb index e03e02f79..0c6164ab5 100644 --- a/lib/pact_broker/db/clean_incremental.rb +++ b/lib/pact_broker/db/clean_incremental.rb @@ -1,5 +1,7 @@ require 'pact_broker/logging' require 'pact_broker/matrix/unresolved_selector' +require 'pact_broker/date_helper' + module PactBroker module DB @@ -47,16 +49,37 @@ def version_ids_to_keep end def call - require 'pact_broker/domain/version' - before_counts = current_counts - - result = PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete - delete_orphan_pact_versions - - after_counts = current_counts - - TABLES.each_with_object({}) do | table_name, comparison_counts | - comparison_counts[table_name.to_s] = { "deleted" => before_counts[table_name] - after_counts[table_name], "kept" => after_counts[table_name] } + require 'pact_broker/db/models' + + if dry_run? + 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 + else + before_counts = current_counts + result = PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete + delete_orphan_pact_versions + after_counts = current_counts + + TABLES.each_with_object({}) do | table_name, comparison_counts | + comparison_counts[table_name.to_s] = { "deleted" => before_counts[table_name] - after_counts[table_name], "kept" => after_counts[table_name] } + end end end @@ -70,6 +93,10 @@ def current_counts end end + def dry_run? + options[:dry_run] + end + 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 diff --git a/lib/pact_broker/tasks/clean_task.rb b/lib/pact_broker/tasks/clean_task.rb index c3f8e57a6..04f161887 100644 --- a/lib/pact_broker/tasks/clean_task.rb +++ b/lib/pact_broker/tasks/clean_task.rb @@ -6,10 +6,12 @@ class CleanTask < ::Rake::TaskLib attr_reader :keep_version_selectors attr_accessor :version_deletion_limit attr_accessor :logger + attr_accessor :dry_run def initialize &block require 'pact_broker/db/clean_incremental' @version_deletion_limit = 1000 + @dry_run = false @keep_version_selectors = PactBroker::DB::CleanIncremental::DEFAULT_KEEP_SELECTORS rake_task &block end @@ -44,14 +46,14 @@ def rake_task &block start_time = Time.now results = PactBroker::DB::CleanIncremental.call( - database_connection, keep: keep_version_selectors, limit: version_deletion_limit, logger: logger) + database_connection, keep: keep_version_selectors, limit: version_deletion_limit, logger: logger, dry_run: dry_run) end_time = Time.now elapsed_seconds = (end_time - start_time).to_i output "Results (#{elapsed_seconds} seconds)", results end def output string, payload = {} - logger ? logger.info(string, payload: payload) : puts("#{string} #{payload}") + logger ? logger.info(string, payload: payload) : puts("#{string} #{payload.to_json}") end end end diff --git a/spec/lib/pact_broker/db/clean_incremental_spec.rb b/spec/lib/pact_broker/db/clean_incremental_spec.rb index c7e2825c7..67fb04222 100644 --- a/spec/lib/pact_broker/db/clean_incremental_spec.rb +++ b/spec/lib/pact_broker/db/clean_incremental_spec.rb @@ -15,15 +15,21 @@ def pact_publication_count_for(consumer_name, version_number) let(:options) { {} } let(:db) { PactBroker::DB.connection } - subject { CleanIncremental.call(PactBroker::DB.connection, options) } + let(:latest_dev_selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "dev", latest: true) } let(:all_prod_selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "prod") } let(:limit) { 3 } + let(:dry_run) { false } + + subject { CleanIncremental.call(PactBroker::DB.connection, options) } describe ".call"do context "when there are specified versions to keep" do before do td.create_pact_with_hierarchy("Foo", "1", "Bar") + .create_webhook + .create_triggered_webhook + .create_webhook_execution .create_consumer_version_tag("prod").comment("keep as one of prod") .create_consumer_version_tag("dev") .add_day @@ -45,7 +51,7 @@ def pact_publication_count_for(consumer_name, version_number) .create_pact end - let(:options) { { keep: [all_prod_selector, latest_dev_selector], limit: limit } } + let(:options) { { keep: [all_prod_selector, latest_dev_selector], limit: limit, dry_run: dry_run } } it "does not delete the consumer versions specified" do expect(PactBroker::Domain::Version.where(number: "1").count).to be 1 @@ -64,8 +70,20 @@ def pact_publication_count_for(consumer_name, version_number) expect(PactBroker::Domain::Version.where(number: "6").count).to be 0 expect(PactBroker::Domain::Version.where(number: "7").count).to be 1 end + + context "when dry_run: true" do + before do + td.create_pact_with_hierarchy("Meep", "2", "Moop") + end + let(:dry_run) { true } + + it "doesn't delete anything" do + expect { subject }.to_not change { PactBroker::Domain::Version.count } + end + end end + context "with orphan pact versions" do before do # Create a pact that will not be deleted