zold 0.14.8 → 0.14.9

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 (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