random-port 0.7.6 → 0.8.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19a3b6d51277760ad0638f741ef63bf1fbc8a4b77663b41569da4c34e251353a
4
- data.tar.gz: 96e0c4061b43248cbf091e318b9e6645371a7fd11189a43cd1cadccf23b9704d
3
+ metadata.gz: 2c6250d7a7a9a68ca737b299b7cef6b4816e35a6fe9452b78633c2df1132bd41
4
+ data.tar.gz: 9ec96d9ae9ce5e2f58c4bd3821f24877cfbc7a88913005d21a32c90d8f465b77
5
5
  SHA512:
6
- metadata.gz: 6ac6711969efbcd97a534391cff9b3bb3e4244a5fe0a4518d7cbb3644a6b849507db8025af1491fac615c1aa9f3edf4db7d7bd9e42faf5619304191c1265afa0
7
- data.tar.gz: f01a9a30993fcc100fd5946290a8f8b60d94cb8a19db6ab8b918527ca48086f92cff89723391d99302f79fc264ed9f4d76a2225bfdfa24819e3af51ec8971396
6
+ metadata.gz: da1f7e7b9daeaf7a60fd935cbc8b0c578a352c558683a85f7c6d66c4a7ef391586a02b389107516c270d2a38215979aa8f4f6cdba5b70f7f128515cc21058a8c
7
+ data.tar.gz: bf6db1f8503993e5388b4cb48909f2684a0618eb26e4f5bc5677fe92b248c67a22e11f9ad8e9f5405223718d7f7287dc51ea50ffe47def18b6b8561ea3dab582
data/Gemfile CHANGED
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  source 'https://rubygems.org'
7
7
  gemspec
8
8
 
9
- gem 'minitest', '~>5.25', require: false
9
+ gem 'minitest', '~>6.0', require: false
10
+ gem 'minitest-mock', '~>5.27', require: false
11
+ gem 'minitest-reporters', '~>1.7', require: false
12
+ gem 'os', '~> 1.1', require: false
10
13
  gem 'qbash', '~>0.2', require: false
11
14
  gem 'rake', '~>13.2', require: false
12
15
  gem 'rubocop', '~>1.75', require: false
@@ -15,5 +18,6 @@ gem 'rubocop-performance', '~>1.25', require: false
15
18
  gem 'rubocop-rake', '~>0.7', require: false
16
19
  gem 'rubocop-rspec', '~> 3.7', require: false
17
20
  gem 'simplecov', '~>0.22', require: false
21
+ gem 'simplecov-cobertura', '~>3.0', require: false
18
22
  gem 'threads', '~>0.4', require: false
19
23
  gem 'yard', '~>0.9', require: false
data/Gemfile.lock CHANGED
@@ -7,35 +7,48 @@ PATH
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ ansi (1.5.0)
10
11
  ast (2.4.3)
11
12
  backtrace (0.4.1)
12
- concurrent-ruby (1.3.5)
13
+ builder (3.3.0)
14
+ concurrent-ruby (1.3.6)
13
15
  docile (1.4.1)
14
- elapsed (0.2.0)
16
+ elapsed (0.3.1)
15
17
  loog (~> 0.6)
16
18
  tago (~> 0.1)
17
- json (2.15.0)
19
+ ellipsized (0.3.0)
20
+ json (2.18.1)
18
21
  language_server-protocol (3.17.0.5)
19
22
  lint_roller (1.1.0)
20
23
  logger (1.7.0)
21
- loog (0.6.1)
24
+ loog (0.8.0)
25
+ ellipsized
22
26
  logger (~> 1.0)
23
- minitest (5.25.5)
27
+ minitest (6.0.1)
28
+ prism (~> 1.5)
29
+ minitest-mock (5.27.0)
30
+ minitest-reporters (1.7.1)
31
+ ansi
32
+ builder
33
+ minitest (>= 5.0)
34
+ ruby-progressbar
35
+ os (1.1.4)
24
36
  parallel (1.27.0)
25
- parser (3.3.9.0)
37
+ parser (3.3.10.1)
26
38
  ast (~> 2.4.1)
27
39
  racc
28
- prism (1.5.1)
29
- qbash (0.4.5)
40
+ prism (1.9.0)
41
+ qbash (0.7.2)
30
42
  backtrace (> 0)
31
43
  elapsed (> 0)
32
44
  loog (> 0)
