bopeep 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/bopeep.rb +224 -153
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 225fd316f342c4a23f15c428d44816f55ce5760e20d2aceef2e84ac27784c218
         | 
| 4 | 
            +
              data.tar.gz: 43e00f49265f4bcac5dc99f1917ecf8d85151a42aea4da86177befebe13a03a0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8e540b83379b5661c897286b30170bda85b72fa6cad22f5cdd7fe0e0bbb7a6924cb33404a24193aeff4bfb7b7e14e749d9f16499bdb1167c1d10ed1f5cfac494
         | 
| 7 | 
            +
              data.tar.gz: 13883aa073f0cb2739c0e7c203833cb53c232724d30110578a92bf2d9a0dde71bf936d3c5239a83e2f84da8872b8eb21eb1b52ec544ffa87c2009750157ca19d
         | 
    
        data/lib/bopeep.rb
    CHANGED
    
    | @@ -424,7 +424,7 @@ module BoPeep | |
| 424 424 | 
             
                class HostStatus
         | 
| 425 425 | 
             
                  attr_accessor :row_number
         | 
| 426 426 |  | 
| 427 | 
            -
                  def initialize(host, console)
         | 
| 427 | 
            +
                  def initialize(host, console = BoPeep.console)
         | 
| 428 428 | 
             
                    @host = host
         | 
| 429 429 | 
             
                    @console = console
         | 
| 430 430 |  | 
| @@ -475,6 +475,19 @@ module BoPeep | |
| 475 475 |  | 
| 476 476 | 
             
                    content
         | 
| 477 477 | 
             
                  end
         | 
| 478 | 
            +
             | 
| 479 | 
            +
                  class DevNull
         | 
| 480 | 
            +
                    def started!
         | 
| 481 | 
            +
                    end
         | 
| 482 | 
            +
             | 
| 483 | 
            +
                    def failed!(*)
         | 
| 484 | 
            +
                    end
         | 
| 485 | 
            +
             | 
| 486 | 
            +
                    def success!
         | 
| 487 | 
            +
                    end
         | 
| 488 | 
            +
                  end
         | 
| 489 | 
            +
             | 
| 490 | 
            +
                  DEV_NULL = DevNull.new
         | 
| 478 491 | 
             
                end
         | 
| 479 492 |  | 
| 480 493 | 
             
                class SelectGraphicRendition
         | 
| @@ -579,8 +592,8 @@ module BoPeep | |
| 579 592 | 
             
                  "localhost"
         | 
| 580 593 | 
             
                end
         | 
| 581 594 |  | 
| 582 | 
            -
                def run
         | 
| 583 | 
            -
                  outcome = CommandOutcome.new
         | 
| 595 | 
            +
                def run(callbacks: nil, log: false)
         | 
| 596 | 
            +
                  outcome = CommandOutcome.new(callbacks: callbacks, log: log)
         | 
| 584 597 |  | 
| 585 598 | 
             
                  begin
         | 
| 586 599 | 
             
                    outcome.command_started!
         | 
| @@ -597,8 +610,15 @@ module BoPeep | |
| 597 610 | 
             
                class CommandOutcome
         | 
| 598 611 | 
             
                  attr_accessor :error
         | 
| 599 612 |  | 
| 600 | 
            -
                  def initialize
         | 
| 601 | 
            -
                    @ | 
| 613 | 
            +
                  def initialize(callbacks: nil, log:)
         | 
| 614 | 
            +
                    @callbacks = Host::Callbacks.from(callbacks)
         | 
| 615 | 
            +
             | 
| 616 | 
            +
                    if log
         | 
| 617 | 
            +
                      @console_status = Console::HostStatus.new(LOCALHOST)
         | 
| 618 | 
            +
                    else
         | 
| 619 | 
            +
                      @console_status = Console::HostStatus::DEV_NULL
         | 
| 620 | 
            +
                    end
         | 
| 621 | 
            +
             | 
| 602 622 | 
             
                    @started_at = nil
         | 
| 603 623 | 
             
                    @finished_at = nil
         | 
| 604 624 | 
             
                  end
         | 
| @@ -624,8 +644,10 @@ module BoPeep | |
| 624 644 |  | 
| 625 645 | 
             
                    if successful?
         | 
| 626 646 | 
             
                      @console_status.success!
         | 
| 647 | 
            +
                      @callbacks.on_success(self)
         | 
| 627 648 | 
             
                    else
         | 
| 628 649 | 
             
                      @console_status.failed!(failure_summary)
         | 
| 650 | 
            +
                      @callbacks.on_failure(self)
         | 
| 629 651 | 
             
                    end
         | 
| 630 652 | 
             
                  end
         | 
| 631 653 |  | 
| @@ -774,8 +796,8 @@ module BoPeep | |
| 774 796 | 
             
                  inspect.hash
         | 
| 775 797 | 
             
                end
         | 
| 776 798 |  | 
| 777 | 
            -
                def run_command(command, &setup)
         | 
| 778 | 
            -
                  outcome = CommandOutcome.new(self, command, &setup)
         | 
| 799 | 
            +
                def run_command(command, callbacks: nil, log: false, &setup)
         | 
| 800 | 
            +
                  outcome = CommandOutcome.new(self, command, callbacks: callbacks, log: log, &setup)
         | 
