warg 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/console-playground +0 -1
  3. data/lib/warg.rb +201 -206
  4. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2f032dcff2708b375e016c4ed2b8809ef80784c1fa3845cf5e480c279003fd7
4
- data.tar.gz: c17eab82ffa3f6e1ae78e1aeabaf460c2596d1d4d7c9c9633be7112d3687d7b7
3
+ metadata.gz: d96b90a94c51248029193228a27c43ef63e630b671a03f2cc5b5791878ef0456
4
+ data.tar.gz: 946d2c64356f0f9033ba9bb1bac0694737ad34c8a0d92c0fd990c2f3aede0913
5
5
  SHA512:
6
- metadata.gz: 8b11f96e8c293f3005767d6471b58e04942121d8b87dbb6f61a9094182cbad8dc779e46c9f6c1d92ce0338e92a85a2231b58a88a1b2e55124028a8141ea04f64
7
- data.tar.gz: 700b611540d8f704e8ea57d11d5be633c78a6e8050745f22a1096dd40e7eebf17f27a2f6280ba4e3c3cdca404fd8799f883f9b03ae6b65f7ac2944a557f685af
6
+ metadata.gz: eb1096029b3b316d249c813463440fae0264872b8be04e88c82dd97d3c9b8f592b0dc072bcbcc8e330fe9a44dedb8fe123d0f60f91b00c2d5afeb3ebe10b310f
7
+ data.tar.gz: 44c808ba4a6d3468a4a3594b9cd10183cf6b87cfc3613caa9c373143ea57b0b97e96fe4c0c8095251d0e50e6329153402e9700c5e68e1684fe3c6298bb0b569b
@@ -23,7 +23,6 @@ end
23
23
  require "pry"
24
24
 
25
25
  # NOTE: Unsure why `"set"` needs to be loaded here
26
- require "set"
27
26
  require "warg"
28
27
 
29
28
  console = Warg::Console.new
data/lib/warg.rb CHANGED
@@ -594,38 +594,6 @@ module Warg
594
594
  outcome
595
595
  end
596
596
 
597
- def defer(command, banner, &block)
598
- run_object = BlockProxy.new(banner, &block)
599
- hosts = CollectionProxy.new
600
-
601
- Executor::Deferred.new(command, run_object, hosts, :serial)
602
- end
603
-
604
- class BlockProxy
605
- def initialize(banner, &block)
606
- @banner = banner
607
- @block = block
608
- end
609
-
610
- def to_s
611
- @banner.dup
612
- end
613
-
614
- def to_proc
615
- @block
616
- end
617
- end
618
-
619
- class CollectionProxy
620
- def run_block(run_object, **)
621
- outcome = LOCALHOST.run(&run_object)
622
-
623
- execution_result = Executor::Result.new
624
- execution_result.update(outcome)
625
- execution_result
626
- end
627
- end
628
-
629
597
  class CommandOutcome
630
598
  attr_accessor :error
631
599
 
@@ -683,6 +651,10 @@ module Warg
683
651
  end
684
652
  end
685
653
 
654
+ def failure_reason
655
+ error
656
+ end
657
+
686
658
  def failure_summary
687
659
  error && error.full_message
688
660
  end
@@ -1378,11 +1350,12 @@ module Warg
1378
1350
  class Context < Config
1379
1351
  attr_reader :argv
1380
1352
  attr_reader :parser
1353
+ attr_reader :playlist
1381
1354
 
1382
- def initialize(argv)
1355
+ def initialize(argv, playlist)
1383
1356
  @argv = argv
1357
+ @playlist = playlist
1384
1358
  @parser = OptionParser.new
1385
- @playlist = Playlist.new
1386
1359
 
1387
1360
  @parser.on("-t", "--target HOSTS", Array, "hosts to use") do |hosts_data|
1388
1361
  hosts_data.each { |host_data| hosts.add(host_data) }
@@ -1395,16 +1368,6 @@ module Warg
1395
1368
  @parser.parse(@argv)
1396
1369
  end
1397
1370
 
1398
- def queue!(command)
1399
- @playlist.queue(command)
1400
- end
1401
-
1402
- def run!
1403
- Console.hostname_width = hosts.map { |host| host.address.length }.max
1404
-
1405
- @playlist.start
1406
- end
1407
-
1408
1371
  def copy(config)
1409
1372
  config.hosts.each do |host|
1410
1373
  hosts.add(host)
@@ -1416,30 +1379,53 @@ module Warg
1416
1379
  end
1417
1380
  end
1418
1381
  end
1382
+ end
1419
1383
 
1420
- class Playlist
1421
- def initialize
1422
- @playing_at = 0
1423
- @insert_at = 0
1424
- @items = []
1425
- @started = false
1426
- end
1384
+ class Playlist
1385
+ attr_reader :insert_at
1427
1386
 