33
45
  tago (> 0)
34
46
  racc (1.8.1)
35
47
  rainbow (3.1.1)
36
- rake (13.3.0)
48
+ rake (13.3.1)
37
49
  regexp_parser (2.11.3)
38
- rubocop (1.80.2)
50
+ rexml (3.4.4)
51
+ rubocop (1.84.1)
39
52
  json (~> 2.3)
40
53
  language_server-protocol (~> 3.17.0.2)
41
54
  lint_roller (~> 1.1.0)
@@ -43,41 +56,44 @@ GEM
43
56
  parser (>= 3.3.0.2)
44
57
  rainbow (>= 2.2.2, < 4.0)
45
58
  regexp_parser (>= 2.9.3, < 3.0)
46
- rubocop-ast (>= 1.46.0, < 2.0)
59
+ rubocop-ast (>= 1.49.0, < 2.0)
47
60
  ruby-progressbar (~> 1.7)
48
61
  unicode-display_width (>= 2.4.0, < 4.0)
49
- rubocop-ast (1.47.1)
62
+ rubocop-ast (1.49.0)
50
63
  parser (>= 3.3.7.2)
51
- prism (~> 1.4)
64
+ prism (~> 1.7)
52
65
  rubocop-minitest (0.38.2)
53
66
  lint_roller (~> 1.1)
54
67
  rubocop (>= 1.75.0, < 2.0)
55
68
  rubocop-ast (>= 1.38.0, < 2.0)
56
- rubocop-performance (1.26.0)
69
+ rubocop-performance (1.26.1)
57
70
  lint_roller (~> 1.1)
58
71
  rubocop (>= 1.75.0, < 2.0)
59
- rubocop-ast (>= 1.44.0, < 2.0)
72
+ rubocop-ast (>= 1.47.1, < 2.0)
60
73
  rubocop-rake (0.7.1)
61
74
  lint_roller (~> 1.1)
62
75
  rubocop (>= 1.72.1)
63
- rubocop-rspec (3.7.0)
76
+ rubocop-rspec (3.9.0)
64
77
  lint_roller (~> 1.1)
65
- rubocop (~> 1.72, >= 1.72.1)
78
+ rubocop (~> 1.81)
66
79
  ruby-progressbar (1.13.0)
67
80
  simplecov (0.22.0)
68
81
  docile (~> 1.1)
69
82
  simplecov-html (~> 0.11)
70
83
  simplecov_json_formatter (~> 0.1)
84
+ simplecov-cobertura (3.1.0)
85
+ rexml
86
+ simplecov (~> 0.19)
71
87
  simplecov-html (0.13.2)
72
88
  simplecov_json_formatter (0.1.4)
73
- tago (0.2.0)
74
- threads (0.4.1)
89
+ tago (0.7.0)
90
+ threads (0.5.0)
75
91
  backtrace (~> 0)
76
92
  concurrent-ruby (~> 1.0)
77
93
  unicode-display_width (3.2.0)
78
94
  unicode-emoji (~> 4.1)
79
- unicode-emoji (4.1.0)
80
- yard (0.9.37)
95
+ unicode-emoji (4.2.0)
96
+ yard (0.9.38)
81
97
 
82
98
  PLATFORMS
83
99
  arm64-darwin-22
@@ -87,7 +103,10 @@ PLATFORMS
87
103
  x86_64-linux
88
104
 
89
105
  DEPENDENCIES
90
- minitest (~> 5.25)
106
+ minitest (~> 6.0)
107
+ minitest-mock (~> 5.27)
108
+ minitest-reporters (~> 1.7)
109
+ os (~> 1.1)
91
110
  qbash (~> 0.2)
92
111
  rake (~> 13.2)
93
112
  random-port!
@@ -97,6 +116,7 @@ DEPENDENCIES
97
116
  rubocop-rake (~> 0.7)
98
117
  rubocop-rspec (~> 3.7)
99
118
  simplecov (~> 0.22)
119
+ simplecov-cobertura (~> 3.0)
100
120
  threads (~> 0.4)
101
121
  yard (~> 0.9)
102
122
 
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2018-2025 Yegor Bugayenko
3
+ Copyright (c) 2018-2026 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/LICENSES/MIT.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2018-2025 Yegor Bugayenko
3
+ Copyright (c) 2018-2026 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/README.md CHANGED
@@ -5,11 +5,10 @@
5
5
 
6
6
  [![rake](https://github.com/yegor256/random-port/actions/workflows/rake.yml/badge.svg)](https://github.com/yegor256/random-port/actions/workflows/rake.yml)
7
7
  [![Gem Version](https://badge.fury.io/rb/random-port.svg)](https://badge.fury.io/rb/random-port)
8
- [![Maintainability](https://api.codeclimate.com/v1/badges/349b8c31884d3b34d926/maintainability)](https://codeclimate.com/github/yegor256/random-port/maintainability)
9
8
  [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://rubydoc.info/github/yegor256/random-port/master/frames)
10
9
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/random-port/blob/master/LICENSE.txt)
11
10
  [![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/random-port.svg)](https://codecov.io/github/yegor256/random-port?branch=master)
12
- [![Hits-of-Code](https://hitsofcode.com/github/yegor256/random-port)](https://hitsofcode.com/view/github/random-port/mailanes)
11
+ [![Hits-of-Code](https://hitsofcode.com/github/yegor256/random-port)](https://hitsofcode.com/view/github/yegor256/random-port)
13
12
 
14
13
  It's a simple Ruby gem to get a random TCP port.
15
14
 
@@ -52,6 +51,15 @@ RandomPort::Pool::SINGLETON.acquire do |port|
52
51
  end
53
52
  ```
54
53
 
54
+ Or use shortened version, all methods called in `RandomPort`
55
+ will be delegated to `Pool::SINGLETON`:
56
+
57
+ ```ruby
58
+ RandomPort.acquire do |port|
59
+ # Use it here...
60
+ end
61
+ ```
62
+
55
63
  The pool is thread-safe by default.
56
64
  You can configure it to be
57
65
  not-thread-safe, using optional `sync` argument of the constructor.
@@ -62,7 +70,7 @@ Read
62
70
  [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html).
63
71
  Make sure your build is green before you contribute
64
72
  your pull request. You will need to have
65
- [Ruby](https://www.ruby-lang.org/en/) 2.3+ and
73
+ [Ruby](https://www.ruby-lang.org/en/) 3.3+ and
66
74
  [Bundler](https://bundler.io/) installed. Then:
67
75
 
68
76
  ```bash
data/Rakefile CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'os'
7
+ require 'qbash'
6
8
  require 'rubygems'
7
9
  require 'rake'
8
10
  require 'rake/clean'
11
+ require 'shellwords'
9
12
 
10
13
  CLEAN << 'coverage'
11
14
 
@@ -17,7 +20,7 @@ def version
17
20
  Gem::Specification.load(Dir['*.gemspec'].first).version
18
21
  end
19
22
 
20
- task default: %i[clean test yard rubocop]
23
+ task default: %i[clean test picks yard rubocop]
21
24
 
22
25
  require 'rake/testtask'
23
26
  desc 'Run all unit tests'
@@ -27,6 +30,16 @@ Rake::TestTask.new(:test) do |test|
27
30
  test.verbose = false
28
31
  end
29
32
 
33
+ desc 'Run them via Ruby, one by one'
34
+ task :picks do
35
+ next if OS.windows?
36
+ %w[test lib].each do |d|
37
+ Dir["#{d}/**/*.rb"].each do |f|
38
+ qbash("bundle exec ruby #{Shellwords.escape(f)}", stdout: $stdout, env: { 'PICKS' => 'yes' })
39
+ end
40
+ end
41
+ end
42
+
30
43
  require 'rubocop/rake_task'
31
44
  desc 'Run RuboCop on all directories'
32
45
  RuboCop::RakeTask.new(:rubocop) do |task|
@@ -37,4 +50,5 @@ require 'yard'
37
50
  desc 'Build Yard documentation'
38
51
  YARD::Rake::YardocTask.new do |t|
39
52
  t.files = ['lib/**/*.rb']
53
+ t.options = ['--fail-on-warning']
40
54
  end
@@ -1,12 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
- # The module for all classes.
6
+ require 'forwardable'
7
+
8
+ # Main module that contains all RandomPort classes and utilities.
9
+ #
10
+ # This module provides a simple way to acquire random TCP ports
11
+ # that are guaranteed to be available for use. It includes a Pool
12
+ # class that manages port allocation and ensures thread safety.
7
13
  #
8
14
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
9
- # Copyright:: Copyright (c) 2018-2025 Yegor Bugayenko
15
+ # Copyright:: Copyright (c) 2018-2026 Yegor Bugayenko
10
16
  # License:: MIT
11
17
  module RandomPort
18
+ extend Forwardable
19
+
20
+ def_delegators :'RandomPort::Pool::SINGLETON', :acquire, :release, :count, :size, :empty?
21
+ module_function :acquire, :release, :count, :size, :empty?
12
22
  end
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'minitest/mock'
6
7
  require 'monitor'
7
8
  require 'socket'
8
9
  require 'tago'
9
10
  require_relative 'module'
10
11
 
11
- # Pool of TPC ports.
12
+ # Pool of TCP ports.
12
13
  #
13
14
  # Use it like this:
14
15
  #
@@ -17,26 +18,27 @@ require_relative 'module'
17
18
  # # to the pool afterwards.
18
19
  # end
19
20
  #
20
- # You can specify the maximum amount of ports to acquire, using +limit+.
21
- # If more acquiring requests will arrive, an exception will be raised.
21
+ # You can specify the maximum number of ports to acquire using +limit+.
22
+ # If more acquisition requests arrive, an exception will be raised.
22
23
  #
23
- # The class is thread-safe, by default. You can configure it to be
24
- # not-thread-safe, using optional +sync+ argument of the constructor,
24
+ # The class is thread-safe by default. You can configure it to be
25
+ # non-thread-safe using the optional +sync+ argument of the constructor,
25
26
  # passing <tt>FALSE</tt>.
26
27
  #
27
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
- # Copyright:: Copyright (c) 2018-2025 Yegor Bugayenko
29
+ # Copyright:: Copyright (c) 2018-2026 Yegor Bugayenko
29
30
  # License:: MIT
30
31
  class RandomPort::Pool
31
- # If can't acquire by time out.
32
+ # Raised when a port cannot be acquired within the timeout period.
32
33
  class Timeout < StandardError; end
33
34
 
35
+ # @return [Integer] The maximum number of ports that can be acquired from this pool
34
36
  attr_reader :limit
35
37
 
36
- # Ctor.
37
- # @param [Boolean] sync Set it to FALSE if you want this pool to be NOT thread-safe
38
- # @param [Integer] limit Set the maximum number of ports in the pool
39
- # @param [Integer] start The next port to try
38
+ # Constructor.
39
+ # @param [Boolean] sync Set to FALSE if you want this pool to be non-thread-safe
40
+ # @param [Integer] limit The maximum number of ports that can be acquired from the pool
41
+ # @param [Integer] start The first port number to try when acquiring
40
42
  def initialize(sync: true, limit: 65_536, start: 1025)
41
43
  @ports = []
42
44
  @sync = sync
@@ -45,27 +47,33 @@ class RandomPort::Pool
45
47
  @next = start
46
48
  end
47
49
 
48
- # Application wide pool of ports
50
+ # Application-wide singleton pool of ports.
49
51
  SINGLETON = RandomPort::Pool.new
50
52
 
51
- # How many ports acquired now?
53
+ # Returns the number of ports currently acquired from the pool.
54
+ # @return [Integer] The count of acquired ports
52
55
  def count
53
56
  @ports.count
54
57
  end
55
58
  alias size count
56
59
 
57
- # Is it empty?
60
+ # Checks if the pool is empty (no ports are currently acquired).
61
+ # @return [Boolean] TRUE if no ports are acquired, FALSE otherwise
58
62
  def empty?
59
63
  @ports.empty?
60
64
  end
61
65
 
62
- # Acquire a new random TCP port.
66
+ # Acquires one or more available TCP ports from the pool.
63
67
  #
64
68
  # You can specify the number of ports to acquire. If it's more than one,
65
- # an array will be returned.
69
+ # an array will be returned. If a block is given, the port(s) will be
70
+ # automatically released after the block execution.
66
71
  #
67
- # You can specify the amount of seconds to wait until a new port
68
- # is available.
72
+ # @param [Integer] total The number of ports to acquire (default: 1)
73
+ # @param [Integer] timeout The maximum seconds to wait for port availability
74
+ # @yield [Integer|Array<Integer>] The acquired port(s)
75
+ # @return [Integer|Array<Integer>] The acquired port(s) if no block given
76
+ # @raise [Timeout] If ports cannot be acquired within the timeout period
69
77
  def acquire(total = 1, timeout: 4)
70
78
  start = Time.now
71
79
  attempt = 0
@@ -77,7 +85,7 @@ class RandomPort::Pool
77
85
  "(#{@ports.size} already occupied) " \
78
86
  "for #{total} port(s), after #{attempt} attempts in #{start.ago}"
79
87
  end
80
- attempt += 1
88
+ attempt += 1
81
89
  opts = safe { group(total) }
82
90
  if opts.nil?
83
91
  @next += 1
@@ -96,9 +104,9 @@ class RandomPort::Pool
96
104
  end
97
105
  end
98
106
 
99
- # Return it/them back to the pool.
100
- # @param [Integer] port TCP port number to release
101
- # @return nil
107
+ # Releases one or more ports back to the pool.
108
+ # @param [Integer|Array<Integer>] port The TCP port number(s) to release
109
+ # @return [nil]
102
110
  def release(port)
103
111
  safe do
104
112
  if port.is_a?(Array)
@@ -111,12 +119,12 @@ class RandomPort::Pool
111
119
 
112
120
  private
113
121
 
114
- # Take a group of ports, if possible.
115
- # @param [Integer] total How many ports to take
116
- # @return [Array<Integer>|nil] Ports found or NIL if impossible now
122
+ # Attempts to acquire a contiguous group of ports.
123
+ # @param [Integer] total The number of ports to acquire
124
+ # @return [Array<Integer>|nil] An array of port numbers if successful, nil otherwise
117
125
  def group(total)
118
126
  return nil if @ports.count + total > @limit
119
- opts = Array.new(0, total)
127
+ opts = Array.new(total, 0)
120
128
  begin
121
129
  (0..(total - 1)).each do |i|
122
130
  port = i.zero? ? @next : opts[i - 1] + 1
@@ -127,31 +135,35 @@ class RandomPort::Pool
127
135
  end
128
136
  return nil if opts.any? { |p| @ports.include?(p) }
129
137
  d = total * (total - 1) / 2
130
- return nil unless opts.inject(&:+) - (total * opts.min) == d
138
+ return nil unless opts.sum - (total * opts.min) == d
131
139
  @ports += opts
132
140
  opts
133
141
  end
134
142
 
135
- # Find one possible TCP port or raise exception if this port can't be used.
143
+ # Verifies that a specific TCP port is available for use.
136
144
  #
137
- # If port is occupied, this method raises an error (+Errno::EADDRINUSE+).
145
+ # Attempts to bind to the port on various interfaces to ensure availability.
146
+ # If the port is occupied, this method raises an error (+Errno::EADDRINUSE+).
138
147
  #
139
- # @param [Integer] port Suggested port number
140
- # @return [Integer] The same port number
148
+ # @param [Integer] port The port number to verify
149
+ # @return [Integer] The same port number if available
150
+ # @raise [Errno::EADDRINUSE] If the port is already in use
151
+ # @raise [SocketError] If there's a socket-related error
141
152
  def take(port)
142
153
  ['127.0.0.1', '::1', '0.0.0.0', 'localhost'].each do |host|
143
- begin
144
- TCPServer.new(host, port).close
145
- rescue Errno::EADDRNOTAVAIL
146
- next
147
- end
154
+ TCPServer.new(host, port).close
155
+ rescue Errno::EADDRNOTAVAIL
156
+ next
148
157
  end
149
158
  port
150
159
  end
151
160
 
152
- def safe(&block)
161
+ # Executes a block of code with or without thread synchronization.
162
+ # @yield The block of code to execute
163
+ # @return The result of the block execution
164
+ def safe(&)
153
165
  if @sync
154
- @monitor.synchronize(&block)
166
+ @monitor.synchronize(&)
155
167
  else
156
168
  yield
157
169
  end
data/lib/random-port.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative 'random-port/module'
data/random-port.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2018-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2018-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'English'
7
7
  Gem::Specification.new do |s|
8
8
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
9
- s.required_ruby_version = '>=2.3'
9
+ s.required_ruby_version = '>=3.3'
10
10
  s.name = 'random-port'
11
- s.version = '0.7.6'
11
+ s.version = '0.8.1'
12
12
  s.license = 'MIT'
13
13
  s.summary = 'Random TCP port'
14
14
  s.description = 'Reserves a random TCP port'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: random-port
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -54,7 +54,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: '2.3'
57
+ version: '3.3'
58
58
  required_rubygems_version: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - ">="