| 779 801 |  | 
| 780 802 | 
             
                  connection.open_channel do |channel|
         | 
| 781 803 | 
             
                    channel.exec(command) do |_, success|
         | 
| @@ -817,12 +839,12 @@ module BoPeep | |
| 817 839 | 
             
                  outcome
         | 
| 818 840 | 
             
                end
         | 
| 819 841 |  | 
| 820 | 
            -
                def run_script(script, &setup)
         | 
| 842 | 
            +
                def run_script(script, callbacks: nil, log: false, &setup)
         | 
| 821 843 | 
             
                  create_directory script.install_directory
         | 
| 822 844 |  | 
| 823 845 | 
             
                  create_file_from script.content, path: script.install_path, mode: 0755
         | 
| 824 846 |  | 
| 825 | 
            -
                  run_command(script.remote_path, &setup)
         | 
| 847 | 
            +
                  run_command(script.remote_path, callbacks: callbacks, log: log, &setup)
         | 
| 826 848 | 
             
                end
         | 
| 827 849 |  | 
| 828 850 | 
             
                def create_directory(directory)
         | 
| @@ -906,6 +928,83 @@ module BoPeep | |
| 906 928 | 
             
                  @id = Digest::SHA1.hexdigest(@uri.to_s)
         | 
| 907 929 | 
             
                end
         | 
| 908 930 |  | 
| 931 | 
            +
                class Callbacks
         | 
| 932 | 
            +
                  def on_stdout(data)
         | 
| 933 | 
            +
                  end
         | 
| 934 | 
            +
             | 
| 935 | 
            +
                  def on_stderr(data)
         | 
| 936 | 
            +
                  end
         | 
| 937 | 
            +
             | 
| 938 | 
            +
                  def on_success(command_outcome)
         | 
| 939 | 
            +
                  end
         | 
| 940 | 
            +
             | 
| 941 | 
            +
                  def on_failure(command_outcome)
         | 
| 942 | 
            +
                  end
         | 
| 943 | 
            +
             | 
| 944 | 
            +
                  class Proxy
         | 
| 945 | 
            +
                    extend Forwardable
         | 
| 946 | 
            +
             | 
| 947 | 
            +
                    def_delegators :@callbacks, :on_stdout, :on_stderr, :on_success, :on_failure
         | 
| 948 | 
            +
             | 
| 949 | 
            +
                    def initialize(callbacks)
         | 
| 950 | 
            +
                      @callbacks = callbacks
         | 
| 951 | 
            +
                    end
         | 
| 952 | 
            +
             | 
| 953 | 
            +
                    def method_missing(name, *args, &block)
         | 
| 954 | 
            +
                      if @callbacks.respond_to?(name)
         | 
| 955 | 
            +
                        @callbacks.send(name, *args, &block)
         | 
| 956 | 
            +
                      else
         | 
| 957 | 
            +
                        super
         | 
| 958 | 
            +
                      end
         | 
| 959 | 
            +
                    end
         | 
| 960 | 
            +
             | 
| 961 | 
            +
                    protected
         | 
| 962 | 
            +
             | 
| 963 | 
            +
                    def respond_to_missing?(name, include_private = false)
         | 
| 964 | 
            +
                      @callbacks.respond_to_missing?(name, include_private) || super
         | 
| 965 | 
            +
                    end
         | 
| 966 | 
            +
                  end
         | 
| 967 | 
            +
             | 
| 968 | 
            +
                  class Definition
         | 
| 969 | 
            +
                    attr_reader :callbacks
         | 
| 970 | 
            +
             | 
| 971 | 
            +
                    def initialize(callbacks = nil, &setup)
         | 
| 972 | 
            +
                      if callbacks
         | 
| 973 | 
            +
                        @callbacks = Proxy.new(callbacks)
         | 
| 974 | 
            +
                      else
         | 
| 975 | 
            +
                        @callbacks = Callbacks.new
         | 
| 976 | 
            +
                      end
         | 
| 977 | 
            +
             | 
| 978 | 
            +
                      case setup&.arity
         | 
| 979 | 
            +
                      when 1
         | 
| 980 | 
            +
                        setup.call(self)
         | 
| 981 | 
            +
                      when 0
         | 
| 982 | 
            +
                        instance_eval(&setup)
         | 
| 983 | 
            +
                      end
         | 
| 984 | 
            +
                    end
         | 
| 985 | 
            +
             | 
| 986 | 
            +
                    def on_stdout(&block)
         | 
| 987 | 
            +
                      @callbacks.singleton_class.define_method(:on_stdout, &block)
         | 
| 988 | 
            +
                    end
         | 
| 989 | 
            +
             | 
| 990 | 
            +
                    def on_stderr(&block)
         | 
| 991 | 
            +
                      @callbacks.singleton_class.define_method(:on_stderr, &block)
         | 
| 992 | 
            +
                    end
         | 
| 993 | 
            +
             | 
| 994 | 
            +
                    def on_success(&block)
         | 
| 995 | 
            +
                      @callbacks.singleton_class.define_method(:on_success, &block)
         | 
| 996 | 
            +
                    end
         | 
| 997 | 
            +
             | 
| 998 | 
            +
                    def on_failure(&block)
         | 
| 999 | 
            +
                      @callbacks.singleton_class.define_method(:on_failure, &block)
         | 
| 1000 | 
            +
                    end
         | 
