zold 0.14.8 → 0.14.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +0 -0
  4. data/Gemfile +2 -0
  5. data/Rakefile +2 -0
  6. data/appveyor.yml +8 -3
  7. data/features/step_definitions/steps.rb +2 -0
  8. data/features/support/env.rb +2 -0
  9. data/fixtures/merge/asserts.rb +2 -0
  10. data/fixtures/merge/into-no-wallet/assert.rb +2 -0
  11. data/fixtures/merge/random-expenses/assert.rb +2 -0
  12. data/fixtures/merge/simple-case/assert.rb +2 -0
  13. data/fixtures/scripts/_head.sh +13 -0
  14. data/fixtures/scripts/distribute-wallet.sh +86 -0
  15. data/fixtures/scripts/spread-wallets.sh +56 -0
  16. data/lib/zold.rb +2 -0
  17. data/lib/zold/amount.rb +3 -1
  18. data/lib/zold/atomic_file.rb +2 -0
  19. data/lib/zold/backtrace.rb +2 -0
  20. data/lib/zold/commands/alias.rb +2 -0
  21. data/lib/zold/commands/args.rb +2 -0
  22. data/lib/zold/commands/calculate.rb +5 -3
  23. data/lib/zold/commands/clean.rb +2 -0
  24. data/lib/zold/commands/create.rb +2 -0
  25. data/lib/zold/commands/diff.rb +2 -0
  26. data/lib/zold/commands/fetch.rb +7 -2
  27. data/lib/zold/commands/invoice.rb +2 -0
  28. data/lib/zold/commands/list.rb +2 -0
  29. data/lib/zold/commands/merge.rb +2 -0
  30. data/lib/zold/commands/node.rb +2 -0
  31. data/lib/zold/commands/pay.rb +2 -0
  32. data/lib/zold/commands/propagate.rb +2 -0
  33. data/lib/zold/commands/pull.rb +2 -0
  34. data/lib/zold/commands/push.rb +2 -0
  35. data/lib/zold/commands/remote.rb +11 -6
  36. data/lib/zold/commands/routines/bonuses.rb +78 -0
  37. data/lib/zold/commands/routines/reconnect.rb +2 -0
  38. data/lib/zold/commands/routines/spread.rb +2 -0
  39. data/lib/zold/commands/show.rb +2 -0
  40. data/lib/zold/commands/taxes.rb +2 -0
  41. data/lib/zold/copies.rb +4 -2
  42. data/lib/zold/hexnum.rb +2 -0
  43. data/lib/zold/http.rb +28 -20
  44. data/lib/zold/hungry_wallets.rb +2 -0
  45. data/lib/zold/id.rb +2 -0
  46. data/lib/zold/json_page.rb +2 -0
  47. data/lib/zold/key.rb +2 -0
  48. data/lib/zold/log.rb +2 -0
  49. data/lib/zold/metronome.rb +2 -0
  50. data/lib/zold/node/async_entrance.rb +3 -3
  51. data/lib/zold/node/emission.rb +2 -0
  52. data/lib/zold/node/entrance.rb +5 -2
  53. data/lib/zold/node/farm.rb +3 -1
  54. data/lib/zold/node/front.rb +4 -1
  55. data/lib/zold/node/safe_entrance.rb +2 -0
  56. data/lib/zold/node/spread_entrance.rb +2 -0
  57. data/lib/zold/patch.rb +2 -0
  58. data/lib/zold/prefixes.rb +2 -0
  59. data/lib/zold/remotes.rb +15 -13
  60. data/lib/zold/score.rb +62 -59
  61. data/lib/zold/signature.rb +2 -0
  62. data/lib/zold/tax.rb +3 -1
  63. data/lib/zold/txn.rb +4 -2
  64. data/lib/zold/type.rb +36 -0
  65. data/lib/zold/upgrades.rb +2 -4
  66. data/lib/zold/verbose_thread.rb +2 -0
  67. data/lib/zold/version.rb +4 -2
  68. data/lib/zold/version_file.rb +2 -0
  69. data/lib/zold/wallet.rb +4 -2
  70. data/lib/zold/wallets.rb +2 -0
  71. data/test/commands/routines/test_bonuses.rb +76 -0
  72. data/test/commands/routines/test_reconnect.rb +2 -0
  73. data/test/commands/routines/test_spread.rb +2 -0
  74. data/test/commands/test_alias.rb +2 -0
  75. data/test/commands/test_calculate.rb +2 -0
  76. data/test/commands/test_clean.rb +2 -0
  77. data/test/commands/test_create.rb +2 -0
  78. data/test/commands/test_diff.rb +2 -0
  79. data/test/commands/test_fetch.rb +2 -0
  80. data/test/commands/test_invoice.rb +2 -0
  81. data/test/commands/test_list.rb +2 -0
  82. data/test/commands/test_merge.rb +2 -0
  83. data/test/commands/test_node.rb +6 -0
  84. data/test/commands/test_pay.rb +2 -0
  85. data/test/commands/test_propagate.rb +2 -0
  86. data/test/commands/test_push.rb +2 -0
  87. data/test/commands/test_remote.rb +40 -0
  88. data/test/commands/test_show.rb +2 -0
  89. data/test/commands/test_taxes.rb +2 -0
  90. data/test/fake_home.rb +2 -0
  91. data/test/node/fake_entrance.rb +2 -0
  92. data/test/node/fake_node.rb +3 -1
  93. data/test/node/test_async_entrance.rb +2 -0
  94. data/test/node/test_emission.rb +2 -0
  95. data/test/node/test_entrance.rb +2 -0
  96. data/test/node/test_farm.rb +9 -7
  97. data/test/node/test_front.rb +15 -10
  98. data/test/node/test_safe_entrance.rb +2 -0
  99. data/test/node/test_spread_entrance.rb +2 -0
  100. data/test/test__helper.rb +2 -0
  101. data/test/test_amount.rb +2 -0
  102. data/test/test_atomic_file.rb +2 -0
  103. data/test/test_backtrace.rb +2 -0
  104. data/test/test_copies.rb +4 -1
  105. data/test/test_hexnum.rb +2 -0
  106. data/test/test_http.rb +5 -3
  107. data/test/test_id.rb +2 -0
  108. data/test/test_key.rb +2 -0
  109. data/test/test_metronome.rb +2 -0
  110. data/test/test_patch.rb +2 -0
  111. data/test/test_prefixes.rb +2 -0
  112. data/test/test_remotes.rb +11 -0
  113. data/test/test_score.rb +26 -24
  114. data/test/test_signature.rb +2 -0
  115. data/test/test_tax.rb +4 -2
  116. data/test/test_txn.rb +2 -0
  117. data/test/test_upgrades.rb +2 -0
  118. data/test/test_verbose_thread.rb +2 -0
  119. data/test/test_version.rb +2 -0
  120. data/test/test_wallet.rb +2 -0
  121. data/test/test_wallets.rb +2 -0
  122. data/test/test_zold.rb +2 -0
  123. data/test/upgrades/test_protocol_up.rb +2 -0
  124. data/upgrades/2.rb +2 -0
  125. data/upgrades/protocol_up.rb +2 -0
  126. data/upgrades/rename_foreign_wallets.rb +2 -0
  127. data/zold.gemspec +5 -1
  128. metadata +38 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2f9cbae830828107bb4b7aa19a24fa9d53620b4
4
- data.tar.gz: 03f51730a5136f765985161d36b9454d59f19748
3
+ metadata.gz: 3f87074edd8e64584ac6834ed6646922c903c4f7
4
+ data.tar.gz: 3e35c4e458186d16a9f5ebf2f635b7757525de74
5
5
  SHA512:
6
- metadata.gz: ed925085a934c77ffed65eb83bf9a8d0d97fb31dcb608ab20538445397a226241904fdf9ee41bb40f6078d0888d92d05e424c3cc7623cb581011b4cb0caaba1a
7
- data.tar.gz: 1d0a2a7233ef74a7b1fb9e51584df480e06836b4efbbb67f71fc3c2238300a9f3409b98d4d2105f03d8905dc3a086066fafe601eda188309a4a8617c9b5a1e0a
6
+ metadata.gz: 05ff08a140bf66931a794d110ef12951389140836c2b0554ffb2e2abf738316d2c193a146decd7a71718e009e4ea9b839e5a7c6ac7778fffa8bab183788e17bc
7
+ data.tar.gz: 5a30ccf3cdfccec6007140021160d197cb5e95728a83aeeb2bb8dc293e4f65d17be997b14396a6b86746e679f0d13d1e6787be56c3a3dd333209eb13ed8cd3d2
@@ -3,7 +3,7 @@ AllCops:
3
3
  - 'bin/**/*'
4
4
  - 'assets/**/*'
5
5
  DisplayCopNames: true
6
- TargetRubyVersion: 2.2
6
+ TargetRubyVersion: 2.3.3
7
7
 
8
8
  Metrics/CyclomaticComplexity:
9
9
  Max: 25
File without changes
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -7,15 +7,20 @@ branches:
7
7
  except:
8
8
  - gh-pages
9
9
  os: Windows Server 2012
10
+ environment:
11
+ matrix:
12
+ - RUBY_VERSION: 23
13
+ - RUBY_VERSION: 24
14
+ - RUBY_VERSION: 25
10
15
  install:
11
- - cmd: SET PATH=C:\Ruby23-x64\bin;%PATH%
16
+ - cmd: set PATH=C:\Ruby%RUBY_VERSION%-X64\bin;%PATH%
12
17
  - cmd: ruby --version
13
18
  - cmd: git --version
19
+ - cmd: bundle config --local path vendor/bundle
14
20
  build_script:
15
21
  - bundle update
16
22
  - bundle install
17
23
  test_script:
18
24
  - rake
19
25
  cache:
20
- - C:\Ruby200\bin -> zold.gemspec
21
- - C:\Ruby200\lib\ruby\gems\2.0.0 -> zold.gemspec
26
+ - vendor/bundle
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -3,12 +3,25 @@ set -e
3
3
  set -x
4
4
  shopt -s expand_aliases
5
5
 
6
+ export RUBYOPT="-W0"
7
+
6
8
  alias zold="$1 --ignore-this-stupid-option --ignore-global-config --trace --network=test --no-colors"
7
9
 
8
10
  function reserve_port {
9
11
  python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
10
12
  }
11
13
 
