wordmove 6.0.0.alpha.4 → 6.0.0.alpha.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff2399e2a947da60d6acac49fb8dc6beb32f3571d4f79cf5f1ea0c5f8f0fcfe6
4
- data.tar.gz: 1aa500f453341eceb9a1d82d03abec6c139de29806b840d0844f578241ae696c
3
+ metadata.gz: 610983a08b3919a1bad04e0f8e2caf2f927c57814974c5d57a2165477971f612
4
+ data.tar.gz: '01686da1b0a39cbef6519de82427b5a804a1677d39dea02370c860896507d005'
5
5
  SHA512:
6
- metadata.gz: 7e3480a25ffeff1808227e5036dc4c7e0d69d92822019b3ffb3e5d47b54bf60809d1a0951c3ee38574dd9e9f345ddcff7d49e92ab171c5930e8d2d0d9f886fd0
7
- data.tar.gz: 5c742c2644d644f9f3d61c0d77dbc15c69957244f98c20dade5e04867b59d55202b88449ea1a9f5ff9ca2952a7e43b1db24fdf8c4e4d387438dd8b0807317096
6
+ metadata.gz: ad5fb4e7fb863a8115c7613e80d6da1797f11d872d6fb82a823763cbfff0efafc929c3039afae9461500b006d3e84e3a305a7fe2f302dfe1881058cc24cd8d8b
7
+ data.tar.gz: 9d3876f6d01bd32c89043d89ed3ea2cb356bfa29280fea52d76ea15bb574c12ddc15906d306e2d45b4ce6cf067af13256bec65a066324d98ef6a7448662cafd5
@@ -17,7 +17,7 @@ jobs:
17
17
  test:
18
18
  runs-on: ubuntu-latest
19
19
  container:
20
- image: welaika/wordmove:latest
20
+ image: welaika/wordmove:php7-wordmove6
21
21
 
22
22
  steps:
23
23
  - uses: actions/checkout@v2
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7.1
2
+ TargetRubyVersion: 3.1.0
3
3
  DisplayCopNames: true
4
4
  DisplayStyleGuide: true
5
5
  NewCops: enable
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.1
1
+ 3.1.0
@@ -9,7 +9,7 @@ module Wordmove
9
9
  class AdaptLocalDb
10
10
  extend ::LightService::Action
11
11
  include Wordmove::Actions::Helpers
12
- include Wordmove::Wpcli
12
+ include Wordmove::WpcliHelpers
13
13
 
14
14
  expects :local_options,
15
15
  :remote_options,
@@ -38,63 +38,104 @@ module Wordmove
38
38
 
39
39
  next context if simulate?(cli_options: context.cli_options)
40
40
 
41
- result = Wordmove::Actions::RunLocalCommand.execute(
42
- cli_options: context.cli_options,
43
- logger: context.logger,
44
- command: mysql_dump_command(
45
- env_db_options: context.local_options[:database],
46
- save_to_path: context.db_paths.local.path
47
- )
48
- )
49
- context.fail_and_return!(result.message) if result.failure?
41
+ context.logger.task_step true, dump_command(context)
42
+ begin
43
+ system(dump_command(context), exception: true)
44
+ rescue RuntimeError, SystemExit => e
45
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
46
+ end
50
47
 
51
48
  if context.cli_options[:no_adapt]
52
49
  context.logger.warn 'Skipping DB adapt'
53
50
  else
54
- result = Wordmove::Actions::RunLocalCommand.execute(
55
- cli_options: context.cli_options,
56
- logger: context.logger,
57
- command: wpcli_search_replace_command(context, :vhost)
58
- )
59
- context.fail_and_return!(result.message) if result.failure?
60
-
61
- result = Wordmove::Actions::RunLocalCommand.execute(
62
- cli_options: context.cli_options,
63
- logger: context.logger,
64
- command: wpcli_search_replace_command(context, :wordpress_path)
65
- )
66
- context.fail_and_return!(result.message) if result.failure?
67
- end
51
+ %i[vhost wordpress_path].each do |key|
52
+ command = search_replace_command(context, key)
53
+ context.logger.task_step true, command
68
54
 
69
- result = Wordmove::Actions::RunLocalCommand.execute(
70
- cli_options: context.cli_options,
55
+ begin
56
+ system(command, exception: true)
57
+ rescue RuntimeError, SystemExit => e
58
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
59
+ end
60
+ end
61
+ end
71
62
 
72
- logger: context.logger,
73
- command: mysql_dump_command(
74
- env_db_options: context.local_options[:database],
75
- save_to_path: context.db_paths.local.adapted_path
76
- )
77
- )
78
- context.fail_and_return!(result.message) if result.failure?
63
+ context.logger.task_step true, dump_adapted_command(context)
64
+ begin
65
+ system(dump_adapted_command(context), exception: true)
66
+ rescue RuntimeError, SystemExit => e
67
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
68
+ end
79
69
 
80
70
  if context.photocopier.is_a? Photocopier::SSH