1428
- def start
1429
- @started = true
1430
- @insert_at = 1
1387
+ def initialize
1388
+ @start = @insert_at = Start.new
1389
+ end
1390
+
1391
+ def play
1392
+ playing = @insert_at = @start
1393
+ command = nil
1394
+
1395
+ while playing.next
1396
+ playing = @insert_at = playing.next
1397
+
1398
+ if command != playing.command
1399
+ command = playing.command
1400
+
1401
+ Warg.console.puts Console::SGR(command.command_name.console).with(text_color: :blue, effect: :bold)
1402
+ end
1403
+
1404
+ Warg.console.puts Console::SGR(" -> #{playing.banner}").with(text_color: :magenta)
1431
1405
 
1432
- until @playing_at >= @items.length
1433
- @items[@playing_at].run
1406
+ result = playing.run
1434
1407
 
1435
- @playing_at += 1
1436
- @insert_at = @playing_at + 1
1408
+ if result.failed?
1409
+ command.on_failure(result)
1437
1410
  end
1438
1411
  end
1412
+ end
1413
+
1414
+ def queue(command_step)
1415
+ if @insert_at.next
1416
+ command_step.next = @insert_at.next
1417
+ end
1418
+
1419
+ command_step.previous = @insert_at
1420
+ @insert_at.next = command_step
1421
+
1422
+ @insert_at = command_step
1423
+ end
1424
+
1425
+ class Start
1426
+ attr_accessor :next
1439
1427
 
1440
- def queue(command)
1441
- @items.insert(@insert_at, command)
1442
- @insert_at += 1
1428
+ def previous
1443
1429
  end
1444
1430
  end
1445
1431
  end
@@ -1448,11 +1434,12 @@ module Warg
1448
1434
  def initialize(argv)
1449
1435
  @argv = argv.dup
1450
1436
  @path = nil
1437
+ @playlist = Playlist.new
1451
1438
 
1452
1439
  find_warg_directory!
1453
1440
  load_config!
1454
1441
 
1455
- @context = Context.new(@argv)
1442
+ @context = Context.new(@argv, @playlist)
1456
1443
  @context.copy(Warg.config)
1457
1444
 
1458
1445
  load_scripts!
@@ -1470,8 +1457,10 @@ module Warg
1470
1457
  @command.(@context)
1471
1458
  @context.parse_options!
1472
1459
 
1460
+ Console.hostname_width = @context.hosts.map { |host| host.address.length }.max
1461
+
1473
1462
  Warg.console.redirecting_stdout_and_stderr do
1474
- @context.run!
1463
+ @playlist.play
1475
1464
  end
1476
1465
  end
1477
1466
 
@@ -1545,7 +1534,7 @@ module Warg
1545
1534
  object = Class.new do
1546
1535
  include Command::BehaviorWithoutRegistration
1547
1536
 
1548
- def setup
1537
+ def run
1549
1538
  run_script
1550
1539
  end
1551
1540
  end
@@ -1619,127 +1608,6 @@ module Warg
1619
1608
  end
1620
1609
  end
1621
1610
 
1622
- class Deferred
1623
- def initialize(command, run_object, hosts, order, &setup)
1624
- @command = command
1625
- @run_object = run_object
1626
- @hosts = hosts
1627
- @order = order
1628
- @setup = setup
1629
-
1630
- @callbacks_queue = CallbacksQueue.new(order)
1631
-
1632
- @run_type = case @run_object
1633
- when Script
1634
- :run_script
1635
- when String
1636
- :run_command
1637
- when Localhost::BlockProxy
1638
- :run_block
1639
- end
1640
- end
1641
-
1642
- def banner
1643
- @run_object
1644
- end
1645
-
1646
- def and_then(&block)
1647
- @callbacks_queue << block
1648
- self
1649
- end
1650
-
1651
- def run
1652
- execution_result = @hosts.public_send(@run_type, @run_object, order: @order, &@setup)
1653
-
1654
- execution_result = @callbacks_queue.drain(execution_result)
1655
-
1656
- if execution_result.failed?
1657
- @command.on_failure(execution_result)
1658
- end
1659
-
1660
- execution_result
1661
- end
1662
-
1663
- class CallbacksQueue
1664
- def initialize(execution_order)
1665
- @queue = []
1666
- @executor_class = Executor.for(execution_order)
1667
- end
1668
-
1669
- def <<(callback)
1670
- @queue << callback
1671
- end
1672
-
1673
- def drain(execution_result)
1674
- drain_queue = @queue.dup
1675
-
1676
- # NOTE: It would be nice to incorporate the failure callback into the code here
1677
- until drain_queue.empty? || execution_result.failed?
1678
- callback = drain_queue.shift
1679
- executor = @executor_class.new(execution_result)
1680
-
1681
- execution_result = executor.run do |outcome, result|
1682
- callback_outcome = Outcome.new(outcome)
1683
-
1684
- begin
1685
- # Use `||=` in case `#value` is set in the callback
1686
- callback_outcome.value ||= callback.(outcome.host, outcome.value, callback_outcome)
1687
- rescue => error
1688
- callback_outcome.error = error
1689
- end
1690
-
1691
- result.update callback_outcome
1692
- end
1693
- end
1694
-
1695
- execution_result
1696
- end
1697
-
1698
- class Outcome
1699
- attr_reader :error
1700
- attr_reader :host
1701
- attr_reader :source_outcome
1702
- attr_accessor :value
1703
-
1704
- def initialize(outcome)
1705
- @source_outcome = outcome
1706
- @host = @source_outcome.host
1707
- @successful = true
1708
- end
1709
-
1710
- def resolve(value)
1711
- @value = value
1712
- end
1713
-
1714
- def fail!(message)
1715
- @successful = false
1716
-
1717
- raise CallbackFailedError.new(message)
1718
- end
1719
-
1720
- def error=(error)
1721
- @successful = false
1722
- @error = error
1723
- end
1724
-
1725
- def successful?
1726
- @successful
1727
- end
1728
-
1729
- def failed?
1730
- !successful?
1731
- end
1732
-
1733
- def failure_summary
1734
- error && error.full_message
1735
- end
1736
- end
1737
- end
1738
-
1739
- class CallbackFailedError < StandardError
1740
- end
1741
- end
1742
-
1743
1611
  class Result
