From 1d68a7b68c3a4a18a0621adf0f6213f1a01ef9eb Mon Sep 17 00:00:00 2001 From: Nikita Bulaj Date: Tue, 18 Oct 2016 18:55:49 +0300 Subject: [PATCH 1/3] Fix info for empty diff, readme update --- README.md | 6 ++++++ lib/capistrano-chewy/diff_parser.rb | 4 ++++ lib/capistrano/tasks/chewy.rake | 10 ++++++---- spec/diff_parser_spec.rb | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index da6130c..6546c38 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ Or install it yourself as: $ gem install capistrano-chewy ``` +If you want to use the latest version from the `master`, then add the following line to your Gemfile: + +```ruby +gem 'capistrano-chewy', git: 'https://github.com/nbulaj/capistrano-chewy.git' +``` + ## Usage Require it in your `Capfile`: diff --git a/lib/capistrano-chewy/diff_parser.rb b/lib/capistrano-chewy/diff_parser.rb index 90239bf..5e441e1 100644 --- a/lib/capistrano-chewy/diff_parser.rb +++ b/lib/capistrano-chewy/diff_parser.rb @@ -8,6 +8,10 @@ def initialize @changed = [] @added = [] end + + def empty? + [@removed, @changed, @added].all?(&:empty?) + end end CHANGED_FILE_PATTERN = /Files\s+.+\s+and\s+(.+)\s+differ/i diff --git a/lib/capistrano/tasks/chewy.rake b/lib/capistrano/tasks/chewy.rake index 82841a0..364a9d1 100644 --- a/lib/capistrano/tasks/chewy.rake +++ b/lib/capistrano/tasks/chewy.rake @@ -107,21 +107,23 @@ namespace :deploy do # -Z, --ignore-trailing-space ignore white space at line end # -B, --ignore-blank-lines ignore changes where lines are all blank # - indexes_diff = capture(:diff, "-qZEB #{chewy_release_path} #{chewy_current_path}", raise_on_non_zero_exit: false) + diff_args = "-qZEB #{chewy_release_path} #{chewy_current_path}" + indexes_diff = capture :diff, diff_args, raise_on_non_zero_exit: false + changes = ::CapistranoChewy::DiffParser.parse(indexes_diff, chewy_current_path, chewy_release_path) # If diff is empty then indices have not changed - if indexes_diff.nil? || indexes_diff.strip.empty? + if changes.empty? info 'Skipping `deploy:chewy:rebuilding` (nothing changed in the Chewy path)' else within release_path do with rails_env: fetch(:chewy_env) do - changes = ::CapistranoChewy::DiffParser.parse(indexes_diff, chewy_current_path, chewy_release_path) - # Reset indexes that were changed or added indexes_to_reset = changes.changed.concat(changes.added) if indexes_to_reset.any? indexes = indexes_to_reset.map { |file| File.basename(file).gsub('_index.rb', '') }.join(',') + + info "Modified or new indexes: #{indexes}" execute :rake, "chewy:reset[#{indexes}]" end diff --git a/spec/diff_parser_spec.rb b/spec/diff_parser_spec.rb index c632b63..0f4a113 100644 --- a/spec/diff_parser_spec.rb +++ b/spec/diff_parser_spec.rb @@ -4,6 +4,7 @@ let(:current_path) { '/project/1/app/chewy' } let(:release_path) { '/project/2/app/chewy' } + # TODO: make a real diff let(:full_diff) do "Files #{current_path}/accounts_index.rb and #{release_path}/accounts_index.rb differ\n" \ "Files #{current_path}/posts_index.rb and #{release_path}/posts_index.rb differ\n" \ @@ -20,6 +21,8 @@ expect(result.changed).to eq(["#{release_path}/accounts_index.rb", "#{release_path}/posts_index.rb", "#{release_path}/comments_index.rb"]) expect(result.added).to eq(["#{release_path}/applications_index.rb"]) expect(result.removed).to eq(["#{current_path}/users_index.rb"]) + + expect(result.empty?).to be_falsey end end @@ -30,6 +33,8 @@ expect(result.changed).to be_empty expect(result.added).to be_empty expect(result.removed).to be_empty + + expect(result.empty?).to be_truthy end end From 008ebaab5944add4be71369064bab5b2c353a323 Mon Sep 17 00:00:00 2001 From: Nikita Bulaj Date: Tue, 18 Oct 2016 23:47:14 +0300 Subject: [PATCH 2/3] Delete removed indexes --- README.md | 4 +-- lib/capistrano/tasks/chewy.rake | 51 +++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index b7fe725..6a55aac 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ cap deploy:chewy:update # Updates data to all the indexes cap deploy:chewy:update[indexes] # Updates data to the specified indexes ``` -By default `Capistrano::Chewy` adds `deploy:chewy:rebuild` task after `deploy:updated`. +By default `Capistrano::Chewy` adds `deploy:chewy:rebuild` task after `deploy:updated` and `deploy:chewy:rollback_indexes` after `deploy:reverted`. If you want to change it, then you need to disable default gem hooks by setting `chewy_default_hooks` to `false` in your deployment config and manually define the order of the tasks. ## Configuration @@ -77,8 +77,8 @@ set :chewy_conditionally_reset, false # Reset only modified Chewy indexes, true set :chewy_path, 'app/my_indexes' # Path to Chewy indexes, 'app/chewy' by default set :chewy_env, :chewy_production # Environment variable for Chewy, equal to RAILS_ENV by default set :chewy_role, :web # Chewy role, :app by default -set :chewy_skip, true # Skip processing Chewy indexes during deploy, false by default set :chewy_default_hooks, false # Add default capistrano-chewy hooks to your deploy flow, true by default +set :chewy_delete_removed_indexes, false # Delete indexes which have been removed ``` ## Contributing diff --git a/lib/capistrano/tasks/chewy.rake b/lib/capistrano/tasks/chewy.rake index 364a9d1..498bd05 100644 --- a/lib/capistrano/tasks/chewy.rake +++ b/lib/capistrano/tasks/chewy.rake @@ -1,11 +1,11 @@ namespace :load do task :defaults do + set :chewy_default_hooks, -> { true } set :chewy_conditionally_reset, -> { true } set :chewy_path, -> { 'app/chewy' } set :chewy_env, -> { fetch(:rails_env, fetch(:stage)) } set :chewy_role, -> { :app } - set :chewy_skip, -> { false } - set :chewy_default_hooks, -> { true } + set :chewy_delete_removed_indexes, -> { true } end end @@ -14,6 +14,10 @@ namespace :deploy do invoke :'deploy:chewy:add_default_hooks' if fetch(:chewy_default_hooks) end + after :reverted, :rollback_chewy_indexes do + invoke :'deploy:chewy:rollback_indexes' if fetch(:chewy_default_hooks) + end + namespace :chewy do # Adds default Capistrano::Chewy hooks to the deploy flow task :add_default_hooks do @@ -56,15 +60,15 @@ namespace :deploy do end end + desc 'Rollback indexes on deployment rollback' + task :rollback_indexes do + # TODO + end + # Smart rebuild of modified Chewy indexes desc 'Reset Chewy indexes if they have been added, changed or removed' task :rebuild do on roles fetch(:chewy_role) do - if fetch(:chewy_skip) - info 'Skipping task according to the deploy settings' - exit 0 - end - info "Checking Chewy directory (#{fetch(:chewy_path)})" chewy_path = File.join(release_path, fetch(:chewy_path)) @@ -91,11 +95,6 @@ namespace :deploy do desc 'Runs smart Chewy indexes rebuilding (only for changed files)' task :rebuilding do on roles fetch(:chewy_role) do - if fetch(:chewy_skip) - info 'Skipping task according to the deploy settings' - exit 0 - end - chewy_path = fetch(:chewy_path) info "Checking changes in #{chewy_path}" @@ -114,20 +113,34 @@ namespace :deploy do # If diff is empty then indices have not changed if changes.empty? info 'Skipping `deploy:chewy:rebuilding` (nothing changed in the Chewy path)' + exit 0 else - within release_path do - with rails_env: fetch(:chewy_env) do - # Reset indexes that were changed or added - indexes_to_reset = changes.changed.concat(changes.added) + indexes_to_reset = changes.changed.concat(changes.added) + indexes_to_delete = changes.removed - if indexes_to_reset.any? - indexes = indexes_to_reset.map { |file| File.basename(file).gsub('_index.rb', '') }.join(',') + # Reset indexes which have been modified or added + if indexes_to_reset.any? + indexes = indexes_to_reset.map { |file| File.basename(file, '_index.rb') }.join(',') + within release_path do + with rails_env: fetch(:chewy_env) do info "Modified or new indexes: #{indexes}" execute :rake, "chewy:reset[#{indexes}]" end + end + end - # TODO: destroy removed indexes? + # Delete indexes which have been removed + if indexes_to_delete.any? && fetch(:chewy_delete_removed_indexes) + indexes = indexes_to_delete.map { |file| File.basename(file, '.rb').camelize } + runner_code = indexes.map { |index| "#{index}.delete"}.join("\n") + + # Removed index files exists only in the old (current) release + within current_path do + with rails_env: fetch(:chewy_env) do + info "Indexes to remove: #{indexes.join(',')}" + execute :rails, "runner '#{runner_code}'" + end end end end From e9aff7e2b9729249be987b808e52e7afc0e3656e Mon Sep 17 00:00:00 2001 From: Nikita Bulaj Date: Wed, 19 Oct 2016 10:02:28 +0300 Subject: [PATCH 3/3] Delete of removed indexes, README update, fixes --- README.md | 8 +++++--- ...ostgres.gemspec => capistrano-chewy.gemspec | 4 ++-- lib/capistrano-chewy/diff_parser.rb | 2 +- lib/capistrano-chewy/version.rb | 2 +- lib/capistrano/tasks/chewy.rake | 18 +++++------------- spec/diff_parser_spec.rb | 10 ++++++++-- 6 files changed, 22 insertions(+), 22 deletions(-) rename capistrano3-postgres.gemspec => capistrano-chewy.gemspec (92%) diff --git a/README.md b/README.md index 6a55aac..f7bceea 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Manage and continuously rebuild your ElasticSearch indexes with [Chewy](https://github.com/toptal/chewy/) and [Capistrano](https://github.com/capistrano/capistrano) v3. -`Capistrano::Chewy` gem adds automatic conditionally reset only modified Chewy indexes to your deploy flow so you do not have to build them manually. +`Capistrano::Chewy` gem adds automatic conditionally reset of only modified Chewy indexes and the removal of deleted index files to your deploy flow so you do not have to do it manually. Moreover, it adds the possibility of manual index management with the base Chewy tasks on the remote server. ## Requirements @@ -51,7 +51,9 @@ Require it in your `Capfile`: ```ruby # Capfile +... require 'capistrano/chewy' +... ``` then you can use `cap -T` to list `Capistrano::Chewy` tasks: @@ -64,7 +66,7 @@ cap deploy:chewy:update # Updates data to all the indexes cap deploy:chewy:update[indexes] # Updates data to the specified indexes ``` -By default `Capistrano::Chewy` adds `deploy:chewy:rebuild` task after `deploy:updated` and `deploy:chewy:rollback_indexes` after `deploy:reverted`. +By default `Capistrano::Chewy` adds `deploy:chewy:rebuild` task after `deploy:updated` and `deploy:reverted`. If you want to change it, then you need to disable default gem hooks by setting `chewy_default_hooks` to `false` in your deployment config and manually define the order of the tasks. ## Configuration @@ -78,7 +80,7 @@ set :chewy_path, 'app/my_indexes' # Path to Chewy indexes, 'app/chewy' by defaul set :chewy_env, :chewy_production # Environment variable for Chewy, equal to RAILS_ENV by default set :chewy_role, :web # Chewy role, :app by default set :chewy_default_hooks, false # Add default capistrano-chewy hooks to your deploy flow, true by default -set :chewy_delete_removed_indexes, false # Delete indexes which have been removed +set :chewy_delete_removed_indexes, false # Delete indexes which files have been deleted, true by default ``` ## Contributing diff --git a/capistrano3-postgres.gemspec b/capistrano-chewy.gemspec similarity index 92% rename from capistrano3-postgres.gemspec rename to capistrano-chewy.gemspec index 1d6a4c8..a26c1a3 100644 --- a/capistrano3-postgres.gemspec +++ b/capistrano-chewy.gemspec @@ -7,8 +7,8 @@ Gem::Specification.new do |spec| spec.name = 'capistrano-chewy' spec.version = CapistranoChewy.gem_version spec.authors = ['Nikita Bulai'] - spec.date = '2016-10-18' - spec.email = ['bulainikita@gmail.com'] + spec.date = '2016-10-19' + spec.email = ['bulajnikita@gmail.com'] spec.summary = 'Manage and continuously rebuild your ElasticSearch indexes with Chewy and Capistrano' spec.description = 'Manage and continuously rebuild your ElasticSearch indexes with Chewy and Capistrano v3.' spec.homepage = 'https://github.com/nbulaj/capistrano-chewy' diff --git a/lib/capistrano-chewy/diff_parser.rb b/lib/capistrano-chewy/diff_parser.rb index 5e441e1..06a1440 100644 --- a/lib/capistrano-chewy/diff_parser.rb +++ b/lib/capistrano-chewy/diff_parser.rb @@ -19,7 +19,7 @@ def empty? class << self def parse(diff, current_path, release_path) - raise ArgumentError, 'current_path can not be the same as release_path!' if current_path == release_path + return Result.new if current_path == release_path diff.split("\n").each_with_object(Result.new) do |line, result| # File was changed diff --git a/lib/capistrano-chewy/version.rb b/lib/capistrano-chewy/version.rb index 45a3f9c..b9de4d0 100644 --- a/lib/capistrano-chewy/version.rb +++ b/lib/capistrano-chewy/version.rb @@ -5,7 +5,7 @@ def self.gem_version module VERSION MAJOR = 0 - MINOR = 1 + MINOR = 2 TINY = 0 STRING = [MAJOR, MINOR, TINY].compact.join('.') diff --git a/lib/capistrano/tasks/chewy.rake b/lib/capistrano/tasks/chewy.rake index 498bd05..a7b9237 100644 --- a/lib/capistrano/tasks/chewy.rake +++ b/lib/capistrano/tasks/chewy.rake @@ -14,14 +14,11 @@ namespace :deploy do invoke :'deploy:chewy:add_default_hooks' if fetch(:chewy_default_hooks) end - after :reverted, :rollback_chewy_indexes do - invoke :'deploy:chewy:rollback_indexes' if fetch(:chewy_default_hooks) - end - namespace :chewy do # Adds default Capistrano::Chewy hooks to the deploy flow task :add_default_hooks do - after 'deploy:updated', 'deploy:chewy:rebuild' + after :'deploy:updated', 'deploy:chewy:rebuild' + after :'deploy:reverted', 'deploy:chewy:rebuild' end # Default Chewy rake tasks @@ -60,11 +57,6 @@ namespace :deploy do end end - desc 'Rollback indexes on deployment rollback' - task :rollback_indexes do - # TODO - end - # Smart rebuild of modified Chewy indexes desc 'Reset Chewy indexes if they have been added, changed or removed' task :rebuild do @@ -132,13 +124,13 @@ namespace :deploy do # Delete indexes which have been removed if indexes_to_delete.any? && fetch(:chewy_delete_removed_indexes) - indexes = indexes_to_delete.map { |file| File.basename(file, '.rb').camelize } - runner_code = indexes.map { |index| "#{index}.delete"}.join("\n") + indexes = indexes_to_delete.map { |file| File.basename(file, '.rb').camelize }.uniq + runner_code = "[#{indexes.join(', ')}].each(&:delete)" # Removed index files exists only in the old (current) release within current_path do with rails_env: fetch(:chewy_env) do - info "Indexes to remove: #{indexes.join(',')}" + info "Removing indexes: #{indexes.join(',')}" execute :rails, "runner '#{runner_code}'" end end diff --git a/spec/diff_parser_spec.rb b/spec/diff_parser_spec.rb index 0f4a113..a6ebed8 100644 --- a/spec/diff_parser_spec.rb +++ b/spec/diff_parser_spec.rb @@ -39,8 +39,14 @@ end context 'with the same directories' do - it 'raises an error' do - expect { described_class.parse('', current_path, current_path) }.to raise_error(ArgumentError) + it 'returns blank result' do + result = described_class.parse('', current_path, current_path) + + expect(result.changed).to be_empty + expect(result.added).to be_empty + expect(result.removed).to be_empty + + expect(result.empty?).to be_truthy end end end