diff --git a/lib/wordmove.rb b/lib/wordmove.rb index aa7358f1..337af73f 100644 --- a/lib/wordmove.rb +++ b/lib/wordmove.rb @@ -17,6 +17,8 @@ require 'photocopier' +require 'wordmove/wpcli' + require 'wordmove/cli' require 'wordmove/doctor' require 'wordmove/doctor/movefile' @@ -32,7 +34,6 @@ require 'wordmove/wordpress_directory' require 'wordmove/version' require 'wordmove/environments_list' -require 'wordmove/wpcli' require 'wordmove/generators/movefile_adapter' require 'wordmove/generators/movefile' diff --git a/lib/wordmove/actions/adapt_local_db.rb b/lib/wordmove/actions/adapt_local_db.rb index 6a7dad06..b03777d6 100644 --- a/lib/wordmove/actions/adapt_local_db.rb +++ b/lib/wordmove/actions/adapt_local_db.rb @@ -9,7 +9,7 @@ module Actions class AdaptLocalDb extend ::LightService::Action include Wordmove::Actions::Helpers - include Wordmove::Wpcli + include Wordmove::WpcliHelpers expects :local_options, :remote_options, @@ -38,63 +38,104 @@ class AdaptLocalDb next context if simulate?(cli_options: context.cli_options) - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: mysql_dump_command( - env_db_options: context.local_options[:database], - save_to_path: context.db_paths.local.path - ) - ) - context.fail_and_return!(result.message) if result.failure? + context.logger.task_step true, dump_command(context) + begin + system(dump_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end if context.cli_options[:no_adapt] context.logger.warn 'Skipping DB adapt' else - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: wpcli_search_replace_command(context, :vhost) - ) - context.fail_and_return!(result.message) if result.failure? - - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: wpcli_search_replace_command(context, :wordpress_path) - ) - context.fail_and_return!(result.message) if result.failure? - end + %i[vhost wordpress_path].each do |key| + command = search_replace_command(context, key) + context.logger.task_step true, command - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, + begin + system(command, exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end + end + end - logger: context.logger, - command: mysql_dump_command( - env_db_options: context.local_options[:database], - save_to_path: context.db_paths.local.adapted_path - ) - ) - context.fail_and_return!(result.message) if result.failure? + context.logger.task_step true, dump_adapted_command(context) + begin + system(dump_adapted_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end if context.photocopier.is_a? Photocopier::SSH - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: compress_command(file_path: context.db_paths.local.adapted_path) - ) - context.fail_and_return!(result.message) if result.failure? + context.logger.task_step true, compress_command(context) + begin + system(compress_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end + end + + context.logger.task_step true, import_original_db_command(context) + begin + system(import_original_db_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end + end + + def self.dump_command(context) + "wp db export #{context.db_paths.local.path} --allow-root --quiet " \ + "--path=#{wpcli_config_path(context)}" + end + + def self.dump_adapted_command(context) + "wp db export #{context.db_paths.local.adapted_path} --allow-root --quiet " \ + "--path=#{wpcli_config_path(context)}" + end + + def self.import_original_db_command(context) + "wp db import #{context.db_paths.local.path} --allow-root --quiet " \ + "--path=#{wpcli_config_path(context)}" + end + + def self.compress_command(context) + command = ['nice'] + command << '-n' + command << '0' + command << 'gzip' + command << '-9' + command << '-f' + command << "\"#{context.db_paths.local.adapted_path}\"" + command.join(' ') + end + + # Compose and returns the search-replace command. It's intended to be + # used from a +LightService::Action+ + # + # @param context [LightService::Context] The context of an action + # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB + # @return [String] + # @!scope class + def self.search_replace_command(context, config_key) + unless %i[vhost wordpress_path].include?(config_key) + raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \ + 'or :wordpress_path expected' end - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: mysql_import_command( - dump_path: context.db_paths.local.path, - env_db_options: context.local_options[:database] - ) - ) - context.fail_and_return!(result.message) if result.failure? + [ + 'wp search-replace', + "--path=#{wpcli_config_path(context)}", + '"\A' + context.dig(:local_options, config_key) + '\Z"', # rubocop:disable Style/StringConcatenation + '"' + context.dig(:remote_options, config_key) + '"', # rubocop:disable Style/StringConcatenation + '--regex-delimiter="|"', + '--regex', + '--precise', + '--quiet', + '--skip-columns=guid', + '--all-tables', + '--allow-root' + ].join(' ') end end end diff --git a/lib/wordmove/actions/adapt_remote_db.rb b/lib/wordmove/actions/adapt_remote_db.rb index 1f4acf8c..9fa59046 100644 --- a/lib/wordmove/actions/adapt_remote_db.rb +++ b/lib/wordmove/actions/adapt_remote_db.rb @@ -14,7 +14,7 @@ module Actions class AdaptRemoteDb extend ::LightService::Action include Wordmove::Actions::Helpers - include Wordmove::Wpcli + include Wordmove::WpcliHelpers expects :local_options, :cli_options, @@ -39,11 +39,12 @@ class AdaptRemoteDb next context if simulate?(cli_options: context.cli_options) if File.exist?(context.db_paths.local.gzipped_path) - Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: uncompress_command(file_path: context.db_paths.local.gzipped_path) - ) + context.logger.task_step true, uncompress_command(context) + begin + system(uncompress_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end end unless File.exist?(context.db_paths.local.path) @@ -52,37 +53,76 @@ class AdaptRemoteDb ) end - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: mysql_import_command( - dump_path: context.db_paths.local.path, - env_db_options: context.local_options[:database] - ) - ) - context.fail_and_return!(result.message) if result.failure? + context.logger.task_step true, import_db_command(context) + begin + system(import_db_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end if context.cli_options[:no_adapt] context.logger.warn 'Skipping DB adapt' next context end - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: wpcli_search_replace_command(context, :vhost) - ) - context.fail_and_return!(result.message) if result.failure? - - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: wpcli_search_replace_command(context, :wordpress_path) - ) - context.fail_and_return!(result.message) if result.failure? + %i[vhost wordpress_path].each do |key| + command = search_replace_command(context, key) + context.logger.task_step true, command + begin + system(command, exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end + end context.logger.success 'Local DB adapted' end + + # Construct the command to deflate a compressed file as a string. + # + # @param file_path [String] The path where the file to be deflated is located + # @return [String] the command + # @!scope class + def self.uncompress_command(context) + command = ['gzip'] + command << '-d' + command << '-f' + command << "\"#{context.db_paths.local.gzipped_path}\"" + command.join(' ') + end + + def self.import_db_command(context) + "wp db import #{context.db_paths.local.path} --allow-root --quiet " \ + "--path=#{wpcli_config_path(context)}" + end + + # Compose and returns the search-replace command. It's intended to be + # used from a +LightService::Action+ + # + # @param context [LightService::Context] The context of an action + # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB + # @return [String] + # @!scope class + def self.search_replace_command(context, config_key) + unless %i[vhost wordpress_path].include?(config_key) + raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \ + 'or :wordpress_path expected' + end + + [ + 'wp search-replace', + "--path=#{wpcli_config_path(context)}", + '"\A' + context.dig(:remote_options, config_key) + '\Z"', # rubocop:disable Style/StringConcatenation + '"' + context.dig(:local_options, config_key) + '"', # rubocop:disable Style/StringConcatenation + '--regex-delimiter="|"', + '--regex', + '--precise', + '--quiet', + '--skip-columns=guid', + '--all-tables', + '--allow-root' + ].join(' ') + end end end end diff --git a/lib/wordmove/actions/backup_local_db.rb b/lib/wordmove/actions/backup_local_db.rb index a6a1b695..c6fb152f 100644 --- a/lib/wordmove/actions/backup_local_db.rb +++ b/lib/wordmove/actions/backup_local_db.rb @@ -30,27 +30,41 @@ class BackupLocalDb next context end - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: mysql_dump_command( - env_db_options: context.local_options[:database], - save_to_path: context.db_paths.backup.local.path - ) - ) - context.fail_and_return!(result.message) if result.failure? + context.logger.task_step true, dump_command(context) - result = Wordmove::Actions::RunLocalCommand.execute( - cli_options: context.cli_options, - logger: context.logger, - command: compress_command(file_path: context.db_paths.backup.local.path) - ) - context.fail_and_return!(result.message) if result.failure? + begin + system(dump_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end + + context.logger.task_step true, compress_command(context) + + begin + system(compress_command(context), exception: true) + rescue RuntimeError, SystemExit => e + context.fail_and_return!("Local command status reports an error: #{e.message}") + end context.logger.success( "Backup saved at #{context.db_paths.backup.local.gzipped_path}" ) end + + def self.dump_command(context) + "wp db export #{context.db_paths.backup.local.path} --allow-root --quiet" + end + + def self.compress_command(context) + command = ['nice'] + command << '-n' + command << '0' + command << 'gzip' + command << '-9' + command << '-f' + command << "\"#{context.db_paths.backup.local.path}\"" + command.join(' ') + end end end end diff --git a/lib/wordmove/assets/wordmove_schema_local.yml b/lib/wordmove/assets/wordmove_schema_local.yml index e2cbe6c5..c8e0d55a 100644 --- a/lib/wordmove/assets/wordmove_schema_local.yml +++ b/lib/wordmove/assets/wordmove_schema_local.yml @@ -3,6 +3,7 @@ mapping: vhost: pattern: /^https?:\/\// wordpress_path: + required: true database: type: map required: true @@ -15,9 +16,6 @@ mapping: required: true host: required: true - mysqldump_options: - port: - charset: paths: type: map mapping: diff --git a/lib/wordmove/movefile.rb b/lib/wordmove/movefile.rb index 726d2608..8d20d761 100644 --- a/lib/wordmove/movefile.rb +++ b/lib/wordmove/movefile.rb @@ -56,8 +56,6 @@ def secrets private def fetch(verbose = true) # rubocop:disable Style/OptionalBooleanParameter - load_dotenv - entries = if config_file_name.nil? Dir["#{File.join(start_dir, '{M,m}ovefile')}{,.yml,.yaml}"] else @@ -75,18 +73,40 @@ def fetch(verbose = true) # rubocop:disable Style/OptionalBooleanParameter end found = entries.first + logger.task("Using Movefile: #{found}") if verbose == true - YAML.safe_load(ERB.new(File.read(found)).result, [], [], true).deep_symbolize_keys! + load_dotenv(verbose) + + options = YAML.safe_load(ERB.new(File.read(found)).result, [], [], true).deep_symbolize_keys! + + merge_local_options_from_wpcli(options) + end + + def merge_local_options_from_wpcli(options) + config_path = options.dig(:local, :wordpress_path) + + options.merge( + local: { + database: { + password: Wordmove::WpcliHelpers.get_config('DB_PASSWORD', config_path: config_path), + host: Wordmove::WpcliHelpers.get_config('DB_HOST', config_path: config_path), + name: Wordmove::WpcliHelpers.get_config('DB_NAME', config_path: config_path), + user: Wordmove::WpcliHelpers.get_config('DB_USER', config_path: config_path) + }, + vhost: Wordmove::WpcliHelpers.get_option('siteurl', config_path: config_path), + wordpress_path: config_path + } + ) end - def load_dotenv + def load_dotenv(verbose) env_files = Dir[File.join(start_dir, '.env')] found_env = env_files.first return false unless found_env.present? - logger.info("Using .env file: #{found_env}") + logger.info("Using .env file: #{found_env}") if verbose Dotenv.load(found_env) end diff --git a/lib/wordmove/wpcli.rb b/lib/wordmove/wpcli.rb index 69c1ab33..fc316b45 100644 --- a/lib/wordmove/wpcli.rb +++ b/lib/wordmove/wpcli.rb @@ -1,7 +1,7 @@ module Wordmove # This class is a sort of mini-wrapper around the wp-cli executable. # It's responsible to run or produce wp-cli commands. - module Wpcli + module WpcliHelpers extend ActiveSupport::Concern included do @@ -17,46 +17,27 @@ def wp_in_path? system('which wp > /dev/null 2>&1') end - # Compose and returns the search-replace command. It's intended to be - # used from a +LightService::Action+ - # - # @param context [LightService::Context] The context of an action - # @param config_key [:vhost, :wordpress_path] Determines what will be replaced in DB - # @return [String] - # @!scope class - def wpcli_search_replace_command(context, config_key) - unless %i[vhost wordpress_path].include?(config_key) - raise ArgumentError, "Unexpected `config_key` #{config_key}.:vhost" \ - 'or :wordpress_path expected' - end - - [ - 'wp search-replace', - "--path=#{wpcli_config_path(context)}", - '"\A' + context.dig(:remote_options, config_key) + '\Z"', # rubocop:disable Style/StringConcatenation - '"' + context.dig(:local_options, config_key) + '"', # rubocop:disable Style/StringConcatenation - '--regex-delimiter="|"', - '--regex', - '--precise', - '--quiet', - '--skip-columns=guid', - '--all-tables', - '--allow-root' - ].join(' ') - end - - def wpcli_db_export_command(save_to_path:) - "wp db export #{save_to_path} --allow-root" - end - # Returns the wordpress path from wp-cli (with precedence) or from movefile # - # It's intended to be used from a +LightService::Action+ + # It's intended to be used from a +LightService::Action+, but it also supports + # to receive a path as argument. If the argument is not a LightService::Context + # then it will be treated as a path. + # The path passed as argument should be the wordpress installation path, but it's + # not strictly mandatory: the method will try to load a wpcli's YAML config + # from that path, so you can potentially use it with any path # - # @param context [LightService::Context] The context of an action + # @param context [LightService::Context|String] The context of an action or a path as string # @return [String] # @!scope class - def wpcli_config_path(context) + def wpcli_config_path(context_or_path) + context = if context_or_path.is_a? LightService::Context + context_or_path + else + # We need to make it quack like a duck in order to be + # backward compatible with previous code + { local_options: { wordpress_path: context_or_path } } + end + load_from_yml(context) || load_from_wpcli || context.dig(:local_options, :wordpress_path) end @@ -67,7 +48,8 @@ def wpcli_config_path(context) # @!scope class # @!visibility private def load_from_yml(context) - yml_path = File.join(context.dig(:local_options, :wordpress_path), 'wp-cli.yml') + config_path = context.dig(:local_options, :wordpress_path) || '.' + yml_path = File.join(config_path, 'wp-cli.yml') return unless File.exist?(yml_path) @@ -91,5 +73,13 @@ def load_from_wpcli nil end end + + def self.get_option(option, config_path:) + `wp option get #{option} --allow-root --path=#{config_path}`.chomp + end + + def self.get_config(config, config_path:) + `wp config get #{config} --allow-root --path=#{config_path}`.chomp + end end end diff --git a/spec/actions/adapt_local_db_spec.rb b/spec/actions/adapt_local_db_spec.rb index 3a0dbe13..b3445354 100644 --- a/spec/actions/adapt_local_db_spec.rb +++ b/spec/actions/adapt_local_db_spec.rb @@ -14,8 +14,6 @@ ] end - let(:local_command_stub) { class_double('Wordmove::Actions::RunLocalCommand').as_stubbed_const } - before do silence_logger! # Note we're stubbing subsequent actions from organizer. @@ -23,7 +21,10 @@ stubbed_actions.each do |action| stub_action(action) end - stub_action(local_command_stub) + + allow(described_class) + .to receive(:system) + .and_return(true) end it 'works like it should' do @@ -31,10 +32,7 @@ context ) - aggregate_failures 'testing sub-actions' do - expect(local_command_stub).to have_received(:execute).exactly(6).times - expect(result).to be_success - end + expect(result).to be_success end context 'when --no-adapt' do @@ -50,8 +48,26 @@ ) aggregate_failures 'testing sub-actions' do - expect(local_command_stub).to have_received(:execute).exactly(4).times expect(result).to be_success + expect(described_class) + .to_not have_received(:system) + .with(/wp search-replace/, exception: true) + end + end + end + + context '.search_replace_command' do + it 'returns the expected command' do + expect(subject.class.search_replace_command(context, :wordpress_path)) + .to eq('wp search-replace --path=~/dev/sites/your_site "\A~/dev/sites/your_site\Z" ' \ + '"/var/www/your_site" --regex-delimiter="|" --regex --precise --quiet ' \ + '--skip-columns=guid --all-tables --allow-root') + end + + context 'when wrong config_key is passed' do + it 'raises an error' do + expect { subject.class.search_replace_command(context, :wrong) } + .to raise_error(ArgumentError) end end end diff --git a/spec/actions/backup_local_db_spec.rb b/spec/actions/backup_local_db_spec.rb new file mode 100644 index 00000000..7c02548a --- /dev/null +++ b/spec/actions/backup_local_db_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +# I know these tests are very weak. I don't know how to make them sturdier +# and having them is better than nothing :) +describe Wordmove::Actions::BackupLocalDb do + let(:context) do + OrganizerContextFactory.make_for(described_class, :pull, cli_options: { db: true }) + end + + let(:stubbed_actions) do + [ + Wordmove::Actions::Ssh::DownloadRemoteDb + ] + end + + before do + silence_logger! + # Note we're stubbing subsequent actions from organizer. + # This stubs could be useful for using spies on classes. + stubbed_actions.each do |action| + stub_action(action) + end + end + + it 'works like it should' do + allow(described_class).to receive(:system).and_return(true) + + result = described_class.execute( + context + ) + + expect(result).to be_success + end + + context 'when system dump command fails' do + before do + allow(described_class) + .to receive(:system) + .with(/wp db export/, exception: true) + .and_raise(RuntimeError.new('Foo')) + end + + it 'fails and reports the error' do + result = described_class.execute( + context + ) + + aggregate_failures do + expect(result).to be_failure + expect(result.message).to match('Foo') + end + end + end + + context 'when system compress command fails' do + before do + allow(described_class) + .to receive(:system) + .with(/wp db export/, exception: true) + + allow(described_class) + .to receive(:system) + .with(/gzip/, exception: true) + .and_raise(RuntimeError.new('Bar')) + end + it 'fails and reports the error' do + result = described_class.execute( + context + ) + + aggregate_failures do + expect(result).to be_failure + expect(result.message).to match('Bar') + end + end + end +end diff --git a/spec/fixtures/movefiles/Movefile b/spec/fixtures/movefiles/Movefile index 12dd4d68..d24f1592 100644 --- a/spec/fixtures/movefiles/Movefile +++ b/spec/fixtures/movefiles/Movefile @@ -1,13 +1,8 @@ global: - sql_adapter: "default" + sql_adapter: "wpcli" local: vhost: "http://vhost.local" wordpress_path: "~/dev/sites/your_site" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" remote: vhost: "http://example.com" wordpress_path: "/var/www/your_site" diff --git a/spec/fixtures/movefiles/custom_paths b/spec/fixtures/movefiles/custom_paths index 5886f5ec..8fef9cb6 100644 --- a/spec/fixtures/movefiles/custom_paths +++ b/spec/fixtures/movefiles/custom_paths @@ -1,13 +1,7 @@ global: - sql_adapter: "default" + sql_adapter: "wpcli" local: - vhost: "http://vhost.local" wordpress_path: "~/dev/sites/your_site" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" paths: uploads: 'wp-content/pirate' remote: diff --git a/spec/fixtures/movefiles/multi_environments b/spec/fixtures/movefiles/multi_environments index 343b217b..db8daa01 100644 --- a/spec/fixtures/movefiles/multi_environments +++ b/spec/fixtures/movefiles/multi_environments @@ -2,15 +2,8 @@ global: sql_adapter: "wpcli" local: - vhost: "http://localhost:8080" wordpress_path: "/home/welaika/sites/your_site" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" - staging: vhost: "http://staging.mysite.example.com" wordpress_path: "/var/www/your_site" # use an absolute path here diff --git a/spec/fixtures/movefiles/multi_environments_wpcli_sql_adapter b/spec/fixtures/movefiles/multi_environments_wpcli_sql_adapter index 343b217b..db8daa01 100644 --- a/spec/fixtures/movefiles/multi_environments_wpcli_sql_adapter +++ b/spec/fixtures/movefiles/multi_environments_wpcli_sql_adapter @@ -2,15 +2,8 @@ global: sql_adapter: "wpcli" local: - vhost: "http://localhost:8080" wordpress_path: "/home/welaika/sites/your_site" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" - staging: vhost: "http://staging.mysite.example.com" wordpress_path: "/var/www/your_site" # use an absolute path here diff --git a/spec/fixtures/movefiles/with_forbidden_tasks b/spec/fixtures/movefiles/with_forbidden_tasks index 3a0eecb4..2e0399fd 100644 --- a/spec/fixtures/movefiles/with_forbidden_tasks +++ b/spec/fixtures/movefiles/with_forbidden_tasks @@ -1,13 +1,7 @@ global: - sql_adapter: "default" + sql_adapter: "wpcli" local: - vhost: "http://vhost.local" wordpress_path: "~/dev/sites/your_site" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" remote: vhost: "http://example.com" wordpress_path: "/var/www/your_site" diff --git a/spec/fixtures/movefiles/with_hooks b/spec/fixtures/movefiles/with_hooks index a7478bd3..b9569332 100644 --- a/spec/fixtures/movefiles/with_hooks +++ b/spec/fixtures/movefiles/with_hooks @@ -1,18 +1,11 @@ <% require 'tmpdir' %> global: - sql_adapter: "default" + sql_adapter: "wpcli" local: - vhost: "http://localhost:8080" wordpress_path: "<%= Dir.tmpdir %>" - database: - name: "database_name" - user: "user" - password: "password" - host: "host" - ssh_with_hooks: vhost: "http://staging.mysite.example.com" wordpress_path: "/var/www/your_site" # use an absolute path here diff --git a/spec/fixtures/movefiles/with_secrets b/spec/fixtures/movefiles/with_secrets index c6b8aba0..aa72f987 100644 --- a/spec/fixtures/movefiles/with_secrets +++ b/spec/fixtures/movefiles/with_secrets @@ -1,13 +1,7 @@ global: - sql_adapter: "default" + sql_adapter: "wpcli" local: - vhost: "http://secrets.local" wordpress_path: "~/dev/sites/your_site" - database: - name: "database_name" - user: "user" - password: "local_database_password" - host: "local_database_host" remote: vhost: "http://secrets.example.com" wordpress_path: "/var/www/your_site" diff --git a/spec/fixtures/movefiles/with_secrets_with_empty_local_db_password b/spec/fixtures/movefiles/with_secrets_with_empty_local_db_password index 61ef7467..0236e8f0 100644 --- a/spec/fixtures/movefiles/with_secrets_with_empty_local_db_password +++ b/spec/fixtures/movefiles/with_secrets_with_empty_local_db_password @@ -1,13 +1,7 @@ global: - sql_adapter: "default" + sql_adapter: "wpcli" local: - vhost: "http://secrets.local" wordpress_path: "~/dev/sites/your_site" - database: - name: "database_name" - user: "user" - password: "" - host: "local_database_host" remote: vhost: "http://secrets.example.com" wordpress_path: "/var/www/your_site" diff --git a/spec/movefile_spec.rb b/spec/movefile_spec.rb index c4f05ddd..264a72a4 100644 --- a/spec/movefile_spec.rb +++ b/spec/movefile_spec.rb @@ -159,7 +159,7 @@ %w[ local_database_password local_database_host - http://secrets.local + http://example.com ~/dev/sites/your_site remote_database_password remote_database_host @@ -175,12 +175,17 @@ end it 'returns all the secrets found in movefile excluding empty string values' do + allow(Wordmove::WpcliHelpers) + .to receive(:get_config) + .with('DB_PASSWORD', config_path: instance_of(String)) + .and_return('') + path = movefile_path_for('with_secrets_with_empty_local_db_password') movefile = described_class.new(config: path) expect(movefile.secrets).to eq( %w[ local_database_host - http://secrets.local + http://example.com ~/dev/sites/your_site remote_database_password remote_database_host diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fa2811b0..e3e017c6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,7 +10,7 @@ require 'wordmove' -Dir[File.expand_path('support/**/*.rb', __dir__)].sort.each { |f| require f } +Dir[File.expand_path('support/**/*.rb', __dir__)].each { |f| require f } # I don't know from where this method was imported, # but since last updates it was lost. I looked about @@ -28,7 +28,7 @@ def silence_stream(stream) old_stream.close end -RSpec.configure do |config| +RSpec.configure do |config| # rubocop:disable Metrics/BlockLength config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end @@ -41,4 +41,34 @@ def silence_stream(stream) config.example_status_persistence_file_path = './spec/examples.txt' config.formatter = :documentation + + config.before :each do + allow(Wordmove::WpcliHelpers) + .to receive(:get_option) + .and_return('an option') + + allow(Wordmove::WpcliHelpers) + .to receive(:get_option) + .with('siteurl', config_path: instance_of(String)) + .and_return('http://example.com') + + allow(Wordmove::WpcliHelpers) + .to receive(:get_config) + .and_return('a config') + + allow(Wordmove::WpcliHelpers) + .to receive(:get_config) + .with('DB_PASSWORD', config_path: instance_of(String)) + .and_return('local_database_password') + + allow(Wordmove::WpcliHelpers) + .to receive(:get_config) + .with('DB_HOST', config_path: instance_of(String)) + .and_return('local_database_host') + + allow(Wordmove::WpcliHelpers) + .to receive(:get_config) + .with('DB_NAME', config_path: instance_of(String)) + .and_return('local_database_name') + end end diff --git a/spec/wordpress_directory_spec.rb b/spec/wordpress_directory_spec.rb index 9e50bc96..bfb4b6af 100644 --- a/spec/wordpress_directory_spec.rb +++ b/spec/wordpress_directory_spec.rb @@ -50,14 +50,14 @@ context 'given an additional path as a string' do it 'returns the URL of the folder joined with the additional path' do wd = described_class.new(:uploads, options) - expect(wd.url('pirate.png')).to eq('http://vhost.local/wp-content/uploads/pirate.png') + expect(wd.url('pirate.png')).to eq('http://example.com/wp-content/uploads/pirate.png') end end context 'without arguments' do it 'returns the URL for the required folder' do wd = described_class.new(:uploads, options) - expect(wd.url).to eq('http://vhost.local/wp-content/uploads') + expect(wd.url).to eq('http://example.com/wp-content/uploads') end end end diff --git a/spec/wpcli_spec.rb b/spec/wpcli_spec.rb index 26ef11dd..200bd74b 100644 --- a/spec/wpcli_spec.rb +++ b/spec/wpcli_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' -describe Wordmove::Wpcli do +describe Wordmove::WpcliHelpers do subject do Class.new do - include Wordmove::Wpcli + include Wordmove::WpcliHelpers end end @@ -20,6 +20,12 @@ end end + context 'when called with a path instead of a config' do + it 'not finding any path using wpcli it will return the path passed as argument' do + expect(subject.wpcli_config_path('/path/to/biscuit')).to eq('/path/to/biscuit') + end + end + context 'when there is not wp-cli.yml in wordpress root directory' do context 'if wp-cli is configured someway with a custom path' do before do @@ -32,6 +38,12 @@ it 'returns the configured path' do expect(subject.wpcli_config_path(a_context)).to eq('/path/to/pudding') end + + context 'when called with a path instead of a config' do + it 'returns the configured path anyway' do + expect(subject.wpcli_config_path('/path/to/biscuit')).to eq('/path/to/pudding') + end + end end context 'when wp-cli param-dump returns empty string' do @@ -49,21 +61,4 @@ end end end - - context '.wpcli_search_replace_command' do - it 'returns the expected command' do - a_context[:local_options][:wordpress_path] = fixture_folder_root_relative_path - expect(subject.wpcli_search_replace_command(a_context, :wordpress_path)) - .to eq('wp search-replace --path=/path/to/steak "\A/var/www/your_site\Z" ' \ - '"spec/fixtures" --regex-delimiter="|" --regex --precise --quiet ' \ - '--skip-columns=guid --all-tables --allow-root') - end - - context 'when wrong config_key is passed' do - it 'raises an error' do - expect { subject.wpcli_search_replace_command(a_context, :wrong) } - .to raise_error(ArgumentError) - end - end - end end