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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +12 -5
  3. data/.rubocop.yml +2 -5
  4. data/.ruby-version +1 -1
  5. data/.yardopts +1 -0
  6. data/CONTRIBUTING.md +15 -0
  7. data/Rakefile +4 -3
  8. data/exe/wordmove +2 -1
  9. data/lib/wordmove/actions/adapt_local_db.rb +103 -0
  10. data/lib/wordmove/actions/adapt_remote_db.rb +90 -0
  11. data/lib/wordmove/actions/backup_local_db.rb +58 -0
  12. data/lib/wordmove/actions/delete_local_file.rb +34 -0
  13. data/lib/wordmove/actions/delete_remote_file.rb +43 -0
  14. data/lib/wordmove/actions/filter_and_setup_tasks_to_run.rb +42 -0
  15. data/lib/wordmove/actions/ftp/backup_remote_db.rb +56 -0
  16. data/lib/wordmove/actions/ftp/cleanup_after_adapt.rb +72 -0
  17. data/lib/wordmove/actions/ftp/download_remote_db.rb +71 -0
  18. data/lib/wordmove/actions/ftp/get_directory.rb +67 -0
  19. data/lib/wordmove/actions/ftp/helpers.rb +91 -0
  20. data/lib/wordmove/actions/ftp/pull_wordpress.rb +56 -0
  21. data/lib/wordmove/actions/ftp/push_wordpress.rb +54 -0
  22. data/lib/wordmove/actions/ftp/put_and_import_dump_remotely.rb +83 -0
  23. data/lib/wordmove/actions/ftp/put_directory.rb +67 -0
  24. data/lib/wordmove/actions/get_file.rb +38 -0
  25. data/lib/wordmove/actions/helpers.rb +142 -0
  26. data/lib/wordmove/actions/put_file.rb +48 -0
  27. data/lib/wordmove/actions/run_after_pull_hook.rb +26 -0
  28. data/lib/wordmove/actions/run_after_push_hook.rb +26 -0
  29. data/lib/wordmove/actions/run_before_pull_hook.rb +26 -0
  30. data/lib/wordmove/actions/run_before_push_hook.rb +26 -0
  31. data/lib/wordmove/actions/run_local_command.rb +34 -0
  32. data/lib/wordmove/actions/setup_context_for_db.rb +78 -0
  33. data/lib/wordmove/actions/ssh/backup_remote_db.rb +51 -0
  34. data/lib/wordmove/actions/ssh/cleanup_after_adapt.rb +56 -0
  35. data/lib/wordmove/actions/ssh/download_remote_db.rb +78 -0
  36. data/lib/wordmove/actions/ssh/get_directory.rb +76 -0
  37. data/lib/wordmove/actions/ssh/helpers.rb +128 -0
  38. data/lib/wordmove/actions/ssh/pull_wordpress.rb +56 -0
  39. data/lib/wordmove/actions/ssh/push_wordpress.rb +54 -0
  40. data/lib/wordmove/actions/ssh/put_and_import_dump_remotely.rb +77 -0
  41. data/lib/wordmove/actions/ssh/put_directory.rb +76 -0
  42. data/lib/wordmove/actions/ssh/run_remote_command.rb +39 -0
  43. data/lib/wordmove/assets/dump.php.erb +6 -6
  44. data/lib/wordmove/assets/import.php.erb +7 -7
  45. data/lib/wordmove/assets/wordmove_schema_global.yml +2 -0
  46. data/lib/wordmove/assets/wordmove_schema_remote.yml +2 -2
  47. data/lib/wordmove/cli.rb +152 -91
  48. data/lib/wordmove/db_paths_config.rb +44 -0
  49. data/lib/wordmove/doctor/movefile.rb +8 -8
  50. data/lib/wordmove/doctor/mysql.rb +18 -15
  51. data/lib/wordmove/doctor/rsync.rb +2 -2
  52. data/lib/wordmove/doctor/ssh.rb +3 -3
  53. data/lib/wordmove/doctor/wpcli.rb +4 -4
  54. data/lib/wordmove/environments_list.rb +4 -4
  55. data/lib/wordmove/exceptions.rb +13 -0
  56. data/lib/wordmove/generators/movefile.rb +7 -5
  57. data/lib/wordmove/generators/movefile_adapter.rb +11 -5
  58. data/lib/wordmove/guardian.rb +5 -5
  59. data/lib/wordmove/hook.rb +15 -16
  60. data/lib/wordmove/logger.rb +11 -10
  61. data/lib/wordmove/movefile.rb +63 -59
  62. data/lib/wordmove/organizers/ftp/pull.rb +52 -0
  63. data/lib/wordmove/organizers/ftp/push.rb +53 -0
  64. data/lib/wordmove/organizers/ssh/pull.rb +52 -0
  65. data/lib/wordmove/organizers/ssh/push.rb +53 -0
  66. data/lib/wordmove/version.rb +1 -1
  67. data/lib/wordmove/wordpress_directory.rb +76 -8
  68. data/lib/wordmove/wpcli.rb +85 -0
  69. data/lib/wordmove.rb +33 -11
  70. data/wordmove.gemspec +37 -30
  71. metadata +141 -43
  72. data/lib/wordmove/deployer/base.rb +0 -193
  73. data/lib/wordmove/deployer/ftp.rb +0 -160
  74. data/lib/wordmove/deployer/ssh/default_sql_adapter.rb +0 -47
  75. data/lib/wordmove/deployer/ssh/wpcli_sql_adapter.rb +0 -55
  76. data/lib/wordmove/deployer/ssh.rb +0 -169
  77. data/lib/wordmove/sql_adapter/default.rb +0 -68
  78. data/lib/wordmove/sql_adapter/wpcli.rb +0 -54
  79. data/lib/wordmove/wordpress_directory/path.rb +0 -11