1744
1612
  include Enumerable
1745
1613
  extend Forwardable
@@ -1924,9 +1792,8 @@ module Warg
1924
1792
  attr_reader :argv
1925
1793
  attr_reader :context
1926
1794
  attr_reader :hosts
1927
- attr_reader :operations
1928
1795
  attr_reader :parser
1929
- attr_reader :steps
1796
+ attr_reader :playlist
1930
1797
 
1931
1798
  def initialize(context)
1932
1799
  @context = context
@@ -1934,11 +1801,9 @@ module Warg
1934
1801
  @parser = @context.parser
1935
1802
  @hosts = @context.hosts
1936
1803
  @argv = @context.argv.dup
1804
+ @playlist = @context.playlist
1937
1805
 
1938
1806
  configure_parser!
1939
-
1940
- @context.queue!(self)
1941
- @steps = []
1942
1807
  end
1943
1808
 
1944
1809
  def name
@@ -1946,20 +1811,11 @@ module Warg
1946
1811
  end
1947
1812
 
1948
1813
  def call
1949
- setup
1814
+ run
1950
1815
  self
1951
1816
  end
1952
1817
 
1953
- def setup
1954
- end
1955
-
1956
1818
  def run
1957
- Warg.console.puts Console::SGR(command_name.console).with(text_color: :blue, effect: :bold)
1958
-
1959
- @steps.each do |deferred|
1960
- Warg.console.puts Console::SGR(" -> #{deferred.banner}").with(text_color: :magenta)
1961
- deferred.run
1962
- end
1963
1819
  end
1964
1820
 
1965
1821
  def command_name
@@ -1984,6 +1840,10 @@ module Warg
1984
1840
  Console::SGR(text)
1985
1841
  end
1986
1842
 
1843
+ def and_then(order: :parallel, &block)
1844
+ @playlist.queue Step.callback(self, @playlist.insert_at, order, block)
1845
+ end
1846
+
1987
1847
  private
1988
1848
 
1989
1849
  def configure_parser!
@@ -1993,21 +1853,21 @@ module Warg
1993
1853
  script_name ||= command_name.script
1994
1854
  script = Script.new(script_name, context)
1995
1855
 
1996
- append Executor::Deferred.new(self, script, on, order, &setup)
1856
+ queue Step.new(self, script, on, order, &setup)
1997
1857
  end
1998
1858
 
1999
1859
  def run_command(command, on: hosts, order: :parallel, &setup)
2000
- append Executor::Deferred.new(self, command, on, order, &setup)
1860
+ queue Step.new(self, command, on, order, &setup)
2001
1861
  end
2002
1862
 
2003
1863
  def on_localhost(banner, &block)
2004
- append LOCALHOST.defer(self, banner, &block)
1864
+ queue Step.local(self, banner, block)
2005
1865
  end
2006
1866
  alias locally on_localhost
2007
1867
 
2008
- def append(deferred)
2009
- @steps << deferred
2010
- deferred
1868
+ def queue(step)
1869
+ @playlist.queue(step)
1870
+ step
2011
1871
  end
2012
1872
  end
2013
1873
 
@@ -2025,6 +1885,141 @@ module Warg
2025
1885
  klass.extend(Chaining)
