tty-screen 0.7.1 → 0.8.0

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: ef837a96a0b6f7282a40e712920b73ffba5c9946899d13c0f1a9a74395b7c6fc
4
- data.tar.gz: 3b58bc3f356329e71aeaf495e7b4dd0cfbe3390bd205d94791cc689abb224111
3
+ metadata.gz: 4e17bafe91486f49afff31f04968d8515502eb3065f3739a796f987bd0ffed96
4
+ data.tar.gz: 80112f9584cfc84a1c76eeeff88e08cac08853714c4d6e179aa92ad753bb9175
5
5
  SHA512:
6
- metadata.gz: 5611619549f9eae4c34152768a263f999eb466106e36604ecc34c73934491f896942446efd31aa8e0229292738ad8feb9d7d7f8fd6d023c39267e9acdd26609f
7
- data.tar.gz: 2a1129f3aa1c066271028c2da550aba4d267174b5e2354a6276a6c0a66acf926e83ba7cc89324cc842afaacdbd6036d6976815f644d6d0eb3a95c72fbed5c4e8
6
+ metadata.gz: c3a00a8c1cfa355c988f7999fdd2d3bd49b903cf7be4d3446cb50e8fa5bc8c17b96b9a6be7f329299ba0f6eb58a54744c2a64ccec9d9a3255498c02bbb37d876
7
+ data.tar.gz: 73a02084a05564198f93fc5bc09b1db6d2eb90d426fbc0ce0d93f965b487c240d5a5c303f651c8afacc6b688c0e0780a1bc0953c0d39fca534432d8aca8eaf44
@@ -1,5 +1,25 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.8.0] - 2020-05-28
4
+
5
+ ### Added
6
+ * Add #windows? platform check
7
+ * Add #command_exist? to see if an executable exists before running it
8
+ * Add performance tests
9
+
10
+ ### Changed
11
+ * Change #jruby? method to hoist within module
12
+ * Change #size_from_win_api to check only on windows platform and
13
+ hoist definition within module
14
+ * Change #size_from_java to hoist within module
15
+ * Change #size_from_ioctl to:
16
+ * check solaris-like system
17
+ * scan all streams to see if any attached to a terminal
18
+ * hoist definition within module
19
+ * Change #size_from_io_console to perform check on JRuby as well
20
+ * Change #size_from_readline to attempt to load readline gem
21
+ * Change #run_command to execute command directly without sub shell or temp files
22
+
3
23
  ## [v0.7.1] - 2020-02-02
4
24
 
5
25
  ### Changed
@@ -111,6 +131,7 @@
111
131
  ### Fixed
112
132
  * Fix bug with screen detection from_io_console by @luxflux
113
133
 
134
+ [v0.8.0]: https://github.com/piotrmurach/tty-screen/compare/v0.7.1...v0.8.0
114
135
  [v0.7.1]: https://github.com/piotrmurach/tty-screen/compare/v0.7.0...v0.7.1
115
136
  [v0.7.0]: https://github.com/piotrmurach/tty-screen/compare/v0.6.5...v0.7.0
116
137
  [v0.6.5]: https://github.com/piotrmurach/tty-screen/compare/v0.6.4...v0.6.5
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://cdn.rawgit.com/piotrmurach/tty/master/images/tty.png" alt="tty logo" /></a>
2
+ <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="tty logo" /></a>
3
3
  </div>
4
4
 
5
5
  # TTY::Screen [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
@@ -19,7 +19,7 @@
19
19
  [coverage]: https://coveralls.io/r/piotrmurach/tty-screen
20
20
  [inchpages]: http://inch-ci.org/github/piotrmurach/tty-screen
21
21
 
22
- > Terminal screen size detection which works on Linux, OS X and Windows/Cygwin platforms and supports MRI, JRuby and Rubinius interpreters.
22
+ > Terminal screen size detection which works on Linux, OS X and Windows/Cygwin platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
23
23
 
