wordmove 5.2.2 → 6.0.0.alpha.1

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 (78) 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 +95 -0
  10. data/lib/wordmove/actions/adapt_remote_db.rb +87 -0
  11. data/lib/wordmove/actions/backup_local_db.rb +54 -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 +54 -0
  16. data/lib/wordmove/actions/ftp/cleanup_after_adapt.rb +70 -0
  17. data/lib/wordmove/actions/ftp/download_remote_db.rb +69 -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 +74 -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 +79 -0
  33. data/lib/wordmove/actions/ssh/backup_remote_db.rb +49 -0
  34. data/lib/wordmove/actions/ssh/cleanup_after_adapt.rb +42 -0
  35. data/lib/wordmove/actions/ssh/download_remote_db.rb +76 -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 +70 -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/cli.rb +152 -91
  47. data/lib/wordmove/db_paths_config.rb +44 -0
  48. data/lib/wordmove/doctor/movefile.rb +8 -8
  49. data/lib/wordmove/doctor/mysql.rb +18 -15
  50. data/lib/wordmove/doctor/rsync.rb +2 -2
  51. data/lib/wordmove/doctor/ssh.rb +3 -3
  52. data/lib/wordmove/doctor/wpcli.rb +4 -4
  53. data/lib/wordmove/environments_list.rb +4 -4
  54. data/lib/wordmove/exceptions.rb +13 -0
  55. data/lib/wordmove/generators/movefile.rb +7 -5
  56. data/lib/wordmove/generators/movefile_adapter.rb +11 -5
  57. data/lib/wordmove/guardian.rb +5 -5
  58. data/lib/wordmove/hook.rb +13 -14
  59. data/lib/wordmove/logger.rb +11 -10
  60. data/lib/wordmove/movefile.rb +63 -59
  61. data/lib/wordmove/organizers/ftp/pull.rb +52 -0
  62. data/lib/wordmove/organizers/ftp/push.rb +53 -0
  63. data/lib/wordmove/organizers/ssh/pull.rb +52 -0
  64. data/lib/wordmove/organizers/ssh/push.rb +53 -0
  65. data/lib/wordmove/version.rb +1 -1
  66. data/lib/wordmove/wordpress_directory.rb +76 -8
  67. data/lib/wordmove/wpcli.rb +85 -0
  68. data/lib/wordmove.rb +33 -11
  69. data/wordmove.gemspec +37 -30
  70. metadata +139 -35
  71. data/lib/wordmove/deployer/base.rb +0 -193
  72. data/lib/wordmove/deployer/ftp.rb +0 -160
  73. data/lib/wordmove/deployer/ssh/default_sql_adapter.rb +0 -47
  74. data/lib/wordmove/deployer/ssh/wpcli_sql_adapter.rb +0 -55
  75. data/lib/wordmove/deployer/ssh.rb +0 -169
  76. data/lib/wordmove/sql_adapter/default.rb +0 -68
  77. data/lib/wordmove/sql_adapter/wpcli.rb +0 -54
  78. data/lib/wordmove/wordpress_directory/path.rb +0 -11
