capistrano-chewy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 36801dffebe67a59da0de98084f1c2775d47371f
4
+ data.tar.gz: 50afbaef407413dd996110e7dc946690b8f63af9
5
+ SHA512:
6
+ metadata.gz: ee2759d696d557a1e858347dbc4c854b4d705de2447d31145c205e1ba7486cd2ff945839e461a1825254a88d6667850f46b1481d1e9bd5f85f02b15856574987
7
+ data.tar.gz: edf506dd5325071b2b06c28a3f9cac42d16bfea928029472117319da29551e8dda7b8c417ea5dc6ba41c16bf0450f0e866c6a88c8891d651cb1e73aa0a878971
data/.gitignore ADDED
@@ -0,0 +1,52 @@
1
+ *.gem
2
+ .idea
3
+ *.rbc
4
+ /.config
5
+ /coverage/
6
+ /InstalledFiles
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/examples.txt
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+ Gemfile.lock
14
+
15
+ # Used by dotenv library to load environment variables.
16
+ # .env
17
+
18
+ ## Specific to RubyMotion:
19
+ .dat*
20
+ .repl_history
21
+ build/
22
+ *.bridgesupport
23
+ build-iPhoneOS/
24
+ build-iPhoneSimulator/
25
+
26
+ ## Specific to RubyMotion (use of CocoaPods):
27
+ #
28
+ # We recommend against adding the Pods directory to your .gitignore. However
29
+ # you should judge for yourself, the pros and cons are mentioned at:
30
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
31
+ #
32
+ # vendor/Pods/
33
+
34
+ ## Documentation cache and generated files:
35
+ /.yardoc/
36
+ /_yardoc/
37
+ /doc/
38
+ /rdoc/
39
+
40
+ ## Environment normalization:
41
+ /.bundle/
42
+ /vendor/bundle
43
+ /lib/bundler/man/
44
+
45
+ # for a library or gem, you might want to ignore these files since the code is
46
+ # intended to run in multiple environments; otherwise, check them in:
47
+ # Gemfile.lock
48
+ # .ruby-version
49
+ # .ruby-gemset
50
+
51
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
52
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ LineLength:
2
+ Max: 120
3
+ AllCops:
4
+ Exclude:
5
+ - 'spec/**/*'
6
+ DisplayCopNames: true
7
+ Rails:
8
+ Enabled: true
9
+ Documentation:
10
+ Enabled: false
11
+ Style/EndOfLine:
12
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ before_install: gem install bundler
3
+ bundler_args: --without yard guard benchmarks
4
+ script: "rake spec"
5
+ rvm:
6
+ - 2.2.4
7
+ - 2.3.1
8
+ - ruby-head
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Nikita Bulai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Capistrano::Chewy
2
+ [![Gem Version](https://badge.fury.io/rb/capistrano-chewy.svg)](http://badge.fury.io/rb/capistrano-chewy)
3
+ [![Build Status](https://travis-ci.org/nbulaj/capistrano-chewy.svg?branch=master)](https://travis-ci.org/nbulaj/capistrano-chewy)
4
+
5
+ Manage and continuously rebuild your ElasticSearch indexes with [Chewy](https://github.com/toptal/chewy/) and [Capistrano](https://github.com/capistrano/capistrano) v3.
6
+
7
+ `Capistrano::Chewy` gem adds automatic conditionally reset only modified Chewy indexes to your deploy flow so you do not have to build them manually.
8
+ Moreover, it adds the possibility of manual index management with the base Chewy tasks on the remote server.
9
+
10
+ ## Requirements
11
+
12
+ * Capistrano >= 3.0
13
+ * Chewy >= 0.4
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'capistrano-chewy', require: false
21
+ ```
22
+
23
+ or:
24
+
25
+ ```ruby
26
+ gem 'capistrano-chewy', require: false, group: :development
27
+ ```
28
+
29
+ And then run bundler:
30
+
31
+ ```
32
+ $ bundle
33
+ ```
34
+
35
+ Or install it yourself as:
36
+
37
+ ```
38
+ $ gem install capistrano-chewy
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ Require it in your `Capfile`:
44
+
45
+ ```ruby
46
+ # Capfile
47
+
48
+ require 'capistrano/chewy'
49
+ ```
50
+
51
+ then you can use `cap -T` to list `Capistrano::Chewy` tasks:
52
+
53
+ ```ruby
54
+ cap deploy:chewy:rebuild # Reset only modified Chewy indexes
55
+ cap deploy:chewy:reset # Destroy, recreate and import data to all the indexes
56
+ cap deploy:chewy:reset[indexes] # Destroy, recreate and import data to the specified indexes
57
+ cap deploy:chewy:update # Updates data to all the indexes
58
+ cap deploy:chewy:update[indexes] # Updates data to the specified indexes
59
+ ```
60
+
61
+ ## Configuration
62
+
63
+ You can setup the following:
64
+
65
+ ```ruby
66
+ # deploy.rb
67
+ set :chewy_conditionally_reset, false # Reset only modified Chewy indexes, true by default
68
+ set :chewy_path, 'app/my_indexes' # Path to Chewy indexes, 'app/chewy' by default
69
+ set :chewy_env, :chewy_production # Environment variable for Chewy, equal to RAILS_ENV by default
70
+ set :chewy_role, :web # Chewy role, :app by default
71
+ set :chewy_skip, true # Skip processing Chewy indexes during deploy, false by default
72
+ set :chewy_default_hooks, false # Add default capistrano-chewy hooks to your deploy flow, true by default
73
+ ```
74
+
75
+ ## Contributing
76
+
77
+ 1. Fork it ( http://github.com/nbulaj/capistrano-chewy/fork )
78
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
79
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
80
+ 4. Push to the branch (`git push origin my-new-feature`)
81
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano-chewy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'capistrano-chewy'
8
+ spec.version = CapistranoChewy.gem_version
9
+ spec.authors = ['Nikita Bulai']
10
+ spec.date = '2016-10-18'
11
+ spec.email = ['bulainikita@gmail.com']
12
+ spec.summary = 'Manage and continuously rebuild your ElasticSearch indexes with Chewy and Capistrano'
13
+ spec.description = 'Manage and continuously rebuild your ElasticSearch indexes with Chewy and Capistrano v3.'
14
+ spec.homepage = 'https://github.com/nbulaj/capistrano-chewy'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($RS)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'capistrano', '~> 3.0'
23
+ spec.add_dependency 'chewy', '~> 0.4'
24
+
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ end
@@ -0,0 +1,5 @@
1
+ require 'capistrano-chewy/version'
2
+ require 'capistrano-chewy/diff_parser'
3
+
4
+ module CapistranoChewy
5
+ end
@@ -0,0 +1,40 @@
1
+ module CapistranoChewy
2
+ class DiffParser
3
+ class Result
4
+ attr_reader :removed, :changed, :added
5
+
6
+ def initialize
7
+ @removed = []
8
+ @changed = []
9
+ @added = []
10
+ end
11
+ end
12
+
13
+ CHANGED_FILE_PATTERN = /Files\s+.+\s+and\s+(.+)\s+differ/i
14
+ NEW_OR_REMOVED_FILE_PATTERN = /Only in (.+):\s+(.+)/i
15
+
16
+ class << self
17
+ def parse(diff, current_path, release_path)
18
+ raise ArgumentError, 'current_path can not be the same as release_path!' if current_path == release_path
19
+
20
+ diff.split("\n").each_with_object(Result.new) do |line, result|
21
+ # File was changed
22
+ CHANGED_FILE_PATTERN.match(line) do |match|
23
+ result.changed << match[1]
24
+ next
25
+ end
26
+
27
+ # File was removed or added
28
+ NEW_OR_REMOVED_FILE_PATTERN.match(line) do |match|
29
+ # if file placed in current path, then it was removed from the release path
30
+ if match[1] == current_path.chomp(File::SEPARATOR)
31
+ result.removed << File.join(match[1], match[2])
32
+ else
33
+ result.added << File.join(match[1], match[2])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ module CapistranoChewy
2
+ def self.gem_version
3
+ Gem::Version.new VERSION::STRING
4
+ end
5
+
6
+ module VERSION
7
+ MAJOR = 0
8
+ MINOR = 1
9
+ TINY = 0
10
+
11
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # Ensure deploy tasks are loaded before we run
2
+ require 'capistrano/deploy'
3
+ require 'capistrano-chewy'
4
+
5
+ load File.expand_path('../tasks/chewy.rake', __FILE__)
@@ -0,0 +1,135 @@
1
+ namespace :load do
2
+ task :defaults do
3
+ set :chewy_conditionally_reset, -> { true }
4
+ set :chewy_path, -> { 'app/chewy' }
5
+ set :chewy_env, -> { fetch(:rails_env, fetch(:stage)) }
6
+ set :chewy_role, -> { :app }
7
+ set :chewy_skip, -> { false }
8
+ set :chewy_default_hooks, -> { true }
9
+ end
10
+ end
11
+
12
+ namespace :deploy do
13
+ before :starting, :check_chewy_hooks do
14
+ invoke :'deploy:chewy:add_default_hooks' if fetch(:chewy_default_hooks)
15
+ end
16
+
17
+ namespace :chewy do
18
+ # Adds default Capistrano::Chewy hooks to the deploy flow
19
+ task :add_default_hooks do
20
+ after 'deploy:updated', 'deploy:chewy:rebuild'
21
+ end
22
+
23
+ # Default Chewy rake tasks
24
+ desc 'Destroy, recreate and import data to all or specified (pass with [one,two]) indexes'
25
+ task :reset do |_task, args|
26
+ indexes = args.extras
27
+
28
+ on roles fetch(:chewy_role) do
29
+ within release_path do
30
+ with rails_env: fetch(:chewy_env) do
31
+ if indexes.any?
32
+ execute :rake, "chewy:reset[#{indexes.join(',')}]"
33
+ else
34
+ # Simply chewy:reset / chewy:update for Chewy > 0.8.4
35
+ execute :rake, 'chewy:reset:all'
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ desc 'Updates data to all or specified (passed with [one,two]) indexes'
43
+ task :update do |_task, args|
44
+ indexes = args.extras
45
+
46
+ on roles fetch(:chewy_role) do
47
+ within release_path do
48
+ with rails_env: fetch(:chewy_env) do
49
+ if indexes.any?
50
+ execute :rake, "chewy:update[#{indexes.join(',')}]"
51
+ else
52
+ execute :rake, 'chewy:update:all'
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Smart rebuild of modified Chewy indexes
60
+ desc 'Reset Chewy indexes if they have been added, changed or removed'
61
+ task :rebuild do
62
+ on roles fetch(:chewy_role) do
63
+ if fetch(:chewy_skip)
64
+ info 'Skipping task according to the deploy settings'
65
+ exit 0
66
+ end
67
+
68
+ info "Checking Chewy directory (#{fetch(:chewy_path)})"
69
+
70
+ chewy_path = File.join(release_path, fetch(:chewy_path))
71
+ unless test("[ -d #{chewy_path} ]")
72
+ error "Directory #{chewy_path} doesn't exist!"
73
+ exit 1
74
+ end
75
+
76
+ if fetch(:chewy_conditionally_reset)
77
+ if test('diff -v')
78
+ info 'Running smart indexes reset...'
79
+ invoke :'deploy:chewy:rebuilding'
80
+ else
81
+ error "Can't check the difference between Chewy indexes - install 'diff' tool first!"
82
+ exit 1
83
+ end
84
+ else
85
+ info 'Running chewy:reset:all'
86
+ invoke :'deploy:chewy:reset:all'
87
+ end
88
+ end
89
+ end
90
+
91
+ desc 'Runs smart Chewy indexes rebuilding (only for changed files)'
92
+ task :rebuilding do
93
+ on roles fetch(:chewy_role) do
94
+ if fetch(:chewy_skip)
95
+ info 'Skipping task according to the deploy settings'
96
+ exit 0
97
+ end
98
+
99
+ chewy_path = fetch(:chewy_path)
100
+ info "Checking changes in #{chewy_path}"
101
+
102
+ chewy_release_path = File.join(release_path, chewy_path)
103
+ chewy_current_path = File.join(current_path, chewy_path)
104
+
105
+ # -q, --brief report only when files differ
106
+ # -E, --ignore-tab-expansion ignore changes due to tab expansion
107
+ # -Z, --ignore-trailing-space ignore white space at line end
108
+ # -B, --ignore-blank-lines ignore changes where lines are all blank
109
+ #
110
+ indexes_diff = capture(:diff, "-qZEB #{chewy_release_path} #{chewy_current_path}", raise_on_non_zero_exit: false)
111
+
112
+ # If diff is empty then indices have not changed
113
+ if indexes_diff.nil? || indexes_diff.strip.empty?
114
+ info 'Skipping `deploy:chewy:rebuilding` (nothing changed in the Chewy path)'
115
+ else
116
+ within release_path do
117
+ with rails_env: fetch(:chewy_env) do
118
+ changes = ::CapistranoChewy::DiffParser.parse(indexes_diff, chewy_current_path, chewy_release_path)
119
+
120
+ # Reset indexes that were changed or added
121
+ indexes_to_reset = changes.changed.concat(changes.added)
122
+
123
+ if indexes_to_reset.any?
124
+ indexes = indexes_to_reset.map { |file| File.basename(file).gsub('_index.rb', '') }.join(',')
125
+ execute :rake, "chewy:reset[#{indexes}]"
126
+ end
127
+
128
+ # TODO: destroy removed indexes?
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapistranoChewy::DiffParser do
4
+ let(:current_path) { '/project/1/app/chewy' }
5
+ let(:release_path) { '/project/2/app/chewy' }
6
+
7
+ let(:full_diff) do
8
+ "Files #{current_path}/accounts_index.rb and #{release_path}/accounts_index.rb differ\n" \
9
+ "Files #{current_path}/posts_index.rb and #{release_path}/posts_index.rb differ\n" \
10
+ "Only in #{release_path}: applications_index.rb\n" \
11
+ "Files #{current_path}/comments_index.rb and #{release_path}/comments_index.rb differ\n" \
12
+ "Only in #{current_path}: users_index.rb\n"
13
+ end
14
+
15
+ describe '#parse' do
16
+ context 'with difference between directories' do
17
+ it 'returns result object with removed, added and changed files' do
18
+ result = described_class.parse(full_diff, current_path, release_path)
19
+
20
+ expect(result.changed).to eq(["#{release_path}/accounts_index.rb", "#{release_path}/posts_index.rb", "#{release_path}/comments_index.rb"])
21
+ expect(result.added).to eq(["#{release_path}/applications_index.rb"])
22
+ expect(result.removed).to eq(["#{current_path}/users_index.rb"])
23
+ end
24
+ end
25
+
26
+ context 'without differences' do
27
+ it 'returns result object with removed, added and changed files' do
28
+ result = described_class.parse('', current_path, release_path)
29
+
30
+ expect(result.changed).to be_empty
31
+ expect(result.added).to be_empty
32
+ expect(result.removed).to be_empty
33
+ end
34
+ end
35
+
36
+ context 'with the same directories' do
37
+ it 'raises an error' do
38
+ expect { described_class.parse('', current_path, current_path) }.to raise_error(ArgumentError)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'capistrano-chewy'
5
+
6
+ RSpec.configure do |config|
7
+ config.order = 'random'
8
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-chewy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikita Bulai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: chewy
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Manage and continuously rebuild your ElasticSearch indexes with Chewy
56
+ and Capistrano v3.
57
+ email:
58
+ - bulainikita@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".rubocop.yml"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - capistrano3-postgres.gemspec
72
+ - lib/capistrano-chewy.rb
73
+ - lib/capistrano-chewy/diff_parser.rb
74
+ - lib/capistrano-chewy/version.rb
75
+ - lib/capistrano/chewy.rb
76
+ - lib/capistrano/tasks/chewy.rake
77
+ - spec/diff_parser_spec.rb
78
+ - spec/spec_helper.rb
79
+ homepage: https://github.com/nbulaj/capistrano-chewy
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.6.3
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Manage and continuously rebuild your ElasticSearch indexes with Chewy and
103
+ Capistrano
104
+ test_files:
105
+ - spec/diff_parser_spec.rb
106
+ - spec/spec_helper.rb
107
+ has_rdoc: