foundry_wordpress_tool 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/bin/fwt +4 -0
- data/foundry_wordpress_tool.gemspec +24 -0
- data/lib/foundry_wordpress_tool/base.rb +34 -0
- data/lib/foundry_wordpress_tool/database.rb +78 -0
- data/lib/foundry_wordpress_tool/uploads.rb +23 -0
- data/lib/foundry_wordpress_tool/version.rb +3 -0
- data/lib/foundry_wordpress_tool.rb +12 -0
- metadata +69 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Foundry Interactive
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Foundry Wordpress Tool #
|
2
|
+
|
3
|
+
## The problem ##
|
4
|
+
|
5
|
+
Wordpress is a fast tool for building a certain kind of website, but boy oh boy is deployment & dealing with multiple environments a pain in the ass.
|
6
|
+
|
7
|
+
## The (beginning of a) solution ##
|
8
|
+
|
9
|
+
Introducing Foundry Wordpress Tool: standardizing deployments of Wordpress over a variety of hosts & environments. First, install the gem:
|
10
|
+
|
11
|
+
```sh
|
12
|
+
$ gem install 'fwt'
|
13
|
+
```
|
14
|
+
|
15
|
+
Next, add a config file called `.fwt.yml` to the root of your local wordpress installation. The file should define as many environments as you want, each with the site root directory as "deploy_to" and ssh info as "username" and "hostname". Currently, specifying a password or an identiy file is not supported, so make sure your ssh config allows you to connect without specifying either. Here's an example:
|
16
|
+
|
17
|
+
```yaml
|
18
|
+
beta:
|
19
|
+
deploy_to: /srv/beta
|
20
|
+
host: beta.example.com
|
21
|
+
username: deploy
|
22
|
+
production:
|
23
|
+
deploy_to: /srv/beta
|
24
|
+
host: www.example.com
|
25
|
+
username: deploy
|
26
|
+
```
|
27
|
+
|
28
|
+
Finally, you should be able to run the following command to get a list of available tasks & usage:
|
29
|
+
|
30
|
+
```sh
|
31
|
+
$ fwt
|
32
|
+
```
|
33
|
+
|
34
|
+
## Some assumptions ##
|
35
|
+
|
36
|
+
We made a few assumptions to keep this tool simple:
|
37
|
+
|
38
|
+
#### The Wordpress server... ####
|
39
|
+
|
40
|
+
* You can SSH to it without specifying a password or an identity file.
|
41
|
+
* Has a MySQL server running and accessible as the deploy user.
|
42
|
+
|
43
|
+
#### The development machine... ####
|
44
|
+
|
45
|
+
* Is running a local build of the wordpress site.
|
46
|
+
* Has a MySQL server running and accessible as you.
|
47
|
+
|
48
|
+
## What this is *not* ##
|
49
|
+
|
50
|
+
* A tool for installing or configuring software packages
|
51
|
+
* A deployment tool
|
52
|
+
* A replacement for a versioning system
|
53
|
+
|
54
|
+
## Some alternatives ##
|
55
|
+
|
56
|
+
In choosing a toolset for dealing with wordpress, you might consider replacing or supplimenting FWT with one of these:
|
57
|
+
|
58
|
+
* [wordpress-capistrano](https://github.com/jestro/wordpress-capistrano)
|
59
|
+
|
60
|
+
## Contribute! ##
|
61
|
+
|
62
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
63
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
64
|
+
* Fork the project.
|
65
|
+
* Start a feature/bugfix branch.
|
66
|
+
* Commit and push until you are happy with your contribution.
|
67
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
68
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
69
|
+
|
70
|
+
## Copyright ##
|
71
|
+
|
72
|
+
Copyright (c) 2012 Foundry Interactive. See LICENSE.txt for
|
73
|
+
further details.
|
74
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/fwt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "foundry_wordpress_tool/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "foundry_wordpress_tool"
|
7
|
+
s.version = FoundryWordpressTool::VERSION
|
8
|
+
s.authors = ["Jonathan Fuchs"]
|
9
|
+
s.email = ["jon@foundryinteractive.com"]
|
10
|
+
s.homepage = "http://github.com/foundryinteractive/foundry_wordpress_tool"
|
11
|
+
s.summary = %q{A simple Wordpress tool}
|
12
|
+
s.description = %q{Helps manage Wordpress environments}
|
13
|
+
|
14
|
+
s.rubyforge_project = "foundry_wordpress_tool"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "thor"
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'foundry_wordpress_tool/uploads'
|
2
|
+
require 'foundry_wordpress_tool/database'
|
3
|
+
|
4
|
+
module FoundryWordpressTool
|
5
|
+
class Base < ::Thor
|
6
|
+
include Thor::Actions
|
7
|
+
include FoundryWordpressTool::Uploads
|
8
|
+
include FoundryWordpressTool::Database
|
9
|
+
|
10
|
+
class_option :env,
|
11
|
+
:desc => 'Name of the remote environment (as found in .fwt.yml).',
|
12
|
+
:required => false,
|
13
|
+
:aliases => '-e'
|
14
|
+
|
15
|
+
def initialize(*args)
|
16
|
+
say "** Welcome to Foundry Wordpress Tool! **\n", Thor::Shell::Color::CYAN
|
17
|
+
super(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
no_tasks do
|
21
|
+
|
22
|
+
def load_environment_config
|
23
|
+
config_yaml = YAML.load_file('.fwt.yml')
|
24
|
+
env = options.env
|
25
|
+
until config_yaml.keys.include? env
|
26
|
+
env = ask("Please select an environment (#{config_yaml.keys.join(', ')}):", Thor::Shell::Color::YELLOW)
|
27
|
+
end
|
28
|
+
@config = config_yaml[env]
|
29
|
+
end
|
30
|
+
|
31
|
+
end # end no_tasks
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module FoundryWordpressTool
|
2
|
+
module Database
|
3
|
+
FORWARDED_MYSQL_PORT = 33334
|
4
|
+
SNAPSHOT_TEMP_FILENAME = '/tmp/fwd_snapshot.sql'
|
5
|
+
def self.included(thor)
|
6
|
+
thor.class_eval do
|
7
|
+
|
8
|
+
desc "db_pull", "Dump the remote database & import it locally"
|
9
|
+
def db_pull
|
10
|
+
load_environment_config()
|
11
|
+
load_database_configs()
|
12
|
+
say_status :db, "Exporting remote database to temporary snapshot"
|
13
|
+
database_tunnel do
|
14
|
+
dump_command = "mysqldump -u #{@remote_db[:username]} -h 127.0.0.1 -P #{FORWARDED_MYSQL_PORT} -p#{@remote_db[:password]} #{@remote_db[:name]} > #{SNAPSHOT_TEMP_FILENAME}"
|
15
|
+
run dump_command
|
16
|
+
end
|
17
|
+
say_status :db, 'Importing temporary snapshot to local database'
|
18
|
+
import_command = "cat #{SNAPSHOT_TEMP_FILENAME} | mysql -u #{@local_db[:username]} -h #{@local_db[:host]} -P #{@local_db[:port]} -p#{@local_db[:password]} #{@local_db[:name]}"
|
19
|
+
run import_command
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "db_push", "Dump the local database & import it remotely"
|
23
|
+
def db_push
|
24
|
+
load_environment_config()
|
25
|
+
load_database_configs()
|
26
|
+
say_status :db, 'Exporting local database to temporary snapshot'
|
27
|
+
import_command = "mysqldump -u #{@local_db[:username]} -h #{@local_db[:host]} -P #{@local_db[:port]} -p#{@local_db[:password]} #{@local_db[:name]} > #{SNAPSHOT_TEMP_FILENAME}"
|
28
|
+
run import_command
|
29
|
+
say_status :db, "Importing temporary snapshot to remote database"
|
30
|
+
database_tunnel do
|
31
|
+
dump_command = "cat #{SNAPSHOT_TEMP_FILENAME} | mysql -u #{@remote_db[:username]} -h 127.0.0.1 -P #{FORWARDED_MYSQL_PORT} -p#{@remote_db[:password]} #{@remote_db[:name]}"
|
32
|
+
run dump_command
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
no_tasks do
|
37
|
+
|
38
|
+
def load_database_configs
|
39
|
+
say_status :db, 'Pulling remote & local MySQL settings from wp-config.php files'
|
40
|
+
# read the remote SSH config:
|
41
|
+
Net::SSH.start(@config['host'], @config['username']) do |ssh|
|
42
|
+
ssh.exec! "cat #{File.join(@config['deploy_to'], 'wp-config.php')}" do |ch, stream, data|
|
43
|
+
@remote_db = parse_db_settings_from_wordpress_config(data)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# read the local SSH config:
|
47
|
+
@local_db = parse_db_settings_from_wordpress_config(File.open("wp-config.php", "rb").read)
|
48
|
+
end
|
49
|
+
|
50
|
+
def database_tunnel(&block)
|
51
|
+
say_status :db, 'Opening SSH tunnel for MySQL'
|
52
|
+
gateway = Net::SSH::Gateway.new(@config['host'], @config['username'])
|
53
|
+
port = gateway.open(@remote_db[:host], @remote_db[:port], FORWARDED_MYSQL_PORT)
|
54
|
+
|
55
|
+
begin
|
56
|
+
yield
|
57
|
+
ensure
|
58
|
+
say_status :db, 'Closing SSH tunnel for MySQL'
|
59
|
+
gateway.shutdown!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_db_settings_from_wordpress_config(config_file_content)
|
64
|
+
remote_db = {}
|
65
|
+
remote_db[:name] = /define\(\'DB_NAME\'\,\s*\'([^']*)\'\)\;/.match(config_file_content)[1]
|
66
|
+
remote_db[:username] = /define\(\'DB_USER\'\,\s*\'([^']*)\'\)\;/.match(config_file_content)[1]
|
67
|
+
remote_db[:password] = /define\(\'DB_PASSWORD\'\,\s*\'([^']*)\'\)\;/.match(config_file_content)[1]
|
68
|
+
remote_db[:host] = /define\(\'DB_HOST\'\,\s*\'([^']*)\'\)\;/.match(config_file_content)[1]
|
69
|
+
remote_db[:port] = /define\(\'DB_PORT\'\,\s*\'([^']*)\'\)\;/.match(data)[1] rescue '3306'
|
70
|
+
return remote_db
|
71
|
+
end
|
72
|
+
|
73
|
+
end # end no_tasks
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FoundryWordpressTool
|
2
|
+
module Uploads
|
3
|
+
def self.included(thor)
|
4
|
+
thor.class_eval do
|
5
|
+
|
6
|
+
desc "uploads_pull", "Pull wp-content/uploads from the remote"
|
7
|
+
def uploads
|
8
|
+
load_environment_config()
|
9
|
+
rsync_command = "rsync -avz --delete #{@config['username']}@#{@config['host']}:#{@config['deploy_to']}/wp-content/uploads/ wp-content/uploads/"
|
10
|
+
run(rsync_command)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "uploads_push", "Push wp-content/uploads to the remote host"
|
14
|
+
def uploads_push
|
15
|
+
load_environment_config()
|
16
|
+
rsync_command = "rsync -avz --delete wp-content/uploads/ #{@config['username']}@#{@config['host']}:#{@config['deploy_to']}/wp-content/uploads/"
|
17
|
+
run(rsync_command)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: foundry_wordpress_tool
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Fuchs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: &70169921932700 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70169921932700
|
25
|
+
description: Helps manage Wordpress environments
|
26
|
+
email:
|
27
|
+
- jon@foundryinteractive.com
|
28
|
+
executables:
|
29
|
+
- fwt
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- Gemfile
|
35
|
+
- LICENSE.txt
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- bin/fwt
|
39
|
+
- foundry_wordpress_tool.gemspec
|
40
|
+
- lib/foundry_wordpress_tool.rb
|
41
|
+
- lib/foundry_wordpress_tool/base.rb
|
42
|
+
- lib/foundry_wordpress_tool/database.rb
|
43
|
+
- lib/foundry_wordpress_tool/uploads.rb
|
44
|
+
- lib/foundry_wordpress_tool/version.rb
|
45
|
+
homepage: http://github.com/foundryinteractive/foundry_wordpress_tool
|
46
|
+
licenses: []
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project: foundry_wordpress_tool
|
65
|
+
rubygems_version: 1.8.15
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: A simple Wordpress tool
|
69
|
+
test_files: []
|