Handle CLI failure exit status at the top-level script (#28322)
This commit is contained in:
		@@ -96,12 +96,11 @@ Rails/FilePath:
 | 
				
			|||||||
Rails/HttpStatus:
 | 
					Rails/HttpStatus:
 | 
				
			||||||
  EnforcedStyle: numeric
 | 
					  EnforcedStyle: numeric
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Reason: Allowed in `tootctl` CLI code and in boot ENV checker
 | 
					# Reason: Allowed in boot ENV checker
 | 
				
			||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
 | 
					# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
 | 
				
			||||||
Rails/Exit:
 | 
					Rails/Exit:
 | 
				
			||||||
  Exclude:
 | 
					  Exclude:
 | 
				
			||||||
    - 'config/boot.rb'
 | 
					    - 'config/boot.rb'
 | 
				
			||||||
    - 'lib/mastodon/cli/*.rb'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
 | 
					# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
 | 
				
			||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
 | 
					# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,13 @@ require_relative '../lib/mastodon/cli/main'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  Chewy.strategy(:mastodon) do
 | 
					  Chewy.strategy(:mastodon) do
 | 
				
			||||||
    Mastodon::CLI::Main.start(ARGV)
 | 
					    Mastodon::CLI::Main.start(ARGV, debug: true) # Enables the script to rescue `Thor::Error`
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					rescue Thor::Error => e
 | 
				
			||||||
 | 
					  Thor::Shell::Color
 | 
				
			||||||
 | 
					    .new
 | 
				
			||||||
 | 
					    .say_error(e.message, :red)
 | 
				
			||||||
 | 
					  exit(1)
 | 
				
			||||||
rescue Interrupt
 | 
					rescue Interrupt
 | 
				
			||||||
  exit(130)
 | 
					  exit(130)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,7 @@ module Mastodon::CLI
 | 
				
			|||||||
        rotate_keys_for_account(Account.find_local(username))
 | 
					        rotate_keys_for_account(Account.find_local(username))
 | 
				
			||||||
        say('OK', :green)
 | 
					        say('OK', :green)
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        say('No account(s) given', :red)
 | 
					        fail_with_message 'No account(s) given'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,10 +73,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      if options[:role]
 | 
					      if options[:role]
 | 
				
			||||||
        role = UserRole.find_by(name: options[:role])
 | 
					        role = UserRole.find_by(name: options[:role])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if role.nil?
 | 
					        fail_with_message 'Cannot find user role with that name' if role.nil?
 | 
				
			||||||
          say('Cannot find user role with that name', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        role_id = role.id
 | 
					        role_id = role.id
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
@@ -114,7 +110,6 @@ module Mastodon::CLI
 | 
				
			|||||||
        say("New password: #{password}")
 | 
					        say("New password: #{password}")
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        report_errors(user.errors)
 | 
					        report_errors(user.errors)
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,18 +147,12 @@ module Mastodon::CLI
 | 
				
			|||||||
    def modify(username)
 | 
					    def modify(username)
 | 
				
			||||||
      user = Account.find_local(username)&.user
 | 
					      user = Account.find_local(username)&.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if user.nil?
 | 
					      fail_with_message 'No user with such username' if user.nil?
 | 
				
			||||||
        say('No user with such username', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:role]
 | 
					      if options[:role]
 | 
				
			||||||
        role = UserRole.find_by(name: options[:role])
 | 
					        role = UserRole.find_by(name: options[:role])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if role.nil?
 | 
					        fail_with_message 'Cannot find user role with that name' if role.nil?
 | 
				
			||||||
          say('Cannot find user role with that name', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        user.role_id = role.id
 | 
					        user.role_id = role.id
 | 
				
			||||||
      elsif options[:remove_role]
 | 
					      elsif options[:remove_role]
 | 
				
			||||||
@@ -185,7 +174,6 @@ module Mastodon::CLI
 | 
				
			|||||||
        say("New password: #{password}") if options[:reset_password]
 | 
					        say("New password: #{password}") if options[:reset_password]
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        report_errors(user.errors)
 | 
					        report_errors(user.errors)
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -200,27 +188,19 @@ module Mastodon::CLI
 | 
				
			|||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def delete(username = nil)
 | 
					    def delete(username = nil)
 | 
				
			||||||
      if username.present? && options[:email].present?
 | 
					      if username.present? && options[:email].present?
 | 
				
			||||||
        say('Use username or --email, not both', :red)
 | 
					        fail_with_message  'Use username or --email, not both'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      elsif username.blank? && options[:email].blank?
 | 
					      elsif username.blank? && options[:email].blank?
 | 
				
			||||||
        say('No username provided', :red)
 | 
					        fail_with_message 'No username provided'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      account = nil
 | 
					      account = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if username.present?
 | 
					      if username.present?
 | 
				
			||||||
        account = Account.find_local(username)
 | 
					        account = Account.find_local(username)
 | 
				
			||||||
        if account.nil?
 | 
					        fail_with_message 'No user with such username' if account.nil?
 | 
				
			||||||
          say('No user with such username', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        account = Account.left_joins(:user).find_by(user: { email: options[:email] })
 | 
					        account = Account.left_joins(:user).find_by(user: { email: options[:email] })
 | 
				
			||||||
        if account.nil?
 | 
					        fail_with_message 'No user with such email' if account.nil?
 | 
				
			||||||
          say('No user with such email', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      say("Deleting user with #{account.statuses_count} statuses, this might take a while...#{dry_run_mode_suffix}")
 | 
					      say("Deleting user with #{account.statuses_count} statuses, this might take a while...#{dry_run_mode_suffix}")
 | 
				
			||||||
@@ -243,23 +223,18 @@ module Mastodon::CLI
 | 
				
			|||||||
      username, domain = from_acct.split('@')
 | 
					      username, domain = from_acct.split('@')
 | 
				
			||||||
      from_account = Account.find_remote(username, domain)
 | 
					      from_account = Account.find_remote(username, domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if from_account.nil? || from_account.local?
 | 
					      fail_with_message "No such account (#{from_acct})" if from_account.nil? || from_account.local?
 | 
				
			||||||
        say("No such account (#{from_acct})", :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      username, domain = to_acct.split('@')
 | 
					      username, domain = to_acct.split('@')
 | 
				
			||||||
      to_account = Account.find_remote(username, domain)
 | 
					      to_account = Account.find_remote(username, domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if to_account.nil? || to_account.local?
 | 
					      fail_with_message "No such account (#{to_acct})" if to_account.nil? || to_account.local?
 | 
				
			||||||
        say("No such account (#{to_acct})", :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if from_account.public_key != to_account.public_key && !options[:force]
 | 
					      if from_account.public_key != to_account.public_key && !options[:force]
 | 
				
			||||||
        say("Accounts don't have the same public key, might not be duplicates!", :red)
 | 
					        fail_with_message <<~ERROR
 | 
				
			||||||
        say('Override with --force', :red)
 | 
					          Accounts don't have the same public key, might not be duplicates!
 | 
				
			||||||
        exit(1)
 | 
					          Override with --force
 | 
				
			||||||
 | 
					        ERROR
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      to_account.merge_with!(from_account)
 | 
					      to_account.merge_with!(from_account)
 | 
				
			||||||
@@ -298,10 +273,7 @@ module Mastodon::CLI
 | 
				
			|||||||
    def backup(username)
 | 
					    def backup(username)
 | 
				
			||||||
      account = Account.find_local(username)
 | 
					      account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if account.nil?
 | 
					      fail_with_message 'No user with such username' if account.nil?
 | 
				
			||||||
        say('No user with such username', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      backup = account.user.backups.create!
 | 
					      backup = account.user.backups.create!
 | 
				
			||||||
      BackupWorker.perform_async(backup.id)
 | 
					      BackupWorker.perform_async(backup.id)
 | 
				
			||||||
@@ -387,10 +359,7 @@ module Mastodon::CLI
 | 
				
			|||||||
          user, domain = user.split('@')
 | 
					          user, domain = user.split('@')
 | 
				
			||||||
          account = Account.find_remote(user, domain)
 | 
					          account = Account.find_remote(user, domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if account.nil?
 | 
					          fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
            say('No such account', :red)
 | 
					 | 
				
			||||||
            exit(1)
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          next if dry_run?
 | 
					          next if dry_run?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -405,8 +374,7 @@ module Mastodon::CLI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        say("OK#{dry_run_mode_suffix}", :green)
 | 
					        say("OK#{dry_run_mode_suffix}", :green)
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        say('No account(s) given', :red)
 | 
					        fail_with_message 'No account(s) given'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -416,10 +384,7 @@ module Mastodon::CLI
 | 
				
			|||||||
    def follow(username)
 | 
					    def follow(username)
 | 
				
			||||||
      target_account = Account.find_local(username)
 | 
					      target_account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if target_account.nil?
 | 
					      fail_with_message 'No such account' if target_account.nil?
 | 
				
			||||||
        say('No such account', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      processed, = parallelize_with_progress(Account.local.without_suspended) do |account|
 | 
					      processed, = parallelize_with_progress(Account.local.without_suspended) do |account|
 | 
				
			||||||
        FollowService.new.call(account, target_account, bypass_limit: true)
 | 
					        FollowService.new.call(account, target_account, bypass_limit: true)
 | 
				
			||||||
@@ -435,10 +400,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      username, domain = acct.split('@')
 | 
					      username, domain = acct.split('@')
 | 
				
			||||||
      target_account = Account.find_remote(username, domain)
 | 
					      target_account = Account.find_remote(username, domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if target_account.nil?
 | 
					      fail_with_message 'No such account' if target_account.nil?
 | 
				
			||||||
        say('No such account', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      processed, = parallelize_with_progress(target_account.followers.local) do |account|
 | 
					      processed, = parallelize_with_progress(target_account.followers.local) do |account|
 | 
				
			||||||
        UnfollowService.new.call(account, target_account)
 | 
					        UnfollowService.new.call(account, target_account)
 | 
				
			||||||
@@ -459,17 +421,11 @@ module Mastodon::CLI
 | 
				
			|||||||
      With the --followers option, the command removes all followers of the account.
 | 
					      With the --followers option, the command removes all followers of the account.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def reset_relationships(username)
 | 
					    def reset_relationships(username)
 | 
				
			||||||
      unless options[:follows] || options[:followers]
 | 
					      fail_with_message 'Please specify either --follows or --followers, or both' unless options[:follows] || options[:followers]
 | 
				
			||||||
        say('Please specify either --follows or --followers, or both', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      account = Account.find_local(username)
 | 
					      account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if account.nil?
 | 
					      fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
        say('No such account', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      total     = 0
 | 
					      total     = 0
 | 
				
			||||||
      total    += account.following.reorder(nil).count if options[:follows]
 | 
					      total    += account.following.reorder(nil).count if options[:follows]
 | 
				
			||||||
@@ -515,6 +471,8 @@ module Mastodon::CLI
 | 
				
			|||||||
      account identified by its username.
 | 
					      account identified by its username.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def approve(username = nil)
 | 
					    def approve(username = nil)
 | 
				
			||||||
 | 
					      fail_with_message 'Number must be positive' if options[:number]&.negative?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:all]
 | 
					      if options[:all]
 | 
				
			||||||
        User.pending.find_each(&:approve!)
 | 
					        User.pending.find_each(&:approve!)
 | 
				
			||||||
        say('OK', :green)
 | 
					        say('OK', :green)
 | 
				
			||||||
@@ -524,16 +482,10 @@ module Mastodon::CLI
 | 
				
			|||||||
      elsif username.present?
 | 
					      elsif username.present?
 | 
				
			||||||
        account = Account.find_local(username)
 | 
					        account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if account.nil?
 | 
					        fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
          say('No such account', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        account.user&.approve!
 | 
					        account.user&.approve!
 | 
				
			||||||
        say('OK', :green)
 | 
					        say('OK', :green)
 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        say('Number must be positive', :red) if options[:number]
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -587,56 +539,34 @@ module Mastodon::CLI
 | 
				
			|||||||
      redirects to a different account that the one specified.
 | 
					      redirects to a different account that the one specified.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def migrate(username)
 | 
					    def migrate(username)
 | 
				
			||||||
      if options[:replay].present? && options[:target].present?
 | 
					      fail_with_message 'Use --replay or --target, not both' if options[:replay].present? && options[:target].present?
 | 
				
			||||||
        say('Use --replay or --target, not both', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:replay].blank? && options[:target].blank?
 | 
					      fail_with_message 'Use either --replay or --target' if options[:replay].blank? && options[:target].blank?
 | 
				
			||||||
        say('Use either --replay or --target', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      account = Account.find_local(username)
 | 
					      account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if account.nil?
 | 
					      fail_with_message "No such account: #{username}" if account.nil?
 | 
				
			||||||
        say("No such account: #{username}", :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      migration = nil
 | 
					      migration = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:replay]
 | 
					      if options[:replay]
 | 
				
			||||||
        migration = account.migrations.last
 | 
					        migration = account.migrations.last
 | 
				
			||||||
        if migration.nil?
 | 
					        fail_with_message 'The specified account has not performed any migration' if migration.nil?
 | 
				
			||||||
          say('The specified account has not performed any migration', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unless options[:force] || migration.target_account_id == account.moved_to_account_id
 | 
					        fail_with_message 'The specified account is not redirecting to its last migration target. Use --force if you want to replay the migration anyway' unless options[:force] || migration.target_account_id == account.moved_to_account_id
 | 
				
			||||||
          say('The specified account is not redirecting to its last migration target. Use --force if you want to replay the migration anyway', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:target]
 | 
					      if options[:target]
 | 
				
			||||||
        target_account = ResolveAccountService.new.call(options[:target])
 | 
					        target_account = ResolveAccountService.new.call(options[:target])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if target_account.nil?
 | 
					        fail_with_message "The specified target account could not be found: #{options[:target]}" if target_account.nil?
 | 
				
			||||||
          say("The specified target account could not be found: #{options[:target]}", :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unless options[:force] || account.moved_to_account_id.nil? || account.moved_to_account_id == target_account.id
 | 
					        fail_with_message 'The specified account is redirecting to a different target account. Use --force if you want to change the migration target' unless options[:force] || account.moved_to_account_id.nil? || account.moved_to_account_id == target_account.id
 | 
				
			||||||
          say('The specified account is redirecting to a different target account. Use --force if you want to change the migration target', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        begin
 | 
					        begin
 | 
				
			||||||
          migration = account.migrations.create!(acct: target_account.acct)
 | 
					          migration = account.migrations.create!(acct: target_account.acct)
 | 
				
			||||||
        rescue ActiveRecord::RecordInvalid => e
 | 
					        rescue ActiveRecord::RecordInvalid => e
 | 
				
			||||||
          say("Error: #{e.message}", :red)
 | 
					          fail_with_message "Error: #{e.message}"
 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -648,18 +578,18 @@ module Mastodon::CLI
 | 
				
			|||||||
    private
 | 
					    private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def report_errors(errors)
 | 
					    def report_errors(errors)
 | 
				
			||||||
      errors.each do |error|
 | 
					      message = errors.map do |error|
 | 
				
			||||||
        say('Failure/Error: ', :red)
 | 
					        <<~STRING
 | 
				
			||||||
        say(error.attribute)
 | 
					          Failure/Error: #{error.attribute}
 | 
				
			||||||
        say("    #{error.type}", :red)
 | 
					              #{error.type}
 | 
				
			||||||
      end
 | 
					        STRING
 | 
				
			||||||
 | 
					      end.join
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      fail_with_message message
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def rotate_keys_for_account(account, delay = 0)
 | 
					    def rotate_keys_for_account(account, delay = 0)
 | 
				
			||||||
      if account.nil?
 | 
					      fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
        say('No such account', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      old_key = account.private_key
 | 
					      old_key = account.private_key
 | 
				
			||||||
      new_key = OpenSSL::PKey::RSA.new(2048)
 | 
					      new_key = OpenSSL::PKey::RSA.new(2048)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,10 @@ module Mastodon
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      private
 | 
					      private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def fail_with_message(message)
 | 
				
			||||||
 | 
					        raise Thor::Error, message
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def pastel
 | 
					      def pastel
 | 
				
			||||||
        @pastel ||= Pastel.new
 | 
					        @pastel ||= Pastel.new
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,8 +31,7 @@ module Mastodon::CLI
 | 
				
			|||||||
          recount_status_stats(status)
 | 
					          recount_status_stats(status)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        say("Unknown type: #{type}", :red)
 | 
					        fail_with_message "Unknown type: #{type}"
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      say
 | 
					      say
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,11 +41,9 @@ module Mastodon::CLI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      # Sanity check on command arguments
 | 
					      # Sanity check on command arguments
 | 
				
			||||||
      if options[:limited_federation_mode] && !domains.empty?
 | 
					      if options[:limited_federation_mode] && !domains.empty?
 | 
				
			||||||
        say('DOMAIN parameter not supported with --limited-federation-mode', :red)
 | 
					        fail_with_message 'DOMAIN parameter not supported with --limited-federation-mode'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      elsif domains.empty? && !options[:limited_federation_mode]
 | 
					      elsif domains.empty? && !options[:limited_federation_mode]
 | 
				
			||||||
        say('No domain(s) given', :red)
 | 
					        fail_with_message 'No domain(s) given'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Build scopes from command arguments
 | 
					      # Build scopes from command arguments
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,10 +30,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      it at the root.
 | 
					      it at the root.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def add(*domains)
 | 
					    def add(*domains)
 | 
				
			||||||
      if domains.empty?
 | 
					      fail_with_message 'No domain(s) given' if domains.empty?
 | 
				
			||||||
        say('No domain(s) given', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      skipped = 0
 | 
					      skipped = 0
 | 
				
			||||||
      processed = 0
 | 
					      processed = 0
 | 
				
			||||||
@@ -76,10 +73,7 @@ module Mastodon::CLI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    desc 'remove DOMAIN...', 'Remove e-mail domain blocks'
 | 
					    desc 'remove DOMAIN...', 'Remove e-mail domain blocks'
 | 
				
			||||||
    def remove(*domains)
 | 
					    def remove(*domains)
 | 
				
			||||||
      if domains.empty?
 | 
					      fail_with_message 'No domain(s) given' if domains.empty?
 | 
				
			||||||
        say('No domain(s) given', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      skipped = 0
 | 
					      skipped = 0
 | 
				
			||||||
      processed = 0
 | 
					      processed = 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,14 +86,8 @@ module Mastodon::CLI
 | 
				
			|||||||
      category         = CustomEmojiCategory.find_by(name: options[:category])
 | 
					      category         = CustomEmojiCategory.find_by(name: options[:category])
 | 
				
			||||||
      export_file_name = File.join(path, 'export.tar.gz')
 | 
					      export_file_name = File.join(path, 'export.tar.gz')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if File.file?(export_file_name) && !options[:overwrite]
 | 
					      fail_with_message "Archive already exists! Use '--overwrite' to overwrite it!" if File.file?(export_file_name) && !options[:overwrite]
 | 
				
			||||||
        say("Archive already exists! Use '--overwrite' to overwrite it!")
 | 
					      fail_with_message "Unable to find category '#{options[:category]}'!" if category.nil? && options[:category]
 | 
				
			||||||
        exit 1
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
      if category.nil? && options[:category]
 | 
					 | 
				
			||||||
        say("Unable to find category '#{options[:category]}'!")
 | 
					 | 
				
			||||||
        exit 1
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      File.open(export_file_name, 'wb') do |file|
 | 
					      File.open(export_file_name, 'wb') do |file|
 | 
				
			||||||
        Zlib::GzipWriter.wrap(file) do |gzip|
 | 
					        Zlib::GzipWriter.wrap(file) do |gzip|
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,10 +43,10 @@ module Mastodon::CLI
 | 
				
			|||||||
            say('Every deletion notice has been sent! You can safely delete all data and decomission your servers!', :green)
 | 
					            say('Every deletion notice has been sent! You can safely delete all data and decomission your servers!', :green)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          exit(0)
 | 
					          raise(SystemExit)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        exit(1) unless ask('Type in the domain of the server to confirm:') == Rails.configuration.x.local_domain
 | 
					        fail_with_message 'Domains do not match. Stopping self-destruct initiation.' unless domain_match_confirmed?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        say(<<~WARNING, :yellow)
 | 
					        say(<<~WARNING, :yellow)
 | 
				
			||||||
          This operation WILL NOT be reversible.
 | 
					          This operation WILL NOT be reversible.
 | 
				
			||||||
@@ -54,19 +54,25 @@ module Mastodon::CLI
 | 
				
			|||||||
          The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).
 | 
					          The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).
 | 
				
			||||||
        WARNING
 | 
					        WARNING
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        exit(1) if no?('Are you sure you want to proceed?')
 | 
					        fail_with_message 'Operation cancelled. Self-destruct will not begin.' if proceed_prompt_negative?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        say(<<~INSTRUCTIONS, :green)
 | 
					        say(<<~INSTRUCTIONS, :green)
 | 
				
			||||||
          To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:
 | 
					          To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:
 | 
				
			||||||
            SELF_DESTRUCT=#{self_destruct_value}
 | 
					            SELF_DESTRUCT=#{self_destruct_value}
 | 
				
			||||||
          You can re-run this command to see the state of the self-destruct process.
 | 
					          You can re-run this command to see the state of the self-destruct process.
 | 
				
			||||||
        INSTRUCTIONS
 | 
					        INSTRUCTIONS
 | 
				
			||||||
      rescue Interrupt
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      private
 | 
					      private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def domain_match_confirmed?
 | 
				
			||||||
 | 
					        ask('Type in the domain of the server to confirm:') == Rails.configuration.x.local_domain
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def proceed_prompt_negative?
 | 
				
			||||||
 | 
					        no?('Are you sure you want to proceed?')
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def self_destruct_value
 | 
					      def self_destruct_value
 | 
				
			||||||
        Rails
 | 
					        Rails
 | 
				
			||||||
          .application
 | 
					          .application
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,17 +27,13 @@ module Mastodon::CLI
 | 
				
			|||||||
      elsif username.present?
 | 
					      elsif username.present?
 | 
				
			||||||
        account = Account.find_local(username)
 | 
					        account = Account.find_local(username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if account.nil?
 | 
					        fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
          say('No such account', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PrecomputeFeedService.new.call(account) unless dry_run?
 | 
					        PrecomputeFeedService.new.call(account) unless dry_run?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        say("OK #{dry_run_mode_suffix}", :green, true)
 | 
					        say("OK #{dry_run_mode_suffix}", :green, true)
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        say('No account(s) given', :red)
 | 
					        fail_with_message 'No account(s) given'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,10 +20,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      option to overwrite it.
 | 
					      option to overwrite it.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def add(*addresses)
 | 
					    def add(*addresses)
 | 
				
			||||||
      if addresses.empty?
 | 
					      fail_with_message 'No IP(s) given' if addresses.empty?
 | 
				
			||||||
        say('No IP(s) given', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      skipped   = 0
 | 
					      skipped   = 0
 | 
				
			||||||
      processed = 0
 | 
					      processed = 0
 | 
				
			||||||
@@ -70,10 +67,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      cover the given IP(s).
 | 
					      cover the given IP(s).
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def remove(*addresses)
 | 
					    def remove(*addresses)
 | 
				
			||||||
      if addresses.empty?
 | 
					      fail_with_message 'No IP(s) given' if addresses.empty?
 | 
				
			||||||
        say('No IP(s) given', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      processed = 0
 | 
					      processed = 0
 | 
				
			||||||
      skipped   = 0
 | 
					      skipped   = 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -199,26 +199,24 @@ module Mastodon::CLI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def verify_schema_version!
 | 
					    def verify_schema_version!
 | 
				
			||||||
      if migrator_version < MIN_SUPPORTED_VERSION
 | 
					      if migrator_version < MIN_SUPPORTED_VERSION
 | 
				
			||||||
        say 'Your version of the database schema is too old and is not supported by this script.', :red
 | 
					        fail_with_message <<~ERROR
 | 
				
			||||||
        say 'Please update to at least Mastodon 3.0.0 before running this script.', :red
 | 
					          Your version of the database schema is too old and is not supported by this script.
 | 
				
			||||||
        exit(1)
 | 
					          Please update to at least Mastodon 3.0.0 before running this script.
 | 
				
			||||||
 | 
					        ERROR
 | 
				
			||||||
      elsif migrator_version > MAX_SUPPORTED_VERSION
 | 
					      elsif migrator_version > MAX_SUPPORTED_VERSION
 | 
				
			||||||
        say 'Your version of the database schema is more recent than this script, this may cause unexpected errors.', :yellow
 | 
					        say 'Your version of the database schema is more recent than this script, this may cause unexpected errors.', :yellow
 | 
				
			||||||
        exit(1) unless yes?('Continue anyway? (Yes/No)')
 | 
					        fail_with_message 'Stopping maintenance script because data is more recent than script version.' unless yes?('Continue anyway? (Yes/No)')
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def verify_sidekiq_not_active!
 | 
					    def verify_sidekiq_not_active!
 | 
				
			||||||
      if Sidekiq::ProcessSet.new.any?
 | 
					      fail_with_message 'It seems Sidekiq is running. All Mastodon processes need to be stopped when using this script.' if Sidekiq::ProcessSet.new.any?
 | 
				
			||||||
        say 'It seems Sidekiq is running. All Mastodon processes need to be stopped when using this script.', :red
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def verify_backup_warning!
 | 
					    def verify_backup_warning!
 | 
				
			||||||
      say 'This task will take a long time to run and is potentially destructive.', :yellow
 | 
					      say 'This task will take a long time to run and is potentially destructive.', :yellow
 | 
				
			||||||
      say 'Please make sure to stop Mastodon and have a backup.', :yellow
 | 
					      say 'Please make sure to stop Mastodon and have a backup.', :yellow
 | 
				
			||||||
      exit(1) unless yes?('Continue? (Yes/No)')
 | 
					      fail_with_message 'Maintenance process stopped.' unless yes?('Continue? (Yes/No)')
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def deduplicate_accounts!
 | 
					    def deduplicate_accounts!
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,15 +31,9 @@ module Mastodon::CLI
 | 
				
			|||||||
      following anyone locally are pruned.
 | 
					      following anyone locally are pruned.
 | 
				
			||||||
    DESC
 | 
					    DESC
 | 
				
			||||||
    def remove
 | 
					    def remove
 | 
				
			||||||
      if options[:prune_profiles] && options[:remove_headers]
 | 
					      fail_with_message '--prune-profiles and --remove-headers should not be specified simultaneously' if options[:prune_profiles] && options[:remove_headers]
 | 
				
			||||||
        say('--prune-profiles and --remove-headers should not be specified simultaneously', :red, true)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:include_follows] && !(options[:prune_profiles] || options[:remove_headers])
 | 
					      fail_with_message '--include-follows can only be used with --prune-profiles or --remove-headers' if options[:include_follows] && !(options[:prune_profiles] || options[:remove_headers])
 | 
				
			||||||
        say('--include-follows can only be used with --prune-profiles or --remove-headers', :red, true)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
      time_ago = options[:days].days.ago
 | 
					      time_ago = options[:days].days.ago
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if options[:prune_profiles] || options[:remove_headers]
 | 
					      if options[:prune_profiles] || options[:remove_headers]
 | 
				
			||||||
@@ -156,11 +150,9 @@ module Mastodon::CLI
 | 
				
			|||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      when :fog
 | 
					      when :fog
 | 
				
			||||||
        say('The fog storage driver is not supported for this operation at this time', :red)
 | 
					        fail_with_message 'The fog storage driver is not supported for this operation at this time'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      when :azure
 | 
					      when :azure
 | 
				
			||||||
        say('The azure storage driver is not supported for this operation at this time', :red)
 | 
					        fail_with_message 'The azure storage driver is not supported for this operation at this time'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      when :filesystem
 | 
					      when :filesystem
 | 
				
			||||||
        require 'find'
 | 
					        require 'find'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -254,10 +246,7 @@ module Mastodon::CLI
 | 
				
			|||||||
        username, domain = options[:account].split('@')
 | 
					        username, domain = options[:account].split('@')
 | 
				
			||||||
        account = Account.find_remote(username, domain)
 | 
					        account = Account.find_remote(username, domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if account.nil?
 | 
					        fail_with_message 'No such account' if account.nil?
 | 
				
			||||||
          say('No such account', :red)
 | 
					 | 
				
			||||||
          exit(1)
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scope = MediaAttachment.where(account_id: account.id)
 | 
					        scope = MediaAttachment.where(account_id: account.id)
 | 
				
			||||||
      elsif options[:domain]
 | 
					      elsif options[:domain]
 | 
				
			||||||
@@ -265,8 +254,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      elsif options[:days].present?
 | 
					      elsif options[:days].present?
 | 
				
			||||||
        scope = MediaAttachment.remote
 | 
					        scope = MediaAttachment.remote
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        say('Specify the source of media attachments', :red)
 | 
					        fail_with_message 'Specify the source of media attachments'
 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false)) if options[:days].present?
 | 
					      scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false)) if options[:days].present?
 | 
				
			||||||
@@ -306,38 +294,25 @@ module Mastodon::CLI
 | 
				
			|||||||
      path_segments = path.split('/')[2..]
 | 
					      path_segments = path.split('/')[2..]
 | 
				
			||||||
      path_segments.delete('cache')
 | 
					      path_segments.delete('cache')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size)
 | 
					      fail_with_message 'Not a media URL' unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size)
 | 
				
			||||||
        say('Not a media URL', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      model_name = path_segments.first.classify
 | 
					      model_name = path_segments.first.classify
 | 
				
			||||||
      record_id  = path_segments[2..-2].join.to_i
 | 
					      record_id  = path_segments[2..-2].join.to_i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      unless PRELOAD_MODEL_WHITELIST.include?(model_name)
 | 
					      fail_with_message "Cannot find corresponding model: #{model_name}" unless PRELOAD_MODEL_WHITELIST.include?(model_name)
 | 
				
			||||||
        say("Cannot find corresponding model: #{model_name}", :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      record = model_name.constantize.find_by(id: record_id)
 | 
					      record = model_name.constantize.find_by(id: record_id)
 | 
				
			||||||
      record = record.status if record.respond_to?(:status)
 | 
					      record = record.status if record.respond_to?(:status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      unless record
 | 
					      fail_with_message 'Cannot find corresponding record' unless record
 | 
				
			||||||
        say('Cannot find corresponding record', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      display_url = ActivityPub::TagManager.instance.url_for(record)
 | 
					      display_url = ActivityPub::TagManager.instance.url_for(record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if display_url.blank?
 | 
					      fail_with_message 'No public URL for this type of record' if display_url.blank?
 | 
				
			||||||
        say('No public URL for this type of record', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      say(display_url, :blue)
 | 
					      say(display_url, :blue)
 | 
				
			||||||
    rescue Addressable::URI::InvalidURIError
 | 
					    rescue Addressable::URI::InvalidURIError
 | 
				
			||||||
      say('Invalid URL', :red)
 | 
					      fail_with_message 'Invalid URL'
 | 
				
			||||||
      exit(1)
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private
 | 
					    private
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,10 +25,7 @@ module Mastodon::CLI
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def parallelize_with_progress(scope)
 | 
					    def parallelize_with_progress(scope)
 | 
				
			||||||
      if options[:concurrency] < 1
 | 
					      fail_with_message 'Cannot run with this concurrency setting, must be at least 1' if options[:concurrency] < 1
 | 
				
			||||||
        say('Cannot run with this concurrency setting, must be at least 1', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      reset_connection_pools!
 | 
					      reset_connection_pools!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,17 +110,11 @@ module Mastodon::CLI
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def verify_deploy_concurrency!
 | 
					    def verify_deploy_concurrency!
 | 
				
			||||||
      return unless options[:concurrency] < 1
 | 
					      fail_with_message 'Cannot run with this concurrency setting, must be at least 1' if options[:concurrency] < 1
 | 
				
			||||||
 | 
					 | 
				
			||||||
      say('Cannot run with this concurrency setting, must be at least 1', :red)
 | 
					 | 
				
			||||||
      exit(1)
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def verify_deploy_batch_size!
 | 
					    def verify_deploy_batch_size!
 | 
				
			||||||
      return unless options[:batch_size] < 1
 | 
					      fail_with_message 'Cannot run with this batch_size setting, must be at least 1' if options[:batch_size] < 1
 | 
				
			||||||
 | 
					 | 
				
			||||||
      say('Cannot run with this batch_size setting, must be at least 1', :red)
 | 
					 | 
				
			||||||
      exit(1)
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def progress_output_options
 | 
					    def progress_output_options
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,10 +26,7 @@ module Mastodon::CLI
 | 
				
			|||||||
      indices before commencing, and removes them afterward.
 | 
					      indices before commencing, and removes them afterward.
 | 
				
			||||||
    LONG_DESC
 | 
					    LONG_DESC
 | 
				
			||||||
    def remove
 | 
					    def remove
 | 
				
			||||||
      if options[:batch_size] < 1
 | 
					      fail_with_message 'Cannot run with this batch_size setting, must be at least 1' if options[:batch_size] < 1
 | 
				
			||||||
        say('Cannot run with this batch_size setting, must be at least 1', :red)
 | 
					 | 
				
			||||||
        exit(1)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      remove_statuses
 | 
					      remove_statuses
 | 
				
			||||||
      vacuum_and_analyze_statuses
 | 
					      vacuum_and_analyze_statuses
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,13 +103,11 @@ module Mastodon::CLI
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def upgrade_storage_fog(_progress, _attachment, _style)
 | 
					    def upgrade_storage_fog(_progress, _attachment, _style)
 | 
				
			||||||
      say('The fog storage driver is not supported for this operation at this time', :red)
 | 
					      fail_with_message 'The fog storage driver is not supported for this operation at this time'
 | 
				
			||||||
      exit(1)
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def upgrade_storage_azure(_progress, _attachment, _style)
 | 
					    def upgrade_storage_azure(_progress, _attachment, _style)
 | 
				
			||||||
      say('The azure storage driver is not supported for this operation at this time', :red)
 | 
					      fail_with_message 'The azure storage driver is not supported for this operation at this time'
 | 
				
			||||||
      exit(1)
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def upgrade_storage_filesystem(progress, attachment, style)
 | 
					    def upgrade_storage_filesystem(progress, attachment, style)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,8 +65,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          it 'exits with an error message' do
 | 
					          it 'exits with an error message' do
 | 
				
			||||||
            expect { subject }
 | 
					            expect { subject }
 | 
				
			||||||
              .to output_results('Failure/Error: email')
 | 
					              .to raise_error(Thor::Error, %r{Failure/Error: email})
 | 
				
			||||||
              .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
@@ -127,8 +126,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          it 'exits with an error message indicating the role name was not found' do
 | 
					          it 'exits with an error message indicating the role name was not found' do
 | 
				
			||||||
            expect { subject }
 | 
					            expect { subject }
 | 
				
			||||||
              .to output_results('Cannot find user role with that name')
 | 
					              .to raise_error(Thor::Error, 'Cannot find user role with that name')
 | 
				
			||||||
              .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
@@ -191,8 +189,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating the user was not found' do
 | 
					      it 'exits with an error message indicating the user was not found' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No user with such username')
 | 
					          .to raise_error(Thor::Error, 'No user with such username')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -214,8 +211,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          it 'exits with an error message indicating the role was not found' do
 | 
					          it 'exits with an error message indicating the role was not found' do
 | 
				
			||||||
            expect { subject }
 | 
					            expect { subject }
 | 
				
			||||||
              .to output_results('Cannot find user role with that name')
 | 
					              .to raise_error(Thor::Error, 'Cannot find user role with that name')
 | 
				
			||||||
              .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -364,8 +360,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message' do
 | 
					        it 'exits with an error message' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('Failure/Error: email')
 | 
					            .to raise_error(Thor::Error, %r{Failure/Error: email})
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -387,16 +382,14 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that only one should be used' do
 | 
					      it 'exits with an error message indicating that only one should be used' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Use username or --email, not both')
 | 
					          .to raise_error(Thor::Error, 'Use username or --email, not both')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'when neither username nor --email are provided' do
 | 
					    context 'when neither username nor --email are provided' do
 | 
				
			||||||
      it 'exits with an error message indicating that no username was provided' do
 | 
					      it 'exits with an error message indicating that no username was provided' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No username provided')
 | 
					          .to raise_error(Thor::Error, 'No username provided')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -425,8 +418,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message indicating that no user was found' do
 | 
					        it 'exits with an error message indicating that no user was found' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('No user with such username')
 | 
					            .to raise_error(Thor::Error, 'No user with such username')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -458,8 +450,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message indicating that no user was found' do
 | 
					        it 'exits with an error message indicating that no user was found' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('No user with such email')
 | 
					            .to raise_error(Thor::Error, 'No user with such email')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -511,8 +502,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message indicating that the number must be positive' do
 | 
					        it 'exits with an error message indicating that the number must be positive' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('Number must be positive')
 | 
					            .to raise_error(Thor::Error, 'Number must be positive')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -545,8 +535,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message indicating that no such account was found' do
 | 
					        it 'exits with an error message indicating that no such account was found' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('No such account')
 | 
					            .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
@@ -560,8 +549,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that no account with the given username was found' do
 | 
					      it 'exits with an error message indicating that no account with the given username was found' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No such account')
 | 
					          .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -596,8 +584,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that no account with the given username was found' do
 | 
					      it 'exits with an error message indicating that no account with the given username was found' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No such account')
 | 
					          .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -634,8 +621,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that there is no such account' do
 | 
					      it 'exits with an error message indicating that there is no such account' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No user with such username')
 | 
					          .to raise_error(Thor::Error, 'No user with such username')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -795,8 +781,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
          allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(nil)
 | 
					          allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('No such account')
 | 
					            .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -892,8 +877,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
    context 'when neither a list of accts nor options are provided' do
 | 
					    context 'when neither a list of accts nor options are provided' do
 | 
				
			||||||
      it 'exits with an error message' do
 | 
					      it 'exits with an error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No account(s) given')
 | 
					          .to raise_error(Thor::Error, 'No account(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -904,8 +888,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
    context 'when neither username nor --all option are given' do
 | 
					    context 'when neither username nor --all option are given' do
 | 
				
			||||||
      it 'exits with an error message' do
 | 
					      it 'exits with an error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No account(s) given')
 | 
					          .to raise_error(Thor::Error, 'No account(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -940,8 +923,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message when the specified username is not found' do
 | 
					      it 'exits with an error message when the specified username is not found' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No such account')
 | 
					          .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -980,8 +962,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
    shared_examples 'an account not found' do |acct|
 | 
					    shared_examples 'an account not found' do |acct|
 | 
				
			||||||
      it 'exits with an error message indicating that there is no such account' do
 | 
					      it 'exits with an error message indicating that there is no such account' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results("No such account (#{acct})")
 | 
					          .to raise_error(Thor::Error, "No such account (#{acct})")
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1031,8 +1012,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that the accounts do not have the same pub key' do
 | 
					      it 'exits with an error message indicating that the accounts do not have the same pub key' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results("Accounts don't have the same public key, might not be duplicates!\nOverride with --force")
 | 
					          .to raise_error(Thor::Error, "Accounts don't have the same public key, might not be duplicates!\nOverride with --force\n")
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      context 'with --force option' do
 | 
					      context 'with --force option' do
 | 
				
			||||||
@@ -1200,8 +1180,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
    context 'when no option is given' do
 | 
					    context 'when no option is given' do
 | 
				
			||||||
      it 'exits with an error message indicating that at least one option is required' do
 | 
					      it 'exits with an error message indicating that at least one option is required' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Please specify either --follows or --followers, or both')
 | 
					          .to raise_error(Thor::Error, 'Please specify either --follows or --followers, or both')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1211,8 +1190,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that there is no such account' do
 | 
					      it 'exits with an error message indicating that there is no such account' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No such account')
 | 
					          .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1368,16 +1346,14 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that using both options is not possible' do
 | 
					      it 'exits with an error message indicating that using both options is not possible' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Use --replay or --target, not both')
 | 
					          .to raise_error(Thor::Error, 'Use --replay or --target, not both')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'when no option is given' do
 | 
					    context 'when no option is given' do
 | 
				
			||||||
      it 'exits with an error message indicating that at least one option must be used' do
 | 
					      it 'exits with an error message indicating that at least one option must be used' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Use either --replay or --target')
 | 
					          .to raise_error(Thor::Error, 'Use either --replay or --target')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1387,8 +1363,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message indicating that there is no such account' do
 | 
					      it 'exits with an error message indicating that there is no such account' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results("No such account: #{arguments.first}")
 | 
					          .to raise_error(Thor::Error, "No such account: #{arguments.first}")
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1398,8 +1373,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
      context 'when the specified account has no previous migrations' do
 | 
					      context 'when the specified account has no previous migrations' do
 | 
				
			||||||
        it 'exits with an error message indicating that the given account has no previous migrations' do
 | 
					        it 'exits with an error message indicating that the given account has no previous migrations' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('The specified account has not performed any migration')
 | 
					            .to raise_error(Thor::Error, 'The specified account has not performed any migration')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1421,8 +1395,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          it 'exits with an error message' do
 | 
					          it 'exits with an error message' do
 | 
				
			||||||
            expect { subject }
 | 
					            expect { subject }
 | 
				
			||||||
              .to output_results('The specified account is not redirecting to its last migration target. Use --force if you want to replay the migration anyway')
 | 
					              .to raise_error(Thor::Error, 'The specified account is not redirecting to its last migration target. Use --force if you want to replay the migration anyway')
 | 
				
			||||||
              .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1449,8 +1422,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message indicating that there is no such account' do
 | 
					        it 'exits with an error message indicating that there is no such account' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results("The specified target account could not be found: #{options[:target]}")
 | 
					            .to raise_error(Thor::Error, "The specified target account could not be found: #{options[:target]}")
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1474,8 +1446,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
      context 'when the migration record is invalid' do
 | 
					      context 'when the migration record is invalid' do
 | 
				
			||||||
        it 'exits with an error indicating that the validation failed' do
 | 
					        it 'exits with an error indicating that the validation failed' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('Error: Validation failed')
 | 
					            .to raise_error(Thor::Error, /Error: Validation failed/)
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1486,8 +1457,7 @@ describe Mastodon::CLI::Accounts do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'exits with an error message' do
 | 
					        it 'exits with an error message' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('The specified account is redirecting to a different target account. Use --force if you want to change the migration target')
 | 
					            .to raise_error(Thor::Error, 'The specified account is redirecting to a different target account. Use --force if you want to change the migration target')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,8 +64,7 @@ describe Mastodon::CLI::Cache do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'Exits with an error message' do
 | 
					      it 'Exits with an error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Unknown')
 | 
					          .to raise_error(Thor::Error, /Unknown/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,8 +35,7 @@ describe Mastodon::CLI::EmailDomainBlocks do
 | 
				
			|||||||
    context 'without any options' do
 | 
					    context 'without any options' do
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No domain(s) given')
 | 
					          .to raise_error(Thor::Error, 'No domain(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,8 +71,7 @@ describe Mastodon::CLI::EmailDomainBlocks do
 | 
				
			|||||||
    context 'without any options' do
 | 
					    context 'without any options' do
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No domain(s) given')
 | 
					          .to raise_error(Thor::Error, 'No domain(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,8 +42,7 @@ describe Mastodon::CLI::Feeds do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'displays an error and exits' do
 | 
					      it 'displays an error and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No such account')
 | 
					          .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,8 +144,7 @@ describe Mastodon::CLI::IpBlocks do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with an error message' do
 | 
					      it 'exits with an error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No IP(s) given')
 | 
					          .to raise_error(Thor::Error, 'No IP(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
@@ -235,8 +234,7 @@ describe Mastodon::CLI::IpBlocks do
 | 
				
			|||||||
    context 'when no IP address is provided' do
 | 
					    context 'when no IP address is provided' do
 | 
				
			||||||
      it 'exits with an error message' do
 | 
					      it 'exits with an error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('No IP(s) given')
 | 
					          .to raise_error(Thor::Error, 'No IP(s) given')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,9 +104,9 @@ describe Mastodon::CLI::Main do
 | 
				
			|||||||
          answer_hostname_incorrectly
 | 
					          answer_hostname_incorrectly
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it 'exits silently' do
 | 
					        it 'exits with mismatch error message' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to raise_error(SystemExit)
 | 
					            .to raise_error(Thor::Error, /Domains do not match/)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,7 +119,7 @@ describe Mastodon::CLI::Main do
 | 
				
			|||||||
        it 'passes first step but stops before instructions' do
 | 
					        it 'passes first step but stops before instructions' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('operation WILL NOT')
 | 
					            .to output_results('operation WILL NOT')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					            .and raise_error(Thor::Error, /Self-destruct will not begin/)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,8 +22,7 @@ describe Mastodon::CLI::Maintenance do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'Exits with error message' do
 | 
					      it 'Exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('is too old')
 | 
					          .to raise_error(Thor::Error, /is too old/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,7 +35,7 @@ describe Mastodon::CLI::Maintenance do
 | 
				
			|||||||
      it 'Exits with error message' do
 | 
					      it 'Exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('more recent')
 | 
					          .to output_results('more recent')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					          .and raise_error(Thor::Error, /more recent/)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,8 +47,7 @@ describe Mastodon::CLI::Maintenance do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'Exits with error message' do
 | 
					      it 'Exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Sidekiq is running')
 | 
					          .to raise_error(Thor::Error, /Sidekiq is running/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('--prune-profiles and --remove-headers should not be specified simultaneously')
 | 
					          .to raise_error(Thor::Error, '--prune-profiles and --remove-headers should not be specified simultaneously')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,8 +29,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('--include-follows can only be used with --prune-profiles or --remove-headers')
 | 
					          .to raise_error(Thor::Error, '--include-follows can only be used with --prune-profiles or --remove-headers')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,8 +96,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'warns about url and exits' do
 | 
					      it 'warns about url and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Not a media URL')
 | 
					          .to raise_error(Thor::Error, 'Not a media URL')
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -121,8 +118,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
    context 'without any options' do
 | 
					    context 'without any options' do
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Specify the source')
 | 
					          .to raise_error(Thor::Error, /Specify the source/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,8 +143,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        it 'warns about usage and exits' do
 | 
					        it 'warns about usage and exits' do
 | 
				
			||||||
          expect { subject }
 | 
					          expect { subject }
 | 
				
			||||||
            .to output_results('No such account')
 | 
					            .to raise_error(Thor::Error, 'No such account')
 | 
				
			||||||
            .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -221,8 +216,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('azure storage driver is not supported')
 | 
					          .to raise_error(Thor::Error, /azure storage driver is not supported/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -233,8 +227,7 @@ describe Mastodon::CLI::Media do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'warns about usage and exits' do
 | 
					      it 'warns about usage and exits' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('fog storage driver is not supported')
 | 
					          .to raise_error(Thor::Error, /fog storage driver is not supported/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,7 @@ describe Mastodon::CLI::Search do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'Exits with error message' do
 | 
					      it 'Exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('this concurrency setting')
 | 
					          .to raise_error(Thor::Error, /this concurrency setting/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,8 +29,7 @@ describe Mastodon::CLI::Search do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'Exits with error message' do
 | 
					      it 'Exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('this batch_size setting')
 | 
					          .to raise_error(Thor::Error, /this batch_size setting/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,7 @@ describe Mastodon::CLI::Statuses do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      it 'exits with error message' do
 | 
					      it 'exits with error message' do
 | 
				
			||||||
        expect { subject }
 | 
					        expect { subject }
 | 
				
			||||||
          .to output_results('Cannot run')
 | 
					          .to raise_error(Thor::Error, /Cannot run/)
 | 
				
			||||||
          .and raise_error(SystemExit)
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user