@@ -0,0 +1,56 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Syncs wordpress folder (usually root folder), exluding +wp-content/+ folder, over SSH
5
+ # protocol from the remote server to local host
6
+ class PullWordpress
7
+ extend ::LightService::Action
8
+ include Wordmove::Actions::Helpers
9
+ include WordpressDirectory::RemoteHelperMethods
10
+
11
+ expects :remote_options,
12
+ :local_options,
13
+ :logger,
14
+ :photocopier
15
+
16
+ # @!method execute
17
+ # @param remote_options [Hash] Remote host options fetched from
18
+ # movefile (with symbolized keys)
19
+ # @param local_options [Hash] Local host options fetched from
20
+ # movefile (with symbolized keys)
21
+ # @param logger [Wordmove::Logger]
22
+ # @param photocopier [Photocopier::SSH]
23
+ # @!scope class
24
+ # @return [LightService::Context] Action's context
25
+ executed do |context|
26
+ local_path = context.local_options[:wordpress_path]
27
+
28
+ remote_path = context.remote_options[:wordpress_path]
29
+
30
+ wp_content_relative_path = remote_wp_content_dir(
31
+ remote_options: context.remote_options
32
+ ).relative_path
33
+
34
+ exclude_wp_content = exclude_dir_contents(
35
+ path: wp_content_relative_path
36
+ )
37
+
38
+ exclude_paths = paths_to_exclude(
39
+ remote_options: context.remote_options
40
+ ).push(exclude_wp_content)
41
+
42
+ result = Wordmove::Actions::Ssh::GetDirectory.execute(
43
+ photocopier: context.photocopier,
44
+ logger: context.logger,
45
+ command_args: [remote_path, local_path, exclude_paths],
46
+ folder_task: :wordpress,
47
+ local_options: context.local_options,
48
+ remote_options: context.remote_options,
49
+ cli_options: context.cli_options
50
+ )
51
+ context.fail!(result.message) if result.failure?
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,54 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Syncs wordpress folder (usually root folder), exluding +wp-content/+ folder, over SSH
5
+ # protocol from local host to the remote server
6
+ class PushWordpress
7
+ extend ::LightService::Action
8
+ include Wordmove::Actions::Helpers
9
+ include WordpressDirectory::LocalHelperMethods
10
+
11
+ expects :remote_options,
12
+ :local_options,
13
+ :logger,
14
+ :photocopier
15
+
16
+ # @!method execute
17
+ # @param remote_options [Hash] Remote host options fetched from
18
+ # movefile (with symbolized keys)
19
+ # @param local_options [Hash] Local host options fetched from
20
+ # movefile (with symbolized keys)
21
+ # @param logger [Wordmove::Logger]
22
+ # @param photocopier [Photocopier::SSH]
23
+ # @!scope class
24
+ # @return [LightService::Context] Action's context
25
+ executed do |context|
26
+ local_path = context.local_options[:wordpress_path]
27
+
28
+ remote_path = context.remote_options[:wordpress_path]
29
+
30
+ wp_content_relative_path = local_wp_content_dir(
31
+ local_options: context.local_options
32
+ ).relative_path
33
+
34
+ exclude_wp_content = exclude_dir_contents(path: wp_content_relative_path)
35
+
36
+ exclude_paths = paths_to_exclude(
37
+ remote_options: context.remote_options
38
+ ).push(exclude_wp_content)
39
+
40
+ result = Wordmove::Actions::Ssh::PutDirectory.execute(
41
+ photocopier: context.photocopier,
42
+ logger: context.logger,
43
+ command_args: [local_path, remote_path, exclude_paths],
44
+ folder_task: :wordpress,
45
+ local_options: context.local_options,
46
+ remote_options: context.remote_options,
47
+ cli_options: context.cli_options
48
+ )
49
+ context.fail!(result.message) if result.failure?
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,77 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Uploads a DB dump to remote host and import it in the remote database over SSH protocol
5
+ class PutAndImportDumpRemotely
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+ include WordpressDirectory::RemoteHelperMethods
9
+ include WordpressDirectory::LocalHelperMethods
10
+
11
+ expects :remote_options,
12
+ :cli_options,
13
+ :logger,
14
+ :photocopier,
15
+ :db_paths
16
+
17
+ # @!method execute
18
+ # @param remote_options [Hash] Remote host options fetched from
19
+ # movefile (with symbolized keys)
20
+ # @param cli_options [Hash] Command line options (with symbolized keys)
21
+ # @param logger [Wordmove::Logger]
22
+ # @param photocopier [Photocopier::SSH]
23
+ # @param db_paths [BbPathsConfig] Configuration object for database
24
+ # @!scope class
25
+ # @return [LightService::Context] Action's context
26
+ executed do |context| # rubocop:disable Metrics/BlockLength
27
+ next context if context.database_task == false
28
+
29
+ context.logger.task 'Upload and import adapted DB'
30
+
31
+ result = Wordmove::Actions::PutFile.execute(
32
+ logger: context.logger,
33
+ photocopier: context.photocopier,
34
+ cli_options: context.cli_options,
35
+ command_args: [
36
+ context.db_paths.local.gzipped_adapted_path,
37
+ context.db_paths.remote.gzipped_path
38
+ ]
39
+ )
40
+ context.fail_and_return!(result.message) if result.failure?
41
+
42
+ result = Wordmove::Actions::Ssh::RunRemoteCommand.execute(
43
+ cli_options: context.cli_options,
44
+ logger: context.logger,
45
+ photocopier: context.photocopier,
46
+ command: uncompress_command(file_path: context.db_paths.remote.gzipped_path)
47
+ )
48
+ context.fail_and_return!(result.message) if result.failure?
49
+
50
+ result = Wordmove::Actions::Ssh::RunRemoteCommand.execute(
51
+ cli_options: context.cli_options,
52
+ logger: context.logger,
53
+ photocopier: context.photocopier,
54
+ command: mysql_import_command(
55
+ dump_path: context.db_paths.remote.path,
56
+ env_db_options: context.remote_options[:database]
57
+ )
58
+ )
59
+ context.fail_and_return!(result.message) if result.failure?
60
+
61
+ result = Wordmove::Actions::DeleteRemoteFile.execute(
62
+ photocopier: context.photocopier,
63
+ logger: context.logger,
64
+ cli_options: context.cli_options,
65
+ remote_file: context.db_paths.remote.path
66
+ )
67
+ if result.failure?
68
+ context.logger.warning 'Failed to delete remote file ' \
69
+ "#{context.db_paths.remote.path} because: " \
70
+ "#{result.message}" \
71
+ '. Manual intervention required'
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,76 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Syncs a whole directory over SSH protocol from local host to remote server
5
+ class PutDirectory
6
+ extend LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+ include Wordmove::Actions::Ssh::Helpers
9
+ include WordpressDirectory::LocalHelperMethods
10
+
11
+ # :folder_task is expected to be one symbol from Wordmove::CLI.wordpress_options array
12
+ expects :logger,
13
+ :local_options,
14
+ :remote_options,
15
+ :cli_options,
16
+ :photocopier,
17
+ :folder_task
18
+
19
+ # @!method execute
20
+ # @param logger [Wordmove::Logger]
21
+ # @param local_options [Hash] Local host options fetched from
22
+ # movefile (with symbolized keys)
23
+ # @param remote_options [Hash] Remote host options fetched from
24
+ # movefile (with symbolized keys)
25
+ # @param cli_options [Hash] Command line options (with symbolized keys)
26
+ # @param photocopier [Photocopier::SSH]
27
+ # @param folder_task [Symbol] Symbolazied folder name
28
+ # @!scope class
29
+ # @return [LightService::Context] Action's context
30
+ executed do |context|
31
+ context.logger.task "Pushing #{context.folder_task}"
32
+
33
+ next context if simulate?(cli_options: context.cli_options)
34
+
35
+ command = 'put_directory'
36
+ # For this action `local_path` and `remote_path` will always be
37
+ # `:wordpress_path`; specific folder for `context.folder_task` will be included by
38
+ # `push_include_paths`
39
+ local_path = context.local_options[:wordpress_path]
40
+ remote_path = context.remote_options[:wordpress_path]
41
+
42
+ # This action can generate `command_args` by itself,
43
+ # but it gives the context the chance to ovveride it.
44
+ # By the way this variable is not `expects`ed.
45
+ # Note that we do not use the second argument to `fetch`
46
+ # to express a default value, because it would be greedly interpreted
47
+ # but if `command_args` is already defined by context, then it's
48
+ # possible that `"local_#{context.folder_task}_dir"` could
49
+ # not be defined.
50
+ command_args = context.fetch(:command_args) || [
51
+ local_path,
52
+ remote_path,
53
+ push_exclude_paths(
54
+ local_task_dir: send(
55
+ "local_#{context.folder_task}_dir",
56
+ local_options: context.local_options
57
+ ),
58
+ paths_to_exclude: paths_to_exclude(remote_options: context.remote_options)
59
+ ),
60
+ push_include_paths(local_task_dir: send(
61
+ "local_#{context.folder_task}_dir",
62
+ local_options: context.local_options
63
+ ))
64
+ ]
65
+
66
+ context.logger.task_step false, "#{command}: #{command_args.join(' ')}"
67
+ result = context.photocopier.send(command, *command_args)
68
+
69
+ next context if result == true
70
+
71
+ context.fail!("Failed to push #{context.folder_task}")
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,39 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Run a command on a remote host using Photocopier
5
+ #
6
+ # @note The remote server is already configured inside the Photocopier object
7
+ # @note This action is *not* meant to be organized, but as a standalone one.
8
+ class RunRemoteCommand
9
+ extend LightService::Action
10
+ include Wordmove::Actions::Helpers
11
+
12
+ expects :photocopier,
13
+ :logger,
14
+ :cli_options,
15
+ :command
16
+
17
+ # @!method execute
18
+ # @param photocopier [Photocopier]
19
+ # @param logger [Wordmove::Logger]
20
+ # @param cli_options [Hash] The hash of command line options
21
+ # @param command [String] the command to run
22
+ # @!scope class
23
+ # @return [LightService::Context] Action's context
24
+ executed do |context|
25
+ context.logger.task_step false, context.command
26
+
27
+ next context if simulate?(cli_options: context.cli_options)
28
+
29
+ _stdout, stderr, exit_code = context.photocopier.exec!(context.command)
30
+
31
+ next context if exit_code.zero?
32
+
33
+ context.fail! "Error code #{exit_code} returned by command "\
34
+ "#{context.command}: #{stderr}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  <?php
2
2
 