81
- result = Wordmove::Actions::RunLocalCommand.execute(
82
- cli_options: context.cli_options,
83
- logger: context.logger,
84
- command: compress_command(file_path: context.db_paths.local.adapted_path)
85
- )
86
- context.fail_and_return!(result.message) if result.failure?
71
+ context.logger.task_step true, compress_command(context)
72
+ begin
73
+ system(compress_command(context), exception: true)
74
+ rescue RuntimeError, SystemExit => e
75
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
76
+ end
77
+ end
78
+
79
+ context.logger.task_step true, import_original_db_command(context)
80
+ begin
81
+ system(import_original_db_command(context), exception: true)
82
+ rescue RuntimeError, SystemExit => e
83
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
84
+ end
85
+ end
86
+
87
+ def self.dump_command(context)
88
+ "wp db export #{context.db_paths.local.path} --allow-root --quiet " \
89
+ "--path=#{wpcli_config_path(context)}"
90
+ end
91
+
92
+ def self.dump_adapted_command(context)
93
+ "wp db export #{context.db_paths.local.adapted_path} --allow-root --quiet " \
94
+ "--path=#{wpcli_config_path(context)}"
95
+ end
96
+
97
+ def self.import_original_db_command(context)
98
+ "wp db import #{context.db_paths.local.path} --allow-root --quiet " \
99
+ "--path=#{wpcli_config_path(context)}"
100
+ end
101
+
102
+ def self.compress_command(context)
103
+ command = ['nice']
104
+ command << '-n'
105
+ command << '0'
106
+ command << 'gzip'
107
+ command << '-9'
108
+ command << '-f'
109
+ command << "\"#{context.db_paths.local.adapted_path}\""
110
+ command.join(' ')
111
+ end
112
+
113
+ # Compose and returns the search-replace command. It's intended to be
114
+ # used from a +LightService::Action+
115
+ #
116
+ # @param context [LightService::Context] The context of an action
117
+ # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB
118
+ # @return [String]
119
+ # @!scope class
120
+ def self.search_replace_command(context, config_key)
121
+ unless %i[vhost wordpress_path].include?(config_key)
122
+ raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \
123
+ 'or :wordpress_path expected'
87
124
  end
88
125
 
89
- result = Wordmove::Actions::RunLocalCommand.execute(
90
- cli_options: context.cli_options,
91
- logger: context.logger,
92
- command: mysql_import_command(
93
- dump_path: context.db_paths.local.path,
94
- env_db_options: context.local_options[:database]
95
- )
96
- )
97
- context.fail_and_return!(result.message) if result.failure?
126
+ [
127
+ 'wp search-replace',
128
+ "--path=#{wpcli_config_path(context)}",
129
+ '"\A' + context.dig(:local_options, config_key) + '\Z"', # rubocop:disable Style/StringConcatenation
130
+ '"' + context.dig(:remote_options, config_key) + '"', # rubocop:disable Style/StringConcatenation
131
+ '--regex-delimiter="|"',
132
+ '--regex',
133
+ '--precise',
134
+ '--quiet',
135
+ '--skip-columns=guid',
136
+ '--all-tables',
137
+ '--allow-root'
138
+ ].join(' ')
98
139
  end
99
140
  end
100
141
  end
@@ -14,7 +14,7 @@ module Wordmove
14
14
  class AdaptRemoteDb
15
15
  extend ::LightService::Action
16
16
  include Wordmove::Actions::Helpers
17
- include Wordmove::Wpcli
17
+ include Wordmove::WpcliHelpers
18
18
 
19
19
  expects :local_options,
20
20
  :cli_options,
@@ -39,11 +39,12 @@ module Wordmove
39
39
  next context if simulate?(cli_options: context.cli_options)
40
40
 
41
41
  if File.exist?(context.db_paths.local.gzipped_path)
42
- Wordmove::Actions::RunLocalCommand.execute(
43
- cli_options: context.cli_options,
44
- logger: context.logger,
45
- command: uncompress_command(file_path: context.db_paths.local.gzipped_path)
46
- )
42
+ context.logger.task_step true, uncompress_command(context)
43
+ begin
44
+ system(uncompress_command(context), exception: true)
45
+ rescue RuntimeError, SystemExit => e
46
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
47
+ end
47
48
  end
48
49
 
49
50
  unless File.exist?(context.db_paths.local.path)
@@ -52,37 +53,76 @@ module Wordmove
52
53
  )
53
54
  end
54
55
 
55
- result = Wordmove::Actions::RunLocalCommand.execute(
56
- cli_options: context.cli_options,
57
- logger: context.logger,
58
- command: mysql_import_command(
59
- dump_path: context.db_paths.local.path,
60
- env_db_options: context.local_options[:database]
61
- )
62
- )
63
- context.fail_and_return!(result.message) if result.failure?
56
+ context.logger.task_step true, import_db_command(context)
57
+ begin
58
+ system(import_db_command(context), exception: true)
59
+ rescue RuntimeError, SystemExit => e
60
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
61
+ end
64
62
 
65
63
  if context.cli_options[:no_adapt]
66
64
  context.logger.warn 'Skipping DB adapt'
67
65
  next context
68
66
  end
69
67
 
70
- result = Wordmove::Actions::RunLocalCommand.execute(
71
- cli_options: context.cli_options,
72
- logger: context.logger,
73
- command: wpcli_search_replace_command(context, :vhost)
74
- )
75
- context.fail_and_return!(result.message) if result.failure?
76
-
77
- result = Wordmove::Actions::RunLocalCommand.execute(
78
- cli_options: context.cli_options,
79
- logger: context.logger,
80
- command: wpcli_search_replace_command(context, :wordpress_path)
81
- )
82
- context.fail_and_return!(result.message) if result.failure?
68
+ %i[vhost wordpress_path].each do |key|
69
+ command = search_replace_command(context, key)
70
+ context.logger.task_step true, command
71
+ begin
72
+ system(command, exception: true)
73
+ rescue RuntimeError, SystemExit => e
74
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
75
+ end
76
+ end
83
77
 
84
78
  context.logger.success 'Local DB adapted'
85
79
  end
80
+
81
+ # Construct the command to deflate a compressed file as a string.
82
+ #
83
+ # @param file_path [String] The path where the file to be deflated is located
84
+ # @return [String] the command
85
+ # @!scope class
86
+ def self.uncompress_command(context)
87
+ command = ['gzip']
88
+ command << '-d'
89
+ command << '-f'
90
+ command << "\"#{context.db_paths.local.gzipped_path}\""
91
+ command.join(' ')
92
+ end
93
+
94
+ def self.import_db_command(context)
95
+ "wp db import #{context.db_paths.local.path} --allow-root --quiet " \
96
+ "--path=#{wpcli_config_path(context)}"
97
+ end
98
+
99
+ # Compose and returns the search-replace command. It's intended to be
100
+ # used from a +LightService::Action+
101
+ #
102
+ # @param context [LightService::Context] The context of an action
103
+ # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB
104
+ # @return [String]
105
+ # @!scope class
106
+ def self.search_replace_command(context, config_key)
107
+ unless %i[vhost wordpress_path].include?(config_key)
108
+ raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \
109
+ 'or :wordpress_path expected'
110
+ end
111
+
112
+ [
113
+ 'wp search-replace',
114
+ "--path=#{wpcli_config_path(context)}",
115
+ '"\A' + context.dig(:remote_options, config_key) + '\Z"', # rubocop:disable Style/StringConcatenation
116
+ '"' + context.dig(:local_options, config_key) + '"', # rubocop:disable Style/StringConcatenation
117
+ '--regex-delimiter="|"',
118
+ '--regex',
119
+ '--precise',
120
+ '--quiet',
121
+ '--skip-columns=guid',
122
+ '--all-tables',
123
+ '--allow-root'
124
+ ].join(' ')
125
+ end
86
126
  end
87
127
  end
88
128
  end
@@ -30,27 +30,41 @@ module Wordmove
30
30
  next context
31
31
  end
32
32
 
33
- result = Wordmove::Actions::RunLocalCommand.execute(
34
- cli_options: context.cli_options,
35
- logger: context.logger,
36
- command: mysql_dump_command(
37
- env_db_options: context.local_options[:database],
38
- save_to_path: context.db_paths.backup.local.path
39
- )
40
- )
41
- context.fail_and_return!(result.message) if result.failure?
33
+ context.logger.task_step true, dump_command(context)
42
34
 
43
- result = Wordmove::Actions::RunLocalCommand.execute(
44
- cli_options: context.cli_options,
45
- logger: context.logger,
46
- command: compress_command(file_path: context.db_paths.backup.local.path)
47
- )
48
- context.fail_and_return!(result.message) if result.failure?
35
+ begin
36
+ system(dump_command(context), exception: true)
37
+ rescue RuntimeError, SystemExit => e
38
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
39
+ end
40
+
41
+ context.logger.task_step true, compress_command(context)
42
+
43
+ begin
44
+ system(compress_command(context), exception: true)
45
+ rescue RuntimeError, SystemExit => e
46
+ context.fail_and_return!("Local command status reports an error: #{e.message}")
47
+ end
49
48
 
50
49
  context.logger.success(
51
50
  "Backup saved at #{context.db_paths.backup.local.gzipped_path}"
52
51
  )
53
52
  end
53
+
54
+ def self.dump_command(context)
55
+ "wp db export #{context.db_paths.backup.local.path} --allow-root --quiet"
56
+ end
57
+
58
+ def self.compress_command(context)
59
+ command = ['nice']
60
+ command << '-n'
61
+ command << '0'
62
+ command << 'gzip'
63
+ command << '-9'
64
+ command << '-f'
65
+ command << "\"#{context.db_paths.backup.local.path}\""
66
+ command.join(' ')
67
+ end
54
68
  end
55
69
  end
56
70
  end
@@ -16,8 +16,6 @@ module Wordmove
16
16
  promises :db_paths
17
17
 
18
18
  executed do |context| # rubocop:disable Metrics/BlockLength
19
- next context if simulate?(cli_options: context.cli_options)
20
-
21
19
  content_dir = local_wp_content_dir(local_options: context.local_options)
22
20
 
23
21
  token = remote_php_scripts_token
@@ -52,12 +50,10 @@ module Wordmove
52
50
  remote_options: context.remote_options
53
51
  ).url('import.php')
54
52
  DbPathsConfig.ftp.local.generated_dump_script_path = generate_dump_script(
55
- remote_db_options: context.remote_options[:database],
56
- token: token
53
+ remote_db_options: context.remote_options[:database], token:
57
54
  )
58
55
  DbPathsConfig.ftp.local.generated_import_script_path = generate_import_script(
59
- remote_db_options: context.remote_options[:database],
60
- token: token
56
+ remote_db_options: context.remote_options[:database], token:
61
57
  )