24
24
  **TTY::Screen** provides independent terminal screen size detection component for [TTY](https://github.com/piotrmurach/tty) toolkit.
25
25
 
@@ -1,6 +1,11 @@
1
- # fronzen_string_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
- require_relative 'screen/version'
3
+ begin
4
+ require "rbconfig"
5
+ rescue LoadError
6
+ end
7
+
8
+ require_relative "screen/version"
4
9
 
5
10
  module TTY
6
11
  # Used for detecting screen properties
@@ -13,6 +18,22 @@ module TTY
13
18
  private_class_method(name)
14
19
  end
15
20
 
21
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG["host_os"] : ::RUBY_PLATFORM)
22
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
23
+ def windows?; true end
24
+ else
25
+ def windows?; false end
26
+ end
27
+ module_function :windows?
28
+
29
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG["ruby_install_name"] : ::RUBY_ENGINE)
30
+ when /jruby/
31
+ def jruby?; true end
32
+ else
33
+ def jruby?; false end
34
+ end
35
+ module_function :jruby?
36
+
16
37
  # Default terminal size
17
38
  #
18
39
  # @api public
@@ -22,10 +43,11 @@ module TTY
22
43
  @output = $stderr
23
44
 
24
45
  class << self
46
+ # Holds the environment variables
47
+ # @api public
25
48
  attr_accessor :env
26
49
 
27
50
  # Specifies an output stream
28
- #
29
51
  # @api public
30
52
  attr_accessor :output
31
53
  end
@@ -33,20 +55,20 @@ module TTY
33
55
  # Get terminal rows and columns
34
56
  #
35
57
  # @return [Array[Integer, Integer]]
36
- # return rows & columns
58
+ # return rows and columns
37
59
  #
38
60
  # @api public
39
- def size
40
- size = size_from_java
41
- size ||= size_from_win_api
42
- size ||= size_from_ioctl
43
- size ||= size_from_io_console
44
- size ||= size_from_readline
45
- size ||= size_from_tput
46
- size ||= size_from_stty
47
- size ||= size_from_env
48
- size ||= size_from_ansicon
49
- size || DEFAULT_SIZE
61
+ def size(verbose: false)
62
+ size_from_java(verbose: verbose) ||
63
+ size_from_win_api(verbose: verbose) ||
64
+ size_from_ioctl ||
65
+ size_from_io_console(verbose: verbose) ||
66
+ size_from_readline(verbose: verbose) ||
67
+ size_from_tput ||
68
+ size_from_stty ||
69
+ size_from_env ||
70
+ size_from_ansicon ||
71
+ size_from_default
50
72
  end
51
73
  module_function :size
52
74
 
@@ -70,35 +92,49 @@ module TTY
70
92
  module_function :rows
71
93
  module_function :lines
72
94
 
73
- STDOUT_HANDLE = 0xFFFFFFF5
95
+ # Default size for the terminal
96
+ #
97
+ # @return [Array[Integer, Integer]]
98
+ #
99
+ # @api private
100
+ def size_from_default
101
+ DEFAULT_SIZE
102
+ end
103
+ module_function :size_from_default
74
104
 
75
105
  # Determine terminal size with a Windows native API
76
106
  #
77
107
  # @return [nil, Array[Integer, Integer]]
78
108
  #
79
109
  # @api private
