wordmove 1.4.0.pre4 → 1.4.0.pre5
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 +4 -4
- data/.rubocop.yml +25 -2
- data/CHANGELOG.md +8 -15
- data/README.mdown +49 -82
- data/Rakefile +3 -0
- data/lib/wordmove.rb +2 -0
- data/lib/wordmove/assets/dump.php.erb +6 -10
- data/lib/wordmove/cli.rb +3 -17
- data/lib/wordmove/deployer/base.rb +33 -53
- data/lib/wordmove/deployer/ftp.rb +11 -14
- data/lib/wordmove/deployer/ssh.rb +16 -27
- data/lib/wordmove/generators/Movefile +1 -3
- data/lib/wordmove/generators/movefile.rb +0 -2
- data/lib/wordmove/generators/movefile_adapter.rb +1 -3
- data/lib/wordmove/logger.rb +0 -1
- data/lib/wordmove/sql_adapter.rb +6 -6
- data/lib/wordmove/version.rb +1 -1
- data/lib/wordmove/wordpress_directory.rb +2 -6
- data/wordmove.gemspec +13 -11
- metadata +18 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3539e79c18d048d429bbf8c74fe16062fea7b247
|
4
|
+
data.tar.gz: 1a342c75af3274424eda5e5d46691e1d8f0408bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 205ec2101b5bbab623950ceee0644160ace684841c7f2c8bb79921b253e37f2063590444b165405fcbcf46744e23d36432f7dac441be9ec45da317bbeb9fdda0
|
7
|
+
data.tar.gz: 1132b2af445f8a3d0f932621e7d1b113f6cfd725a05513689036126454f8fb358013573d691789b178554cdd4a6aba3f90cb5be20ba8c9796d920e0ff74284e5
|
data/.rubocop.yml
CHANGED
@@ -1,12 +1,35 @@
|
|
1
|
+
Rails:
|
2
|
+
Enabled: true
|
3
|
+
|
4
|
+
Rails/Output:
|
5
|
+
Enabled: false
|
6
|
+
|
1
7
|
AllCops:
|
2
|
-
|
8
|
+
TargetRubyVersion: 2.2
|
9
|
+
DisplayCopNames: true
|
10
|
+
DisplayStyleGuide: true
|
11
|
+
|
3
12
|
Exclude:
|
4
|
-
- 'db/**/*'
|
5
13
|
- 'bin/*'
|
14
|
+
|
6
15
|
Metrics/LineLength:
|
7
16
|
Max: 100
|
17
|
+
|
18
|
+
Metrics/MethodLength:
|
19
|
+
Max: 15
|
20
|
+
|
21
|
+
Metrics/ClassLength:
|
22
|
+
Max: 200
|
23
|
+
|
8
24
|
Style/StringLiterals:
|
9
25
|
Enabled: false
|
10
26
|
EnforcedStyle: double_quotes
|
27
|
+
|
11
28
|
Style/Documentation:
|
12
29
|
Enabled: false
|
30
|
+
|
31
|
+
Style/FrozenStringLiteralComment:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Metrics/AbcSize:
|
35
|
+
Max: 35
|
data/CHANGELOG.md
CHANGED
@@ -1,18 +1,11 @@
|
|
1
|
-
# 1.4.0
|
2
|
-
- Implemented compression of sql files before and after transfers
|
3
|
-
- Implemented compression of sql backup files inside wp-content
|
4
|
-
- Implemented support to mu-plugins directory. Thanks connormckelvey
|
5
|
-
- Update `dump.php` library to support database VIEWS
|
6
|
-
|
7
|
-
|
8
1
|
# 1.3.1
|
9
|
-
-
|
2
|
+
- fix typo in dump.php.erb
|
10
3
|
|
11
4
|
# 1.3.0
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
15
|
-
-
|
16
|
-
-
|
17
|
-
-
|
18
|
-
-
|
5
|
+
- fix UTF-8 encoding issue when `wordmove init` with a wrong .sample file
|
6
|
+
- fix problem with ftp password and special chars
|
7
|
+
- fix duplicated wordpress tree in languages folder (ftp only)
|
8
|
+
- update db import / export php libraries
|
9
|
+
- add `--version` option
|
10
|
+
- required ruby version ~> 2.0
|
11
|
+
- updated test suite with rspec 3.x
|
data/README.mdown
CHANGED
@@ -2,20 +2,16 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
-
Wordmove is a
|
5
|
+
Wordmove is a gem that lets you automatically mirror local Wordpress
|
6
6
|
installations and DB data back and forth from your local development machine to
|
7
|
-
the remote staging server.
|
7
|
+
the remote staging server.
|
8
|
+
|
9
|
+
**SSH** connections are fully supported, while [FTP support is planned to be discontinued](https://github.com/welaika/wordmove/wiki/FTP-support-disclaimer) when new features will be introduced.
|
8
10
|
|
9
11
|
Think of it like Capistrano for Wordpress, complete with push/pull capabilities.
|
10
12
|
|
11
13
|
[](https://travis-ci.org/welaika/wordmove)
|
12
14
|
|
13
|
-
## Screencasts
|
14
|
-
|
15
|
-
* Push all WordPress, including database and uploads: http://vimeo.com/74648079
|
16
|
-
* Pull database and uploads, adapting paths and urls: http://vimeo.com/74646861
|
17
|
-
* Push only theme, transfer only modified files: http://vimeo.com/74647529
|
18
|
-
|
19
15
|
## Installation
|
20
16
|
|
21
17
|
That's easy:
|
@@ -24,15 +20,6 @@ That's easy:
|
|
24
20
|
gem install wordmove
|
25
21
|
```
|
26
22
|
|
27
|
-
## Upgrading?
|
28
|
-
|
29
|
-
Beware!
|
30
|
-
|
31
|
-
From version 1.0 we have decided to change wordmove flags' behaviour: they used to tell
|
32
|
-
wordmove which options to **skip**, now they tell instead which options to **include**.
|
33
|
-
In the Movefile, we have also changed all "username" fields to be just "user".
|
34
|
-
|
35
|
-
So please, be very careful when upgrading :heart:
|
36
23
|
|
37
24
|
## Usage
|
38
25
|
|
@@ -45,11 +32,21 @@ Tasks:
|
|
45
32
|
wordmove push # Pushes WP data from local machine to remote host
|
46
33
|
```
|
47
34
|
|
35
|
+
Move inside the Wordpress folder and use `wordmove init` to generate a new `Movefile` and edit it with your settings. Read the next paragraph for more info.
|
36
|
+
|
37
|
+
See the wiki article: [Usage and flags explained](https://github.com/welaika/wordmove/wiki/Usage-and-flags-explained) for more info.
|
38
|
+
|
39
|
+
### Screencasts
|
40
|
+
|
41
|
+
* Push all WordPress, including database and uploads: http://vimeo.com/74648079
|
42
|
+
* Pull database and uploads, adapting paths and urls: http://vimeo.com/74646861
|
43
|
+
* Push only theme, transfer only modified files: http://vimeo.com/74647529
|
44
|
+
|
48
45
|
## Movefile
|
49
46
|
|
50
|
-
You can configure Wordmove creating a `Movefile`. That's just a YAML file with
|
47
|
+
You can configure Wordmove creating a `Movefile`. That's just a YAML file with local and remote host infos:
|
51
48
|
|
52
|
-
```
|
49
|
+
```
|
53
50
|
local:
|
54
51
|
vhost: "http://vhost.local"
|
55
52
|
wordpress_path: "/home/john/sites/your_site" # use an absolute path here
|
@@ -70,7 +67,6 @@ production:
|
|
70
67
|
password: "password"
|
71
68
|
host: "host"
|
72
69
|
# port: "3308" # Use just in case you have exotic server config
|
73
|
-
# mysqldump_options: "--max_allowed_packet=50MB" # Only available if using SSH
|
74
70
|
|
75
71
|
exclude:
|
76
72
|
- ".git/"
|
@@ -82,77 +78,35 @@ production:
|
|
82
78
|
- "Movefile"
|
83
79
|
- "wp-config.php"
|
84
80
|
- "wp-content/*.sql"
|
85
|
-
|
86
|
-
# paths: # you can customize wordpress internal paths
|
87
|
-
# wp_content: "wp-content"
|
88
|
-
# uploads: "wp-content/uploads"
|
89
|
-
# plugins: "wp-content/plugins"
|
90
|
-
# mu_plugins: "wp-content/mu-plugins"
|
91
|
-
# themes: "wp-content/themes"
|
92
|
-
# languages: "wp-content/languages"
|
93
|
-
# themes: "wp-content/themes"
|
94
|
-
|
95
|
-
# ssh:
|
96
|
-
# host: "host"
|
97
|
-
# user: "user"
|
98
|
-
# password: "password" # password is optional, will use public keys if available.
|
99
|
-
# port: 22 # Port is optional
|
100
|
-
# rsync_options: "--verbose" # Additional rsync options, optional
|
101
|
-
# gateway: # Gateway is optional
|
102
|
-
# host: "host"
|
103
|
-
# user: "user"
|
104
|
-
# password: "password" # password is optional, will use public keys if available.
|
105
|
-
|
106
|
-
# ftp:
|
107
|
-
# user: "user"
|
108
|
-
# password: "password"
|
109
|
-
# host: "host"
|
110
|
-
# passive: true
|
111
|
-
# scheme: "ftps" # default "ftp"
|
112
|
-
|
113
|
-
# staging: # multiple environments can be specified
|
114
|
-
# [...]
|
115
81
|
```
|
116
82
|
|
117
|
-
|
83
|
+
We warmly **recommend** to read the wiki article [Multiple environments explained
|
84
|
+
](https://github.com/welaika/wordmove/wiki/Multiple-environments-explained) if you need multi-stage support, and the wiki article [Movefile configurations explained](https://github.com/welaika/wordmove/wiki/Movefile-configurations-explained) to understand about the supported configurations.
|
118
85
|
|
119
|
-
|
120
|
-
|
86
|
+
## Supports
|
87
|
+
### OS
|
121
88
|
|
122
|
-
|
123
|
-
Just delete the `remote.ssh.password` field in your `Movefile`. Easy peasy.
|
89
|
+
OS X and Linux are fully supported.
|
124
90
|
|
125
|
-
|
126
|
-
Please take a look at the various gotchas of the underlying [`photocopier` gem](https://github.com/welaika/photocopier#password-gotchas).
|
91
|
+
See the [Windows (un)support disclaimer](https://github.com/welaika/wordmove/wiki/Windows-(un)support-disclaimer)
|
127
92
|
|
128
|
-
|
93
|
+
### SSH
|
129
94
|
|
130
|
-
|
131
|
-
|
95
|
+
* You need `rsync` on your machine; as far as we know it's already installed on OS X and Linux.
|
96
|
+
* if you want to use your SSH public key for authentication,just delete the `production.ssh.password` field in your `Movefile`. Easy peasy.
|
97
|
+
* writing the password inside the move file was and is somewhat supported, but we discourage this practice in favor of password-less authentication with pub key. Read [here](https://github.com/welaika/wordmove/wiki/%5Bdeprecated%5D-SSH-password-inside-Movefile) for old informations.
|
132
98
|
|
133
|
-
|
134
|
-
* Use the absolute FTP path as `wordpress_absolute_path` (you may need to recover this from the `__FILE__` constant)
|
99
|
+
### FTP
|
135
100
|
|
136
|
-
|
137
|
-
|
101
|
+
* You need to install `lftp` on your machine. See community wiki article: [Install lftp on OSX yosemite](https://github.com/welaika/wordmove/wiki/Install-lftp-on-OSX-yosemite)).
|
102
|
+
* Use the relative FTP path as `production.wordpress_path`
|
103
|
+
* Use the absolute FTP path as `production.wordpress_absolute_path` (you may need to recover this from the `__FILE__` [magic constant](http://php.net/manual/en/language.constants.predefined.php)
|
104
|
+
* if you want to specify a passive FTP connection add to the YAML config a `production.ftp.passive` flag and set it to `true`.
|
138
105
|
|
139
|
-
|
140
|
-
If server's certificate is not signed by a known Certificate Authority, you can disable `lftp` check by adding
|
141
|
-
`set ssl:verify-certificate no` to your `~/.lftprc` or `~/.lftp/rc`
|
106
|
+
FTP support is [planned to be discontinued](https://github.com/welaika/wordmove/wiki/FTP-support-disclaimer) at some point of future development.
|
142
107
|
|
143
|
-
|
144
|
-
`lftp` check by adding `set ssl:check-hostname no` to your `~/.lftprc` or `~/.lftp/rc`
|
108
|
+
### Multistage
|
145
109
|
|
146
|
-
More `lftp` [configuration flags here.](https://gist.github.com/gaubert/822090)
|
147
|
-
|
148
|
-
### How the heck you are able to sync the DB via FTP?
|
149
|
-
We're glad you asked! We basically upload via FTP a PHP script that performs the various
|
150
|
-
import/export operations. This script then gets executed via HTTP. Don't worry
|
151
|
-
too much about security though: the script is deleted just after the usage,
|
152
|
-
and can only be executed by `wordmove`, as each time it requires a pre-shared
|
153
|
-
one-time-password to be run.
|
154
|
-
|
155
|
-
## Multi environment
|
156
110
|
You can define multiple environments in your `Movefile`, such as production, staging, etc.
|
157
111
|
Use `-e` with `pull` or `push` to run the command on the specified environment.
|
158
112
|
|
@@ -160,15 +114,27 @@ For example:
|
|
160
114
|
```
|
161
115
|
wordmove push -e staging -d
|
162
116
|
```
|
163
|
-
will push your local database to the staging environment only
|
117
|
+
will push your local database to the staging environment only.
|
118
|
+
|
119
|
+
We warmly **recommend** to read the wiki article: [Multiple environments explained
|
120
|
+
](https://github.com/welaika/wordmove/wiki/Multiple-environments-explained)
|
121
|
+
|
122
|
+
## Notes
|
123
|
+
### How the heck you are able to sync the DB via FTP?
|
124
|
+
|
125
|
+
We're glad you asked! We basically upload via FTP a PHP script that performs the various
|
126
|
+
import/export operations. This script then gets executed via HTTP. Don't worry
|
127
|
+
too much about security though: the script is deleted just after the usage,
|
128
|
+
and can only be executed by `wordmove`, as each time it requires a pre-shared
|
129
|
+
one-time-password to be run.
|
164
130
|
|
165
131
|
## Need more tools?
|
166
132
|
Visit [Wordpress Tools](http://wptools.it).
|
167
133
|
|
168
134
|
## Credits
|
169
135
|
|
170
|
-
* The dump script is the [`MYSQL-dump` PHP package](https://github.com/dg/MySQL-dump) by David Grudl
|
171
|
-
* The import script used is the [BigDump](http://www.ozerov.de/bigdump/) library
|
136
|
+
* The dump script is the [`MYSQL-dump` PHP package](https://github.com/dg/MySQL-dump) by David Grudl
|
137
|
+
* The import script used is the [BigDump](http://www.ozerov.de/bigdump/) library
|
172
138
|
|
173
139
|
## Contribute
|
174
140
|
|
@@ -202,3 +168,4 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
202
168
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
203
169
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
204
170
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
171
|
+
|
data/Rakefile
CHANGED
data/lib/wordmove.rb
CHANGED
@@ -78,20 +78,14 @@ class MySQLDump
|
|
78
78
|
throw new Exception('Argument must be stream resource.');
|
79
79
|
}
|
80
80
|
|
81
|
-
$tables =
|
81
|
+
$tables = array();
|
82
82
|
|
83
|
-
$res = $this->connection->query('SHOW
|
83
|
+
$res = $this->connection->query('SHOW TABLES');
|
84
84
|
while ($row = $res->fetch_row()) {
|
85
|
-
|
86
|
-
$views[] = $row[0];
|
87
|
-
} else {
|
88
|
-
$tables[] = $row[0];
|
89
|
-
}
|
85
|
+
$tables[] = $row[0];
|
90
86
|
}
|
91
87
|
$res->close();
|
92
88
|
|
93
|
-
$tables = array_merge($tables, $views); // views must be last
|
94
|
-
|
95
89
|
$this->connection->query('LOCK TABLES `' . implode('` READ, `', $tables) . '` READ');
|
96
90
|
|
97
91
|
$db = $this->connection->query('SELECT DATABASE()')->fetch_row();
|
@@ -225,4 +219,6 @@ $db_name = '<%= escape_php db[:name] %>';
|
|
225
219
|
|
226
220
|
$connection = new mysqli($db_host, $db_user, $db_password, $db_name, $db_port);
|
227
221
|
$dump = new MySQLDump($connection);
|
228
|
-
$
|
222
|
+
$db_file = 'dump.mysql';
|
223
|
+
$dump->save($db_file);
|
224
|
+
readfile($db_file);
|
data/lib/wordmove/cli.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Wordmove
|
2
2
|
class CLI < Thor
|
3
|
-
map %w
|
3
|
+
map %w(--version -v) => :__print_version
|
4
4
|
|
5
5
|
desc "--version, -v", "Print the version"
|
6
6
|
def __print_version
|
@@ -17,7 +17,6 @@ module Wordmove
|
|
17
17
|
uploads: { aliases: "-u", type: :boolean },
|
18
18
|
themes: { aliases: "-t", type: :boolean },
|
19
19
|
plugins: { aliases: "-p", type: :boolean },
|
20
|
-
mu_plugins: { aliases: "-m", type: :boolean },
|
21
20
|
languages: { aliases: "-l", type: :boolean },
|
22
21
|
db: { aliases: "-d", type: :boolean },
|
23
22
|
|
@@ -32,20 +31,10 @@ module Wordmove
|
|
32
31
|
|
33
32
|
no_tasks do
|
34
33
|
def handle_options(options)
|
35
|
-
|
36
|
-
yield task if options[task] || options[
|
34
|
+
%w(wordpress uploads themes plugins languages db).map(&:to_sym).each do |task|
|
35
|
+
yield task if options[task] || options[:all]
|
37
36
|
end
|
38
37
|
end
|
39
|
-
|
40
|
-
def wordpress_options
|
41
|
-
%w(wordpress uploads themes plugins mu_plugins languages db)
|
42
|
-
end
|
43
|
-
|
44
|
-
def ensure_wordpress_options_presence!(options)
|
45
|
-
return if (options.keys & (wordpress_options + ["all"])).present?
|
46
|
-
puts "No options given. See wordmove --help"
|
47
|
-
exit 1
|
48
|
-
end
|
49
38
|
end
|
50
39
|
|
51
40
|
desc "pull", "Pulls WP data from remote host to the local machine"
|
@@ -53,7 +42,6 @@ module Wordmove
|
|
53
42
|
method_option option, args
|
54
43
|
end
|
55
44
|
def pull
|
56
|
-
ensure_wordpress_options_presence!(options)
|
57
45
|
deployer = Wordmove::Deployer::Base.deployer_for(options)
|
58
46
|
handle_options(options) do |task|
|
59
47
|
deployer.send("pull_#{task}")
|
@@ -65,12 +53,10 @@ module Wordmove
|
|
65
53
|
method_option option, args
|
66
54
|
end
|
67
55
|
def push
|
68
|
-
ensure_wordpress_options_presence!(options)
|
69
56
|
deployer = Wordmove::Deployer::Base.deployer_for(options)
|
70
57
|
handle_options(options) do |task|
|
71
58
|
deployer.send("push_#{task}")
|
72
59
|
end
|
73
60
|
end
|
74
|
-
|
75
61
|
end
|
76
62
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Wordmove
|
2
2
|
module Deployer
|
3
|
-
|
4
3
|
class Base
|
5
4
|
attr_reader :options
|
6
5
|
attr_reader :logger
|
@@ -13,21 +12,20 @@ module Wordmove
|
|
13
12
|
options.merge!(cli_options).deep_symbolize_keys!
|
14
13
|
|
15
14
|
if available_enviroments.size > 1 && options[:environment].nil?
|
16
|
-
raise
|
15
|
+
raise(
|
16
|
+
UndefinedEnvironment,
|
17
|
+
"You need to specify an environment with --environment parameter"
|
18
|
+
)
|
17
19
|
end
|
18
20
|
environment = (options[:environment] || available_enviroments.first).to_sym
|
19
21
|
|
20
|
-
if options[environment][:ftp]
|
21
|
-
|
22
|
-
|
23
|
-
SSH.new(environment, options)
|
24
|
-
else
|
25
|
-
raise NoAdapterFound, "No valid adapter found."
|
26
|
-
end
|
22
|
+
return FTP.new(environment, options) if options[environment][:ftp]
|
23
|
+
return SSH.new(environment, options) if options[environment][:ssh]
|
24
|
+
raise NoAdapterFound, "No valid adapter found."
|
27
25
|
end
|
28
26
|
|
29
27
|
def extract_available_envs(options)
|
30
|
-
options.keys.map(&:to_sym) - [
|
28
|
+
options.keys.map(&:to_sym) - [:local]
|
31
29
|
end
|
32
30
|
|
33
31
|
def fetch_movefile(name = nil, start_dir = current_dir)
|
@@ -35,21 +33,13 @@ module Wordmove
|
|
35
33
|
entries = Dir["#{File.join(start_dir, name)}*"]
|
36
34
|
|
37
35
|
if entries.empty?
|
38
|
-
if last_dir?(start_dir)
|
39
|
-
|
40
|
-
else
|
41
|
-
return fetch_movefile(name, upper_dir(start_dir))
|
42
|
-
end
|
36
|
+
raise MovefileNotFound, "Could not find a valid Movefile" if last_dir?(start_dir)
|
37
|
+
return fetch_movefile(name, upper_dir(start_dir))
|
43
38
|
end
|
44
39
|
|
45
40
|
found = entries.first
|
46
41
|
logger.task("Using Movefile: #{found}")
|
47
|
-
|
48
|
-
YAML::load(File.open(found))
|
49
|
-
rescue Psych::SyntaxError
|
50
|
-
puts "Your Movefile is not a valid YAML file. Please, check your Movefile with a YAML linter such as http://lmgtfy.com/?q=yaml+linter"
|
51
|
-
exit 1
|
52
|
-
end
|
42
|
+
YAML.load(ERB.new(File.read(found)).result)
|
53
43
|
end
|
54
44
|
|
55
45
|
def current_dir
|
@@ -57,7 +47,7 @@ module Wordmove
|
|
57
47
|
end
|
58
48
|
|
59
49
|
def last_dir?(directory)
|
60
|
-
directory == "/" || File.
|
50
|
+
directory == "/" || File.exist?(File.join(directory, 'wp-config.php'))
|
61
51
|
end
|
62
52
|
|
63
53
|
def upper_dir(directory)
|
@@ -84,9 +74,10 @@ module Wordmove
|
|
84
74
|
end
|
85
75
|
|
86
76
|
def remote_get_directory(directory); end
|
77
|
+
|
87
78
|
def remote_put_directory(directory); end
|
88
79
|
|
89
|
-
%w(uploads themes plugins
|
80
|
+
%w(uploads themes plugins languages).each do |task|
|
90
81
|
define_method "push_#{task}" do
|
91
82
|
logger.task "Pushing #{task.titleize}"
|
92
83
|
local_path = send("local_#{task}_dir").path
|
@@ -131,14 +122,14 @@ module Wordmove
|
|
131
122
|
protected
|
132
123
|
|
133
124
|
def paths_to_exclude
|
134
|
-
remote_options[:exclude] ||
|
125
|
+
remote_options[:exclude] || []
|
135
126
|
end
|
136
127
|
|
137
128
|
def run(command)
|
138
129
|
logger.task_step true, command
|
139
130
|
unless simulate?
|
140
131
|
system(command)
|
141
|
-
raise ShellCommandError, "Return code reports an error" unless
|
132
|
+
raise ShellCommandError, "Return code reports an error" unless $CHILD_STATUS.success?
|
142
133
|
end
|
143
134
|
end
|
144
135
|
|
@@ -155,14 +146,14 @@ module Wordmove
|
|
155
146
|
options[:simulate]
|
156
147
|
end
|
157
148
|
|
158
|
-
[
|
149
|
+
[
|
150
|
+
WordpressDirectory::PATH::WP_CONTENT,
|
159
151
|
WordpressDirectory::PATH::PLUGINS,
|
160
|
-
WordpressDirectory::PATH::MU_PLUGINS,
|
161
152
|
WordpressDirectory::PATH::THEMES,
|
162
153
|
WordpressDirectory::PATH::UPLOADS,
|
163
154
|
WordpressDirectory::PATH::LANGUAGES
|
164
155
|
].each do |type|
|
165
|
-
[
|
156
|
+
[:remote, :local].each do |location|
|
166
157
|
define_method "#{location}_#{type}_dir" do
|
167
158
|
options = send("#{location}_options")
|
168
159
|
WordpressDirectory.new(type, options)
|
@@ -173,9 +164,7 @@ module Wordmove
|
|
173
164
|
def adapt_sql(save_to_path, local, remote)
|
174
165
|
unless options[:no_adapt]
|
175
166
|
logger.task_step true, "adapt dump"
|
176
|
-
unless simulate?
|
177
|
-
SqlAdapter.new(save_to_path, local, remote).adapt!
|
178
|
-
end
|
167
|
+
SqlAdapter.new(save_to_path, local, remote).adapt! unless simulate?
|
179
168
|
end
|
180
169
|
end
|
181
170
|
|
@@ -184,11 +173,14 @@ module Wordmove
|
|
184
173
|
command << "--host=#{Shellwords.escape(options[:host])}" if options[:host].present?
|
185
174
|
command << "--port=#{Shellwords.escape(options[:port])}" if options[:port].present?
|
186
175
|
command << "--user=#{Shellwords.escape(options[:user])}" if options[:user].present?
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
176
|
+
if options[:password].present?
|
177
|
+
command << "--password=#{Shellwords.escape(options[:password])}"
|
178
|
+
end
|
179
|
+
if options[:charset].present?
|
180
|
+
command << "--default-character-set=#{Shellwords.escape(options[:charset])}"
|
181
|
+
end
|
191
182
|
command << Shellwords.escape(options[:name])
|
183
|
+
command << "--result-file=#{Shellwords.escape(save_to_path)}"
|
192
184
|
puts command.join(" ")
|
193
185
|
command.join(" ")
|
194
186
|
end
|
@@ -198,29 +190,18 @@ module Wordmove
|
|
198
190
|
command << "--host=#{Shellwords.escape(options[:host])}" if options[:host].present?
|
199
191
|
command << "--port=#{Shellwords.escape(options[:port])}" if options[:port].present?
|
200
192
|
command << "--user=#{Shellwords.escape(options[:user])}" if options[:user].present?
|
201
|
-
|
202
|
-
|
193
|
+
if options[:password].present?
|
194
|
+
command << "--password=#{Shellwords.escape(options[:password])}"
|
195
|
+
end
|
196
|
+
if options[:charset].present?
|
197
|
+
command << "--default-character-set=#{Shellwords.escape(options[:charset])}"
|
198
|
+
end
|
203
199
|
command << "--database=#{Shellwords.escape(options[:name])}"
|
204
200
|
command << "--execute=#{Shellwords.escape("SOURCE #{dump_path}")}"
|
205
201
|
puts command.join(" ")
|
206
202
|
command.join(" ")
|
207
203
|
end
|
208
204
|
|
209
|
-
def compress_command(path)
|
210
|
-
command = ["gzip"]
|
211
|
-
command << "--best"
|
212
|
-
command << Shellwords.escape(path)
|
213
|
-
puts command.join(" ")
|
214
|
-
command.join(" ")
|
215
|
-
end
|
216
|
-
|
217
|
-
def uncompress_command(path)
|
218
|
-
command = ["gunzip"]
|
219
|
-
command << Shellwords.escape(path)
|
220
|
-
puts command.join(" ")
|
221
|
-
command.join(" ")
|
222
|
-
end
|
223
|
-
|
224
205
|
def rm_command(path)
|
225
206
|
"rm #{Shellwords.escape(path)}"
|
226
207
|
end
|
@@ -238,6 +219,5 @@ module Wordmove
|
|
238
219
|
options[:local].clone
|
239
220
|
end
|
240
221
|
end
|
241
|
-
|
242
222
|
end
|
243
223
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Wordmove
|
2
2
|
module Deployer
|
3
3
|
class FTP < Base
|
4
|
-
|
5
4
|
def initialize(environment, options)
|
6
5
|
super
|
7
6
|
ftp_options = remote_options[:ftp]
|
@@ -52,22 +51,18 @@ module Wordmove
|
|
52
51
|
|
53
52
|
%w(get get_directory put_directory delete).each do |command|
|
54
53
|
define_method "remote_#{command}" do |*args|
|
55
|
-
logger.task_step false, "#{command}: #{args.join(
|
56
|
-
unless simulate?
|
57
|
-
@copier.send(command, *args)
|
58
|
-
end
|
54
|
+
logger.task_step false, "#{command}: #{args.join(' ')}"
|
55
|
+
@copier.send(command, *args) unless simulate?
|
59
56
|
end
|
60
57
|
end
|
61
58
|
|
62
59
|
def remote_put(thing, path)
|
63
|
-
if File.
|
60
|
+
if File.exist?(thing)
|
64
61
|
logger.task_step false, "copying #{thing} to #{path}"
|
65
62
|
else
|
66
63
|
logger.task_step false, "write #{path}"
|
67
64
|
end
|
68
|
-
unless simulate?
|
69
|
-
@copier.put(thing, path)
|
70
|
-
end
|
65
|
+
@copier.put(thing, path) unless simulate?
|
71
66
|
end
|
72
67
|
|
73
68
|
def escape_php(string)
|
@@ -75,7 +70,7 @@ module Wordmove
|
|
75
70
|
|
76
71
|
# replaces \ with \\
|
77
72
|
# replaces ' with \'
|
78
|
-
string.gsub('\\','\\\\\\').gsub(/[']/, '\\\\\'')
|
73
|
+
string.gsub('\\', '\\\\\\').gsub(/[']/, '\\\\\'')
|
79
74
|
end
|
80
75
|
|
81
76
|
def generate_dump_script(db, password)
|
@@ -97,7 +92,7 @@ module Wordmove
|
|
97
92
|
# upload the dump script
|
98
93
|
remote_put(dump_script, remote_dump_script)
|
99
94
|
# download the resulting dump (using the password)
|
100
|
-
dump_url = "#{remote_wp_content_dir.url(
|
95
|
+
dump_url = "#{remote_wp_content_dir.url('dump.php')}?shared_key=#{one_time_password}"
|
101
96
|
download(dump_url, local_dump_path)
|
102
97
|
# remove it remotely
|
103
98
|
remote_delete(remote_dump_script)
|
@@ -113,14 +108,16 @@ module Wordmove
|
|
113
108
|
# upload import script
|
114
109
|
remote_put(import_script, remote_import_script_path)
|
115
110
|
# run import script
|
116
|
-
import_url =
|
111
|
+
import_url = [
|
112
|
+
remote_wp_content_dir.url('import.php').to_s,
|
113
|
+
"?shared_key=#{one_time_password}",
|
114
|
+
"&start=1&foffset=0&totalqueries=0&fn=dump.sql"
|
115
|
+
].join
|
117
116
|
download(import_url, temp_path)
|
118
117
|
run rm_command(temp_path)
|
119
118
|
# remove script remotely
|
120
119
|
remote_delete(remote_import_script_path)
|
121
120
|
end
|
122
|
-
|
123
121
|
end
|
124
122
|
end
|
125
123
|
end
|
126
|
-
|
@@ -11,30 +11,23 @@ module Wordmove
|
|
11
11
|
super
|
12
12
|
|
13
13
|
local_dump_path = local_wp_content_dir.path("dump.sql")
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
download_remote_db(local_gizipped_backup_path)
|
14
|
+
local_backup_path = local_wp_content_dir.path("#{environment}-backup-#{Time.now.to_i}.sql")
|
15
|
+
download_remote_db(local_backup_path)
|
18
16
|
|
19
17
|
save_local_db(local_dump_path)
|
20
18
|
adapt_sql(local_dump_path, local_options, remote_options)
|
21
|
-
|
22
|
-
|
23
|
-
run rm_command(local_gzipped_dump_path)
|
19
|
+
import_remote_dump(local_dump_path)
|
20
|
+
run rm_command(local_dump_path)
|
24
21
|
end
|
25
22
|
|
26
23
|
def pull_db
|
27
24
|
super
|
28
25
|
|
29
26
|
local_dump_path = local_wp_content_dir.path("dump.sql")
|
30
|
-
local_gzipped_dump_path = local_dump_path + '.gz'
|
31
27
|
local_backup_path = local_wp_content_dir.path("local-backup-#{Time.now.to_i}.sql")
|
32
|
-
|
33
28
|
save_local_db(local_backup_path)
|
34
|
-
run compress_command(local_backup_path)
|
35
29
|
|
36
|
-
download_remote_db(
|
37
|
-
run uncompress_command(local_gzipped_dump_path)
|
30
|
+
download_remote_db(local_dump_path)
|
38
31
|
adapt_sql(local_dump_path, remote_options, local_options)
|
39
32
|
run mysql_import_command(local_dump_path, local_options[:database])
|
40
33
|
run rm_command(local_dump_path)
|
@@ -44,38 +37,34 @@ module Wordmove
|
|
44
37
|
|
45
38
|
%w(get put get_directory put_directory delete).each do |command|
|
46
39
|
define_method "remote_#{command}" do |*args|
|
47
|
-
logger.task_step false, "#{command}: #{args.join(
|
48
|
-
unless simulate?
|
49
|
-
@copier.send(command, *args)
|
50
|
-
end
|
40
|
+
logger.task_step false, "#{command}: #{args.join(' ')}"
|
41
|
+
@copier.send(command, *args) unless simulate?
|
51
42
|
end
|
52
43
|
end
|
53
44
|
|
54
45
|
def remote_run(command)
|
55
46
|
logger.task_step false, command
|
56
47
|
unless simulate?
|
57
|
-
|
58
|
-
raise
|
48
|
+
_stdout, stderr, exit_code = @copier.exec! command
|
49
|
+
raise(
|
50
|
+
ShellCommandError,
|
51
|
+
"Error code #{exit_code} returned by command \"#{command}\": #{stderr}"
|
52
|
+
) unless exit_code.zero?
|
59
53
|
end
|
60
54
|
end
|
61
55
|
|
62
|
-
def download_remote_db(
|
56
|
+
def download_remote_db(local_dump_path)
|
63
57
|
remote_dump_path = remote_wp_content_dir.path("dump.sql")
|
64
58
|
# dump remote db into file
|
65
59
|
remote_run mysql_dump_command(remote_options[:database], remote_dump_path)
|
66
|
-
remote_run compress_command(remote_dump_path)
|
67
|
-
remote_dump_path += '.gz'
|
68
60
|
# download remote dump
|
69
|
-
remote_get(remote_dump_path,
|
61
|
+
remote_get(remote_dump_path, local_dump_path)
|
70
62
|
remote_delete(remote_dump_path)
|
71
63
|
end
|
72
64
|
|
73
|
-
def import_remote_dump(
|
65
|
+
def import_remote_dump(local_dump_path)
|
74
66
|
remote_dump_path = remote_wp_content_dir.path("dump.sql")
|
75
|
-
|
76
|
-
|
77
|
-
remote_put(local_gizipped_dump_path, remote_gizipped_dump_path)
|
78
|
-
remote_run uncompress_command(remote_gizipped_dump_path)
|
67
|
+
remote_put(local_dump_path, remote_dump_path)
|
79
68
|
remote_run mysql_import_command(remote_dump_path, remote_options[:database])
|
80
69
|
remote_delete(remote_dump_path)
|
81
70
|
end
|
@@ -18,7 +18,6 @@ production:
|
|
18
18
|
password: "password"
|
19
19
|
host: "host"
|
20
20
|
# port: "3308" # Use just in case you have exotic server config
|
21
|
-
# mysqldump_options: "--max_allowed_packet=1G" # Only available if using SSH
|
22
21
|
|
23
22
|
exclude:
|
24
23
|
- ".git/"
|
@@ -36,10 +35,8 @@ production:
|
|
36
35
|
# wp_content: "wp-content"
|
37
36
|
# uploads: "wp-content/uploads"
|
38
37
|
# plugins: "wp-content/plugins"
|
39
|
-
# mu_plugins: "wp-content/mu-plugins"
|
40
38
|
# themes: "wp-content/themes"
|
41
39
|
# languages: "wp-content/languages"
|
42
|
-
# themes: "wp-content/themes"
|
43
40
|
|
44
41
|
# ssh:
|
45
42
|
# host: "host"
|
@@ -61,3 +58,4 @@ production:
|
|
61
58
|
|
62
59
|
# staging: # multiple environments can be specified
|
63
60
|
# [...]
|
61
|
+
|
@@ -28,7 +28,7 @@ module Wordmove
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def wp_config_exists?
|
31
|
-
File.
|
31
|
+
File.exist?(WordpressDirectory.default_path_for(:wp_config))
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -78,8 +78,6 @@ module Wordmove
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
82
81
|
end
|
83
82
|
end
|
84
83
|
end
|
85
|
-
|
data/lib/wordmove/logger.rb
CHANGED
data/lib/wordmove/sql_adapter.rb
CHANGED
@@ -41,12 +41,12 @@ module Wordmove
|
|
41
41
|
def serialized_replace!(source_field, dest_field)
|
42
42
|
length_delta = source_field.length - dest_field.length
|
43
43
|
|
44
|
-
sql_content.gsub!(/s:(\d+):([\\]*['"])(.*?)\2;/) do |
|
45
|
-
length =
|
46
|
-
delimiter =
|
47
|
-
string =
|
44
|
+
sql_content.gsub!(/s:(\d+):([\\]*['"])(.*?)\2;/) do |_|
|
45
|
+
length = Regexp.last_match(1).to_i
|
46
|
+
delimiter = Regexp.last_match(2)
|
47
|
+
string = Regexp.last_match(3)
|
48
48
|
|
49
|
-
string.gsub!(/#{Regexp.escape(source_field)}/) do |
|
49
|
+
string.gsub!(/#{Regexp.escape(source_field)}/) do |_|
|
50
50
|
length -= length_delta
|
51
51
|
dest_field
|
52
52
|
end
|
@@ -60,7 +60,7 @@ module Wordmove
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def write_sql!
|
63
|
-
File.open(sql_path, 'w') {|f| f.write(sql_content) }
|
63
|
+
File.open(sql_path, 'w') { |f| f.write(sql_content) }
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/wordmove/version.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
WordpressDirectory = Struct.new(:type, :options) do
|
3
2
|
module PATH
|
4
3
|
WP_CONTENT = :wp_content
|
5
4
|
WP_CONFIG = :wp_config
|
6
5
|
PLUGINS = :plugins
|
7
|
-
MU_PLUGINS = :mu_plugins
|
8
6
|
THEMES = :themes
|
9
7
|
UPLOADS = :uploads
|
10
8
|
LANGUAGES = :languages
|
@@ -14,11 +12,10 @@ class WordpressDirectory < Struct.new(:type, :options)
|
|
14
12
|
PATH::WP_CONTENT => 'wp-content',
|
15
13
|
PATH::WP_CONFIG => 'wp-config.php',
|
16
14
|
PATH::PLUGINS => 'wp-content/plugins',
|
17
|
-
PATH::MU_PLUGINS => 'wp-content/mu-plugins',
|
18
15
|
PATH::THEMES => 'wp-content/themes',
|
19
16
|
PATH::UPLOADS => 'wp-content/uploads',
|
20
17
|
PATH::LANGUAGES => 'wp-content/languages'
|
21
|
-
}
|
18
|
+
}.freeze
|
22
19
|
|
23
20
|
def self.default_path_for(sym)
|
24
21
|
DEFAULT_PATHS[sym]
|
@@ -40,5 +37,4 @@ class WordpressDirectory < Struct.new(:type, :options)
|
|
40
37
|
end
|
41
38
|
File.join(path, *args)
|
42
39
|
end
|
43
|
-
|
44
40
|
end
|
data/wordmove.gemspec
CHANGED
@@ -7,14 +7,22 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "wordmove"
|
8
8
|
spec.version = Wordmove::VERSION
|
9
9
|
spec.authors = ["Stefano Verna", "Ju Liu", "Fabrizio Monti", "Alessandro Fazzi"]
|
10
|
-
spec.email = [
|
10
|
+
spec.email = [
|
11
|
+
"stefano.verna@welaika.com",
|
12
|
+
"ju.liu@welaika.com",
|
13
|
+
"fabrizio.monti@welaika.com",
|
14
|
+
"alessandro.fazzi@welaika.com"
|
15
|
+
]
|
11
16
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
17
|
+
spec.summary = "Wordmove, Capistrano for Wordpress"
|
18
|
+
spec.description = "Wordmove deploys your WordPress websites at the speed of light."
|
14
19
|
spec.homepage = "https://github.com/welaika/wordmove"
|
15
20
|
spec.license = "MIT"
|
16
21
|
|
17
|
-
spec.files = `git ls-files -z
|
22
|
+
spec.files = `git ls-files -z`
|
23
|
+
.split("\x0")
|
24
|
+
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
|
18
26
|
spec.bindir = "exe"
|
19
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
28
|
spec.require_paths = ["lib"]
|
@@ -32,11 +40,5 @@ Gem::Specification.new do |spec|
|
|
32
40
|
spec.add_development_dependency "simplecov", "~> 0.9"
|
33
41
|
spec.add_development_dependency "pry-byebug", "~> 3.1"
|
34
42
|
spec.add_development_dependency "priscilla", "~> 1.0"
|
35
|
-
|
36
|
-
spec.post_install_message = <<-RAINBOW
|
37
|
-
Starting from 1.4.0 Wordmove will compress SQL dumps both in remote and locale environments.
|
38
|
-
If something will broke, please check if gzip and gunzip executables are present locally and
|
39
|
-
remotely. We are considering obviuos they are installed in any web environment.
|
40
|
-
Open an issue on github at your needs.
|
41
|
-
RAINBOW
|
43
|
+
spec.add_development_dependency "rubocop", "~> 0.37.0"
|
42
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wordmove
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.
|
4
|
+
version: 1.4.0.pre5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefano Verna
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2016-02-05 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: colorize
|
@@ -153,6 +153,20 @@ dependencies:
|
|
153
153
|
- - "~>"
|
154
154
|
- !ruby/object:Gem::Version
|
155
155
|
version: '1.0'
|
156
|
+
- !ruby/object:Gem::Dependency
|
157
|
+
name: rubocop
|
158
|
+
requirement: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - "~>"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: 0.37.0
|
163
|
+
type: :development
|
164
|
+
prerelease: false
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - "~>"
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 0.37.0
|
156
170
|
description: Wordmove deploys your WordPress websites at the speed of light.
|
157
171
|
email:
|
158
172
|
- stefano.verna@welaika.com
|
@@ -202,11 +216,7 @@ homepage: https://github.com/welaika/wordmove
|
|
202
216
|
licenses:
|
203
217
|
- MIT
|
204
218
|
metadata: {}
|
205
|
-
post_install_message:
|
206
|
-
Starting from 1.4.0 Wordmove will compress SQL dumps both in remote and locale environments.
|
207
|
-
If something will broke, please check if gzip and gunzip executables are present locally and
|
208
|
-
remotely. We are considering obviuos they are installed in any web environment.
|
209
|
-
Open an issue on github at your needs.
|
219
|
+
post_install_message:
|
210
220
|
rdoc_options: []
|
211
221
|
require_paths:
|
212
222
|
- lib
|
@@ -222,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
232
|
version: 1.3.1
|
223
233
|
requirements: []
|
224
234
|
rubyforge_project:
|
225
|
-
rubygems_version: 2.
|
235
|
+
rubygems_version: 2.5.1
|
226
236
|
signing_key:
|
227
237
|
specification_version: 4
|
228
238
|
summary: Wordmove, Capistrano for Wordpress
|