| 1001 | 
            +
                  end
         | 
| 1002 | 
            +
             | 
| 1003 | 
            +
                  def self.from(callbacks = nil, &setup)
         | 
| 1004 | 
            +
                    Definition.new(callbacks, &setup).callbacks
         | 
| 1005 | 
            +
                  end
         | 
| 1006 | 
            +
                end
         | 
| 1007 | 
            +
             | 
| 909 1008 | 
             
                class CommandOutcome
         | 
| 910 1009 | 
             
                  attr_reader :command
         | 
| 911 1010 | 
             
                  attr_reader :connection_error_code
         | 
| @@ -920,46 +1019,37 @@ module BoPeep | |
| 920 1019 | 
             
                  attr_reader :stderr
         | 
| 921 1020 | 
             
                  attr_reader :stdout
         | 
| 922 1021 |  | 
| 923 | 
            -
                  def initialize(host, command, &setup)
         | 
| 1022 | 
            +
                  def initialize(host, command, callbacks: nil, log: false, &setup)
         | 
| 924 1023 | 
             
                    @host = host
         | 
| 925 1024 | 
             
                    @command = command
         | 
| 926 1025 |  | 
| 927 | 
            -
                     | 
| 1026 | 
            +
                    if log
         | 
| 1027 | 
            +
                      @console_status = Console::HostStatus.new(host)
         | 
| 1028 | 
            +
                    else
         | 
| 1029 | 
            +
                      @console_status = Console::HostStatus::DEV_NULL
         | 
| 1030 | 
            +
                    end
         | 
| 928 1031 |  | 
| 929 1032 | 
             
                    @stdout = ""
         | 
| 930 | 
            -
                    @stdout_callback = proc {}
         | 
| 931 | 
            -
             | 
| 932 1033 | 
             
                    @stderr = ""
         | 
| 933 | 
            -
                    @stderr_callback = proc {}
         | 
| 934 1034 |  | 
| 935 1035 | 
             
                    @started_at = nil
         | 
| 936 1036 | 
             
                    @finished_at = nil
         | 
| 937 1037 |  | 
| 938 | 
            -
                     | 
| 939 | 
            -
                      instance_eval(&setup)
         | 
| 940 | 
            -
                    end
         | 
| 1038 | 
            +
                    @callbacks = Callbacks.from(callbacks, &setup)
         | 
| 941 1039 | 
             
                  end
         | 
| 942 1040 |  | 
| 943 1041 | 
             
                  def value
         | 
| 944 1042 | 
             
                    self
         | 
| 945 1043 | 
             
                  end
         | 
| 946 1044 |  | 
| 947 | 
            -
                  def on_stdout(&block)
         | 
| 948 | 
            -
                    @stdout_callback = block
         | 
| 949 | 
            -
                  end
         | 
| 950 | 
            -
             | 
| 951 1045 | 
             
                  def collect_stdout(data)
         | 
| 952 1046 | 
             
                    @stdout << data
         | 
| 953 | 
            -
                    @ | 
| 954 | 
            -
                  end
         | 
| 955 | 
            -
             | 
| 956 | 
            -
                  def on_stderr(&block)
         | 
| 957 | 
            -
                    @stderr_callback = block
         | 
| 1047 | 
            +
                    @callbacks.on_stdout(data)
         | 
| 958 1048 | 
             
                  end
         | 
| 959 1049 |  | 
| 960 1050 | 
             
                  def collect_stderr(data)
         | 
| 961 1051 | 
             
                    @stderr << data
         | 
| 962 | 
            -
                    @ | 
| 1052 | 
            +
                    @callbacks.on_stderr(data)
         | 
| 963 1053 | 
             
                  end
         | 
| 964 1054 |  | 
| 965 1055 | 
             
                  def successful?
         | 
| @@ -986,6 +1076,7 @@ module BoPeep | |
| 986 1076 |  | 
| 987 1077 | 
             
                      if failed?
         | 
| 988 1078 | 
             
                        @failure_reason = :nonzero_exit_status
         | 
| 1079 | 
            +
                        @callbacks.on_failure(self)
         | 
| 989 1080 | 
             
                      end
         | 
| 990 1081 | 
             
                    end
         | 
| 991 1082 |  | 
| @@ -1000,6 +1091,8 @@ module BoPeep | |
| 1000 1091 | 
             
                      @exit_signal.freeze
         | 
| 1001 1092 |  | 
| 1002 1093 | 
             
                      @failure_reason = :exit_signal
         | 
| 1094 | 
            +
             | 
| 1095 | 
            +
                      @callbacks.on_failure(self)
         | 
| 1003 1096 | 
             
                    end
         | 
| 1004 1097 |  | 
| 1005 1098 | 
             
                    value
         | 
| @@ -1034,6 +1127,7 @@ module BoPeep | |
| 1034 1127 |  | 
| 1035 1128 | 
             
                      if successful?
         | 
| 1036 1129 | 
             
                        @console_status.success!
         | 
| 1130 | 
            +
                        @callbacks.on_success(self)
         | 
| 1037 1131 | 
             
                      else
         | 
| 1038 1132 | 
             
                        @console_status.failed!(failure_summary)
         | 
| 1039 1133 | 
             
                      end
         | 
| @@ -1049,6 +1143,8 @@ module BoPeep | |
| 1049 1143 | 
             
                    unless started?
         | 
| 1050 1144 | 
             
                      @console_status.failed!(failure_summary)
         | 
| 1051 1145 | 
             
                    end
         | 
| 1146 | 
            +
             | 
| 1147 | 
            +
                    @callbacks.on_failure(self)
         | 
| 1052 1148 | 
             
                  end
         | 
| 1053 1149 |  | 
| 1054 1150 | 
             
                  def failure_summary
         | 
| @@ -1192,15 +1288,15 @@ module BoPeep | |
| 1192 1288 | 
             
                    end
         | 
| 1193 1289 | 
             
                  end
         | 
| 1194 1290 |  | 
| 1195 | 
            -
                  def run_script(script, order: :parallel, &setup)
         | 
| 1291 | 
            +
                  def run_script(script, order: :parallel, callbacks: nil, log: false, &setup)
         | 
| 1196 1292 | 
             
                    run(order: order) do |host, result|
         | 
| 1197 | 
            -
                      result.update host.run_script(script, &setup)
         | 
| 1293 | 
            +
                      result.update host.run_script(script, callbacks: callbacks, log: log, &setup)
         | 
| 1198 1294 | 
             
                    end
         | 
| 1199 1295 | 
             
                  end
         | 
| 1200 1296 |  | 
| 1201 | 
            -
                  def run_command(command, order: :parallel, &setup)
         | 
| 1297 | 
            +
                  def run_command(command, order: :parallel, callbacks: nil, log: false, &setup)
         | 
| 1202 1298 | 
             
                    run(order: order) do |host, result|
         | 
| 1203 | 
            -
                      result.update host.run_command(command, &setup)
         | 
| 1299 | 
            +
                      result.update host.run_command(command, callbacks: callbacks, log: log, &setup)
         | 
| 1204 1300 | 
             
                    end
         | 
| 1205 1301 | 
             
                  end
         | 
| 1206 1302 |  | 
| @@ -1297,6 +1393,7 @@ module BoPeep | |
| 1297 1393 | 
             
              class Config
         | 
| 1298 1394 | 
             
                attr_accessor :default_user
         | 
| 1299 1395 | 
             
                attr_reader :hosts
         | 
| 1396 | 
            +
                attr_accessor :on_failure_command
         | 
| 1300 1397 | 
             
                attr_reader :variables_sets
         | 
| 1301 1398 |  | 
| 1302 1399 | 
             
                def initialize
         | 
| @@ -1318,7 +1415,7 @@ module BoPeep | |
| 1318 1415 | 
             
                  end
         | 
| 1319 1416 | 
             
                end
         | 