80
- def size_from_win_api(verbose: nil)
81
- require 'fiddle'
82
-
83
- kernel32 = Fiddle::Handle.new('kernel32')
84
- get_std_handle = Fiddle::Function.new(kernel32['GetStdHandle'],
85
- [-Fiddle::TYPE_INT], Fiddle::TYPE_INT)
86
- get_console_buffer_info = Fiddle::Function.new(
87
- kernel32['GetConsoleScreenBufferInfo'],
88
- [Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
89
-
90
- format = 'SSSSSssssSS'
91
- buffer = ([0] * format.size).pack(format)
92
- stdout_handle = get_std_handle.(STDOUT_HANDLE)
93
-
94
- get_console_buffer_info.(stdout_handle, buffer)
95
- _, _, _, _, _, left, top, right, bottom, = buffer.unpack(format)
96
- size = [bottom - top + 1, right - left + 1]
97
- return size if nonzero_column?(size[1] - 1)
98
- rescue LoadError
99
- warn 'no native fiddle module found' if verbose
100
- rescue Fiddle::DLError
101
- # non windows platform or no kernel32 lib
110
+ if windows?
111
+ STDOUT_HANDLE = 0xFFFFFFF5
112
+
113
+ def size_from_win_api(verbose: false)
114
+ require "fiddle" unless defined?(Fiddle)
115
+
116
+ kernel32 = Fiddle::Handle.new("kernel32")
117
+ get_std_handle = Fiddle::Function.new(kernel32["GetStdHandle"],
118
+ [-Fiddle::TYPE_INT], Fiddle::TYPE_INT)
119
+ get_console_buffer_info = Fiddle::Function.new(
120
+ kernel32["GetConsoleScreenBufferInfo"],
121
+ [Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
122
+
123
+ format = "SSSSSssssSS"
124
+ buffer = ([0] * format.size).pack(format)
125
+ stdout_handle = get_std_handle.(STDOUT_HANDLE)
126
+
127
+ get_console_buffer_info.(stdout_handle, buffer)
128
+ _, _, _, _, _, left, top, right, bottom, = buffer.unpack(format)
129
+ size = [bottom - top + 1, right - left + 1]
130
+ return size if nonzero_column?(size[1] - 1)
131
+ rescue LoadError
132
+ warn "no native fiddle module found" if verbose
133
+ rescue Fiddle::DLError
134
+ # non windows platform or no kernel32 lib
135
+ end
136
+ else
137
+ def size_from_win_api(verbose: false); nil end
102
138
  end
103
139
  module_function :size_from_win_api
104
140
 
@@ -107,15 +143,19 @@ module TTY
107
143
  # @return [nil, Array[Integer, Integer]]
108
144
  #
109
145
  # @api private
110
- def size_from_java(verbose: nil)
111
- return unless jruby?
112
- require 'java'
113
- java_import 'jline.TerminalFactory'
114
- terminal = TerminalFactory.get
115
- size = [terminal.get_height, terminal.get_width]
116
- return size if nonzero_column?(size[1])
117
- rescue
118
- warn 'failed to import java terminal package' if verbose
146
+ if jruby?
147
+ def size_from_java(verbose: false)
148
+ require "java"
149
+
150
+ java_import "jline.TerminalFactory"
151
+ terminal = TerminalFactory.get
152
+ size = [terminal.get_height, terminal.get_width]
153
+ return size if nonzero_column?(size[1])
154
+ rescue
155
+ warn "failed to import java terminal package" if verbose
156
+ end
157
+ else
158
+ def size_from_java(verbose: false); nil end
119
159
  end
120
160
  module_function :size_from_java
121
161
 
@@ -128,62 +168,75 @@ module TTY
128
168
  # @return [nil, Array[Integer, Integer]]
129
169
  #
130
170
  # @api private
131
- def size_from_io_console(verbose: nil)
132
- return if jruby?
133
- require 'io/console'
134
-
135
- begin
136
- if @output.tty? && IO.method_defined?(:winsize)
137
- size = @output.winsize
138
- size if nonzero_column?(size[1])
139
- end
140
- rescue Errno::EOPNOTSUPP
141
- # no support for winsize on output
142
- end
171
+ def size_from_io_console(verbose: false)
172
+ require "io/console" unless IO.method_defined?(:winsize)
173
+
174
+ return unless @output.tty? && @output.respond_to?(:winsize)
175
+
176
+ size = @output.winsize
177
+ size if nonzero_column?(size[1])
178
+ rescue Errno::EOPNOTSUPP
179
+ # no support for winsize on output
143
180
  rescue LoadError
144
- warn 'no native io/console support or io-console gem' if verbose
181
+ warn "no native io/console support or io-console gem" if verbose
145
182
  end
146
183
  module_function :size_from_io_console
147
184
 
148
- TIOCGWINSZ = 0x5413
149
- TIOCGWINSZ_PPC = 0x40087468
185
+ if !jruby? && @output.respond_to?(:ioctl)
186
+ TIOCGWINSZ = 0x5413 # linux
187
+ TIOCGWINSZ_PPC = 0x40087468 # macos, freedbsd, netbsd, openbsd
188
+ TIOCGWINSZ_SOL = 0x5468 # solaris
150
189
 
151
- # Read terminal size from Unix ioctl
152
- #
153
- # @return [nil, Array[Integer, Integer]]
154
- #
155
- # @api private
156
- def size_from_ioctl
157
- return if jruby?
158
- return unless @output.respond_to?(:ioctl)
159
-
160
- format = 'SSSS'
161
- buffer = ([0] * format.size).pack(format)
162
- if ioctl?(TIOCGWINSZ, buffer) || ioctl?(TIOCGWINSZ_PPC, buffer)
163
- rows, cols, = buffer.unpack(format)[0..1]
164
- return [rows, cols] if nonzero_column?(cols)
190
+ # Read terminal size from Unix ioctl
191
+ #
192
+ # @return [nil, Array[Integer, Integer]]
193
+ #
194
+ # @api private
195
+ def size_from_ioctl
196
+ format = "SSSS"
197
+ buffer = ([0] * format.size).pack(format)
198
+
199
+ if ioctl?(TIOCGWINSZ, buffer) ||
200
+ ioctl?(TIOCGWINSZ_PPC, buffer) ||
201
+ ioctl?(TIOCGWINSZ_SOL, buffer)
202
+
203
+ rows, cols, = buffer.unpack(format)[0..1]
204
+ return [rows, cols] if nonzero_column?(cols)
205
+ end
165
206
  end
166
- end
167
- module_function :size_from_ioctl
168
207
 
169
- # Check if ioctl can be called and the device is attached to terminal
170
- #
171
- # @api private
172
- def ioctl?(control, buf)
173
- @output.ioctl(control, buf) >= 0
174
- rescue SystemCallError
175
- false
208
+ # Check if ioctl can be called and any of the streams is
209
+ # attached to a terminal.
210
+ #
211
+ # @return [Boolean]
212
+ # True if any of the streams is attached to a terminal, false otherwise.
213
+ #
214
+ # @api private
215
+ def ioctl?(control, buf)
216
+ ($stdout.ioctl(control, buf) >= 0) ||
217
+ ($stdin.ioctl(control, buf) >= 0) ||
218
+ ($stderr.ioctl(control, buf) >= 0)
219
+ rescue SystemCallError
220
+ false
221
+ end
222
+ module_function :ioctl?
223
+ else
224
+ def size_from_ioctl; nil end
176
225
  end
177
- module_function :ioctl?
226
+ module_function :size_from_ioctl
178
227
 
179
228
  # Detect screen size using Readline
180
229
  #
181
230
  # @api private
182
- def size_from_readline
183
- if defined?(Readline) && Readline.respond_to?(:get_screen_size)
184
- size = Readline.get_screen_size
185
- size if nonzero_column?(size[1])
186
- end
231
+ def size_from_readline(verbose: false)
232
+ require "readline" unless defined?(::Readline)
233
+
234
+ return unless ::Readline.respond_to?(:get_screen_size)
235
+
236
+ size = ::Readline.get_screen_size
237
+ size if nonzero_column?(size[1])
238
+ rescue LoadError
239
+ warn "no readline gem" if verbose
187
240
  rescue NotImplementedError
188
241
  end
189
242
  module_function :size_from_readline
@@ -192,11 +245,13 @@ module TTY
192
245
  #
193
246
  # @api private
194
247
  def size_from_tput
195
- return unless @output.tty?
196
- lines = run_command('tput', 'lines').to_i
197
- cols = run_command('tput', 'cols').to_i
198
- [lines, cols] if nonzero_column?(lines)
199
- rescue IOError, SystemCallError
248
+ return unless @output.tty? && command_exist?("tput")
249
+
250
+ lines = run_command("tput", "lines")
251
+ return unless lines
252
+
253
+ cols = run_command("tput", "cols")
254
+ [lines.to_i, cols.to_i] if nonzero_column?(lines)
200
255
  end
201
256
  module_function :size_from_tput
202
257
 
@@ -204,12 +259,13 @@ module TTY
204
259
  #
205
260
  # @api private
206
261
  def size_from_stty
207
- return unless @output.tty?
208
- out = run_command('stty', 'size')
262
+ return unless @output.tty? && command_exist?("stty")
263
+
264
+ out = run_command("stty", "size")
209
265
  return unless out
266
+
210
267
  size = out.split.map(&:to_i)
211
268
  size if nonzero_column?(size[1])
212
- rescue IOError, SystemCallError
213
269
  end
214
270
  module_function :size_from_stty
215
271
 
@@ -224,8 +280,9 @@ module TTY
224
280
  #
225
281
  # @api private
226
282
  def size_from_env
227
- return unless @env['COLUMNS'] =~ /^\d+$/
228
- size = [(@env['LINES'] || @env['ROWS']).to_i, @env['COLUMNS'].to_i]
283
+ return unless @env["COLUMNS"] =~ /^\d+$/
284
+
285
+ size = [(@env["LINES"] || @env["ROWS"]).to_i, @env["COLUMNS"].to_i]
229
286
  size if nonzero_column?(size[1])
230
287
  end
231
288
  module_function :size_from_env
@@ -234,24 +291,34 @@ module TTY
234
291
  #
235
292
  # @api private
236
293
  def size_from_ansicon
237
- return unless @env['ANSICON'] =~ /\((.*)x(.*)\)/
294
+ return unless @env["ANSICON"] =~ /\((.*)x(.*)\)/
295
+
238
296
  size = [$2, $1].map(&:to_i)
239
297
  size if nonzero_column?(size[1])
240
298
  end
241
299
  module_function :size_from_ansicon
242
300
 
301
+ # Check if command exists
302
+ #
303
+ # @return [Boolean]
304
+ #
305
+ # @api private
306
+ def command_exist?(command)
307
+ exts = env.fetch("PATHEXT", "").split(::File::PATH_SEPARATOR)
308
+ env.fetch("PATH", "").split(File::PATH_SEPARATOR).any? do |dir|
309
+ file = ::File.join(dir, command)
310
+ ::File.exist?(file) || exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
311
+ end
312
+ end
313
+ private_module_function :command_exist?
314
+
243
315
  # Runs command silently capturing the output
244
316
  #
245
317
  # @api private
246
318
  def run_command(*args)
247
- require 'tempfile'
248
- out = Tempfile.new('tty-screen')
249
- result = system(*args, out: out.path, err: File::NULL)
250
- return if result.nil?
251
- out.rewind
252
- out.read
253
- ensure
254
- out.close if out
319
+ %x(#{args.join(" ")})
320
+ rescue IOError, SystemCallError
321
+ nil
255
322
  end
256
323
  private_module_function :run_command
257
324
 
@@ -264,10 +331,5 @@ module TTY
264
331
  column.to_i > 0
265
332
  end
266
333
  private_module_function :nonzero_column?
267
-
268
- def jruby?
269
- RbConfig::CONFIG['ruby_install_name'] == 'jruby'
270
- end
271
- private_module_function :jruby?
272
334
  end # Screen
273
335
  end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  module Screen
5
- VERSION = "0.7.1"
5
+ VERSION = "0.8.0"
6
6
  end # Screen
7
7
  end # TTY
metadata CHANGED
@@ -1,17 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-screen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-02 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
13
41
  description: Terminal screen size detection which works on Linux, OS X and Windows/Cygwin
14
- platforms and supports MRI, JRuby and Rubinius interpreters.
42
+ platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
15
43
  email:
16
44
  - piotr@piotrmurach.com
17
45
  executables: []
@@ -19,6 +47,7 @@ extensions: []
19
47
  extra_rdoc_files:
20
48
  - README.md
21
49
  - CHANGELOG.md
50
+ - LICENSE.txt
22
51
  files:
23
52
  - CHANGELOG.md
24
53
  - LICENSE.txt
@@ -55,5 +84,5 @@ rubygems_version: 3.1.2
55
84
  signing_key:
56
85
  specification_version: 4
57
86
  summary: Terminal screen size detection which works on Linux, OS X and Windows/Cygwin
58
- platforms and supports MRI, JRuby and Rubinius interpreters.
87
+ platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
59
88
  test_files: []