62
58
  DbPathsConfig.ftp.local.temp_path = local_wp_content_dir(
63
59
  local_options: context.local_options
@@ -3,6 +3,7 @@ mapping:
3
3
  vhost:
4
4
  pattern: /^https?:\/\//
5
5
  wordpress_path:
6
+ required: true
6
7
  database:
7
8
  type: map
8
9
  required: true
@@ -15,9 +16,6 @@ mapping:
15
16
  required: true
16
17
  host:
17
18
  required: true
18
- mysqldump_options:
19
- port:
20
- charset:
21
19
  paths:
22
20
  type: map
23
21
  mapping:
data/lib/wordmove/cli.rb CHANGED
@@ -32,23 +32,16 @@ module Wordmove
32
32
  exit 1
33
33
  end
34
34
 
35
- def initial_context(cli_options)
36
- cli_options.deep_symbolize_keys!
37
- movefile = Wordmove::Movefile.new(cli_options)
38
-
39
- [cli_options, movefile]
40
- end
41
-
42
- def movefile_from(**cli_options)
35
+ def movefile_from(cli_options)
43
36
  ensure_wordpress_options_presence!(cli_options)
44
- Wordmove::Movefile.new(cli_options)
37
+ Wordmove::Movefile.new(cli_options, nil, true)
45
38
  rescue MovefileNotFound => e
46
39
  Logger.new($stdout).error(e.message)
47
40
  exit 1
48
41
  end
49
42
 
50
- def call_organizer_with(klass:, movefile:, **cli_options)
51
- result = klass.call(cli_options: cli_options, movefile: movefile)
43
+ def call_organizer_with(klass:, movefile:, cli_options:)
44
+ result = klass.call(cli_options, movefile)
52
45
 
53
46
  exit 0 if result.success?
54
47
 
@@ -114,22 +107,22 @@ module Wordmove
114
107
  private
115
108
 
116
109
  def call_pull_organizer_with(**cli_options)
117
- movefile = movefile_from(**cli_options)
110
+ movefile = movefile_from(cli_options)
118
111
 
119
112
  if movefile.options.dig(movefile.environment, :ssh)
120
113
  call_organizer_with(
121
114
  klass: Wordmove::Organizers::Ssh::Pull,
122
- movefile: movefile,
123
- **cli_options
115
+ movefile:, cli_options:
124
116
  )
125
117
  elsif movefile.options.dig(movefile.environment, :ftp)
126
118
  call_organizer_with(
127
119
  klass: Wordmove::Organizers::Ftp::Pull,
128
- movefile: movefile,
129
- **cli_options
120
+ movefile:, cli_options:
130
121
  )
131
122
  else
132
- raise NoAdapterFound, 'No valid adapter found.'
123
+ raise NoAdapterFound, 'No valid adapter found. It seems like your movefile.yml lacks ' \
124
+ 'an ssh or ftp section for the current environment. ' \
125
+ 'Run `wordmove doctor` for more info'
133
126
  end
134
127
  rescue NoAdapterFound => e
135
128
  Logger.new($stdout).error(e.message)
@@ -149,22 +142,22 @@ module Wordmove
149
142
  private
150
143
 
151
144
  def call_push_organizer_with(**cli_options)
152
- movefile = movefile_from(**cli_options)
145
+ movefile = movefile_from(cli_options)
153
146
 
154
147
  if movefile.options.dig(movefile.environment, :ssh)
155
148
  call_organizer_with(
156
149
  klass: Wordmove::Organizers::Ssh::Push,
157
- movefile: movefile,
158
- **cli_options
150
+ movefile:, cli_options:
159
151
  )
160
152
  elsif movefile.options.dig(movefile.environment, :ftp)
161
153
  call_organizer_with(
162
154
  klass: Wordmove::Organizers::Ftp::Push,
163
- movefile: movefile,
164
- **cli_options
155
+ movefile:, cli_options:
165
156
  )
166
157
  else
167
- raise NoAdapterFound, 'No valid adapter found.'
158
+ raise NoAdapterFound, 'No valid adapter found. It seems like your movefile.yml lacks ' \
159
+ 'an ssh or ftp section for the current environment. ' \
160
+ 'Run `wordmove doctor` for more info'
168
161
  end
169
162
  rescue NoAdapterFound => e
170
163
  Logger.new($stdout).error(e.message)
@@ -5,7 +5,7 @@ module Wordmove
5
5
  attr_reader :movefile, :contents, :root_keys
6
6
 
7
7
  def initialize(cli_options = {}, dir = '.')
8
- @movefile = Wordmove::Movefile.new(cli_options, dir)
8
+ @movefile = Wordmove::Movefile.new(cli_options, dir, false)
9
9
 
10
10
  begin
11
11
  @contents = movefile.options
@@ -7,7 +7,7 @@ module Wordmove
7
7
  @logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
8
8
  begin
9
9
  @config = Wordmove::Movefile
10
- .new({ config: movefile_name }, movefile_dir)
10
+ .new({ config: movefile_name }, movefile_dir, false)
11
11
  .options[:local][:database]
12
12
  rescue Psych::SyntaxError => e
13
13
  logger.error e.message
@@ -16,8 +16,8 @@ module Wordmove
16
16
  end
17
17
 
18
18
  def print
19
- contents = parse_movefile(movefile: movefile)
20
- generate_vhost_list(contents: contents)
19
+ contents = parse_movefile(movefile:)
20
+ generate_vhost_list(contents:)
21
21
  output
22
22
  end
23
23
 
@@ -55,7 +55,7 @@ module Wordmove
55
55
  #
56
56
  def generate_vhost_list(contents:)
57
57
  # select object which has 'vhost' only
58
- vhosts = select_vhost(contents: contents)
58
+ vhosts = select_vhost(contents:)
59
59
  vhosts.each do |list|
60
60
  if list[:env] == :local
61
61
  @local_vhost << list
@@ -1,16 +1,15 @@
1
1
  module Wordmove
2
2
  module Generators
3
3
  class Movefile
4
- include MovefileAdapter
5
-
6
4
  def self.generate
7
- new.copy_movefile
5
+ copy_movefile
8
6
  end
9
7
 
10
- def copy_movefile
8
+ def self.copy_movefile
9
+ wordpress_path = File.expand_path(Dir.pwd)
11
10
  content = ERB.new(File.read(File.join(__dir__, 'movefile.yml'))).result(binding)
12
- files = Dry::Files.new
13
11
 
12
+ files = Dry::Files.new
14
13
  files.write('movefile.yml', content)
15
14
  end
16
15
  end
@@ -2,14 +2,15 @@ global:
2
2
  sql_adapter: wpcli
3
3
 
4
4
  local:
5
- vhost: http://vhost.local
6
5
  wordpress_path: <%= wordpress_path %> # use an absolute path here
7
6
 
8
- database:
9
- name: <%= database.name %>
10
- user: <%= database.user %>
11
- password: "<%= database.password %>" # could be blank, so always use quotes around
12
- host: <%= database.host %>
7
+ # paths: # you can customize wordpress internal paths
8
+ # wp_content: wp-content
9
+ # uploads: wp-content/uploads
10
+ # plugins: wp-content/plugins
11
+ # mu_plugins: wp-content/mu-plugins
12
+ # themes: wp-content/themes
13
+ # languages: wp-content/languages
13
14
 
14
15
  production:
15
16
  vhost: http://example.com
@@ -40,6 +41,7 @@ production:
40
41
  - 'wp-config.php'
41
42
  - 'wp-content/*.sql.gz'
42
43
  - '*.orig'
44
+ - 'wp-cli.yml'
43
45
 
44
46
  # paths: # you can customize wordpress internal paths
45
47
  # wp_content: wp-content
@@ -56,8 +56,6 @@ module Wordmove
56
56
  private
57
57
 
58
58
  def fetch(verbose = true) # rubocop:disable Style/OptionalBooleanParameter
59
- load_dotenv
60
-
61
59
  entries = if config_file_name.nil?
62
60
  Dir["#{File.join(start_dir, '{M,m}ovefile')}{,.yml,.yaml}"]
63
61
  else
@@ -75,18 +73,40 @@ module Wordmove
75
73
  end
76
74
 
77
75
  found = entries.first
76
+
78
77
  logger.task("Using Movefile: #{found}") if verbose == true
79
- YAML.safe_load(ERB.new(File.read(found)).result, [], [], true).deep_symbolize_keys!
78
+ load_dotenv(verbose)
79
+
80
+ options = YAML.safe_load(ERB.new(File.read(found)).result, symbolize_names: true)
81
+
82
+ merge_local_options_from_wpcli(options)
83
+ end
84
+
85
+ def merge_local_options_from_wpcli(options)
86
+ config_path = options.dig(:local, :wordpress_path)
87
+
88
+ options.merge(
89
+ local: {
90
+ database: {
91
+ password: Wordmove::WpcliHelpers.get_config('DB_PASSWORD', config_path:),
92
+ host: Wordmove::WpcliHelpers.get_config('DB_HOST', config_path:),
93
+ name: Wordmove::WpcliHelpers.get_config('DB_NAME', config_path:),
94
+ user: Wordmove::WpcliHelpers.get_config('DB_USER', config_path:)
95
+ },
96
+ vhost: Wordmove::WpcliHelpers.get_option('home', config_path:),
97
+ wordpress_path: config_path
98
+ }
99
+ )
80
100
  end
81
101
 
82
- def load_dotenv
102
+ def load_dotenv(verbose)
83
103
  env_files = Dir[File.join(start_dir, '.env')]
84
104
 
85
105
  found_env = env_files.first
86
106
 
87
107
  return false unless found_env.present?
88
108
 
89
- logger.info("Using .env file: #{found_env}")
109
+ logger.info("Using .env file: #{found_env}") if verbose
90
110
  Dotenv.load(found_env)
91
111
  end
92
112
 
@@ -6,21 +6,23 @@ module Wordmove
6
6
  include Wordmove::Actions::Helpers
7
7
  include Wordmove::Actions::Ftp::Helpers
8
8
 
9
- def self.call(cli_options:, movefile:)
9
+ # Can't use keyword arguments since LightService still has some problems with modern
10
+ # ruby syntax: https://github.com/adomokos/light-service/pull/224
11
+ def self.call(cli_options, movefile)
10
12
  logger = Logger.new($stdout, movefile.secrets).tap { |l| l.level = Logger::DEBUG }
11
13
  remote_options = movefile.options[movefile.environment]
12
- ftp_opts = ftp_options(remote_options: remote_options)
14
+ ftp_opts = ftp_options(remote_options:)
13
15
 
14
16
  LightService::Configuration.logger = ::Logger.new($stdout) if cli_options[:debug]
15
17
 
16
18
  with(
17
- cli_options: cli_options,
19
+ cli_options:,
18
20
  global_options: movefile.options[:global],
19
21
  local_options: movefile.options[:local],
20
- remote_options: remote_options,
21
- movefile: movefile,
22
- guardian: Wordmove::Guardian.new(cli_options: cli_options, action: :pull),
23
- logger: logger,
22
+ remote_options:,
23
+ movefile:,
24
+ guardian: Wordmove::Guardian.new(cli_options:, action: :pull),
25
+ logger:,
24
26
  photocopier: Photocopier::FTP
25
27
  .new(ftp_opts)
26
28
  .tap { |c| c.logger = logger }
@@ -6,21 +6,23 @@ module Wordmove
6
6
  include Wordmove::Actions::Helpers
7
7
  include Wordmove::Actions::Ftp::Helpers
8
8
 
9
- def self.call(cli_options:, movefile:)
9
+ # Can't use keyword arguments since LightService still has some problems with modern
10
+ # ruby syntax: https://github.com/adomokos/light-service/pull/224
11
+ def self.call(cli_options, movefile)
10
12
  logger = Logger.new($stdout, movefile.secrets).tap { |l| l.level = Logger::DEBUG }
11
13
  remote_options = movefile.options[movefile.environment]
12
- ftp_opts = ftp_options(remote_options: remote_options)
14
+ ftp_opts = ftp_options(remote_options:)
13
15
 
14
16
  LightService::Configuration.logger = ::Logger.new($stdout) if cli_options[:debug]
15
17
 
16
18
  with(
17
- cli_options: cli_options,
19
+ cli_options:,
18
20
  global_options: movefile.options[:global],
19
21
  local_options: movefile.options[:local],
20
- remote_options: remote_options,
21
- movefile: movefile,
22
- guardian: Wordmove::Guardian.new(cli_options: cli_options, action: :push),
23
- logger: logger,
22
+ remote_options:,
23
+ movefile:,
24
+ guardian: Wordmove::Guardian.new(cli_options:, action: :push),
25
+ logger:,
24
26
  photocopier: Photocopier::FTP
25
27
  .new(ftp_opts)
26
28
  .tap { |c| c.logger = logger }
@@ -6,21 +6,23 @@ module Wordmove
6
6
  include Wordmove::Actions::Helpers
7
7
  include Wordmove::Actions::Ssh::Helpers
8
8
 
9
- def self.call(cli_options:, movefile:)
9
+ # Can't use keyword arguments since LightService still has some problems with modern
10
+ # ruby syntax: https://github.com/adomokos/light-service/pull/224
11
+ def self.call(cli_options, movefile)
10
12
  logger = Logger.new($stdout, movefile.secrets).tap { |l| l.level = Logger::DEBUG }
11
13
  remote_options = movefile.options[movefile.environment]
12
- ssh_opts = ssh_options(remote_options: remote_options, simulate: cli_options[:simulate])
14
+ ssh_opts = ssh_options(remote_options:, simulate: cli_options[:simulate])
13
15
 
14
16
  LightService::Configuration.logger = ::Logger.new($stdout) if cli_options[:debug]
15
17
 
16
18
  with(
17
- cli_options: cli_options,
19
+ cli_options:,
18
20
  global_options: movefile.options[:global],
19
21
  local_options: movefile.options[:local],
20
- remote_options: remote_options,
21
- movefile: movefile,
22
- guardian: Wordmove::Guardian.new(cli_options: cli_options, action: :pull),
23
- logger: logger,
22
+ remote_options:,
23
+ movefile:,
24
+ guardian: Wordmove::Guardian.new(cli_options:, action: :pull),
25
+ logger:,
24
26
  photocopier: Photocopier::SSH
25
27
  .new(ssh_opts)
26
28
  .tap { |c| c.logger = logger }
@@ -6,21 +6,23 @@ module Wordmove
6
6
  include Wordmove::Actions::Helpers
7
7
  include Wordmove::Actions::Ssh::Helpers
8
8
 
9
- def self.call(cli_options:, movefile:)
9
+ # Can't use keyword arguments since LightService still has some problems with modern
10
+ # ruby syntax: https://github.com/adomokos/light-service/pull/224
11
+ def self.call(cli_options, movefile)
10
12
  logger = Logger.new($stdout, movefile.secrets).tap { |l| l.level = Logger::DEBUG }
11
13
  remote_options = movefile.options[movefile.environment]
12
- ssh_opts = ssh_options(remote_options: remote_options, simulate: cli_options[:simulate])
14
+ ssh_opts = ssh_options(remote_options:, simulate: cli_options[:simulate])
13
15
 
14
16
  LightService::Configuration.logger = ::Logger.new($stdout) if cli_options[:debug]
15
17
 
16
18
  with(
17
- cli_options: cli_options,
19
+ cli_options:,
18
20
  global_options: movefile.options[:global],
19
21
  local_options: movefile.options[:local],
20
- remote_options: remote_options,
21
- movefile: movefile,
22
- guardian: Wordmove::Guardian.new(cli_options: cli_options, action: :push),
23
- logger: logger,
22
+ remote_options:,
23
+ movefile:,
24
+ guardian: Wordmove::Guardian.new(cli_options:, action: :push),
25
+ logger:,
24
26
  photocopier: Photocopier::SSH
25
27
  .new(ssh_opts)
26
28
  .tap { |c| c.logger = logger }
@@ -1,3 +1,3 @@
1
1
  module Wordmove
2
- VERSION = '6.0.0.alpha.4'.freeze
2
+ VERSION = '6.0.0.alpha.8'.freeze
3
3
  end
@@ -1,7 +1,7 @@
1
1
  module Wordmove
2
2
  # This class is a sort of mini-wrapper around the wp-cli executable.
3
3
  # It's responsible to run or produce wp-cli commands.
4
- module Wpcli
4
+ module WpcliHelpers
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
@@ -17,39 +17,27 @@ module Wordmove
17
17
  system('which wp > /dev/null 2>&1')
18
18
  end
19
19
 
20
- # Compose and returns the search-replace command. It's intended to be
21
- # used from a +LightService::Action+
22
- #
23
- # @param context [LightService::Context] The context of an action
24
- # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB
25
- # @return [String]
26
- # @!scope class
27
- def wpcli_search_replace_command(context, config_key)
28
- unless %i[vhost wordpress_path].include?(config_key)
29
- raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \
30
- 'or :wordpress_path expected'
31
- end
32
-
33
- [
34
- 'wp search-replace',
35
- "--path=#{wpcli_config_path(context)}",
36
- context.dig(:remote_options, config_key),
37
- context.dig(:local_options, config_key),
38
- '--quiet',
39
- '--skip-columns=guid',
40
- '--all-tables',
41
- '--allow-root'
42
- ].join(' ')
43
- end
44
-
45
20
  # Returns the wordpress path from wp-cli (with precedence) or from movefile
46
21
  #
47
- # It's intended to be used from a +LightService::Action+
22
+ # It's intended to be used from a +LightService::Action+, but it also supports
23
+ # to receive a path as argument. If the argument is not a LightService::Context
24
+ # then it will be treated as a path.
25
+ # The path passed as argument should be the wordpress installation path, but it's
26
+ # not strictly mandatory: the method will try to load a wpcli's YAML config
27
+ # from that path, so you can potentially use it with any path
48
28
  #
49
- # @param context [LightService::Context] The context of an action
29
+ # @param context [LightService::Context|String] The context of an action or a path as string
50
30
  # @return [String]
51
31
  # @!scope class
52
- def wpcli_config_path(context)
32
+ def wpcli_config_path(context_or_path)
33
+ context = if context_or_path.is_a? LightService::Context
34
+ context_or_path
35
+ else
36
+ # We need to make it quack like a duck in order to be
37
+ # backward compatible with previous code
38
+ { local_options: { wordpress_path: context_or_path } }
39
+ end
40
+
53
41
  load_from_yml(context) || load_from_wpcli || context.dig(:local_options, :wordpress_path)
54
42
  end
55
43
 
@@ -60,7 +48,8 @@ module Wordmove
60
48
  # @!scope class
61
49
  # @!visibility private
62
50
  def load_from_yml(context)
63
- yml_path = File.join(context.dig(:local_options, :wordpress_path), 'wp-cli.yml')
51
+ config_path = context.dig(:local_options, :wordpress_path) || '.'
52
+ yml_path = File.join(config_path, 'wp-cli.yml')
64
53
 
65
54
  return unless File.exist?(yml_path)
66
55
 
@@ -84,5 +73,13 @@ module Wordmove
84
73
  nil
85
74
  end
86
75
  end
76
+
77
+ def self.get_option(option, config_path:)
78
+ `wp option get #{option} --allow-root --path=#{config_path}`.chomp
79
+ end
80
+
81
+ def self.get_config(config, config_path:)
82
+ `wp config get #{config} --allow-root --path=#{config_path}`.chomp
83
+ end
87
84
  end
88
85
  end
data/lib/wordmove.rb CHANGED
@@ -17,6 +17,8 @@ require 'yaml'
17
17
 
18
18
  require 'photocopier'
19
19
 
20
+ require 'wordmove/wpcli'
21
+
20
22
  require 'wordmove/cli'
21
23
  require 'wordmove/doctor'
22
24
  require 'wordmove/doctor/movefile'
@@ -32,9 +34,7 @@ require 'wordmove/movefile'
32
34
  require 'wordmove/wordpress_directory'
33
35
  require 'wordmove/version'
34
36
  require 'wordmove/environments_list'
35
- require 'wordmove/wpcli'
36
37
 
37
- require 'wordmove/generators/movefile_adapter'
38
38
  require 'wordmove/generators/movefile'
39
39
 
40
40
  require 'wordmove/db_paths_config'
@@ -42,8 +42,8 @@ require 'wordmove/db_paths_config'
42
42
  require 'wordmove/actions/helpers'
43
43
  require 'wordmove/actions/ssh/helpers'
44
44
  require 'wordmove/actions/ftp/helpers'
45
- Dir[File.join(__dir__, 'wordmove/actions/**/*.rb')].sort.each { |file| require file }
46
- Dir[File.join(__dir__, 'wordmove/organizers/**/*.rb')].sort.each { |file| require file }
45
+ Dir[File.join(__dir__, 'wordmove/actions/**/*.rb')].each { |file| require file }
46
+ Dir[File.join(__dir__, 'wordmove/organizers/**/*.rb')].each { |file| require file }
47
47
 
48
48
  module Wordmove
49
49
  # Interactors' namespce. Interactors are called "Actions", following the LightService convention.
data/wordmove.gemspec CHANGED
@@ -36,12 +36,12 @@ Gem::Specification.new do |spec|
36
36
  spec.add_runtime_dependency 'dry-configurable', '~> 0.13.0'
37
37
  spec.add_runtime_dependency 'kwalify', '~> 0.7.2'
38
38
  spec.add_runtime_dependency 'light-service', '~> 0.17.0'
39
- spec.add_runtime_dependency 'photocopier', '~> 1.4', '>= 1.4.0'
39
+ spec.add_runtime_dependency 'photocopier', '~> 1.4', '>= 1.4.1'
40
40
  # spec.add_runtime_dependency 'thor', '~> 0.20.3'
41
41
  spec.add_runtime_dependency 'dry-cli', '~> 0.7.0'
42
42
  spec.add_runtime_dependency 'dry-files', '~> 0.1.0'
43
43
 
44
- spec.required_ruby_version = '>= 2.6.0' # rubocop:disable Gemspec/RequiredRubyVersion
44
+ spec.required_ruby_version = '>= 3.1.0'
45
45
 
46
46
  spec.add_development_dependency 'bundler', '~> 2.3.3'
47
47
  spec.add_development_dependency 'pry-byebug', '~> 3.1'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wordmove
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.alpha.4
4
+ version: 6.0.0.alpha.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Verna
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2021-12-30 00:00:00.000000000 Z
15
+ date: 2022-01-04 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -107,7 +107,7 @@ dependencies:
107
107
  version: '1.4'
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 1.4.0
110
+ version: 1.4.1
111
111
  type: :runtime
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
@@ -117,7 +117,7 @@ dependencies:
117
117
  version: '1.4'
118
118
  - - ">="
119
119
  - !ruby/object:Gem::Version
120
- version: 1.4.0
120
+ version: 1.4.1
121
121
  - !ruby/object:Gem::Dependency
122
122
  name: dry-cli
123
123
  requirement: !ruby/object:Gem::Requirement
@@ -375,7 +375,6 @@ files:
375
375
  - lib/wordmove/exceptions.rb
376
376
  - lib/wordmove/generators/movefile.rb
377
377
  - lib/wordmove/generators/movefile.yml
378
- - lib/wordmove/generators/movefile_adapter.rb
379
378
  - lib/wordmove/guardian.rb
380
379
  - lib/wordmove/hook.rb
381
380
  - lib/wordmove/logger.rb
@@ -410,14 +409,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
410
409
  requirements:
411
410
  - - ">="
412
411
  - !ruby/object:Gem::Version
413
- version: 2.6.0
412
+ version: 3.1.0
414
413
  required_rubygems_version: !ruby/object:Gem::Requirement
415
414
  requirements:
416
415
  - - ">"
417
416
  - !ruby/object:Gem::Version
418
417
  version: 1.3.1
419
418
  requirements: []
420
- rubygems_version: 3.1.2
419
+ rubygems_version: 3.3.3
421
420
  signing_key:
422
421
  specification_version: 4
423
422
  summary: Wordmove, Capistrano for Wordpress
@@ -1,89 +0,0 @@
1
- module Wordmove
2
- module Generators
3
- module MovefileAdapter
4
- def wordpress_path
5
- File.expand_path(Dir.pwd)
6
- end
7
-
8
- def database
9
- DBConfigReader.config
10
- end
11
- end
12
-
13
- class DBConfigReader
14
- def self.config
15
- new.config
16
- end
17
-
18
- def config
19
- Struct.new(
20
- :name,
21
- :user,
22
- :password,
23
- :host,
24
- keyword_init: true
25
- ).new(database_config)
26
- end
27
-
28
- def database_config
29
- if wp_config_exists?
30
- WordpressDBConfig.config
31
- else
32
- DefaultDBConfig.config
33
- end
34
- end
35
-
36
- def wp_config_exists?
37
- File.exist?(WordpressDirectory.default_path_for(:wp_config))
38
- end
39
- end
40
-
41
- class DefaultDBConfig
42
- def self.config
43
- {
44
- name: 'database_name',
45
- user: 'user',
46
- password: 'password',
47
- host: '127.0.0.1'
48
- }
49
- end
50
- end
51
-
52
- class WordpressDBConfig
53
- def self.config
54
- new.config
55
- end
56
-
57
- def wp_config
58
- @wp_config ||= File.read(
59
- WordpressDirectory.default_path_for(:wp_config)
60
- ).encode('utf-8', invalid: :replace)
61
- end
62
-
63
- def wp_definitions
64
- {
65
- name: 'DB_NAME',
66
- user: 'DB_USER',
67
- password: 'DB_PASSWORD',
68
- host: 'DB_HOST'
69
- }
70
- end
71
-
72
- def wp_definition_regex(definition)
73
- /['"]#{definition}['"],\s*["'](?<value>.*)['"]/
74
- end
75
-
76
- def defaults
77
- DefaultDBConfig.config.clone
78
- end
79
-
80
- def config
81
- wp_definitions.each_with_object(defaults) do |(key, definition), result|
82
- wp_config.match(wp_definition_regex(definition)) do |match|
83
- result[key] = match[:value]
84
- end
85
- end
86
- end
87
- end
88
- end
89
- end