@@ -0,0 +1,26 @@
1
+ module Wordmove
2
+ module Actions
3
+ # Runs after push hooks by invoking the external service
4
+ # Wordmove::Hook
5
+ class RunAfterPushHook
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+
9
+ expects :movefile,
10
+ :cli_options
11
+
12
+ # @!method execute
13
+ # @param movefile [Wordmove::Movefile]
14
+ # @param cli_options [Hash]
15
+ # @return [LightService::Context] Action's context
16
+ executed do |context|
17
+ Wordmove::Hook.run(
18
+ :push,
19
+ :after,
20
+ movefile: context.movefile,
21
+ simulate: simulate?(cli_options: context.cli_options)
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Wordmove
2
+ module Actions
3
+ # Runs before pull hooks by invoking the external service
4
+ # Wordmove::Hook
5
+ class RunBeforePullHook
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+
9
+ expects :movefile,
10
+ :cli_options
11
+
12
+ # @!method execute
13
+ # @param movefile [Wordmove::Movefile]
14
+ # @param cli_options [Hash]
15
+ # @return [LightService::Context] Action's context
16
+ executed do |context|
17
+ Wordmove::Hook.run(
18
+ :pull,
19
+ :before,
20
+ movefile: context.movefile,
21
+ simulate: simulate?(cli_options: context.cli_options)
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Wordmove
2
+ module Actions
3
+ # Runs before push hooks by invoking the external service
4
+ # Wordmove::Hook
5
+ class RunBeforePushHook
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+
9
+ expects :movefile,
10
+ :cli_options
11
+
12
+ # @!method execute
13
+ # @param movefile [Wordmove::Movefile]
14
+ # @param cli_options [Hash]
15
+ # @return [LightService::Context] Action's context
16
+ executed do |context|
17
+ Wordmove::Hook.run(
18
+ :push,
19
+ :before,
20
+ movefile: context.movefile,
21
+ simulate: simulate?(cli_options: context.cli_options)
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'English'
2
+
3
+ module Wordmove
4
+ module Actions
5
+ # Run a command on the local system.
6
+ # Command won't be run if +--simulate+ flag is present on CLI.
7
+ # @note This action is *not* meant to be organized, but as a standalone one.
8
+ class RunLocalCommand
9
+ extend LightService::Action
10
+ include Wordmove::Actions::Helpers
11
+
12
+ expects :command,
13
+ :cli_options,
14
+ :logger
15
+
16
+ # @!method execute
17
+ # @param command [String] The command to run
18
+ # @param cli_options [Hash]
19
+ # @param logger [Wordmove::Logger]
20
+ # @return [LightService::Context] Action's context
21
+ executed do |context|
22
+ context.logger.task_step true, context.command
23
+
24
+ next context if simulate?(cli_options: context.cli_options)
25
+
26
+ begin
27
+ system(context.command, exception: true)
28
+ rescue RuntimeError, SystemExit => e
29
+ context.fail!("Local command status reports an error: #{e.message}")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,79 @@
1
+ module Wordmove
2
+ module Actions
3
+ class SetupContextForDb
4
+ extend ::LightService::Action
5
+ include Wordmove::Actions::Helpers
6
+ include Wordmove::Actions::Ftp::Helpers
7
+ include WordpressDirectory::LocalHelperMethods
8
+ include WordpressDirectory::RemoteHelperMethods
9
+
10
+ expects :cli_options,
11
+ :local_options,
12
+ :remote_options,
13
+ :logger,
14
+ :movefile,
15
+ :database_task
16
+ promises :db_paths
17
+
18
+ executed do |context| # rubocop:disable Metrics/BlockLength
19
+ if context.database_task == false
20
+ context.skip_remaining!
21
+ context.db_paths = false
22
+ next context
23
+ end
24
+
25
+ next context if simulate?(cli_options: context.cli_options)
26
+
27
+ content_dir = local_wp_content_dir(local_options: context.local_options)
28
+
29
+ token = remote_php_scripts_token
30
+
31
+ DbPathsConfig.local.path = content_dir.path('dump.sql')
32
+ DbPathsConfig.local.gzipped_path = "#{DbPathsConfig.local.path}.gz"
33
+ DbPathsConfig.remote.path = remote_wp_content_dir(
34
+ remote_options: context.remote_options
35
+ ).path('dump.sql')
36
+ DbPathsConfig.remote.gzipped_path = "#{DbPathsConfig.remote.path}.gz"
37
+ DbPathsConfig.local.adapted_path = content_dir.path('search_replace_dump.sql')
38
+ DbPathsConfig.local.gzipped_adapted_path = "#{DbPathsConfig.local.adapted_path}.gz"
39
+ DbPathsConfig.backup.local.path = content_dir.path("local-backup-#{Time.now.to_i}.sql")
40
+ DbPathsConfig.backup.local.gzipped_path = "#{DbPathsConfig.backup.local.path}.gz"
41
+ DbPathsConfig.backup.remote.path =
42
+ content_dir.path("#{context.movefile.environment}-backup-#{Time.now.to_i}.sql")
43
+ DbPathsConfig.backup.remote.gzipped_path = "#{DbPathsConfig.backup.remote.path}.gz"
44
+
45
+ DbPathsConfig.ftp.remote.dump_script_path = remote_wp_content_dir(
46
+ remote_options: context.remote_options
47
+ ).path('dump.php')
48
+ DbPathsConfig.ftp.remote.dumped_path = remote_wp_content_dir(
49
+ remote_options: context.remote_options
50
+ ).path('dump.mysql')
51
+ DbPathsConfig.ftp.remote.dump_script_url = remote_wp_content_dir(
52
+ remote_options: context.remote_options
53
+ ).url('dump.php')
54
+ DbPathsConfig.ftp.remote.import_script_path = remote_wp_content_dir(
55
+ remote_options: context.remote_options
56
+ ).path('import.php')
57
+ DbPathsConfig.ftp.remote.import_script_url = remote_wp_content_dir(
58
+ remote_options: context.remote_options
59
+ ).url('import.php')
60
+ DbPathsConfig.ftp.local.generated_dump_script_path = generate_dump_script(
61
+ remote_db_options: context.remote_options[:database],
62
+ token: token
63
+ )
64
+ DbPathsConfig.ftp.local.generated_import_script_path = generate_import_script(
65
+ remote_db_options: context.remote_options[:database],
66
+ token: token
67
+ )
68
+ DbPathsConfig.ftp.local.temp_path = local_wp_content_dir(
69
+ local_options: context.local_options
70
+ ).path('log.html')
71
+ # I know this is not a path, but it's used to generate
72
+ # a URL to dump the DB, so it's somewhat in context
73
+ DbPathsConfig.ftp.token = token
74
+
75
+ context.db_paths = DbPathsConfig
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,49 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Bakups an alrady downloaded remote dump
5
+ class BackupRemoteDb
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+
9
+ expects :cli_options,
10
+ :logger,
11
+ :db_paths
12
+
13
+ # @!method execute
14
+ # @param cli_options [Hash] Command line options (with symbolized keys)
15
+ # @param logger [Wordmove::Logger]
16
+ # @param db_paths [BbPathsConfig] Configuration object for database
17
+ # @!scope class
18
+ # @return [LightService::Context] Action's context
19
+ executed do |context|
20
+ context.logger.task 'Backup remote DB'
21
+
22
+ if simulate?(cli_options: context.cli_options)
23
+ context.logger.info 'A backup of the remote DB would have been saved into ' \
24
+ "#{context.db_paths.backup.remote.gzipped_path}, " \
25
+ 'but you\'re simulating'
26
+ next context
27
+ end
28
+
29
+ # Most of the expectations are needed to be proxied to `DownloadRemoteDb`
30
+ # Wordmove::Actions::Ssh::DownloadRemoteDb.execute(context)
31
+ # DownloadRemoteDB will save the file in `db_paths.local.gzipped_path`
32
+
33
+ begin
34
+ FileUtils.mv(
35
+ context.db_paths.local.gzipped_path,
36
+ context.db_paths.backup.remote.gzipped_path
37
+ )
38
+
39
+ context.logger.success(
40
+ "Backup saved at #{context.db_paths.backup.remote.gzipped_path}"
41
+ )
42
+ rescue Errno::ENOENT => e
43
+ context.fail_and_return!("Remote DB backup failed with: #{e.message}. Aborting.")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Cleanup file created during DB push/pull operations
5
+ class CleanupAfterAdapt
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+
9
+ expects :db_paths,
10
+ :cli_options,
11
+ :logger
12
+
13
+ # @!method execute
14
+ # @param db_paths [BbPathsConfig] Configuration object for database
15
+ # @param cli_options [Hash] Command line options (with symbolized keys)
16
+ # @param logger [Wordmove::Logger]
17
+ # @!scope class
18
+ # @return [LightService::Context] Action's context
19
+ executed do |context|
20
+ context.logger.task 'Cleanup'
21
+
22
+ if simulate?(cli_options: context.cli_options)
23
+ context.logger.info 'No cleanup during simulation'
24
+ next context
25
+ end
26
+
27
+ Wordmove::Actions::DeleteLocalFile.execute(
28
+ logger: context.logger,
29
+ cli_options: context.cli_options,
30
+ file_path: context.db_paths.local.path
31
+ )
32
+
33
+ Wordmove::Actions::DeleteLocalFile.execute(
34
+ cli_options: context.cli_options,
35
+ logger: context.logger,
36
+ file_path: context.db_paths.local.gzipped_adapted_path
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,76 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Downloads the remote DB over SSH protocol
5
+ class DownloadRemoteDb
6
+ extend ::LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+ include WordpressDirectory::LocalHelperMethods
9
+ include WordpressDirectory::RemoteHelperMethods
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
+ context.logger.task 'Download remote DB'
28
+
29
+ next context if simulate?(cli_options: context.cli_options)
30
+
31
+ result = Wordmove::Actions::Ssh::RunRemoteCommand.execute(
32
+ cli_options: context.cli_options,
33
+ photocopier: context.photocopier,
34
+ logger: context.logger,
35
+ command: mysql_dump_command(
36
+ env_db_options: context.remote_options[:database],
37
+ save_to_path: context.db_paths.remote.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
+ photocopier: context.photocopier,
45
+ logger: context.logger,
46
+ command: compress_command(file_path: context.db_paths.remote.path)
47
+ )
48
+ context.fail_and_return!(result.message) if result.failure?
49
+
50
+ result = Wordmove::Actions::GetFile.execute(
51
+ photocopier: context.photocopier,
52
+ logger: context.logger,
53
+ cli_options: context.cli_options,
54
+ command_args: [
55
+ context.db_paths.remote.gzipped_path,
56
+ context.db_paths.local.gzipped_path
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.gzipped_path
66
+ )
67
+ context.fail_and_return!(result.message) if result.failure?
68
+
69
+ context.logger.success(
70
+ "Remote DB dump downloaded in #{context.db_paths.local.gzipped_path}"
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,76 @@
1
+ module Wordmove
2
+ module Actions
3
+ module Ssh
4
+ # Syncs a whole directory over SSH protocol from the remote server to local host
5
+ class GetDirectory
6
+ extend LightService::Action
7
+ include Wordmove::Actions::Helpers
8
+ include Wordmove::Actions::Ssh::Helpers
9
+ include WordpressDirectory::RemoteHelperMethods
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 "Pulling #{context.folder_task}"
32
+
33
+ next context if simulate?(cli_options: context.cli_options)
34
+
35
+ command = 'get_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
+ # `pull_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 `"remote_#{context.folder_task}_dir"` could
49
+ # not be defined.
50
+ command_args = context.fetch(:command_args) || [
51
+ remote_path,
52
+ local_path,
53
+ pull_exclude_paths(
54
+ remote_task_dir: send(
55
+ "remote_#{context.folder_task}_dir",
56
+ remote_options: context.remote_options
57
+ ),
58
+ paths_to_exclude: paths_to_exclude(remote_options: context.remote_options)
59
+ ),
60
+ pull_include_paths(remote_task_dir: send(
61
+ "remote_#{context.folder_task}_dir",
62
+ remote_options: context.remote_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,128 @@
1
+ require 'pathname'
2
+
3
+ # rubocop:disable Metrics/BlockLength
4
+ module Wordmove
5
+ module Actions
6
+ module Ssh
7
+ module Helpers
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ #
12
+ # Utility method to retrieve and augment ssh options from the superset of remote options.
13
+ # This is useful most because it appends +--dy-run+ rsync's flag to ssh options based
14
+ # on +--simulate+ flag presence
15
+ #
16
+ # @param [Hash] remote_options Remote host options fetcehd from movefile
17
+ # @param [Bool] simulate Tell the moethod if you're in a simulated operation
18
+ #
19
+ # @return [Hash] Ssh options
20
+ #
21
+ def ssh_options(remote_options:, simulate: false)
22
+ ssh_options = remote_options[:ssh]
23
+
24
+ if simulate == true && ssh_options[:rsync_options]
25
+ ssh_options[:rsync_options].concat(' --dry-run')
26
+ elsif simulate == true
27
+ ssh_options[:rsync_options] = '--dry-run'
28
+ end
29
+
30
+ ssh_options
31
+ end
32
+
33
+ #
34
+ # Given the directory you're pushing/pulling, generates an array of path to be included
35
+ # by rsync while pushing. Note that by design include paths are always required but are
36
+ # only programmatically deduced and never user configured.
37
+ #
38
+ # @note The business logic behind how these paths are produced should be deepened
39
+ #
40
+ # @param [WordpressDirectory] local_task_dir An object representing a wordpress folder
41
+ #
42
+ # @return [Array<String>] The array of path to be included by rsync
43
+ #
44
+ def push_include_paths(local_task_dir:)
45
+ Pathname.new(local_task_dir.relative_path)
46
+ .ascend
47
+ .each_with_object([]) do |directory, array|
48
+ path = directory.to_path
49
+ path.prepend('/') unless path.match? %r{^/}
50
+ path.concat('/') unless path.match? %r{/$}
51
+ array << path
52
+ end
53
+ end
54
+
55
+ #
56
+ # Given the directory you're pushing/pulling and the user configured exclude list,
57
+ # generates an array of path to be excluded
58
+ # by rsync while pushing. Note that by design exclude some paths are always required
59
+ # even when the user does not confiure any exclusion.
60
+ #
61
+ # @note The business logic behind how these paths are produced should be deepened
62
+ #
63
+ # @param [WordpressDirectory] local_task_dir An object representing a wordpress folder
64
+ # @param [Array<String>] pats_to_exclude An array of paths
65
+ #
66
+ # @return [Array<String>] The array of path to be included by rsync
67
+ #
68
+ def push_exclude_paths(local_task_dir:, paths_to_exclude:)
69
+ Pathname.new(local_task_dir.relative_path)
70
+ .dirname
71
+ .ascend
72
+ .each_with_object([]) do |directory, array|
73
+ path = directory.to_path
74
+ path.prepend('/') unless path.match? %r{^/}
75
+ path.concat('/') unless path.match? %r{/$}
76
+ path.concat('*')
77
+ array << path
78
+ end
79
+ .concat(paths_to_exclude)
80
+ .concat(['/*'])
81
+ end
82
+
83
+ #
84
+ # Same as Wordmove::Actions::Ssh::Helpers.push_include_path but for pull actions
85
+ #
86
+ # @param [WordpressDirectory] local_task_dir An object representing a wordpress folder
87
+ #
88
+ # @return [Array<String>] An array of paths
89
+ #
90
+ def pull_include_paths(remote_task_dir:)
91
+ Pathname.new(remote_task_dir.relative_path)
92
+ .ascend
93
+ .each_with_object([]) do |directory, array|
94
+ path = directory.to_path
95
+ path.prepend('/') unless path.match? %r{^/}
96
+ path.concat('/') unless path.match? %r{/$}
97
+ array << path
98
+ end
99
+ end
100
+
101
+ #
102
+ # Same as Wordmove::Actions::Ssh::Helpers.push_exclude_path but for pull actions
103
+ #
104
+ # @param [WordpressDirectory] local_task_dir An object representing a wordpress folder
105
+ # @param [Array<String>] paths_to_exclude User configured array of paths to exclude
106
+ #
107
+ # @return [Array<String>] Array of paths to be excluded
108
+ #
109
+ def pull_exclude_paths(remote_task_dir:, paths_to_exclude:)
110
+ Pathname.new(remote_task_dir.relative_path)
111
+ .dirname
112
+ .ascend
113
+ .each_with_object([]) do |directory, array|
114
+ path = directory.to_path
115
+ path.prepend('/') unless path.match? %r{^/}
116
+ path.concat('/') unless path.match? %r{/$}
117
+ path.concat('*')
118
+ array << path
119
+ end
120
+ .concat(paths_to_exclude)
121
+ .concat(['/*'])
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ # rubocop:enable Metrics/BlockLength
@@ -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