wordmove 5.2.1 → 6.0.0.alpha.3
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/.github/workflows/ruby.yml +12 -5
- data/.rubocop.yml +2 -5
- data/.ruby-version +1 -1
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +15 -0
- data/Rakefile +4 -3
- data/exe/wordmove +2 -1
- data/lib/wordmove/actions/adapt_local_db.rb +103 -0
- data/lib/wordmove/actions/adapt_remote_db.rb +90 -0
- data/lib/wordmove/actions/backup_local_db.rb +58 -0
- data/lib/wordmove/actions/delete_local_file.rb +34 -0
- data/lib/wordmove/actions/delete_remote_file.rb +43 -0
- data/lib/wordmove/actions/filter_and_setup_tasks_to_run.rb +42 -0
- data/lib/wordmove/actions/ftp/backup_remote_db.rb +56 -0
- data/lib/wordmove/actions/ftp/cleanup_after_adapt.rb +72 -0
- data/lib/wordmove/actions/ftp/download_remote_db.rb +71 -0
- data/lib/wordmove/actions/ftp/get_directory.rb +67 -0
- data/lib/wordmove/actions/ftp/helpers.rb +91 -0
- data/lib/wordmove/actions/ftp/pull_wordpress.rb +56 -0
- data/lib/wordmove/actions/ftp/push_wordpress.rb +54 -0
- data/lib/wordmove/actions/ftp/put_and_import_dump_remotely.rb +83 -0
- data/lib/wordmove/actions/ftp/put_directory.rb +67 -0
- data/lib/wordmove/actions/get_file.rb +38 -0
- data/lib/wordmove/actions/helpers.rb +142 -0
- data/lib/wordmove/actions/put_file.rb +48 -0
- data/lib/wordmove/actions/run_after_pull_hook.rb +26 -0
- data/lib/wordmove/actions/run_after_push_hook.rb +26 -0
- data/lib/wordmove/actions/run_before_pull_hook.rb +26 -0
- data/lib/wordmove/actions/run_before_push_hook.rb +26 -0
- data/lib/wordmove/actions/run_local_command.rb +34 -0
- data/lib/wordmove/actions/setup_context_for_db.rb +78 -0
- data/lib/wordmove/actions/ssh/backup_remote_db.rb +51 -0
- data/lib/wordmove/actions/ssh/cleanup_after_adapt.rb +56 -0
- data/lib/wordmove/actions/ssh/download_remote_db.rb +83 -0
- data/lib/wordmove/actions/ssh/get_directory.rb +76 -0
- data/lib/wordmove/actions/ssh/helpers.rb +128 -0
- data/lib/wordmove/actions/ssh/pull_wordpress.rb +56 -0
- data/lib/wordmove/actions/ssh/push_wordpress.rb +54 -0
- data/lib/wordmove/actions/ssh/put_and_import_dump_remotely.rb +77 -0
- data/lib/wordmove/actions/ssh/put_directory.rb +76 -0
- data/lib/wordmove/actions/ssh/run_remote_command.rb +39 -0
- data/lib/wordmove/assets/dump.php.erb +6 -6
- data/lib/wordmove/assets/import.php.erb +7 -7
- data/lib/wordmove/assets/wordmove_schema_global.yml +2 -0
- data/lib/wordmove/assets/wordmove_schema_remote.yml +2 -2
- data/lib/wordmove/cli.rb +152 -91
- data/lib/wordmove/db_paths_config.rb +44 -0
- data/lib/wordmove/doctor/movefile.rb +8 -8
- data/lib/wordmove/doctor/mysql.rb +18 -15
- data/lib/wordmove/doctor/rsync.rb +2 -2
- data/lib/wordmove/doctor/ssh.rb +3 -3
- data/lib/wordmove/doctor/wpcli.rb +5 -5
- data/lib/wordmove/environments_list.rb +4 -4
- data/lib/wordmove/exceptions.rb +13 -0
- data/lib/wordmove/generators/movefile.rb +7 -5
- data/lib/wordmove/generators/movefile_adapter.rb +11 -5
- data/lib/wordmove/guardian.rb +5 -5
- data/lib/wordmove/hook.rb +13 -14
- data/lib/wordmove/logger.rb +11 -10
- data/lib/wordmove/movefile.rb +63 -59
- data/lib/wordmove/organizers/ftp/pull.rb +52 -0
- data/lib/wordmove/organizers/ftp/push.rb +53 -0
- data/lib/wordmove/organizers/ssh/pull.rb +52 -0
- data/lib/wordmove/organizers/ssh/push.rb +53 -0
- data/lib/wordmove/version.rb +1 -1
- data/lib/wordmove/wordpress_directory.rb +76 -8
- data/lib/wordmove/wpcli.rb +88 -0
- data/lib/wordmove.rb +33 -11
- data/wordmove.gemspec +37 -30
- metadata +139 -35
- data/lib/wordmove/deployer/base.rb +0 -193
- data/lib/wordmove/deployer/ftp.rb +0 -160
- data/lib/wordmove/deployer/ssh/default_sql_adapter.rb +0 -47
- data/lib/wordmove/deployer/ssh/wpcli_sql_adapter.rb +0 -55
- data/lib/wordmove/deployer/ssh.rb +0 -169
- data/lib/wordmove/sql_adapter/default.rb +0 -68
- data/lib/wordmove/sql_adapter/wpcli.rb +0 -54
- data/lib/wordmove/wordpress_directory/path.rb +0 -11
@@ -1,47 +0,0 @@
|
|
1
|
-
module Wordmove
|
2
|
-
module Deployer
|
3
|
-
module Ssh
|
4
|
-
class DefaultSqlAdapter < SSH
|
5
|
-
private
|
6
|
-
|
7
|
-
def backup_remote_db!
|
8
|
-
download_remote_db(local_gzipped_backup_path)
|
9
|
-
end
|
10
|
-
|
11
|
-
def adapt_local_db!
|
12
|
-
save_local_db(local_dump_path)
|
13
|
-
adapt_sql(local_dump_path, local_options, remote_options)
|
14
|
-
run compress_command(local_dump_path)
|
15
|
-
import_remote_dump(local_gzipped_dump_path)
|
16
|
-
end
|
17
|
-
|
18
|
-
def after_push_cleanup!
|
19
|
-
local_delete(local_gzipped_dump_path)
|
20
|
-
end
|
21
|
-
|
22
|
-
def backup_local_db!
|
23
|
-
save_local_db(local_backup_path)
|
24
|
-
run compress_command(local_backup_path)
|
25
|
-
end
|
26
|
-
|
27
|
-
def adapt_remote_db!
|
28
|
-
download_remote_db(local_gzipped_dump_path)
|
29
|
-
run uncompress_command(local_gzipped_dump_path)
|
30
|
-
adapt_sql(local_dump_path, remote_options, local_options)
|
31
|
-
run mysql_import_command(local_dump_path, local_options[:database])
|
32
|
-
end
|
33
|
-
|
34
|
-
def after_pull_cleanup!
|
35
|
-
local_delete(local_dump_path)
|
36
|
-
end
|
37
|
-
|
38
|
-
def adapt_sql(save_to_path, local, remote)
|
39
|
-
return if options[:no_adapt]
|
40
|
-
|
41
|
-
logger.task_step true, "Adapt dump"
|
42
|
-
SqlAdapter::Default.new(save_to_path, local, remote).adapt! unless simulate?
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Wordmove
|
2
|
-
module Deployer
|
3
|
-
module Ssh
|
4
|
-
class WpcliSqlAdapter < SSH
|
5
|
-
def backup_remote_db!
|
6
|
-
download_remote_db(local_gzipped_backup_path)
|
7
|
-
end
|
8
|
-
|
9
|
-
def adapt_local_db!
|
10
|
-
save_local_db(local_dump_path)
|
11
|
-
run wpcli_search_replace(local_options, remote_options, :vhost)
|
12
|
-
run wpcli_search_replace(local_options, remote_options, :wordpress_path)
|
13
|
-
|
14
|
-
local_search_replace_dump_path = local_wp_content_dir.path("search_replace_dump.sql")
|
15
|
-
local_gzipped_search_replace_dump_path = local_search_replace_dump_path + '.gz'
|
16
|
-
|
17
|
-
save_local_db(local_search_replace_dump_path)
|
18
|
-
run compress_command(local_search_replace_dump_path)
|
19
|
-
import_remote_dump(local_gzipped_search_replace_dump_path)
|
20
|
-
local_delete(local_gzipped_search_replace_dump_path)
|
21
|
-
run mysql_import_command(local_dump_path, local_options[:database])
|
22
|
-
end
|
23
|
-
|
24
|
-
def after_push_cleanup!
|
25
|
-
local_delete(local_dump_path)
|
26
|
-
end
|
27
|
-
|
28
|
-
def backup_local_db!
|
29
|
-
save_local_db(local_backup_path)
|
30
|
-
run compress_command(local_backup_path)
|
31
|
-
end
|
32
|
-
|
33
|
-
def adapt_remote_db!
|
34
|
-
download_remote_db(local_gzipped_dump_path)
|
35
|
-
run uncompress_command(local_gzipped_dump_path)
|
36
|
-
run mysql_import_command(local_dump_path, local_options[:database])
|
37
|
-
run wpcli_search_replace(remote_options, local_options, :vhost)
|
38
|
-
run wpcli_search_replace(remote_options, local_options, :wordpress_path)
|
39
|
-
end
|
40
|
-
|
41
|
-
def after_pull_cleanup!
|
42
|
-
local_delete(local_dump_path)
|
43
|
-
end
|
44
|
-
|
45
|
-
def wpcli_search_replace(local, remote, config_key)
|
46
|
-
return if options[:no_adapt]
|
47
|
-
|
48
|
-
logger.task_step true, "adapt dump for #{config_key}"
|
49
|
-
path = local_options[:wordpress_path]
|
50
|
-
SqlAdapter::Wpcli.new(local, remote, config_key, path).command unless simulate?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,169 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
|
-
module Wordmove
|
4
|
-
module Deployer
|
5
|
-
class SSH < Base
|
6
|
-
attr_reader :local_dump_path,
|
7
|
-
:local_backup_path,
|
8
|
-
:local_gzipped_dump_path,
|
9
|
-
:local_gzipped_backup_path
|
10
|
-
|
11
|
-
def initialize(environment, options)
|
12
|
-
super(environment, options)
|
13
|
-
ssh_options = remote_options[:ssh]
|
14
|
-
|
15
|
-
if simulate? && ssh_options[:rsync_options]
|
16
|
-
ssh_options[:rsync_options].concat(" --dry-run")
|
17
|
-
elsif simulate?
|
18
|
-
ssh_options[:rsync_options] = "--dry-run"
|
19
|
-
end
|
20
|
-
|
21
|
-
@copier = Photocopier::SSH.new(ssh_options).tap { |c| c.logger = logger }
|
22
|
-
|
23
|
-
@local_dump_path = local_wp_content_dir.path("dump.sql")
|
24
|
-
@local_backup_path = local_wp_content_dir.path("local-backup-#{Time.now.to_i}.sql")
|
25
|
-
@local_gzipped_dump_path = local_dump_path + '.gz'
|
26
|
-
@local_gzipped_backup_path = local_wp_content_dir
|
27
|
-
.path("#{environment}-backup-#{Time.now.to_i}.sql.gz")
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def push_db
|
33
|
-
super
|
34
|
-
|
35
|
-
return true if simulate?
|
36
|
-
|
37
|
-
backup_remote_db!
|
38
|
-
adapt_local_db!
|
39
|
-
after_push_cleanup!
|
40
|
-
end
|
41
|
-
|
42
|
-
def pull_db
|
43
|
-
super
|
44
|
-
|
45
|
-
return true if simulate?
|
46
|
-
|
47
|
-
backup_local_db!
|
48
|
-
adapt_remote_db!
|
49
|
-
after_pull_cleanup!
|
50
|
-
end
|
51
|
-
|
52
|
-
# In following commands, we do not guard for simulate?
|
53
|
-
# because it is handled through --dry-run rsync option.
|
54
|
-
# @see initialize
|
55
|
-
%w[get put get_directory put_directory delete].each do |command|
|
56
|
-
define_method "remote_#{command}" do |*args|
|
57
|
-
logger.task_step false, "#{command}: #{args.join(' ')}"
|
58
|
-
@copier.send(command, *args)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def remote_run(command)
|
63
|
-
logger.task_step false, command
|
64
|
-
return true if simulate?
|
65
|
-
|
66
|
-
_stdout, stderr, exit_code = @copier.exec! command
|
67
|
-
|
68
|
-
return true if exit_code.zero?
|
69
|
-
|
70
|
-
raise(
|
71
|
-
ShellCommandError,
|
72
|
-
"Error code #{exit_code} returned by command \"#{command}\": #{stderr}"
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
|
-
def download_remote_db(local_gizipped_dump_path)
|
77
|
-
remote_dump_path = remote_wp_content_dir.path("dump.sql")
|
78
|
-
# dump remote db into file
|
79
|
-
remote_run mysql_dump_command(remote_options[:database], remote_dump_path)
|
80
|
-
remote_run compress_command(remote_dump_path)
|
81
|
-
remote_dump_path += '.gz'
|
82
|
-
# download remote dump
|
83
|
-
remote_get(remote_dump_path, local_gizipped_dump_path)
|
84
|
-
remote_delete(remote_dump_path)
|
85
|
-
end
|
86
|
-
|
87
|
-
def import_remote_dump(local_gizipped_dump_path)
|
88
|
-
remote_dump_path = remote_wp_content_dir.path("dump.sql")
|
89
|
-
remote_gizipped_dump_path = remote_dump_path + '.gz'
|
90
|
-
|
91
|
-
remote_put(local_gizipped_dump_path, remote_gizipped_dump_path)
|
92
|
-
remote_run uncompress_command(remote_gizipped_dump_path)
|
93
|
-
remote_run mysql_import_command(remote_dump_path, remote_options[:database])
|
94
|
-
remote_delete(remote_dump_path)
|
95
|
-
end
|
96
|
-
|
97
|
-
%w[uploads themes plugins mu_plugins languages].each do |task|
|
98
|
-
define_method "push_#{task}" do
|
99
|
-
logger.task "Pushing #{task.titleize}"
|
100
|
-
local_path = local_options[:wordpress_path]
|
101
|
-
remote_path = remote_options[:wordpress_path]
|
102
|
-
|
103
|
-
remote_put_directory(local_path, remote_path,
|
104
|
-
push_exclude_paths(task), push_inlcude_paths(task))
|
105
|
-
end
|
106
|
-
|
107
|
-
define_method "pull_#{task}" do
|
108
|
-
logger.task "Pulling #{task.titleize}"
|
109
|
-
local_path = local_options[:wordpress_path]
|
110
|
-
remote_path = remote_options[:wordpress_path]
|
111
|
-
remote_get_directory(remote_path, local_path,
|
112
|
-
pull_exclude_paths(task), pull_include_paths(task))
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def push_inlcude_paths(task)
|
117
|
-
Pathname.new(send(:"local_#{task}_dir").relative_path)
|
118
|
-
.ascend
|
119
|
-
.each_with_object([]) do |directory, array|
|
120
|
-
path = directory.to_path
|
121
|
-
path.prepend('/') unless path.match? %r{^/}
|
122
|
-
path.concat('/') unless path.match? %r{/$}
|
123
|
-
array << path
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def push_exclude_paths(task)
|
128
|
-
Pathname.new(send(:"local_#{task}_dir").relative_path)
|
129
|
-
.dirname
|
130
|
-
.ascend
|
131
|
-
.each_with_object([]) do |directory, array|
|
132
|
-
path = directory.to_path
|
133
|
-
path.prepend('/') unless path.match? %r{^/}
|
134
|
-
path.concat('/') unless path.match? %r{/$}
|
135
|
-
path.concat('*')
|
136
|
-
array << path
|
137
|
-
end
|
138
|
-
.concat(paths_to_exclude)
|
139
|
-
.concat(['/*'])
|
140
|
-
end
|
141
|
-
|
142
|
-
def pull_include_paths(task)
|
143
|
-
Pathname.new(send(:"remote_#{task}_dir").relative_path)
|
144
|
-
.ascend
|
145
|
-
.each_with_object([]) do |directory, array|
|
146
|
-
path = directory.to_path
|
147
|
-
path.prepend('/') unless path.match? %r{^/}
|
148
|
-
path.concat('/') unless path.match? %r{/$}
|
149
|
-
array << path
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def pull_exclude_paths(task)
|
154
|
-
Pathname.new(send(:"remote_#{task}_dir").relative_path)
|
155
|
-
.dirname
|
156
|
-
.ascend
|
157
|
-
.each_with_object([]) do |directory, array|
|
158
|
-
path = directory.to_path
|
159
|
-
path.prepend('/') unless path.match? %r{^/}
|
160
|
-
path.concat('/') unless path.match? %r{/$}
|
161
|
-
path.concat('*')
|
162
|
-
array << path
|
163
|
-
end
|
164
|
-
.concat(paths_to_exclude)
|
165
|
-
.concat(['/*'])
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module Wordmove
|
2
|
-
module SqlAdapter
|
3
|
-
class Default
|
4
|
-
attr_writer :sql_content
|
5
|
-
attr_reader :sql_path, :source_config, :dest_config
|
6
|
-
|
7
|
-
def initialize(sql_path, source_config, dest_config)
|
8
|
-
@sql_path = sql_path
|
9
|
-
@source_config = source_config
|
10
|
-
@dest_config = dest_config
|
11
|
-
end
|
12
|
-
|
13
|
-
def sql_content
|
14
|
-
@sql_content ||= File.open(sql_path).read
|
15
|
-
end
|
16
|
-
|
17
|
-
def adapt!
|
18
|
-
replace_vhost!
|
19
|
-
replace_wordpress_path!
|
20
|
-
write_sql!
|
21
|
-
end
|
22
|
-
|
23
|
-
def replace_vhost!
|
24
|
-
source_vhost = source_config[:vhost]
|
25
|
-
dest_vhost = dest_config[:vhost]
|
26
|
-
replace_field!(source_vhost, dest_vhost)
|
27
|
-
end
|
28
|
-
|
29
|
-
def replace_wordpress_path!
|
30
|
-
source_path = source_config[:wordpress_absolute_path] || source_config[:wordpress_path]
|
31
|
-
dest_path = dest_config[:wordpress_absolute_path] || dest_config[:wordpress_path]
|
32
|
-
replace_field!(source_path, dest_path)
|
33
|
-
end
|
34
|
-
|
35
|
-
def replace_field!(source_field, dest_field)
|
36
|
-
return false unless source_field && dest_field
|
37
|
-
|
38
|
-
serialized_replace!(source_field, dest_field)
|
39
|
-
simple_replace!(source_field, dest_field)
|
40
|
-
end
|
41
|
-
|
42
|
-
def serialized_replace!(source_field, dest_field)
|
43
|
-
length_delta = source_field.length - dest_field.length
|
44
|
-
|
45
|
-
sql_content.gsub!(/s:(\d+):([\\]*['"])(.*?)\2;/) do |_|
|
46
|
-
length = Regexp.last_match(1).to_i
|
47
|
-
delimiter = Regexp.last_match(2)
|
48
|
-
string = Regexp.last_match(3)
|
49
|
-
|
50
|
-
string.gsub!(/#{Regexp.escape(source_field)}/) do |_|
|
51
|
-
length -= length_delta
|
52
|
-
dest_field
|
53
|
-
end
|
54
|
-
|
55
|
-
%(s:#{length}:#{delimiter}#{string}#{delimiter};)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def simple_replace!(source_field, dest_field)
|
60
|
-
sql_content.gsub!(source_field, dest_field)
|
61
|
-
end
|
62
|
-
|
63
|
-
def write_sql!
|
64
|
-
File.open(sql_path, 'w') { |f| f.write(sql_content) }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module Wordmove
|
2
|
-
module SqlAdapter
|
3
|
-
class Wpcli
|
4
|
-
attr_accessor :sql_content
|
5
|
-
attr_reader :from, :to, :local_path
|
6
|
-
|
7
|
-
def initialize(source_config, dest_config, config_key, local_path)
|
8
|
-
@from = source_config[config_key]
|
9
|
-
@to = dest_config[config_key]
|
10
|
-
@local_path = local_path
|
11
|
-
end
|
12
|
-
|
13
|
-
def command
|
14
|
-
unless wp_in_path?
|
15
|
-
raise UnmetPeerDependencyError, "WP-CLI is not installed or not in your $PATH"
|
16
|
-
end
|
17
|
-
|
18
|
-
opts = [
|
19
|
-
"--path=#{cli_config_path}",
|
20
|
-
from,
|
21
|
-
to,
|
22
|
-
"--quiet",
|
23
|
-
"--skip-columns=guid",
|
24
|
-
"--all-tables",
|
25
|
-
"--allow-root"
|
26
|
-
]
|
27
|
-
|
28
|
-
"wp search-replace #{opts.join(' ')}"
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def wp_in_path?
|
34
|
-
system('which wp > /dev/null 2>&1')
|
35
|
-
end
|
36
|
-
|
37
|
-
def cli_config_path
|
38
|
-
load_from_yml || load_from_cli || local_path
|
39
|
-
end
|
40
|
-
|
41
|
-
def load_from_yml
|
42
|
-
cli_config_path = File.join(local_path, "wp-cli.yml")
|
43
|
-
return unless File.exist?(cli_config_path)
|
44
|
-
|
45
|
-
YAML.load_file(cli_config_path).with_indifferent_access["path"]
|
46
|
-
end
|
47
|
-
|
48
|
-
def load_from_cli
|
49
|
-
cli_config = JSON.parse(`wp cli param-dump --with-values`, symbolize_names: true)
|
50
|
-
cli_config.dig(:path, :current)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|