3
- $shared_key = '<%= password %>';
3
+ $shared_key = '<%= token %>';
4
4
  if ($_GET['shared_key'] != $shared_key) {
5
5
  die();
6
6
  }
@@ -214,14 +214,14 @@ class MySQLDump
214
214
 
215
215
  }
216
216
 
217
- $db_host = '<%= escape_php db[:host] %>';
218
- $db_port = '<%= db[:port] %>';
217
+ $db_host = '<%= escape_php(string: remote_db_options[:host]) %>';
218
+ $db_port = '<%= remote_db_options[:port] %>';
219
219
  if (!$db_port) {
220
220
  $db_port = ini_get("mysqli.default_port");
221
221
  }
222
- $db_user = '<%= escape_php db[:user] %>';
223
- $db_password = '<%= escape_php db[:password] %>';
224
- $db_name = '<%= escape_php db[:name] %>';
222
+ $db_user = '<%= escape_php(string: remote_db_options[:user]) %>';
223
+ $db_password = '<%= escape_php(string: remote_db_options[:password]) %>';
224
+ $db_name = '<%= escape_php(string: remote_db_options[:name]) %>';
225
225
 
226
226
  $connection = new mysqli($db_host, $db_user, $db_password, $db_name, $db_port);
227
227
  $dump = new MySQLDump($connection);
