tty-screen 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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: []