2026
1886
  end
2027
1887
  end
1888
+
1889
+ class Step
1890
+ def self.local(command, banner, block)
1891
+ new(command, BlockProxy.new(banner, block), LOCALHOST, :serial)
1892
+ end
1893
+
1894
+ def self.callback(command, last_step, order, block)
1895
+ new \
1896
+ command,
1897
+ Callback.new(last_step, block),
1898
+ last_step.hosts,
1899
+ order
1900
+ end
1901
+
1902
+ attr_reader :command
1903
+ attr_reader :hosts
1904
+ attr_accessor :next
1905
+ attr_accessor :previous
1906
+ attr_reader :result
1907
+
1908
+ def initialize(command, run_object, hosts, order, &setup)
1909
+ @command = command
1910
+ @run_object = run_object
1911
+ @hosts = hosts
1912
+ @order = order
1913
+ @setup = setup
1914
+ end
1915
+
1916
+ def banner
1917
+ @run_object
1918
+ end
1919
+
1920
+ def and_then(order: :parallel, &block)
1921
+ @command.and_then order: order, &block
1922
+ end
1923
+
1924
+ def run
1925
+ @result = case @run_object
1926
+ when String
1927
+ @hosts.run_command(@run_object, order: @order, &@setup)
1928
+ when Script
1929
+ @hosts.run_script(@run_object, order: @order, &@setup)
1930
+ when Callback
1931
+ @run_object.run(@order)
1932
+ when BlockProxy
1933
+ # NOTE: A `Proc` means `@hosts` is `LOCALHOST`
1934
+ Executor::Result.new.tap do |result|
1935
+ result.update LOCALHOST.run(&@run_object)
1936
+ end
1937
+ end
1938
+ end
1939
+
1940
+ class BlockProxy < Struct.new(:banner, :block)
1941
+ def to_s
1942
+ banner
1943
+ end
1944
+
1945
+ def to_proc
1946
+ block
1947
+ end
1948
+ end
1949
+
1950
+ class Callback
1951
+ def initialize(last_step, run_object)
1952
+ @last_step = last_step
1953
+ @run_object = run_object
1954
+ end
1955
+
1956
+ def run(order)
1957
+ Executor.for(order).new(@last_step.result).run do |last_outcome, result|
1958
+ callback_outcome = Outcome.new(last_outcome)
1959
+
1960
+ begin
1961
+ # Use `||=` in case `#value` is set in the callback
1962
+ callback_outcome.value ||= @run_object.(last_outcome.host, last_outcome.value, callback_outcome)
1963
+ rescue => error
1964
+ callback_outcome.error = error
1965
+ end
1966
+
1967
+ result.update callback_outcome
1968
+ end
1969
+ end
1970
+
1971
+ def to_s
1972
+ "(callback)"
1973
+ end
1974
+
1975
+ class Outcome
1976
+ attr_reader :error
1977
+ attr_reader :host
1978
+ attr_reader :last_outcome
1979
+ attr_accessor :value
1980
+
1981
+ def initialize(outcome)
1982
+ @last_outcome = outcome
1983
+ @host = @last_outcome.host
1984
+ @successful = true
1985
+ end
1986
+
1987
+ def resolve(value)
1988
+ @value = value
1989
+ end
1990
+
1991
+ def fail!(message)
1992
+ @successful = false
1993
+
1994
+ raise CallbackFailedError.new(message)
1995
+ end
1996
+
1997
+ def error=(error)
1998
+ @successful = false
1999
+ @error = error
2000
+ end
2001
+
2002
+ def successful?
2003
+ @successful
2004
+ end
2005
+
2006
+ def failed?
2007
+ !successful?
2008
+ end
2009
+
2010
+ def failure_reason
2011
+ error
2012
+ end
2013
+
2014
+ def failure_summary
2015
+ error && error.full_message
2016
+ end
2017
+ end
2018
+ end
2019
+
2020
+ class CallbackFailedError < StandardError
2021
+ end
2022
+ end
2028
2023
  end
2029
2024
 
2030
2025
  class ChainCommand
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Gutierrez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-16 00:00:00.000000000 Z
11
+ date: 2023-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt_pbkdf
@@ -120,6 +120,20 @@ dependencies:
120
120
  - - "~>"
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0.13'
123
+ - !ruby/object:Gem::Dependency
124
+ name: pry-remote
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '0.1'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '0.1'
123
137
  - !ruby/object:Gem::Dependency
124
138
  name: minitest
125
139
  requirement: !ruby/object:Gem::Requirement
@@ -179,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
181
195
  requirements: []
182
- rubygems_version: 3.3.7
196
+ rubygems_version: 3.2.3
183
197
  signing_key:
184
198
  specification_version: 4
185
199
  summary: Light-weight interaction with servers