@@ -1,6 +1,6 @@
1
1
  <?php
2
2
 
3
- $shared_key = '<%= password %>';
3
+ $shared_key = '<%= token %>';
4
4
  if ($_GET['shared_key'] != $shared_key) {
5
5
  die();
6
6
  }
@@ -43,20 +43,20 @@ error_reporting(E_ALL);
43
43
 
44
44
  // Database configuration
45
45
 
46
- $db_port = '<%= escape_php db[:port] %>';
46
+ $db_port = '<%= escape_php(string: remote_db_options[:port]) %>';
47
47
  if (!$db_port) {
48
48
  $db_port = ini_get("mysqli.default_port");
49
49
  }
50
- $db_server = '<%= escape_php db[:host] %>';
51
- $db_username = '<%= escape_php db[:user] %>';
52
- $db_password = '<%= escape_php db[:password] %>';
53
- $db_name = '<%= escape_php db[:name] %>';
50
+ $db_server = '<%= escape_php(string: remote_db_options[:host]) %>';
51
+ $db_username = '<%= escape_php(string: remote_db_options[:user]) %>';
52
+ $db_password = '<%= escape_php(string: remote_db_options[:password]) %>';
53
+ $db_name = '<%= escape_php(string: remote_db_options[:name]) %>';
54
54
 
55
55
  // Connection charset should be the same as the dump file charset (utf8, latin1, cp1251, koi8r etc.)
56
56
  // See http://dev.mysql.com/doc/refman/5.0/en/charset-charsets.html for the full list
57
57
  // Change this if you have problems with non-latin letters
58
58
 
59
- $db_connection_charset = '<%= db[:charset] || 'utf8' %>';
59
+ $db_connection_charset = '<%= remote_db_options[:charset] || 'utf8' %>';
60
60
 
61
61
  // OPTIONAL SETTINGS
62
62
 
@@ -1,4 +1,6 @@
1
1
  type: map
2
2
  mapping:
3
3
  sql_adapter:
4
+ type: str
4
5
  required: true
6
+ pattern: /\Awpcli\Z/
@@ -162,7 +162,7 @@ mapping:
162
162
  type: bool
163
163
  uploads:
164
164
  type: bool
165
- mu-plugins:
165
+ mu_plugins:
166
166
  type: bool
167
167
  push:
168
168
  type: map
@@ -177,5 +177,5 @@ mapping:
177
177
  type: bool
178
178
  uploads:
179
179
  type: bool
180
- mu-plugins:
180
+ mu_plugins:
181
181
  type: bool
data/lib/wordmove/cli.rb CHANGED
@@ -1,122 +1,183 @@
1
1
  module Wordmove
2
- class CLI < Thor
3
- map %w[--version -v] => :__print_version
2
+ module CLI
3
+ module PullPushShared
4
+ extend ActiveSupport::Concern
5
+ WORDPRESS_OPTIONS = %i[wordpress uploads themes plugins mu_plugins languages db].freeze
6
+
7
+ included do # rubocop:disable Metrics/BlockLength
8
+ option :wordpress, type: :boolean, aliases: %w[w]
9
+ option :uploads, type: :boolean, aliases: %w[u]
10
+ option :themes, type: :boolean, aliases: %w[t]
11
+ option :plugins, type: :boolean, aliases: %w[p]
12
+ option :mu_plugins, type: :boolean, aliases: %w[m]
13
+ option :languages, type: :boolean, aliases: %w[l]
14
+ option :db, type: :boolean, aliases: %w[d]
15
+ option :simulate, type: :boolean
16
+ option :environment, aliases: %w[e]
17
+ option :config, aliases: %w[c]
18
+ option :no_adapt, type: :boolean
19
+ option :all, type: :boolean
20
+ # option :verbose, type: :boolean, aliases: %w[v]
21
+ option :debug, type: :boolean
22
+
23
+ private
24
+
25
+ def ensure_wordpress_options_presence!(cli_options)
26
+ return if (
27
+ cli_options.deep_symbolize_keys.keys &
28
+ (Wordmove::CLI::PullPushShared::WORDPRESS_OPTIONS + [:all])
29
+ ).present?
30
+
31
+ puts 'No options given. See wordmove --help'
32
+ exit 1
33
+ end
4
34
 
5
- desc "--version, -v", "Print the version"
6
- def __print_version
7
- puts Wordmove::VERSION
8
- end
35
+ def initial_context(cli_options)
36
+ cli_options.deep_symbolize_keys!
37
+ movefile = Wordmove::Movefile.new(cli_options)
9
38
 
10
- desc "init", "Generates a brand new movefile.yml"
11
- def init
12
- Wordmove::Generators::Movefile.start
13
- end
39
+ [cli_options, movefile]
40
+ end
14
41
 
15
- desc "doctor", "Do some local configuration and environment checks"
16
- def doctor
17
- Wordmove::Doctor.start
18
- end
42
+ def movefile_from(**cli_options)
43
+ ensure_wordpress_options_presence!(cli_options)
44
+ Wordmove::Movefile.new(cli_options)
45
+ rescue MovefileNotFound => e
46
+ Logger.new($stdout).error(e.message)
47
+ exit 1
48
+ end
49
+
50
+ def call_organizer_with(klass:, movefile:, **cli_options)
51
+ result = klass.call(cli_options: cli_options, movefile: movefile)
19
52
 