14
+ function wait_for_url {
15
+ while ! curl --silent --fail $1 > /dev/null; do
16
+ ((p++)) || sleep 1
17
+ if ((p==30)); then
18
+ echo URL $1 is not available after $p seconds of waiting
19
+ exit -1
20
+ fi
21
+ sleep 1
22
+ done
23
+ }
24
+
12
25
  function wait_for_port {
13
26
  while ! nc -z localhost $1; do
14
27
  ((p++)) || sleep 1
@@ -0,0 +1,86 @@
1
+ #!/bin/bash
2
+
3
+ function start_node {
4
+ port=$(reserve_port)
5
+ mkdir ${port}
6
+ cd ${port}
7
+ zold node --trace --invoice=NOPREFIX@ffffffffffffffff \
8
+ --host=localhost --port=${port} --bind-port=${port} \
9
+ --threads=0 --routine-immediately > log.txt &
10
+ pid=$!
11
+ echo ${pid} > pid
12
+ cd ..
13
+ wait_for_url http://localhost:${port}/
14
+ echo ${port}
15
+ }
16
+
17
+ # We start two nodes and kill them both at the end of the script. If we
18
+ # don't do the TRAP for killing, the test will never end.
19
+ first=$(start_node)
20
+ second=$(start_node)
21
+ trap "kill -9 $(cat ${first}/pid) $(cat ${second}/pid)" EXIT
22
+
23
+ # The first node is linked to the second one and the second one
24
+ # is linked to the first one. The --home argument specifies their
25
+ # locations.
26
+ zold --home=${first} remote clean
27
+ zold --home=${first} remote add localhost ${second}
28
+ zold --home=${second} remote clean
29
+ zold --home=${second} remote add localhost ${first}
30
+
31
+ # Locally we create a new root wallet (to avoid negative balance checking)
32
+ # and connect our local Zold home to the first remote node. Then, we push
33
+ # the wallet to the remote, expecting it to distribute it to the second
34
+ # wallet automatically.
35
+ zold --public-key=id_rsa.pub create 0000000000000000
36
+ zold pay --private-key=id_rsa 0000000000000000 NOPREFIX@aaaabbbbccccdddd 4.95 'To help you, dude!'
37
+ zold remote add localhost ${first}
38
+ zold push 0000000000000000
39
+ zold remote clean
40
+ zold remote add localhost ${second}
41
+
42
+ # Here we fetch the wallet from the second remote node. The wallet has
43
+ # to be visible there. We are doing a number of attempts with a small
44
+ # delay between them, in order to give the first node a chance to distribute
45
+ # the wallet.
46
+ until zold fetch 0000000000000000 --ignore-score-weakness; do
47
+ echo 'Failed to fetch, let us try again'
48
+ ((i++)) || sleep 1
49
+ if ((i==5)); then
50
+ cat ${first}/log.txt
51
+ echo "The wallet has not been distributed, after ${i} attempts"
52
+ exit -1
53
+ fi
54
+ sleep 1
55
+ done
56
+
57
+ # Here we check the JSON of the first node to make sure all status
58
+ # indicators are clean.
59
+ json=$(curl --silent --show-error http://localhost:${first})
60
+ if [ ! $(echo ${json} | jq -r '.entrance.queue') == "0" ]; then
61
+ echo "The queue is not empty after PUSH, it's a bug"
62
+ exit -1
63
+ fi
64
+ if [ $(echo ${json} | jq -r '.entrance.history_size') == "0" ]; then
65
+ echo "The history doesn't have a wallet, it's a bug"
66
+ exit -1
67
+ fi
68
+ if [ ! $(echo ${json} | jq -r '.wallets') == "1" ]; then
69
+ echo "The wallet is not there for some reason, it's a bug"
70
+ exit -1
71
+ fi
72
+
73
+ # Now, we remove the wallet from the second node and expect the first
74
+ # one to "spread" it again, almost immediately.
75
+ rm ${second}/0000000000000000.z
76
+ until zold fetch 0000000000000000 --ignore-score-weakness; do
77
+ echo 'Failed to fetch, let us try again'
78
+ ((i++)) || sleep 1
79
+ if ((i==5)); then
80
+ cat ${first}/log.txt
81
+ echo "The wallet has not been spread, after ${i} attempts"
82
+ exit -1
83
+ fi
84
+ sleep 1
85
+ done
86
+
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+
3
+ function start_node {
4
+ port=$(reserve_port)
5
+ mkdir ${port}
6
+ cd ${port}
7
+ zold node --trace --invoice=NOPREFIX@ffffffffffffffff \
8
+ --host=localhost --port=${port} --bind-port=${port} \
9
+ --threads=0 > log.txt &
10
+ pid=$!
11
+ echo ${pid} > pid
12
+ cd ..
13
+ wait_for_url http://localhost:${port}/
14
+ echo ${port}
15
+ }
16
+
17
+ first=$(start_node)
18
+ second=$(start_node)
19
+ trap "kill -9 $(cat ${first}/pid) $(cat ${second}/pid)" EXIT
20
+
21
+ zold --home=${first} remote clean
22
+ zold --home=${first} remote add localhost ${second}
23
+ zold --home=${second} remote clean
24
+ zold --home=${second} remote add localhost ${first}
25
+
26
+ zold --public-key=id_rsa.pub create 0000000000000000
27
+ zold pay --private-key=id_rsa 0000000000000000 NOPREFIX@aaaabbbbccccdddd 4.95 'To help you, dude!'
28
+ zold remote add localhost ${first}
29
+ zold push 0000000000000000
30
+ zold remote clean
31
+ zold remote add localhost ${second}
32
+
33
+ until zold fetch 0000000000000000 --ignore-score-weakness; do
34
+ echo 'Failed to fetch, let us try again'
35
+ ((i++)) || sleep 2
36
+ if ((i==5)); then
37
+ cat ${first}/log.txt
38
+ echo "The wallet has not been distributed, after ${i} attempts"
39
+ exit -1
40
+ fi
41
+ sleep 2
42
+ done
43
+
44
+ json=$(curl --silent --show-error http://localhost:${first})
45
+ if [ ! $(echo ${json} | jq -r '.entrance.queue') == "0" ]; then
46
+ echo "The queue is not empty after PUSH, it's a bug"
47
+ exit -1
48
+ fi
49
+ if [ ! $(echo ${json} | jq -r '.entrance.history_size') == "1" ]; then
50
+ echo "The history doesn't have a wallet, it's a bug"
51
+ exit -1
52
+ fi
53
+ if [ ! $(echo ${json} | jq -r '.wallets') == "1" ]; then
54
+ echo "The wallet is not there for some reason, it's a bug"
55
+ exit -1
56
+ fi
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -106,7 +108,7 @@ module Zold
106
108
  end
107
109
 
108
110
  def negative?
109
- @coins < 0
111
+ @coins.negative?
110
112
  end
111
113
 
112
114
  def *(other)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'slop'
2
4
  require 'rainbow'
3
5
  require_relative 'args'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -74,12 +76,12 @@ Available options:"
74
76
  strength = opts[:strength]
75
77
  raise "Invalid strength: #{strength}" if strength <= 0 || strength > 8
76
78
  score = Zold::Score.new(
77
- Time.parse(opts[:time]), opts[:host], opts[:port].to_i,
78
- opts[:invoice], strength: strength
79
+ time: Time.parse(opts[:time]), host: opts[:host], port: opts[:port].to_i,
80
+ invoice: opts[:invoice], strength: strength
79
81
  )
80
82
  loop do
81
83
  msg = score.to_s
82
- msg += (score.value > 0 ? ' ' + score.hash : '') unless opts['hide-hash']
84
+ msg += (score.value.positive? ? ' ' + score.hash : '') unless opts['hide-hash']
83
85
  msg += " #{(Time.now - mstart).round(2)}s" unless opts['hide-time']
84
86
  @log.info(msg)
85
87
  break if score.value >= opts[:max].to_i
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -55,6 +57,9 @@ Available options:"
55
57
  o.array '--ignore-node',
56
58
  'Ignore this node and don\'t fetch from it',
57
59
  default: []
60
+ o.bool '--quiet-if-absent',
61
+ 'Don\'t fail if the wallet is absent in all remote nodes',
62
+ default: false
58
63
  o.string '--network',
59
64
  'The name of the network we work in',
60
65
  default: 'test'
@@ -79,8 +84,8 @@ Available options:"
79
84
  done += 1
80
85
  end
81
86
  raise "There are no remote nodes, run 'zold remote reset'" if nodes.zero?
82
- raise "No nodes out of #{nodes} have the wallet #{id}" if done.zero?
83
- @log.info("#{nodes} copies of #{id} fetched for the total score of #{total}")
87
+ raise "No nodes out of #{nodes} have the wallet #{id}" if done.zero? && !opts['quiet-if-absent']
88
+ @log.info("#{done} copies of #{id} fetched for the total score of #{total} from #{nodes} nodes")
84
89
  @log.debug("#{cps.all.count} local copies:\n #{cps.all.map { |c| "#{c[:name]}: #{c[:score]}" }.join("\n ")}")
85
90
  end
86
91
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy