capistrano-alchemy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 23b06236d8630f276cc6449283e6ed27b8f4bc87
4
+ data.tar.gz: 64dc5c41fc122c2e272b2a2aa8243da990c34dfc
5
+ SHA512:
6
+ metadata.gz: a4360e229f218c1813783cfe50ce07ef866758a2234aaea8ead73d038a15110bdb604887c9e5ebf5c884e124ab242214f62fe662e975d887610869a2395a652e
7
+ data.tar.gz: 66939c594c735184266cf6e58033b2d6b2c8376f43497a5e37e97f518cb546ddb7b3e12bbf847b7d65d4a7c339d58a5762f39d625e9769b361c86cd8482ab5ea
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-alchemy.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Martin Meyerhoff
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # Capistrano Tasks for Alchemy CMS
2
+
3
+ Capistrano::Alchemy adds four folders to Capistranos `shared_folders` array: `uploads/pictures`, `uploads/attachments`, `tmp/cache/assets`, and Alchemy's picture cache. It also runs Alchemy's Seeder after migrating the database.
4
+
5
+ In addition, it offers several tasks to synchronize your shared folders and your database between environments.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'capistrano-alchemy', github: 'AlchemyCMS/capistrano-alchemy', branch: 'master', group: :development, require: false
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install capistrano-alchemy
23
+
24
+ If your application is not prepared for capistrano yet, you need to do so now:
25
+
26
+ $ bundle exec cap install
27
+
28
+ You have to add the `Capistrano::Alchemy` and Rails specific tasks to your `Capfile`
29
+
30
+ ```ruby
31
+ require 'capistrano/rails'
32
+ require 'capistrano/alchemy'
33
+ ```
34
+
35
+ ## Usage
36
+
37
+
38
+ ### Synchronize your data
39
+
40
+ Alchemy Capistrano receipts offer much more then only deployment related tasks. We also have tasks to make your local development easier. To get a list of all receipts type:
41
+
42
+ ```shell
43
+ $ bundle exec cap -T alchemy
44
+ ```
45
+
46
+ #### Import data from server
47
+
48
+ ```shell
49
+ $ bundle exec cap staging alchemy:import:all
50
+ ```
51
+
52
+ This imports your staging server's data onto your local development machine. This is very handy if you want to clone the current server state. Replace `staging` for `production` if you need the production data.
53
+
54
+ #### Export data to server
55
+
56
+ That even works the other way around:
57
+
58
+ ```shell
59
+ $ bundle exec cap staging alchemy:export:all
60
+ ```
61
+
62
+ **NOTE:** This will **overwrite the database** on your `staging` server. But calm down my dear friend, Alchemy will ask you to perform a backup before overwriting it.
63
+
64
+ ## Contributing
65
+
66
+ 1. Fork it ( https://github.com/[my-github-username]/capistrano-alchemy/fork )
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
69
+ 4. Push to the branch (`git push origin my-new-feature`)
70
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/alchemy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "capistrano-alchemy"
8
+ spec.version = Capistrano::Alchemy::VERSION
9
+ spec.authors = ["Martin Meyerhoff"]
10
+ spec.email = ["mamhoff@googlemail.com"]
11
+ spec.summary = %q{Capistrano Tasks for AlchemyCMS.}
12
+ spec.homepage = "https://alchemy-cms.com"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "capistrano-rails", "~> 1.1"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency 'alchemy_cms', "~> 3.0"
25
+ end
@@ -0,0 +1,55 @@
1
+ require 'spinner'
2
+
3
+ module Capistrano::Alchemy::DeploySupport
4
+ # Makes a backup of the remote database and stores it in db/ folder
5
+ def backup_database
6
+ puts 'Backing up database'
7
+ timestamp = Time.now.strftime('%Y-%m-%d-%H-%M')
8
+ rake "RAILS_ENV=#{fetch(:rails_env, 'production')} alchemy:db:dump DUMP_FILENAME=db/dump-#{timestamp}.sql"
9
+ end
10
+
11
+ # Sends the database via ssh to the server
12
+ def export_database(server)
13
+ puts "Exporting the database. Please wait..."
14
+ system db_export_cmd(server)
15
+ end
16
+
17
+ def db_import_cmd(server)
18
+ raise "No server given" if !server
19
+ dump_cmd = "cd #{release_path} && bundle exec rake RAILS_ENV=#{fetch(:rails_env, 'production')} alchemy:db:dump"
20
+ sql_stream = "#{ssh_command(server)} '#{dump_cmd}'"
21
+ "#{sql_stream} | #{database_import_command(database_config['adapter'])} 1>/dev/null 2>&1"
22
+ end
23
+
24
+ # The actual export command that sends the data
25
+ def db_export_cmd(server)
26
+ raise "No server given" if !server
27
+ import_cmd = "cd #{release_path} && bundle exec rake RAILS_ENV=#{fetch(:rails_env, 'production')} alchemy:db:import"
28
+ ssh_cmd = "#{ssh_command(server)} '#{import_cmd}'"
29
+ "#{database_dump_command(database_config['adapter'])} | #{ssh_cmd}"
30
+ end
31
+
32
+ # Sends files of given type via rsync to server
33
+ def send_files(type, server)
34
+ raise "No server given" if !server
35
+ FileUtils.mkdir_p "./uploads/#{type}"
36
+ system "rsync --progress -rue 'ssh -p #{ssh_port(server)}' uploads/#{type} #{server.user}@#{server.hostname}:#{shared_path}/uploads/"
37
+ end
38
+
39
+ def get_files(type, server)
40
+ raise "No server given" if !server
41
+ FileUtils.mkdir_p "./uploads"
42
+ puts "Importing #{type}. Please wait..."
43
+ system "rsync --progress -rue 'ssh -p #{ssh_port(server)}' #{server.user}@#{server.hostname}:#{shared_path}/uploads/#{type} ./uploads/"
44
+ end
45
+
46
+ private
47
+
48
+ def ssh_command(server)
49
+ "ssh -p #{ssh_port(server)} #{server.user}@#{server.hostname}"
50
+ end
51
+
52
+ def ssh_port(server)
53
+ server.port || 22
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module Alchemy
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ require "capistrano/alchemy/version"
2
+
3
+ require 'fileutils'
4
+ require 'alchemy/tasks/helpers'
5
+ # Loading the rails app
6
+ # require './config/environment.rb'
7
+ # so we can read the current mount point of Alchemy
8
+ require 'alchemy/mount_point'
9
+ require 'capistrano/alchemy/deploy_support'
10
+
11
+ include Alchemy::Tasks::Helpers
12
+ include Capistrano::Alchemy::DeploySupport
13
+
14
+ load File.expand_path('../tasks/alchemy.rake', __FILE__)
15
+ load File.expand_path('../tasks/alchemy_capistrano_hooks.rake', __FILE__)
16
+
@@ -0,0 +1,168 @@
1
+ namespace :alchemy do
2
+
3
+ # TODO: split up this namespace into something that runs once on `cap install` and
4
+ # once on every deploy
5
+ desc "Prepare Alchemy for deployment."
6
+ task :default_paths do
7
+ set :alchemy_picture_cache_path,
8
+ -> { File.join('public', Alchemy::MountPoint.get, 'pictures') }
9
+
10
+ set :linked_dirs, fetch(:linked_dirs, []) + [
11
+ "uploads/pictures",
12
+ "uploads/attachments",
13
+ fetch(:alchemy_picture_cache_path),
14
+ "tmp/cache/assets"
15
+ ]
16
+
17
+ # TODO: Check, if this is the right approach to ensure that we don't overwrite existing settings?
18
+ # Or does Capistrano already handle this for us?
19
+ set :linked_files, fetch(:linked_files, []) + %w(config/database.yml)
20
+ end
21
+
22
+ # TODO: Do we really need this in Alchemy or should we release an official Capistrano plugin for that?
23
+ namespace :database_yml do
24
+ desc "Creates the database.yml file"
25
+ task create: ['alchemy:default_paths', 'deploy:check'] do
26
+ set :db_environment, ask("the environment", fetch(:rails_env, 'production'))
27
+ set :db_adapter, ask("database adapter (mysql or postgresql)", 'mysql')
28
+ set :db_adapter, fetch(:db_adapter).gsub(/\Amysql\z/, 'mysql2')
29
+ set :db_name, ask("database name", nil)
30
+ set :db_username, ask("database username", nil)
31
+ set :db_password, ask("database password", nil)
32
+ default_db_host = fetch(:db_adapter) == 'mysql2' ? 'localhost' : '127.0.0.1'
33
+ set :db_host, ask("database host", default_db_host)
34
+ db_config = ERB.new <<-EOF
35
+ #{fetch(:db_environment)}:
36
+ adapter: #{fetch(:db_adapter)}
37
+ encoding: utf8
38
+ reconnect: false
39
+ pool: 5
40
+ database: #{fetch(:db_name)}
41
+ username: #{fetch(:db_username)}
42
+ password: #{fetch(:db_password)}
43
+ host: #{fetch(:db_host)}
44
+ EOF
45
+ on roles :app do
46
+ execute :mkdir, '-p', "#{shared_path}/config"
47
+ upload! StringIO.new(db_config.result), "#{shared_path}/config/database.yml"
48
+ end
49
+ end
50
+ end
51
+
52
+ namespace :db do
53
+ desc "Seeds the database with essential data."
54
+ task seed: ['alchemy:default_paths', 'deploy:check'] do
55
+ on roles :db do
56
+ within release_path do
57
+ with rails_env: fetch(:rails_env, 'production') do
58
+ execute :rake, 'db:seed'
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ desc "Dumps the database into 'db/dumps' on the server."
65
+ task dump: ['alchemy:default_paths', 'deploy:check'] do
66
+ on roles :db do
67
+ within release_path do
68
+ timestamp = Time.now.strftime('%Y-%m-%d-%H-%M')
69
+ execute :mkdir, '-p', 'db/dumps'
70
+ with dump_filename: "db/dumps/#{timestamp}.sql", rails_env: fetch(:rails_env, 'production') do
71
+ execute :rake, 'alchemy:db:dump'
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ namespace :import do
79
+ desc "Imports all data (Pictures, attachments and the database) into your local development machine."
80
+ task all: ['alchemy:default_paths', 'deploy:check'] do
81
+ on roles [:app, :db] do
82
+ invoke('alchemy:import:pictures')
83
+ puts "\n"
84
+ invoke('alchemy:import:attachments')
85
+ puts "\n"
86
+ invoke('alchemy:import:database')
87
+ end
88
+ end
89
+
90
+ desc "Imports the server database into your local development machine."
91
+ task database: ['alchemy:default_paths', 'deploy:check'] do
92
+ on roles :db do |server|
93
+ puts "Importing database. Please wait..."
94
+ system db_import_cmd(server)
95
+ puts "Done."
96
+ end
97
+ end
98
+
99
+ desc "Imports attachments into your local machine using rsync."
100
+ task attachments: ['alchemy:default_paths', 'deploy:check'] do
101
+ on roles :app do |server|
102
+ get_files(:attachments, server)
103
+ end
104
+ end
105
+
106
+ desc "Imports pictures into your local machine using rsync."
107
+ task pictures: ['alchemy:default_paths', 'deploy:check'] do
108
+ on roles :app do |server|
109
+ get_files(:pictures, server)
110
+ end
111
+ end
112
+ end
113
+
114
+ namespace :export do
115
+ desc "Sends all data (Pictures, attachments and the database) to your remote machine."
116
+ task all: ['alchemy:default_paths', 'deploy:check'] do
117
+ invoke 'alchemy:export:pictures'
118
+ invoke 'alchemy:export:attachments'
119
+ invoke 'alchemy:export:database'
120
+ end
121
+
122
+ desc "Imports the server database into your local development machine."
123
+ task database: ['alchemy:default_paths', 'deploy:check'] do
124
+ on roles :db do |host|
125
+ within release_path do
126
+ if ask(:backup_confirm, 'WARNING: This task will overwrite your remote database. Do you want me to make a backup? (y/n)') == "y"
127
+ backup_database
128
+ export_database(host)
129
+ else
130
+ if ask(:overwrite_confirm, 'Are you sure? (y/n)') == "y"
131
+ export_database(host)
132
+ else
133
+ backup_database
134
+ export_database(host)
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ desc "Sends attachments to your remote machine using rsync."
142
+ task attachments: ['alchemy:default_paths', 'deploy:check'] do
143
+ on roles :app do |host|
144
+ send_files :attachments, host
145
+ end
146
+ end
147
+
148
+ desc "Sends pictures to your remote machine using rsync."
149
+ task pictures: ['alchemy:default_paths', 'deploy:check'] do
150
+ on roles :app do |host|
151
+ send_files :pictures, host
152
+ end
153
+ end
154
+ end
155
+
156
+ desc "Upgrades production database to current Alchemy CMS version"
157
+ task upgrade: ['alchemy:default_paths', 'deploy:check'] do
158
+ on roles [:app, :db] do
159
+ within release_path do
160
+ with rails_env: fetch(:rails_env, 'production') do
161
+ execute :rake, 'alchemy:upgrade'
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+
@@ -0,0 +1,10 @@
1
+ namespace :load do
2
+ task :defaults do
3
+ invoke 'alchemy:default_paths'
4
+ end
5
+ end
6
+
7
+ namespace :deploy do
8
+ after :migrate, 'alchemy:db:seed'
9
+ end
10
+
File without changes
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-alchemy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Meyerhoff
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: alchemy_cms
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description:
70
+ email:
71
+ - mamhoff@googlemail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - capistrano-alchemy.gemspec
82
+ - lib/capistrano-alchemy.rb
83
+ - lib/capistrano/alchemy.rb
84
+ - lib/capistrano/alchemy/deploy_support.rb
85
+ - lib/capistrano/alchemy/version.rb
86
+ - lib/capistrano/tasks/alchemy.rake
87
+ - lib/capistrano/tasks/alchemy_capistrano_hooks.rake
88
+ homepage: https://alchemy-cms.com
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.8
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Capistrano Tasks for AlchemyCMS.
112
+ test_files: []