20
- shared_options = {
21
- wordpress: { aliases: "-w", type: :boolean },
22
- uploads: { aliases: "-u", type: :boolean },
23
- themes: { aliases: "-t", type: :boolean },
24
- plugins: { aliases: "-p", type: :boolean },
25
- mu_plugins: { aliases: "-m", type: :boolean },
26
- languages: { aliases: "-l", type: :boolean },
27
- db: { aliases: "-d", type: :boolean },
28
- verbose: { aliases: "-v", type: :boolean },
29
- simulate: { aliases: "-s", type: :boolean },
30
- environment: { aliases: "-e" },
31
- config: { aliases: "-c" },
32
- debug: { type: :boolean },
33
- no_adapt: { type: :boolean },
34
- all: { type: :boolean }
35
- }
36
-
37
- no_tasks do
38
- def handle_options(options)
39
- wordpress_options.each do |task|
40
- yield task if options[task] || (options["all"] && options[task] != false)
53
+ exit 0 if result.success?
54
+
55
+ Logger.new($stdout).error(result.message)
56
+ exit 1
41
57
  end
42
58
  end
59
+ end
43
60
 
44
- def wordpress_options
45
- %w[wordpress uploads themes plugins mu_plugins languages db]
46
- end
61
+ module Commands
62
+ extend Dry::CLI::Registry
47
63
 
48
- def ensure_wordpress_options_presence!(options)
49
- return if (options.keys & (wordpress_options + ["all"])).present?
64
+ class Version < Dry::CLI::Command
65
+ desc 'Print the version'
50
66
 
51
- puts "No options given. See wordmove --help"
52
- exit 1
67
+ def call(*)
68
+ puts Wordmove::VERSION
69
+ end
53
70
  end
54
71
 
55
- def logger
56
- Logger.new(STDOUT).tap { |l| l.level = Logger::DEBUG }
72
+ class Init < Dry::CLI::Command
73
+ desc 'Generates a brand new movefile.yml'
74
+
75
+ def call(*)
76
+ Wordmove::Generators::Movefile.generate
77
+ end
57
78
  end
58
- end
59
79
 
60
- desc "list", "List all environments and vhosts"
61
- shared_options.each do |option, args|
62
- method_option option, args
63
- end
64
- def list
65
- Wordmove::EnvironmentsList.print(options)
66
- rescue Wordmove::MovefileNotFound => e
67
- logger.error(e.message)
68
- exit 1
69
- rescue Psych::SyntaxError => e
70
- logger.error("Your movefile is not parsable due to a syntax error: #{e.message}")
71
- exit 1
72
- end
80
+ class Doctor < Dry::CLI::Command
81
+ desc 'Do some local configuration and environment checks'
73
82
 
74
- desc "pull", "Pulls WP data from remote host to the local machine"
75
- shared_options.each do |option, args|
76
- method_option option, args
77
- end
78
- def pull
79
- ensure_wordpress_options_presence!(options)
80
- begin
81
- deployer = Wordmove::Deployer::Base.deployer_for(options.deep_symbolize_keys)
82
- rescue MovefileNotFound => e
83
- logger.error(e.message)
84
- exit 1
83
+ def call(*)
84
+ Wordmove::Doctor.start
85
+ end
85
86
  end
86
87
 
87
- Wordmove::Hook.run(:pull, :before, options)
88
+ class List < Dry::CLI::Command
89
+ desc 'List all environments and vhosts'
88
90
 
89
- guardian = Wordmove::Guardian.new(options: options, action: :pull)
91
+ option :config, aliases: %w[c]
90
92
 
91
- handle_options(options) do |task|
92
- deployer.send("pull_#{task}") if guardian.allows(task.to_sym)
93
+ def call(**cli_options)
94
+ Wordmove::EnvironmentsList.print(cli_options)
95
+ rescue Wordmove::MovefileNotFound => e
96
+ Logger.new($stdout).error(e.message)
97
+ exit 1
98
+ rescue Psych::SyntaxError => e
99
+ Logger.new($stdout)
100
+ .error("Your movefile is not parsable due to a syntax error: #{e.message}")
101
+ exit 1
102
+ end
93
103
  end
94
104
 
95
- Wordmove::Hook.run(:pull, :after, options)
96
- end
105
+ class Pull < Dry::CLI::Command
106
+ desc 'Pulls WP data from remote host to the local machine'
97
107
 
98
- desc "push", "Pushes WP data from local machine to remote host"
99
- shared_options.each do |option, args|
100
- method_option option, args
101
- end
102
- def push
103
- ensure_wordpress_options_presence!(options)
104
- begin
105
- deployer = Wordmove::Deployer::Base.deployer_for(options.deep_symbolize_keys)
106
- rescue MovefileNotFound => e
107
- logger.error(e.message)
108
- exit 1
108
+ include Wordmove::CLI::PullPushShared
109
+
110
+ def call(**cli_options)
111
+ call_pull_organizer_with(**cli_options)
112
+ end
113
+
114
+ private
115
+
116
+ def call_pull_organizer_with(**cli_options)
117
+ movefile = movefile_from(**cli_options)
118
+
119
+ if movefile.options.dig(movefile.environment, :ssh)
120
+ call_organizer_with(
121
+ klass: Wordmove::Organizers::Ssh::Pull,
122
+ movefile: movefile,
123
+ **cli_options
124
+ )
125
+ elsif movefile.options.dig(movefile.environment, :ftp)
126
+ call_organizer_with(
127
+ klass: Wordmove::Organizers::Ftp::Pull,
128
+ movefile: movefile,
129
+ **cli_options
130
+ )
131
+ else
132
+ raise NoAdapterFound, 'No valid adapter found.'
133
+ end
134
+ rescue NoAdapterFound => e
135
+ Logger.new($stdout).error(e.message)
136
+ exit 1
137
+ end
109
138
  end
110
139
 
111
- Wordmove::Hook.run(:push, :before, options)
140
+ class Push < Dry::CLI::Command
141
+ desc 'Pulls WP data from remote host to the local machine'
112
142
 
113
- guardian = Wordmove::Guardian.new(options: options, action: :push)
143
+ include Wordmove::CLI::PullPushShared
114
144
 
115
- handle_options(options) do |task|
116
- deployer.send("push_#{task}") if guardian.allows(task.to_sym)
145
+ def call(**cli_options)
146
+ call_push_organizer_with(**cli_options)
147
+ end
148
+
149
+ private
150
+
151
+ def call_push_organizer_with(**cli_options)
152
+ movefile = movefile_from(**cli_options)
153
+
154
+ if movefile.options.dig(movefile.environment, :ssh)
155
+ call_organizer_with(
156
+ klass: Wordmove::Organizers::Ssh::Push,
157
+ movefile: movefile,
158
+ **cli_options
159
+ )
160
+ elsif movefile.options.dig(movefile.environment, :ftp)
161
+ call_organizer_with(
162
+ klass: Wordmove::Organizers::Ftp::Push,
163
+ movefile: movefile,
164
+ **cli_options
165
+ )
166
+ else
167
+ raise NoAdapterFound, 'No valid adapter found.'
168
+ end
169
+ rescue NoAdapterFound => e
170
+ Logger.new($stdout).error(e.message)
171
+ exit 1
172
+ end
117
173
  end
118
174
 
119
- Wordmove::Hook.run(:push, :after, options)
175
+ register 'version', Version, aliases: %w[v -v --version]
176
+ register 'init', Init
177
+ register 'doctor', Doctor
178
+ register 'list', List
179
+ register 'pull', Pull
180
+ register 'push', Push
120
181
  end
121
182
  end
122
183
  end