wordmove 5.2.0 → 6.0.0.alpha.2
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 +78 -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 +4 -4
- 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 +15 -16
- 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 +85 -0
- data/lib/wordmove.rb +33 -11
- data/wordmove.gemspec +37 -30
- metadata +141 -43
- 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
@@ -0,0 +1,44 @@
|
|
1
|
+
class DbPathsConfig
|
2
|
+
extend Dry::Configurable
|
3
|
+
|
4
|
+
setting :local, reader: true do
|
5
|
+
setting :path
|
6
|
+
setting :gzipped_path
|
7
|
+
setting :adapted_path
|
8
|
+
setting :gzipped_adapted_path
|
9
|
+
end
|
10
|
+
|
11
|
+
setting :remote, reader: true do
|
12
|
+
setting :path
|
13
|
+
setting :gzipped_path
|
14
|
+
end
|
15
|
+
|
16
|
+
setting :backup, reader: true do
|
17
|
+
setting :local do
|
18
|
+
setting :path
|
19
|
+
setting :gzipped_path
|
20
|
+
end
|
21
|
+
|
22
|
+
setting :remote do
|
23
|
+
setting :path
|
24
|
+
setting :gzipped_path
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# FTP settings are intentionally taken apart
|
29
|
+
setting :ftp, reader: true do
|
30
|
+
setting :remote, reader: true do
|
31
|
+
setting :dump_script_path
|
32
|
+
setting :dump_script_url
|
33
|
+
setting :dumped_path
|
34
|
+
setting :import_script_path
|
35
|
+
setting :import_script_url
|
36
|
+
end
|
37
|
+
setting :local, reader: true do
|
38
|
+
setting :generated_dump_script_path
|
39
|
+
setting :generated_import_script_path
|
40
|
+
setting :temp_path
|
41
|
+
end
|
42
|
+
setting :token
|
43
|
+
end
|
44
|
+
end
|
@@ -4,17 +4,17 @@ module Wordmove
|
|
4
4
|
MANDATORY_SECTIONS = %i[global local].freeze
|
5
5
|
attr_reader :movefile, :contents, :root_keys
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@movefile = Wordmove::Movefile.new(
|
7
|
+
def initialize(cli_options = {}, dir = '.')
|
8
|
+
@movefile = Wordmove::Movefile.new(cli_options, dir)
|
9
9
|
|
10
10
|
begin
|
11
|
-
@contents = movefile.
|
11
|
+
@contents = movefile.options
|
12
12
|
@root_keys = contents.keys
|
13
13
|
rescue Psych::SyntaxError
|
14
|
-
movefile.logger.error
|
14
|
+
movefile.logger.error 'Your movefile is not parsable due to a syntax error'\
|
15
15
|
"so we can't continue to validate it."
|
16
|
-
movefile.logger.debug
|
17
|
-
|
16
|
+
movefile.logger.debug 'You could try to use https://yamlvalidator.com/ to'\
|
17
|
+
'get a clue about the problem.'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -40,7 +40,7 @@ module Wordmove
|
|
40
40
|
errors = validator.validate(contents[key].deep_stringify_keys)
|
41
41
|
|
42
42
|
if errors&.empty?
|
43
|
-
movefile.logger.success
|
43
|
+
movefile.logger.success 'Formal validation passed'
|
44
44
|
|
45
45
|
return true
|
46
46
|
end
|
@@ -69,7 +69,7 @@ module Wordmove
|
|
69
69
|
def validate_protocol_presence(keys)
|
70
70
|
return true if keys.include?(:ssh) || keys.include?(:ftp)
|
71
71
|
|
72
|
-
movefile.logger.error
|
72
|
+
movefile.logger.error 'This remote has not ssh nor ftp protocol defined'
|
73
73
|
|
74
74
|
false
|
75
75
|
end
|
@@ -4,16 +4,18 @@ module Wordmove
|
|
4
4
|
attr_reader :config, :logger
|
5
5
|
|
6
6
|
def initialize(movefile_name = nil, movefile_dir = '.')
|
7
|
-
@logger = Logger.new(
|
7
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
8
8
|
begin
|
9
|
-
@config = Wordmove::Movefile
|
10
|
-
|
11
|
-
|
9
|
+
@config = Wordmove::Movefile
|
10
|
+
.new({ config: movefile_name }, movefile_dir)
|
11
|
+
.options[:local][:database]
|
12
|
+
rescue Psych::SyntaxError => e
|
13
|
+
logger.error e.message
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
17
|
def check!
|
16
|
-
logger.task
|
18
|
+
logger.task 'Checking local database commands and connection'
|
17
19
|
|
18
20
|
return logger.error "Can't connect to mysql using your movefile.yml" if config.nil?
|
19
21
|
|
@@ -26,18 +28,18 @@ module Wordmove
|
|
26
28
|
private
|
27
29
|
|
28
30
|
def mysql_client_doctor
|
29
|
-
if system(
|
30
|
-
logger.success
|
31
|
+
if system('which mysql', out: File::NULL)
|
32
|
+
logger.success '`mysql` command is in $PATH'
|
31
33
|
else
|
32
|
-
logger.error
|
34
|
+
logger.error '`mysql` command is not in $PATH'
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
def mysqldump_doctor
|
37
|
-
if system(
|
38
|
-
logger.success
|
39
|
+
if system('which mysqldump', out: File::NULL)
|
40
|
+
logger.success '`mysqldump` command is in $PATH"'
|
39
41
|
else
|
40
|
-
logger.error
|
42
|
+
logger.error '`mysqldump` command is not in $PATH'
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -45,7 +47,7 @@ module Wordmove
|
|
45
47
|
command = mysql_command
|
46
48
|
|
47
49
|
if system(command, out: File::NULL, err: File::NULL)
|
48
|
-
logger.success
|
50
|
+
logger.success 'Successfully connected to the MySQL server'
|
49
51
|
else
|
50
52
|
logger.error <<-LONG
|
51
53
|
We can't connect to the MySQL server using credentials
|
@@ -63,7 +65,7 @@ module Wordmove
|
|
63
65
|
command = mysql_command(database: config[:name])
|
64
66
|
|
65
67
|
if system(command, out: File::NULL, err: File::NULL)
|
66
|
-
logger.success
|
68
|
+
logger.success 'Successfully connected to the database'
|
67
69
|
else
|
68
70
|
logger.error <<-LONG
|
69
71
|
We can't connect to the database using credentials
|
@@ -79,16 +81,17 @@ module Wordmove
|
|
79
81
|
end
|
80
82
|
|
81
83
|
def mysql_command(database: nil)
|
82
|
-
command = [
|
84
|
+
command = ['mysql']
|
83
85
|
command << "--host=#{Shellwords.escape(config[:host])}" if config[:host].present?
|
84
86
|
command << "--port=#{Shellwords.escape(config[:port])}" if config[:port].present?
|
85
87
|
command << "--user=#{Shellwords.escape(config[:user])}" if config[:user].present?
|
86
88
|
if config[:password].present?
|
87
89
|
command << "--password=#{Shellwords.escape(config[:password])}"
|
88
90
|
end
|
91
|
+
command << Shellwords.split(config[:mysql_options]) if config[:mysql_options].present?
|
89
92
|
command << database if database.present?
|
90
93
|
command << "-e'QUIT'"
|
91
|
-
command.join(
|
94
|
+
command.join(' ')
|
92
95
|
end
|
93
96
|
end
|
94
97
|
end
|
@@ -4,11 +4,11 @@ module Wordmove
|
|
4
4
|
attr_reader :logger
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
@logger = Logger.new(
|
7
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
8
8
|
end
|
9
9
|
|
10
10
|
def check!
|
11
|
-
logger.task
|
11
|
+
logger.task 'Checking rsync'
|
12
12
|
|
13
13
|
if (version = /\d\.\d.\d/.match(`rsync --version | head -n1`)[0])
|
14
14
|
logger.success "rsync is installed at version #{version}"
|
data/lib/wordmove/doctor/ssh.rb
CHANGED
@@ -4,14 +4,14 @@ module Wordmove
|
|
4
4
|
attr_reader :logger
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
@logger = Logger.new(
|
7
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
8
8
|
end
|
9
9
|
|
10
10
|
def check!
|
11
|
-
logger.task
|
11
|
+
logger.task 'Checking SSH client'
|
12
12
|
|
13
13
|
if system('which ssh', out: File::NULL, err: File::NULL)
|
14
|
-
logger.success
|
14
|
+
logger.success 'SSH command found'
|
15
15
|
else
|
16
16
|
logger.error "SSH command not found. And belive me: it's really strange it's not there."
|
17
17
|
end
|
@@ -4,17 +4,17 @@ module Wordmove
|
|
4
4
|
attr_reader :logger
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
@logger = Logger.new(
|
7
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
8
8
|
end
|
9
9
|
|
10
10
|
def check!
|
11
|
-
logger.task
|
11
|
+
logger.task 'Checking local wp-cli installation'
|
12
12
|
|
13
13
|
if in_path?
|
14
|
-
logger.success
|
14
|
+
logger.success 'wp-cli is correctly installed'
|
15
15
|
|
16
16
|
if up_to_date?
|
17
|
-
logger.success
|
17
|
+
logger.success 'wp-cli is up to date'
|
18
18
|
else
|
19
19
|
logger.error <<-LONG
|
20
20
|
wp-cli is not up to date.
|
@@ -9,8 +9,8 @@ module Wordmove
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(options)
|
12
|
-
@logger = Logger.new(
|
13
|
-
@movefile = Wordmove::Movefile.new(options
|
12
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
13
|
+
@movefile = Wordmove::Movefile.new(options)
|
14
14
|
@remote_vhosts = []
|
15
15
|
@local_vhost = []
|
16
16
|
end
|
@@ -29,7 +29,7 @@ module Wordmove
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def parse_movefile(movefile:)
|
32
|
-
movefile.
|
32
|
+
movefile.options
|
33
33
|
end
|
34
34
|
|
35
35
|
def output
|
@@ -43,7 +43,7 @@ module Wordmove
|
|
43
43
|
def output_string(vhost_list:)
|
44
44
|
return 'vhost list is empty' if vhost_list.empty?
|
45
45
|
|
46
|
-
vhost_list.each_with_object(
|
46
|
+
vhost_list.each_with_object('') do |entry, retval|
|
47
47
|
retval << "#{entry[:env]}: #{entry[:vhost]}\n"
|
48
48
|
end
|
49
49
|
end
|
data/lib/wordmove/exceptions.rb
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
module Wordmove
|
2
2
|
class UndefinedEnvironment < StandardError; end
|
3
|
+
|
3
4
|
class NoAdapterFound < StandardError; end
|
5
|
+
|
4
6
|
class MovefileNotFound < StandardError; end
|
7
|
+
|
5
8
|
class ShellCommandError < StandardError; end
|
9
|
+
|
6
10
|
class ImplementInSubclassError < StandardError; end
|
11
|
+
|
7
12
|
class UnmetPeerDependencyError < StandardError; end
|
13
|
+
|
8
14
|
class RemoteHookException < StandardError; end
|
15
|
+
|
9
16
|
class LocalHookException < StandardError; end
|
17
|
+
|
18
|
+
class FtpNotSupportedException < StandardError
|
19
|
+
def message
|
20
|
+
'FTP protocol is no more supported in verison >= 6.0'
|
21
|
+
end
|
22
|
+
end
|
10
23
|
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
module Wordmove
|
2
2
|
module Generators
|
3
|
-
class Movefile
|
4
|
-
include Thor::Actions
|
3
|
+
class Movefile
|
5
4
|
include MovefileAdapter
|
6
5
|
|
7
|
-
def self.
|
8
|
-
|
6
|
+
def self.generate
|
7
|
+
new.copy_movefile
|
9
8
|
end
|
10
9
|
|
11
10
|
def copy_movefile
|
12
|
-
|
11
|
+
content = ERB.new(File.read(File.join(__dir__, 'movefile.yml'))).result(binding)
|
12
|
+
files = Dry::Files.new
|
13
|
+
|
14
|
+
files.write('movefile.yml', content)
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -16,7 +16,13 @@ module Wordmove
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def config
|
19
|
-
|
19
|
+
Struct.new(
|
20
|
+
:name,
|
21
|
+
:user,
|
22
|
+
:password,
|
23
|
+
:host,
|
24
|
+
keyword_init: true
|
25
|
+
).new(database_config)
|
20
26
|
end
|
21
27
|
|
22
28
|
def database_config
|
@@ -35,10 +41,10 @@ module Wordmove
|
|
35
41
|
class DefaultDBConfig
|
36
42
|
def self.config
|
37
43
|
{
|
38
|
-
name:
|
39
|
-
user:
|
40
|
-
password:
|
41
|
-
host:
|
44
|
+
name: 'database_name',
|
45
|
+
user: 'user',
|
46
|
+
password: 'password',
|
47
|
+
host: '127.0.0.1'
|
42
48
|
}
|
43
49
|
end
|
44
50
|
end
|
data/lib/wordmove/guardian.rb
CHANGED
@@ -2,11 +2,11 @@ module Wordmove
|
|
2
2
|
class Guardian
|
3
3
|
attr_reader :movefile, :environment, :action, :logger
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@movefile = Wordmove::Movefile.new(
|
7
|
-
@environment = @movefile.environment
|
5
|
+
def initialize(cli_options: nil, action: nil)
|
6
|
+
@movefile = Wordmove::Movefile.new(cli_options, nil, false)
|
7
|
+
@environment = @movefile.environment.to_sym
|
8
8
|
@action = action
|
9
|
-
@logger = Logger.new(
|
9
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::DEBUG }
|
10
10
|
end
|
11
11
|
|
12
12
|
def allows(task)
|
@@ -27,7 +27,7 @@ module Wordmove
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def forbidden_tasks
|
30
|
-
environment_options = movefile.
|
30
|
+
environment_options = movefile.options[environment]
|
31
31
|
return {} unless environment_options.key?(:forbid)
|
32
32
|
return {} unless environment_options[:forbid].key?(action)
|
33
33
|
|
data/lib/wordmove/hook.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Wordmove
|
2
2
|
class Hook
|
3
3
|
def self.logger
|
4
|
-
Logger.new(
|
4
|
+
Logger.new($stdout).tap { |l| l.level = Logger::DEBUG }
|
5
5
|
end
|
6
6
|
|
7
7
|
# rubocop:disable Metrics/MethodLength
|
8
|
-
def self.run(action, step,
|
9
|
-
|
10
|
-
|
11
|
-
environment = movefile.environment(cli_options)
|
8
|
+
def self.run(action, step, movefile:, simulate: false)
|
9
|
+
options = movefile.options
|
10
|
+
environment = movefile.environment
|
12
11
|
|
13
12
|
hooks = Wordmove::Hook::Config.new(
|
14
13
|
options[environment][:hooks],
|
@@ -21,17 +20,17 @@ module Wordmove
|
|
21
20
|
logger.task "Running #{action}/#{step} hooks"
|
22
21
|
|
23
22
|
hooks.all_commands.each do |command|
|
24
|
-
case command
|
23
|
+
case command.fetch(:where)
|
25
24
|
when 'local'
|
26
|
-
Wordmove::Hook::Local.run(command, options[:local],
|
25
|
+
Wordmove::Hook::Local.run(command, options[:local], simulate)
|
27
26
|
when 'remote'
|
28
27
|
if options[environment][:ftp]
|
29
|
-
logger.debug
|
30
|
-
|
28
|
+
logger.debug 'You have configured remote hooks to run over '\
|
29
|
+
'an FTP connection, but this is not possible. Skipping.'
|
31
30
|
next
|
32
31
|
end
|
33
32
|
|
34
|
-
Wordmove::Hook::Remote.run(command, options[environment],
|
33
|
+
Wordmove::Hook::Remote.run(command, options[environment], simulate)
|
35
34
|
else
|
36
35
|
next
|
37
36
|
end
|
@@ -78,10 +77,10 @@ module Wordmove
|
|
78
77
|
|
79
78
|
class Local
|
80
79
|
def self.logger
|
81
|
-
|
80
|
+
Wordmove::Hook.logger
|
82
81
|
end
|
83
82
|
|
84
|
-
def self.run(command_hash, options, simulate = false)
|
83
|
+
def self.run(command_hash, options, simulate = false) # rubocop:disable Style/OptionalBooleanParameter
|
85
84
|
wordpress_path = options[:wordpress_path]
|
86
85
|
|
87
86
|
logger.task_step true, "Exec command: #{command_hash[:command]}"
|
@@ -91,7 +90,7 @@ module Wordmove
|
|
91
90
|
logger.task_step true, "Output: #{stdout_return}"
|
92
91
|
|
93
92
|
if $CHILD_STATUS.exitstatus.zero?
|
94
|
-
logger.success
|
93
|
+
logger.success ''
|
95
94
|
else
|
96
95
|
logger.error "Error code: #{$CHILD_STATUS.exitstatus}"
|
97
96
|
raise Wordmove::LocalHookException unless command_hash[:raise].eql? false
|
@@ -101,10 +100,10 @@ module Wordmove
|
|
101
100
|
|
102
101
|
class Remote
|
103
102
|
def self.logger
|
104
|
-
|
103
|
+
Wordmove::Hook.logger
|
105
104
|
end
|
106
105
|
|
107
|
-
def self.run(command_hash, options, simulate = false)
|
106
|
+
def self.run(command_hash, options, simulate = false) # rubocop:disable Style/OptionalBooleanParameter
|
108
107
|
ssh_options = options[:ssh]
|
109
108
|
wordpress_path = options[:wordpress_path]
|
110
109
|
|
@@ -118,7 +117,7 @@ module Wordmove
|
|
118
117
|
|
119
118
|
if exit_code.zero?
|
120
119
|
logger.task_step false, "Output: #{stdout}"
|
121
|
-
logger.success
|
120
|
+
logger.success ''
|
122
121
|
else
|
123
122
|
logger.task_step false, "Output: #{stderr}"
|
124
123
|
logger.error "Error code #{exit_code}"
|
data/lib/wordmove/logger.rb
CHANGED
@@ -4,7 +4,8 @@ module Wordmove
|
|
4
4
|
|
5
5
|
def initialize(device, strings_to_hide = [])
|
6
6
|
super(device, formatter: proc { |_severity, _datetime, _progname, message|
|
7
|
-
formatted_message = if strings_to_hide.empty?
|
7
|
+
formatted_message = if strings_to_hide.empty? ||
|
8
|
+
ENV.fetch('WORDMOVE_REVEAL_SECRETS', nil).present?
|
8
9
|
message
|
9
10
|
else
|
10
11
|
message.gsub(
|
@@ -20,38 +21,38 @@ module Wordmove
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def task(title)
|
23
|
-
prefix =
|
24
|
+
prefix = '▬' * 2
|
24
25
|
title = " #{title} "
|
25
|
-
padding =
|
26
|
+
padding = '▬' * padding_length(title)
|
26
27
|
add(INFO, prefix + title.light_white + padding)
|
27
28
|
end
|
28
29
|
|
29
30
|
def task_step(local_step, title)
|
30
31
|
if local_step
|
31
|
-
add(INFO,
|
32
|
+
add(INFO, ' local'.cyan + ' | '.black + title.to_s)
|
32
33
|
else
|
33
|
-
add(INFO,
|
34
|
+
add(INFO, ' remote'.yellow + ' | '.black + title.to_s)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
38
|
def error(message)
|
38
|
-
add(ERROR,
|
39
|
+
add(ERROR, ' ❌ error'.red + ' | '.black + message.to_s)
|
39
40
|
end
|
40
41
|
|
41
42
|
def success(message)
|
42
|
-
add(INFO,
|
43
|
+
add(INFO, ' ✅ success'.green + ' | '.black + message.to_s)
|
43
44
|
end
|
44
45
|
|
45
46
|
def debug(message)
|
46
|
-
add(DEBUG,
|
47
|
+
add(DEBUG, ' 🛠 debug'.magenta + ' | '.black + message.to_s)
|
47
48
|
end
|
48
49
|
|
49
50
|
def warn(message)
|
50
|
-
add(WARN,
|
51
|
+
add(WARN, ' ⚠️ warning'.yellow + ' | '.black + message.to_s)
|
51
52
|
end
|
52
53
|
|
53
54
|
def info(message)
|
54
|
-
add(INFO,
|
55
|
+
add(INFO, ' ℹ️ info'.yellow + ' | '.black + message.to_s)
|
55
56
|
end
|
56
57
|
|
57
58
|
def plain(message)
|
data/lib/wordmove/movefile.rb
CHANGED
@@ -1,24 +1,73 @@
|
|
1
1
|
module Wordmove
|
2
2
|
class Movefile
|
3
|
-
attr_reader :logger,
|
3
|
+
attr_reader :logger,
|
4
|
+
:config_file_name,
|
5
|
+
:start_dir,
|
6
|
+
:options,
|
7
|
+
:cli_options
|
8
|
+
|
9
|
+
def initialize(cli_options = {}, start_dir = nil, verbose = true) # rubocop:disable Style/OptionalBooleanParameter
|
10
|
+
@logger = Logger.new($stdout).tap { |l| l.level = Logger::DEBUG }
|
11
|
+
@cli_options = cli_options.deep_symbolize_keys || {}
|
12
|
+
@config_file_name = @cli_options.fetch(:config, nil)
|
13
|
+
@start_dir = start_dir || current_dir
|
14
|
+
|
15
|
+
@options = fetch(verbose)
|
16
|
+
.deep_symbolize_keys!
|
17
|
+
.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
def environment
|
21
|
+
available_enviroments = extract_available_envs(options)
|
22
|
+
|
23
|
+
if available_enviroments.size > 1 && cli_options[:environment].nil?
|
24
|
+
raise(
|
25
|
+
UndefinedEnvironment,
|
26
|
+
'You need to specify an environment with --environment parameter'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
if cli_options[:environment].present? &&
|
31
|
+
!available_enviroments.include?(cli_options[:environment].to_sym)
|
32
|
+
raise UndefinedEnvironment, "No environment found for \"#{options[:environment]}\". "\
|
33
|
+
"Available Environments: #{available_enviroments.join(' ')}"
|
34
|
+
end
|
4
35
|
|
5
|
-
|
6
|
-
|
7
|
-
@name = name
|
8
|
-
@start_dir = start_dir
|
36
|
+
# NOTE: This is Hash#fetch, not self.fetch.
|
37
|
+
cli_options.fetch(:environment, available_enviroments.first).to_sym
|
9
38
|
end
|
10
39
|
|
11
|
-
def
|
12
|
-
|
40
|
+
def secrets
|
41
|
+
secrets = []
|
42
|
+
options.each_key do |env|
|
43
|
+
secrets << options.dig(env, :database, :password)
|
44
|
+
secrets << options.dig(env, :database, :host)
|
45
|
+
secrets << options.dig(env, :vhost)
|
46
|
+
secrets << options.dig(env, :ssh, :password)
|
47
|
+
secrets << options.dig(env, :ssh, :host)
|
48
|
+
secrets << options.dig(env, :ftp, :password)
|
49
|
+
secrets << options.dig(env, :ftp, :host)
|
50
|
+
secrets << options.dig(env, :wordpress_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
secrets.compact.delete_if(&:empty?)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def fetch(verbose = true) # rubocop:disable Style/OptionalBooleanParameter
|
59
|
+
load_dotenv
|
60
|
+
|
61
|
+
entries = if config_file_name.nil?
|
13
62
|
Dir["#{File.join(start_dir, '{M,m}ovefile')}{,.yml,.yaml}"]
|
14
63
|
else
|
15
|
-
Dir["#{File.join(start_dir,
|
64
|
+
Dir["#{File.join(start_dir, config_file_name)}{,.yml,.yaml}"]
|
16
65
|
end
|
17
66
|
|
18
67
|
if entries.empty?
|
19
68
|
if last_dir?(start_dir)
|
20
|
-
raise MovefileNotFound,
|
21
|
-
" for filename \"#{
|
69
|
+
raise MovefileNotFound, 'Could not find a valid Movefile. Searched'\
|
70
|
+
" for filename \"#{config_file_name}\" in folder \"#{start_dir}\""
|
22
71
|
end
|
23
72
|
|
24
73
|
@start_dir = upper_dir(start_dir)
|
@@ -30,9 +79,8 @@ module Wordmove
|
|
30
79
|
YAML.safe_load(ERB.new(File.read(found)).result, [], [], true).deep_symbolize_keys!
|
31
80
|
end
|
32
81
|
|
33
|
-
def load_dotenv
|
34
|
-
|
35
|
-
env_files = Dir[File.join(start_dir, ".env{.#{env},}")]
|
82
|
+
def load_dotenv
|
83
|
+
env_files = Dir[File.join(start_dir, '.env')]
|
36
84
|
|
37
85
|
found_env = env_files.first
|
38
86
|
|
@@ -42,56 +90,12 @@ module Wordmove
|
|
42
90
|
Dotenv.load(found_env)
|
43
91
|
end
|
44
92
|
|
45
|
-
def environment(cli_options = {})
|
46
|
-
options = fetch(false)
|
47
|
-
available_enviroments = extract_available_envs(options)
|
48
|
-
options.merge!(cli_options).deep_symbolize_keys!
|
49
|
-
|
50
|
-
if options[:environment] != 'local'
|
51
|
-
if available_enviroments.size > 1 && options[:environment].nil?
|
52
|
-
raise(
|
53
|
-
UndefinedEnvironment,
|
54
|
-
"You need to specify an environment with --environment parameter"
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
if options[:environment].present?
|
59
|
-
unless available_enviroments.include?(options[:environment].to_sym)
|
60
|
-
raise UndefinedEnvironment, "No environment found for \"#{options[:environment]}\". "\
|
61
|
-
"Available Environments: #{available_enviroments.join(' ')}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
(options[:environment] || available_enviroments.first).to_sym
|
67
|
-
end
|
68
|
-
|
69
|
-
def secrets
|
70
|
-
options = fetch(false)
|
71
|
-
|
72
|
-
secrets = []
|
73
|
-
options.each_key do |env|
|
74
|
-
secrets << options.dig(env, :database, :password)
|
75
|
-
secrets << options.dig(env, :database, :host)
|
76
|
-
secrets << options.dig(env, :vhost)
|
77
|
-
secrets << options.dig(env, :ssh, :password)
|
78
|
-
secrets << options.dig(env, :ssh, :host)
|
79
|
-
secrets << options.dig(env, :ftp, :password)
|
80
|
-
secrets << options.dig(env, :ftp, :host)
|
81
|
-
secrets << options.dig(env, :wordpress_path)
|
82
|
-
end
|
83
|
-
|
84
|
-
secrets.compact.delete_if(&:empty?)
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
93
|
def extract_available_envs(options)
|
90
|
-
options.keys
|
94
|
+
options.keys - %i[local global]
|
91
95
|
end
|
92
96
|
|
93
97
|
def last_dir?(directory)
|
94
|
-
directory ==
|
98
|
+
directory == '/' || File.exist?(File.join(directory, 'wp-config.php'))
|
95
99
|
end
|
96
100
|
|
97
101
|
def upper_dir(directory)
|