| 1320 1417 |  | 
| 1321 | 
            -
                def variables(name | 
| 1418 | 
            +
                def variables(name)
         | 
| 1322 1419 | 
             
                  variables_name = name.to_s
         | 
| 1323 1420 | 
             
                  ivar_name = "@#{variables_name}"
         | 
| 1324 1421 |  | 
| @@ -1331,7 +1428,7 @@ module BoPeep | |
| 1331 1428 | 
             
                    variables_object = instance_variable_set(ivar_name, VariableSet.new(variables_name, self))
         | 
| 1332 1429 | 
             
                  end
         | 
| 1333 1430 |  | 
| 1334 | 
            -
                   | 
| 1431 | 
            +
                  yield variables_object
         | 
| 1335 1432 | 
             
                end
         | 
| 1336 1433 |  | 
| 1337 1434 | 
             
                class VariableSet
         | 
| @@ -1352,15 +1449,25 @@ module BoPeep | |
| 1352 1449 | 
             
                    @properties.include?(property_name.to_s)
         | 
| 1353 1450 | 
             
                  end
         | 
| 1354 1451 |  | 
| 1355 | 
            -
                  def define!(property_name)
         | 
| 1356 | 
            -
                     | 
| 1452 | 
            +
                  def define!(property_name, value = nil, &block)
         | 
| 1453 | 
            +
                    property_name = property_name.to_s
         | 
| 1454 | 
            +
             | 
| 1455 | 
            +
                    if self.defined?(property_name)
         | 
| 1456 | 
            +
                      raise ArgumentError, "`#{@_name}.#{property_name}' is already defined"
         | 
| 1457 | 
            +
                    elsif Property::REGEXP.match?(property_name)
         | 
| 1458 | 
            +
                      @properties << property_name
         | 
| 1459 | 
            +
             | 
| 1460 | 
            +
                      extend Property.new(property_name, block || value)
         | 
| 1461 | 
            +
                    else
         | 
| 1462 | 
            +
                      raise ArgumentError, "`#{property_name}' is not a valid property name"
         | 
| 1463 | 
            +
                    end
         | 
| 1357 1464 | 
             
                  end
         | 
| 1358 1465 |  | 
| 1359 1466 | 
             
                  def copy(other)
         | 
| 1360 1467 | 
             
                    other.properties.each do |property_name|
         | 
| 1361 1468 | 
             
                      value = other.instance_variable_get("@#{property_name}")
         | 
| 1362 1469 |  | 
| 1363 | 
            -
                       | 
| 1470 | 
            +
                      define!(property_name, value)
         | 
| 1364 1471 | 
             
                    end
         | 
| 1365 1472 | 
             
                  end
         | 
| 1366 1473 |  | 
| @@ -1378,7 +1485,7 @@ module BoPeep | |
| 1378 1485 | 
             
                    writer_name = name.to_s
         | 
| 1379 1486 | 
             
                    reader_name = writer_name.chomp("=")
         | 
| 1380 1487 |  | 
| 1381 | 
            -
                    if  | 
| 1488 | 
            +
                    if ! Property::REGEXP.match?(reader_name)
         | 
| 1382 1489 | 
             
                      super
         | 
| 1383 1490 | 
             
                    elsif reader_name == writer_name && block.nil?
         | 
| 1384 1491 | 
             
                      $stderr.puts "`#{@_name}.#{reader_name}' was accessed before it was defined"
         | 
| @@ -1386,7 +1493,7 @@ module BoPeep | |
| 1386 1493 | 
             
                    elsif writer_name.end_with?("=") or not block.nil?
         | 
| 1387 1494 | 
             
                      value = block || args
         | 
| 1388 1495 |  | 
| 1389 | 
            -
                       | 
| 1496 | 
            +
                      define!(reader_name, *value)
         | 
| 1390 1497 | 
             
                    end
         | 
| 1391 1498 | 
             
                  end
         | 
| 1392 1499 |  | 
| @@ -1401,8 +1508,6 @@ module BoPeep | |
| 1401 1508 | 
             
                    end
         | 
| 1402 1509 |  | 
| 1403 1510 | 
             
                    def extended(variables_set)
         | 
| 1404 | 
            -
                      variables_set.define! @name
         | 
| 1405 | 
            -
             | 
| 1406 1511 | 
             
                      variables_set.singleton_class.class_eval <<-PROPERTY_METHODS
         | 
| 1407 1512 | 
             
                        attr_writer :#{@name}
         | 
| 1408 1513 |  | 
| @@ -1433,9 +1538,9 @@ module BoPeep | |
| 1433 1538 | 
             
                attr_reader :parser
         | 
| 1434 1539 | 
             
                attr_reader :playlist
         | 
| 1435 1540 |  | 
| 1436 | 
            -
                def initialize(argv | 
| 1541 | 
            +
                def initialize(argv)
         | 
| 1437 1542 | 
             
                  @argv = argv
         | 
| 1438 | 
            -
                  @playlist =  | 
| 1543 | 
            +
                  @playlist = Playlist.new(self)
         | 
| 1439 1544 | 
             
                  @parser = OptionParser.new
         | 
| 1440 1545 |  | 
| 1441 1546 | 
             
                  @parser.on("-t", "--target HOSTS", Array, "hosts to use") do |hosts_data|
         | 
| @@ -1462,24 +1567,37 @@ module BoPeep | |
| 1462 1567 | 
             
                    hosts.add(host)
         | 
| 1463 1568 | 
             
                  end
         | 
| 1464 1569 |  | 
| 1570 | 
            +
                  self.on_failure_command = config.on_failure_command
         | 
| 1571 | 
            +
             | 
| 1465 1572 | 
             
                  config.variables_sets.each do |variables_name|
         | 
| 1466 1573 | 
             
                    variables(variables_name) do |variables_object|
         | 
| 1467 1574 | 
             
                      variables_object.copy config.instance_variable_get("@#{variables_name}")
         | 
| 1468 1575 | 
             
                    end
         | 
| 1469 1576 | 
             
                  end
         | 
| 1470 1577 | 
             
                end
         | 
| 1578 | 
            +
             | 
| 1579 | 
            +
                def on_failure_command
         | 
| 1580 | 
            +
                  case @on_failure_command
         | 
| 1581 | 
            +
                  when String
         | 
| 1582 | 
            +
                    Object.const_get(@on_failure_command)
         | 
| 1583 | 
            +
                  else
         | 
| 1584 | 
            +
                    @on_failure_command
         | 
| 1585 | 
            +
                  end
         | 
| 1586 | 
            +
                end
         | 
| 1471 1587 | 
             
              end
         | 
| 1472 1588 |  | 
| 1473 1589 | 
             
              class Playlist
         | 
| 1474 1590 | 
             
                attr_reader :insert_at
         | 
| 1475 1591 |  | 
| 1476 | 
            -
                def initialize
         | 
| 1592 | 
            +
                def initialize(context)
         | 
| 1593 | 
            +
                  @context = context
         | 
| 1477 1594 | 
             
                  @start = @insert_at = Start.new
         | 
| 1478 1595 | 
             
                end
         | 
| 1479 1596 |  | 
| 1480 1597 | 
             
                def play
         | 
| 1481 1598 | 
             
                  playing = @insert_at = @start
         | 
| 1482 1599 | 
             
                  command = nil
         | 
| 1600 | 
            +
                  on_failure_command_used = false
         | 
| 1483 1601 |  | 
| 1484 1602 | 
             
                  while playing.next
         | 
| 1485 1603 | 
             
                    playing = @insert_at = playing.next
         | 
| @@ -1487,15 +1605,23 @@ module BoPeep | |
| 1487 1605 | 
             
                    if command != playing.command
         | 
| 1488 1606 | 
             
                      command = playing.command
         | 
| 1489 1607 |  | 
| 1490 | 
            -
                       | 
| 1608 | 
            +
                      playing.log_command
         | 
| 1491 1609 | 
             
                    end
         | 
| 1492 1610 |  | 
| 1493 | 
            -
                     | 
| 1611 | 
            +
                    playing.log_step
         | 
| 1494 1612 |  | 
| 1495 1613 | 
             
                    result = playing.run
         | 
| 1496 1614 |  | 
| 1497 1615 | 
             
                    if result.failed?
         | 
| 1498 | 
            -
                       | 
| 1616 | 
            +
                      if @context.on_failure_command && on_failure_command_used == false
         | 
| 1617 | 
            +
                        playing.next = nil
         | 
| 1618 | 
            +
                        @context.on_failure_command.(@context)
         | 
| 1619 | 
            +
                        # Prevents infinite loops if `on_failure_command` fails
         | 
| 1620 | 
            +
                        on_failure_command_used = true
         | 
| 1621 | 
            +
                      else
         | 
| 1622 | 
            +
                        # This is redefined in `test/test_helper.rb` to avoid exiting the test process
         | 
| 1623 | 
            +
                        exit 1
         | 
| 1624 | 
            +
                      end
         | 
| 1499 1625 | 
             
                    end
         | 
| 1500 1626 | 
             
                  end
         | 
| 1501 1627 | 
             
                end
         | 
| @@ -1523,12 +1649,11 @@ module BoPeep | |
| 1523 1649 | 
             
                def initialize(argv)
         | 
| 1524 1650 | 
             
                  @argv = argv.dup
         | 
| 1525 1651 | 
             
                  @path = nil
         | 
| 1526 | 
            -
                  @playlist = Playlist.new
         | 
| 1527 1652 |  | 
| 1528 1653 | 
             
                  find_bopeep_directory!
         | 
| 1529 1654 | 
             
                  load_config!
         | 
| 1530 1655 |  | 
| 1531 | 
            -
                  @context = Context.new(@argv | 
| 1656 | 
            +
                  @context = Context.new(@argv)
         | 
| 1532 1657 | 
             
                  @context.copy(BoPeep.config)
         | 
| 1533 1658 |  | 
| 1534 1659 | 
             
                  load_scripts!
         | 
| @@ -1550,7 +1675,7 @@ module BoPeep | |
| 1550 1675 | 
             
                  Console.hostname_width = @context.hosts.map { |host| host.address.length }.max
         | 
| 1551 1676 |  | 
| 1552 1677 | 
             
                  BoPeep.console.redirecting_stdout_and_stderr do
         | 
| 1553 | 
            -
                    @playlist.play
         | 
| 1678 | 
            +
                    @context.playlist.play
         | 
| 1554 1679 | 
             
                  end
         | 
| 1555 1680 | 
             
                end
         | 
| 1556 1681 |  | 
| @@ -1922,16 +2047,20 @@ module BoPeep | |
| 1922 2047 | 
             
                    end
         | 
| 1923 2048 | 
             
                  end
         | 
| 1924 2049 |  | 
| 1925 | 
            -
                  def  | 
| 1926 | 
            -
                    exit 1
         | 
| 2050 | 
            +
                  def on_stdout(data)
         | 
| 1927 2051 | 
             
                  end
         | 
| 1928 2052 |  | 
| 1929 | 
            -
                  def  | 
| 1930 | 
            -
                    Console::SGR(text)
         | 
| 2053 | 
            +
                  def on_stderr(data)
         | 
| 1931 2054 | 
             
                  end
         | 
| 1932 2055 |  | 
| 1933 | 
            -
                  def  | 
| 1934 | 
            -
             | 
| 2056 | 
            +
                  def on_success(command_outcome)
         | 
| 2057 | 
            +
                  end
         | 
| 2058 | 
            +
             | 
| 2059 | 
            +
                  def on_failure(command_outcome)
         | 
| 2060 | 
            +
                  end
         | 
| 2061 | 
            +
             | 
| 2062 | 
            +
                  def SGR(text)
         | 
| 2063 | 
            +
                    Console::SGR(text)
         | 
| 1935 2064 | 
             
                  end
         | 
| 1936 2065 |  | 
| 1937 2066 | 
             
                  private
         | 
| @@ -1939,19 +2068,19 @@ module BoPeep | |
| 1939 2068 | 
             
                  def configure_parser!
         | 
| 1940 2069 | 
             
                  end
         | 
| 1941 2070 |  | 
| 1942 | 
            -
                  def run_script(script_name = nil, on: hosts,  | 
| 2071 | 
            +
                  def run_script(script_name = nil, on: hosts, **options, &setup)
         | 
| 1943 2072 | 
             
                    script_name ||= command_name.script
         | 
| 1944 2073 | 
             
                    script = Script.new(script_name, context)
         | 
| 1945 2074 |  | 
| 1946 | 
            -
                    queue Step.new(self, script, on,  | 
| 2075 | 
            +
                    queue Step.new(self, script, on, **options, &setup)
         | 
| 1947 2076 | 
             
                  end
         | 
| 1948 2077 |  | 
| 1949 | 
            -
                  def run_command(command, on: hosts,  | 
| 1950 | 
            -
                    queue Step.new(self, command, on,  | 
| 2078 | 
            +
                  def run_command(command, on: hosts, **options, &setup)
         | 
| 2079 | 
            +
                    queue Step.new(self, command, on, **options, &setup)
         | 
| 1951 2080 | 
             
                  end
         | 
| 1952 2081 |  | 
| 1953 | 
            -
                  def on_localhost(banner, &block)
         | 
| 1954 | 
            -
                    queue Step.local(self, banner, block)
         | 
| 2082 | 
            +
                  def on_localhost(banner, **options, &block)
         | 
| 2083 | 
            +
                    queue Step.local(self, banner, block, **options)
         | 
| 1955 2084 | 
             
                  end
         | 
| 1956 2085 | 
             
                  alias locally on_localhost
         | 
| 1957 2086 |  | 
| @@ -1977,16 +2106,8 @@ module BoPeep | |
| 1977 2106 | 
             
                end
         | 
| 1978 2107 |  | 
| 1979 2108 | 
             
                class Step
         | 
| 1980 | 
            -
                  def self.local(command, banner, block)
         | 
| 1981 | 
            -
                    new(command, BlockProxy.new(banner, block), LOCALHOST,  | 
| 1982 | 
            -
                  end
         | 
| 1983 | 
            -
             | 
| 1984 | 
            -
                  def self.callback(command, last_step, order, block)
         | 
| 1985 | 
            -
                    new \
         | 
| 1986 | 
            -
                      command,
         | 
| 1987 | 
            -
                      Callback.new(last_step, block),
         | 
| 1988 | 
            -
                      last_step.hosts,
         | 
| 1989 | 
            -
                      order
         | 
| 2109 | 
            +
                  def self.local(command, banner, block, **options)
         | 
| 2110 | 
            +
                    new(command, BlockProxy.new(banner, block), LOCALHOST, **options)
         | 
| 1990 2111 | 
             
                  end
         | 
| 1991 2112 |  | 
| 1992 2113 | 
             
                  attr_reader :command
         | 
| @@ -1995,120 +2116,70 @@ module BoPeep | |
| 1995 2116 | 
             
                  attr_accessor :previous
         | 
| 1996 2117 | 
             
                  attr_reader :result
         | 
| 1997 2118 |  | 
| 1998 | 
            -
                  def initialize(command, run_object, hosts, order, &setup)
         | 
| 2119 | 
            +
                  def initialize(command, run_object, hosts, order: nil, log: nil, &setup)
         | 
| 1999 2120 | 
             
                    @command = command
         | 
| 2000 2121 | 
             
                    @run_object = run_object
         | 
| 2001 2122 | 
             
                    @hosts = hosts
         | 
| 2002 | 
            -
                    @order = order
         | 
| 2003 | 
            -
                    @ | 
| 2123 | 
            +
                    @order = order || :parallel
         | 
| 2124 | 
            +
                    @log = log.nil? ? true : log
         | 
| 2125 | 
            +
                    @callbacks_definition = Host::Callbacks::Definition.new(command, &setup)
         | 
| 2004 2126 | 
             
                  end
         | 
| 2005 2127 |  | 
| 2006 | 
            -
                  def  | 
| 2007 | 
            -
                    @ | 
| 2008 | 
            -
                  end
         | 
| 2009 | 
            -
             | 
| 2010 | 
            -
                  def and_then(order: :parallel, &block)
         | 
| 2011 | 
            -
                    @command.and_then order: order, &block
         | 
| 2128 | 
            +
                  def log?
         | 
| 2129 | 
            +
                    @log
         | 
| 2012 2130 | 
             
                  end
         | 
| 2013 2131 |  | 
| 2014 2132 | 
             
                  def run
         | 
| 2015 2133 | 
             
                    @result = case @run_object
         | 
| 2016 2134 | 
             
                              when String
         | 
| 2017 | 
            -
                                @hosts.run_command(@run_object, order: @order,  | 
| 2135 | 
            +
                                @hosts.run_command(@run_object, order: @order, callbacks: @callbacks_definition.callbacks, log: @log)
         | 
| 2018 2136 | 
             
                              when Script
         | 
| 2019 | 
            -
                                @hosts.run_script(@run_object, order: @order,  | 
| 2020 | 
            -
                              when Callback
         | 
| 2021 | 
            -
                                @run_object.run(@order)
         | 
| 2137 | 
            +
                                @hosts.run_script(@run_object, order: @order, callbacks: @callbacks_definition.callbacks, log: @log)
         | 
| 2022 2138 | 
             
                              when BlockProxy
         | 
| 2023 2139 | 
             
                                # NOTE: A `Proc` means `@hosts` is `LOCALHOST`
         | 
| 2024 2140 | 
             
                                Executor::Result.new.tap do |result|
         | 
| 2025 | 
            -
                                  result.update LOCALHOST.run(&@run_object)
         | 
| 2141 | 
            +
                                  result.update LOCALHOST.run(callbacks: @callbacks_definition.callbacks, log: @log, &@run_object)
         | 
| 2026 2142 | 
             
                                end
         | 
| 2027 2143 | 
             
                              end
         | 
| 2028 2144 | 
             
                  end
         | 
| 2029 2145 |  | 
| 2030 | 
            -
                   | 
| 2031 | 
            -
                     | 
| 2032 | 
            -
                       | 
| 2146 | 
            +
                  def log_command
         | 
| 2147 | 
            +
                    if log?
         | 
| 2148 | 
            +
                      BoPeep.console.puts Console::SGR(command.command_name.console).with(text_color: :blue, effect: :bold)
         | 
| 2033 2149 | 
             
                    end
         | 
| 2150 | 
            +
                  end
         | 
| 2034 2151 |  | 
| 2035 | 
            -
             | 
| 2036 | 
            -
             | 
| 2152 | 
            +
                  def log_step
         | 
| 2153 | 
            +
                    if log?
         | 
| 2154 | 
            +
                      BoPeep.console.puts Console::SGR(" -> #{@run_object}").with(text_color: :magenta)
         | 
| 2037 2155 | 
             
                    end
         | 
| 2038 2156 | 
             
                  end
         | 
| 2039 2157 |  | 
| 2040 | 
            -
                   | 
| 2041 | 
            -
                     | 
| 2042 | 
            -
             | 
| 2043 | 
            -
                      @run_object = run_object
         | 
| 2044 | 
            -
                    end
         | 
| 2158 | 
            +
                  def on_stdout(&block)
         | 
| 2159 | 
            +
                    @callbacks_definition.on_stdout(&block)
         | 
| 2160 | 
            +
                  end
         | 
| 2045 2161 |  | 
| 2046 | 
            -
             | 
| 2047 | 
            -
             | 
| 2048 | 
            -
             | 
| 2162 | 
            +
                  def on_stderr(&block)
         | 
| 2163 | 
            +
                    @callbacks_definition.on_stderr(&block)
         | 
| 2164 | 
            +
                  end
         | 
| 2049 2165 |  | 
| 2050 | 
            -
             | 
| 2051 | 
            -
             | 
| 2052 | 
            -
             | 
| 2053 | 
            -
                        rescue => error
         | 
| 2054 | 
            -
                          callback_outcome.error = error
         | 
| 2055 | 
            -
                        end
         | 
| 2166 | 
            +
                  def on_success(&block)
         | 
| 2167 | 
            +
                    @callbacks_definition.on_success(&block)
         | 
| 2168 | 
            +
                  end
         | 
| 2056 2169 |  | 
| 2057 | 
            -
             | 
| 2058 | 
            -
             | 
| 2059 | 
            -
             | 
| 2170 | 
            +
                  def on_failure(&block)
         | 
| 2171 | 
            +
                    @callbacks_definition.on_failure(&block)
         | 
| 2172 | 
            +
                  end
         | 
| 2060 2173 |  | 
| 2174 | 
            +
                  class BlockProxy < Struct.new(:banner, :block)
         | 
| 2061 2175 | 
             
                    def to_s
         | 
| 2062 | 
            -
                       | 
| 2176 | 
            +
                      banner
         | 
| 2063 2177 | 
             
                    end
         | 
| 2064 2178 |  | 
| 2065 | 
            -
                     | 
| 2066 | 
            -
                       | 
| 2067 | 
            -
                      attr_reader :host
         | 
| 2068 | 
            -
                      attr_reader :last_outcome
         | 
| 2069 | 
            -
                      attr_accessor :value
         | 
| 2070 | 
            -
             | 
| 2071 | 
            -
                      def initialize(outcome)
         | 
| 2072 | 
            -
                        @last_outcome = outcome
         | 
| 2073 | 
            -
                        @host = @last_outcome.host
         | 
| 2074 | 
            -
                        @successful = true
         | 
| 2075 | 
            -
                      end
         | 
| 2076 | 
            -
             | 
| 2077 | 
            -
                      def resolve(value)
         | 
| 2078 | 
            -
                        @value = value
         | 
| 2079 | 
            -
                      end
         | 
| 2080 | 
            -
             | 
| 2081 | 
            -
                      def fail!(message)
         | 
| 2082 | 
            -
                        @successful = false
         | 
| 2083 | 
            -
             | 
| 2084 | 
            -
                        raise CallbackFailedError.new(message)
         | 
| 2085 | 
            -
                      end
         | 
| 2086 | 
            -
             | 
| 2087 | 
            -
                      def error=(error)
         | 
| 2088 | 
            -
                        @successful = false
         | 
| 2089 | 
            -
                        @error = error
         | 
| 2090 | 
            -
                      end
         | 
| 2091 | 
            -
             | 
| 2092 | 
            -
                      def successful?
         | 
| 2093 | 
            -
                        @successful
         | 
| 2094 | 
            -
                      end
         | 
| 2095 | 
            -
             | 
| 2096 | 
            -
                      def failed?
         | 
| 2097 | 
            -
                        !successful?
         | 
| 2098 | 
            -
                      end
         | 
| 2099 | 
            -
             | 
| 2100 | 
            -
                      def failure_reason
         | 
| 2101 | 
            -
                        error
         | 
| 2102 | 
            -
                      end
         | 
| 2103 | 
            -
             | 
| 2104 | 
            -
                      def failure_summary
         | 
| 2105 | 
            -
                        error && error.full_message
         | 
| 2106 | 
            -
                      end
         | 
| 2179 | 
            +
                    def to_proc
         | 
| 2180 | 
            +
                      block
         | 
| 2107 2181 | 
             
                    end
         | 
| 2108 2182 | 
             
                  end
         | 
| 2109 | 
            -
             | 
| 2110 | 
            -
                  class CallbackFailedError < StandardError
         | 
| 2111 | 
            -
                  end
         | 
| 2112 2183 | 
             
                end
         | 
| 2113 2184 | 
             
              end
         | 
| 2114 2185 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: bopeep
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Eduardo Gutierrez
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-08-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bcrypt_pbkdf
         |