ptools 1.4.1-universal-mingw32 → 1.4.3-universal-mingw32

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: daf33ac7c6c26eb73262fde47054dfdee711c306995c67a7ead5dd7c64f41984
4
- data.tar.gz: 53af13a0aa13df74392375e21d91014d71c3c55b01f183faed53fee52332ceb8
3
+ metadata.gz: 62ddf1987bbb18bc423f29d935e20c777be8a4c7b8761868dea85e2b0dfd34b0
4
+ data.tar.gz: 0c159601c5f2c369c6dea2a5690c852f1bd4f2f2758a56a46bfe68aac5634558
5
5
  SHA512:
6
- metadata.gz: 302d30c2b116019561aeacc3c116697230456f2baa958e8dc22d2de69f2b453a3cbfd24353c07ce16f83ad781405a3559fb743d00d5ebdedf4a57697e90b4b60
7
- data.tar.gz: 2418dd67eaa224bf83fca03ccee8a7851a0434ac4ce7adc99620910e6dd454516e5a99c58661007134fa8d2aa446aace208bb014e50219c9fdf12cac8a24620f
6
+ metadata.gz: 8e555a0fb96caedb8f3dbc19d932aa4399ba21f711f0b7fc1cdddc585d0b6623fbb59a81f5ec204e44bafc3f0ebeea2138556cc2b2755042a82f8b9827c118a9
7
+ data.tar.gz: 6beaaabc8fe9dd953153adf0a0a03727584a9abd905c09b52b22d7881ff8eb30155b415e46375a64e750c9016cb2bb2fb04482f98bfa1e4dd59e5b4d2845a16b
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 1.4.3 - 26-Nov-2022
2
+ * Added more image specs.
3
+ * Updated the File.bmp? method. It now looks at the first six bytes, and
4
+ uses four of those bytes to verify the file size.
5
+
6
+ ## 1.4.2 - 6-Jan-2021
7
+ * Fixed a private access modifier that wasn't actually working as intended.
8
+ * Two Windows constants that were never meant for public consumption have been marked private.
9
+ * Minor tweak to one of the touch specs.
10
+ * The Gemfile now just uses the gemspec.
11
+ * The image? singleton method was effectively ignoring filename extensions. This
12
+ has been fixed, though with the option to disable that check if desired.
13
+
1
14
  ## 1.4.1 - 29-Dec-2020
2
15
  * Switch from rdoc to markdown since github is not rendering rdoc properly.
3
16
  * Added metadata to gemspec.
data/Gemfile CHANGED
@@ -1,12 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'structured_warnings'
4
-
5
- group :production do
6
- gem 'win32-file' if File::ALT_SEPARATOR
7
- end
8
-
9
- group :test do
10
- gem 'rake'
11
- gem 'rspec'
12
- end
3
+ gemspec
data/MANIFEST.md CHANGED
@@ -17,6 +17,7 @@
17
17
  * spec/wc_spec.rb
18
18
  * spec/whereis_spec.rb
19
19
  * spec/which_spec.rb
20
+ * spec/img/jpg_no_ext
20
21
  * spec/img/test.gif
21
22
  * spec/img/test.ico
22
23
  * spec/img/test.jpg
data/README.md CHANGED
@@ -1,13 +1,18 @@
1
+ [![Ruby](https://github.com/djberg96/ptools/actions/workflows/ruby.yml/badge.svg)](https://github.com/djberg96/ptools/actions/workflows/ruby.yml)
2
+
1
3
  ## Description
2
- The ptools (power tools) library is an additional set of commands for the
3
- File class based on Unix command line tools.
4
+ The ptools (power tools) library is an additional set of commands for the
5
+ File class based on Unix command line tools.
4
6
 
5
7
  ## Prerequisites
6
- On MS Windows you will need the win32-file gem.
8
+ On MS Windows you will need the win32-file gem.
7
9
 
8
10
  ## Installation
9
11
  `gem install ptools`
10
12
 
13
+ ## Adding the trusted cert
14
+ `gem cert --add <(curl -Ls https://raw.githubusercontent.com/djberg96/ptools/main/certs/djberg96_pub.pem)`
15
+
11
16
  ## Synopsis
12
17
  ```ruby
13
18
  require "ptools"
@@ -29,42 +34,42 @@ File.nl_convert("myfile", "newfile", "dos")
29
34
  ```
30
35
 
31
36
  ## Known Bugs
32
- The File.which and File.whereis methods may fail when using JRuby on Windows.
33
- See https://github.com/jruby/jruby/issues/2291 for details.
37
+ The File.which and File.whereis methods may fail when using JRuby on Windows.
38
+ See https://github.com/jruby/jruby/issues/2291 for details.
34
39
 
35
- Please report any other issues on the github project page.
40
+ Please report any other issues on the github project page.
36
41
 
37
- http://www.github.com/djberg96/ptools
42
+ http://www.github.com/djberg96/ptools
38
43
 
39
44
  ## Acknowledgements
40
- The File.which method was originally adopted from the FileWhich code posted
41
- by Michael Granger on the now defunct rubygarden.org website. That code was
42
- later replaced by a version based on the ruby-which library.
45
+ The `File.which` method was originally adopted from the `FileWhich` code posted
46
+ by Michael Granger on the now defunct rubygarden.org website. That code was
47
+ later replaced by a version based on the `ruby-which` library.
43
48
 
44
- The File.nl_convert method is based on the nlcvt program found at
45
- http://www.perl.com/language/ppt/src/nlcvt/nlcvt, written by Tom Christiansen.
49
+ The `File.nl_convert` method is based on the nlcvt program found at
50
+ http://www.perl.com/language/ppt/src/nlcvt/nlcvt, written by Tom Christiansen.
46
51
 
47
- The binary?() method was based almost entirely on a blog post by Ryan
48
- Davis (who, in turn, based his code on Perl's -B switch).
52
+ The `binary?` method was based almost entirely on a blog post by Ryan
53
+ Davis (who, in turn, based his code on Perl's -B switch).
49
54
 
50
- Thanks go to Matt Hoyle for help with the File.tail method.
55
+ Thanks go to Matt Hoyle for help with the File.tail method.
51
56
 
52
- And thanks to any and all contributors!
57
+ And thanks to any and all contributors!
53
58
 
54
59
  ## Future Plans
55
- Add whatever other tools people think might be useful.
60
+ Add whatever other tools people think might be useful.
56
61
 
57
62
  ## License
58
- Artistic-2.0
63
+ Artistic-2.0
59
64
 
60
65
  ## Copyright
61
- (C) 2003-2020 Daniel J. Berger
62
- All Rights Reserved.
66
+ (C) 2003-2022 Daniel J. Berger
67
+ All Rights Reserved.
63
68
 
64
69
  ## Warranty
65
- This package is provided "as is" and without any express or
66
- implied warranties, including, without limitation, the implied
67
- warranties of merchantability and fitness for a particular purpose.
70
+ This package is provided "as is" and without any express or
71
+ implied warranties, including, without limitation, the implied
72
+ warranties of merchantability and fitness for a particular purpose.
68
73
 
69
74
  ## Author
70
- Daniel J. Berger
75
+ Daniel J. Berger
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'rake/clean'
3
3
  require 'rake/testtask'
4
4
  require 'rbconfig'
5
5
  require 'rspec/core/rake_task'
6
+ require 'rubocop/rake_task'
6
7
  include RbConfig
7
8
 
8
9
  CLEAN.include("**/*.gem", "**/*.rbc", "**/*coverage*", "**/*.lock")
@@ -18,7 +19,7 @@ namespace 'gem' do
18
19
  desc 'Create the ptools gem'
19
20
  task :create => [:clean] do
20
21
  require 'rubygems/package'
21
- spec = eval(IO.read('ptools.gemspec'))
22
+ spec = Gem::Specification.load('ptools.gemspec')
22
23
  spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
23
24
  Gem::Package.build(spec)
24
25
  end
@@ -84,4 +85,6 @@ namespace 'spec' do
84
85
  end
85
86
  end
86
87
 
88
+ RuboCop::RakeTask.new
89
+
87
90
  task :default => 'spec:all'
data/lib/ptools.rb CHANGED
@@ -3,7 +3,7 @@ require 'win32/file' if File::ALT_SEPARATOR
3
3
 
4
4
  class File
5
5
  # The version of the ptools library.
6
- PTOOLS_VERSION = '1.4.1'.freeze
6
+ PTOOLS_VERSION = '1.4.3'.freeze
7
7
 
8
8
  # :stopdoc:
9
9
 
@@ -11,25 +11,34 @@ class File
11
11
  if File::ALT_SEPARATOR
12
12
  MSWINDOWS = true
13
13
  if ENV['PATHEXT']
14
- WIN32EXTS = ('.{' + ENV['PATHEXT'].tr(';', ',').tr('.','') + '}').downcase
14
+ WIN32EXTS = ".{#{ENV['PATHEXT'].tr(';', ',').tr('.', '')}}".downcase
15
15
  else
16
- WIN32EXTS = '.{exe,com,bat}'
16
+ WIN32EXTS = '.{exe,com,bat}'.freeze
17
17
  end
18
18
  else
19
19
  MSWINDOWS = false
20
20
  end
21
21
 
22
- IMAGE_EXT = %w[.bmp .gif .jpg .jpeg .png]
22
+ if File::ALT_SEPARATOR
23
+ private_constant :WIN32EXTS
24
+ private_constant :MSWINDOWS
25
+ end
26
+
27
+ IMAGE_EXT = %w[.bmp .gif .jpg .jpeg .png .ico].freeze
23
28
 
24
29
  # :startdoc:
25
30
 
26
31
  # Returns whether or not the file is an image. Only JPEG, PNG, BMP,
27
32
  # GIF, and ICO are checked against.
28
33
  #
29
- # This method does some simple read and extension checks. For a version
34
+ # This reads and checks the first few bytes of the file. For a version
30
35
  # that is more robust, but which depends on a 3rd party C library (and is
31
36
  # difficult to build on MS Windows), see the 'filemagic' library.
32
37
  #
38
+ # By default the filename extension is also checked. You can disable this
39
+ # by passing false as the second argument, in which case only the contents
40
+ # are checked.
41
+ #
33
42
  # Examples:
34
43
  #
35
44
  # File.image?('somefile.jpg') # => true
@@ -38,9 +47,11 @@ class File
38
47
  # The approach I used here is based on information found at
39
48
  # http://en.wikipedia.org/wiki/Magic_number_(programming)
40
49
  #
41
- def self.image?(file)
42
- bool = IMAGE_EXT.include?(File.extname(file).downcase)
50
+ def self.image?(file, check_file_extension: true)
43
51
  bool = bmp?(file) || jpg?(file) || png?(file) || gif?(file) || tiff?(file) || ico?(file)
52
+
53
+ bool &&= IMAGE_EXT.include?(File.extname(file).downcase) if check_file_extension
54
+
44
55
  bool
45
56
  end
46
57
 
@@ -65,11 +76,12 @@ class File
65
76
  return false if File.stat(file).zero?
66
77
  return false if image?(file)
67
78
  return false if check_bom?(file)
79
+
68
80
  bytes = File.stat(file).blksize
69
81
  bytes = 4096 if bytes > 4096
70
- s = (File.read(file, bytes) || "")
71
- s = s.encode('US-ASCII', :undef => :replace).split(//)
72
- ((s.size - s.grep(" ".."~").size) / s.size.to_f) > percentage
82
+ s = (File.read(file, bytes) || '')
83
+ s = s.encode('US-ASCII', :undef => :replace).chars
84
+ ((s.size - s.grep(' '..'~').size) / s.size.to_f) > percentage
73
85
  end
74
86
 
75
87
  # Looks for the first occurrence of +program+ within +path+.
@@ -85,10 +97,8 @@ class File
85
97
  # File.which('ruby') # => '/usr/local/bin/ruby'
86
98
  # File.which('foo') # => nil
87
99
  #
88
- def self.which(program, path=ENV['PATH'])
89
- if path.nil? || path.empty?
90
- raise ArgumentError, "path cannot be empty"
91
- end
100
+ def self.which(program, path = ENV['PATH'])
101
+ raise ArgumentError, 'path cannot be empty' if path.nil? || path.empty?
92
102
 
93
103
  # Bail out early if an absolute path is provided.
94
104
  if program =~ /^\/|^[a-z]:[\\\/]/i
@@ -102,16 +112,17 @@ class File
102
112
  end
103
113
 
104
114
  # Iterate over each path glob the dir + program.
105
- path.split(File::PATH_SEPARATOR).each{ |dir|
115
+ path.split(File::PATH_SEPARATOR).each do |dir|
106
116
  dir = File.expand_path(dir)
107
117
 
108
118
  next unless File.exist?(dir) # In case of bogus second argument
119
+
109
120
  file = File.join(dir, program)
110
121
 
111
122
  # Dir[] doesn't handle backslashes properly, so convert them. Also, if
112
123
  # the program name doesn't have an extension, try them all.
113
124
  if MSWINDOWS
114
- file = file.tr("\\", "/")
125
+ file = file.tr(File::ALT_SEPARATOR, File::SEPARATOR)
115
126
  file += WIN32EXTS if File.extname(program).empty?
116
127
  end
117
128
 
@@ -122,7 +133,7 @@ class File
122
133
  found.tr!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
123
134
  return found
124
135
  end
125
- }
136
+ end
126
137
 
127
138
  nil
128
139
  end
@@ -139,21 +150,19 @@ class File
139
150
  # File.whereis('ruby') # => ['/usr/bin/ruby', '/usr/local/bin/ruby']
140
151
  # File.whereis('foo') # => nil
141
152
  #
142
- def self.whereis(program, path=ENV['PATH'])
143
- if path.nil? || path.empty?
144
- raise ArgumentError, "path cannot be empty"
145
- end
153
+ def self.whereis(program, path = ENV['PATH'])
154
+ raise ArgumentError, 'path cannot be empty' if path.nil? || path.empty?
146
155
 
147
156
  paths = []
148
157
 
149
158
  # Bail out early if an absolute path is provided.
150
159
  if program =~ /^\/|^[a-z]:[\\\/]/i
151
160
  program += WIN32EXTS if MSWINDOWS && File.extname(program).empty?
152
- program = program.tr("\\", '/') if MSWINDOWS
161
+ program = program.tr(File::ALT_SEPARATOR, File::SEPARATOR) if MSWINDOWS
153
162
  found = Dir[program]
154
163
  if found[0] && File.executable?(found[0]) && !File.directory?(found[0])
155
164
  if File::ALT_SEPARATOR
156
- return found.map{ |f| f.tr('/', "\\") }
165
+ return found.map{ |f| f.tr(File::SEPARATOR, File::ALT_SEPARATOR) }
157
166
  else
158
167
  return found
159
168
  end
@@ -163,14 +172,15 @@ class File
163
172
  end
164
173
 
165
174
  # Iterate over each path glob the dir + program.
166
- path.split(File::PATH_SEPARATOR).each{ |dir|
175
+ path.split(File::PATH_SEPARATOR).each do |dir|
167
176
  next unless File.exist?(dir) # In case of bogus second argument
177
+
168
178
  file = File.join(dir, program)
169
179
 
170
180
  # Dir[] doesn't handle backslashes properly, so convert them. Also, if
171
181
  # the program name doesn't have an extension, try them all.
172
182
  if MSWINDOWS
173
- file = file.tr("\\", "/")
183
+ file = file.tr(File::ALT_SEPARATOR, File::SEPARATOR)
174
184
  file += WIN32EXTS if File.extname(program).empty?
175
185
  end
176
186
 
@@ -181,7 +191,7 @@ class File
181
191
  found.tr!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
182
192
  paths << found
183
193
  end
184
- }
194
+ end
185
195
 
186
196
  paths.empty? ? nil : paths.uniq
187
197
  end
@@ -197,20 +207,21 @@ class File
197
207
  # # Use a block
198
208
  # File.head('somefile.txt'){ |line| puts line }
199
209
  #
200
- def self.head(filename, num_lines=10)
210
+ def self.head(filename, num_lines = 10)
201
211
  a = []
202
212
 
203
- IO.foreach(filename){ |line|
213
+ File.foreach(filename) do |line|
204
214
  break if num_lines <= 0
215
+
205
216
  num_lines -= 1
206
217
  if block_given?
207
218
  yield line
208
219
  else
209
220
  a << line
210
221
  end
211
- }
222
+ end
212
223
 
213
- return a.empty? ? nil : a # Return nil in block form
224
+ a.empty? ? nil : a # Return nil in block form
214
225
  end
215
226
 
216
227
  # In block form, yields the last +num_lines+ of file +filename+.
@@ -227,7 +238,7 @@ class File
227
238
  # Internally I'm using a 64 chunk of memory at a time. I may allow the size
228
239
  # to be configured in the future as an optional 3rd argument.
229
240
  #
230
- def self.tail(filename, num_lines=10)
241
+ def self.tail(filename, num_lines = 10, &block)
231
242
  tail_size = 2**16 # 64k chunks
232
243
 
233
244
  # MS Windows gets unhappy if you try to seek backwards past the
@@ -241,7 +252,7 @@ class File
241
252
  buf = ''
242
253
 
243
254
  # Open in binary mode to ensure line endings aren't converted.
244
- File.open(filename, 'rb'){ |fh|
255
+ File.open(filename, 'rb') do |fh|
245
256
  position = file_size - read_bytes # Set the starting read position
246
257
 
247
258
  # Loop until we have the lines or run out of file
@@ -251,12 +262,12 @@ class File
251
262
  read_bytes = tail_size
252
263
  position -= read_bytes
253
264
  end
254
- }
265
+ end
255
266
 
256
267
  lines = buf.split(line_sep).pop(num_lines)
257
268
 
258
269
  if block_given?
259
- lines.each{ |line| yield line }
270
+ lines.each(&block)
260
271
  else
261
272
  lines
262
273
  end
@@ -277,47 +288,33 @@ class File
277
288
  # ArgumentError is raised.
278
289
  #
279
290
  def self.nl_convert(old_file, new_file = old_file, platform = 'local')
280
- unless File::Stat.new(old_file).file?
281
- raise ArgumentError, 'Only valid for plain text files'
282
- end
291
+ raise ArgumentError, 'Only valid for plain text files' unless File::Stat.new(old_file).file?
283
292
 
284
293
  format = nl_for_platform(platform)
285
294
 
286
- orig = $\ # $OUTPUT_RECORD_SEPARATOR
287
- $\ = format
288
-
289
295
  if old_file == new_file
290
- require 'fileutils'
291
296
  require 'tempfile'
297
+ temp_name = Time.new.strftime('%Y%m%d%H%M%S')
298
+ nf = Tempfile.new("ruby_temp_#{temp_name}")
299
+ else
300
+ nf = File.new(new_file, 'w')
301
+ end
292
302
 
293
- begin
294
- temp_name = Time.new.strftime("%Y%m%d%H%M%S")
295
- tf = Tempfile.new('ruby_temp_' + temp_name)
296
- tf.open
297
-
298
- IO.foreach(old_file){ |line|
299
- line.chomp!
300
- tf.print line
301
- }
302
- ensure
303
- tf.close if tf && !tf.closed?
303
+ begin
304
+ nf.open if old_file == new_file
305
+ File.foreach(old_file) do |line|
306
+ line.chomp!
307
+ nf.print("#{line}#{format}")
304
308
  end
305
-
306
- File.delete(old_file)
307
- FileUtils.mv(tf.path, old_file)
308
- else
309
- begin
310
- nf = File.new(new_file, 'w')
311
- IO.foreach(old_file){ |line|
312
- line.chomp!
313
- nf.print line
314
- }
315
- ensure
316
- nf.close if nf && !nf.closed?
309
+ ensure
310
+ nf.close if nf && !nf.closed?
311
+ if old_file == new_file
312
+ require 'fileutils'
313
+ File.delete(old_file)
314
+ FileUtils.mv(nf.path, old_file)
317
315
  end
318
316
  end
319
317
 
320
- $\ = orig
321
318
  self
322
319
  end
323
320
 
@@ -340,49 +337,43 @@ class File
340
337
  # Valid options are 'bytes', 'characters' (or just 'chars'), 'words' and
341
338
  # 'lines'.
342
339
  #
343
- def self.wc(filename, option='all')
340
+ def self.wc(filename, option = 'all')
344
341
  option.downcase!
345
- valid = %w/all bytes characters chars lines words/
342
+ valid = %w[all bytes characters chars lines words]
346
343
 
347
- unless valid.include?(option)
348
- raise ArgumentError, "Invalid option: '#{option}'"
349
- end
344
+ raise ArgumentError, "Invalid option: '#{option}'" unless valid.include?(option)
350
345
 
351
346
  n = 0
352
347
 
353
348
  if option == 'lines'
354
- IO.foreach(filename){ n += 1 }
355
- return n
349
+ File.foreach(filename){ n += 1 }
350
+ n
356
351
  elsif option == 'bytes'
357
- File.open(filename){ |f|
352
+ File.open(filename) do |f|
358
353
  f.each_byte{ n += 1 }
359
- }
360
- return n
361
- elsif option == 'characters' || option == 'chars'
362
- File.open(filename){ |f|
363
- while f.getc
364
- n += 1
365
- end
366
- }
367
- return n
354
+ end
355
+ n
356
+ elsif %w[characters chars].include?(option)
357
+ File.open(filename) do |f|
358
+ n += 1 while f.getc
359
+ end
360
+ n
368
361
  elsif option == 'words'
369
- IO.foreach(filename){ |line|
362
+ File.foreach(filename) do |line|
370
363
  n += line.split.length
371
- }
372
- return n
364
+ end
365
+ n
373
366
  else
374
- bytes,chars,lines,words = 0,0,0,0
375
- IO.foreach(filename){ |line|
367
+ bytes, chars, lines, words = 0, 0, 0, 0
368
+ File.foreach(filename) do |line|
376
369
  lines += 1
377
370
  words += line.split.length
378
- chars += line.split('').length
379
- }
380
- File.open(filename){ |f|
381
- while f.getc
382
- bytes += 1
383
- end
384
- }
385
- return [bytes,chars,words,lines]
371
+ chars += line.chars.length
372
+ end
373
+ File.open(filename) do |f|
374
+ bytes += 1 while f.getc
375
+ end
376
+ [bytes, chars, words, lines]
386
377
  end
387
378
  end
388
379
 
@@ -402,8 +393,6 @@ class File
402
393
  end
403
394
  end
404
395
 
405
- private
406
-
407
396
  # Returns whether or not the given +text+ contains a BOM marker.
408
397
  # If present, we can generally assume it's a text file.
409
398
  #
@@ -411,66 +400,77 @@ class File
411
400
  text = File.read(file, 4).force_encoding('utf-8')
412
401
 
413
402
  bool = false
414
- bool = true if text[0,3] == "\xEF\xBB\xBF"
415
- bool = true if text[0,4] == "\x00\x00\xFE\xFF" || text[0,4] == "\xFF\xFE\x00\x00"
416
- bool = true if text[0,2] == "\xFF\xFE" || text[0,2] == "\xFE\xFF"
403
+ bool = true if text[0, 3] == "\xEF\xBB\xBF"
404
+ bool = true if text[0, 4] == "\x00\x00\xFE\xFF" || text[0, 4] == "\xFF\xFE\x00\x00"
405
+ bool = true if text[0, 2] == "\xFF\xFE" || text[0, 2] == "\xFE\xFF"
417
406
 
418
407
  bool
419
408
  end
420
409
 
410
+ private_class_method :check_bom?
411
+
412
+ # Returns the newline characters for the given platform.
413
+ #
421
414
  def self.nl_for_platform(platform)
422
- platform = RbConfig::CONFIG["host_os"] if platform == 'local'
415
+ platform = RbConfig::CONFIG['host_os'] if platform == 'local'
423
416
 
424
417
  case platform
425
418
  when /dos|windows|win32|mswin|mingw/i
426
- return "\cM\cJ"
419
+ "\cM\cJ"
427
420
  when /unix|linux|bsd|cygwin|osx|darwin|solaris|sunos/i
428
- return "\cJ"
421
+ "\cJ"
429
422
  when /mac|apple|macintosh/i
430
- return "\cM"
423
+ "\cM"
431
424
  else
432
- raise ArgumentError, "Invalid platform string"
425
+ raise ArgumentError, 'Invalid platform string'
433
426
  end
434
427
  end
435
428
 
429
+ # Is the file a bitmap file?
430
+ #
436
431
  def self.bmp?(file)
437
- IO.read(file, 3) == "BM6"
432
+ data = File.read(file, 6, nil, :encoding => 'binary')
433
+ data[0,2] == 'BM' && File.size(file) == data[2,4].unpack('i').first
438
434
  end
439
435
 
436
+ # Is the file a jpeg file?
437
+ #
440
438
  def self.jpg?(file)
441
- IO.read(file, 10, nil, :encoding => 'binary') == "\377\330\377\340\000\020JFIF".force_encoding(Encoding::BINARY)
439
+ File.read(file, 10, nil, :encoding => 'binary') == "\377\330\377\340\000\020JFIF".force_encoding(Encoding::BINARY)
442
440
  end
443
441
 
442
+ # Is the file a png file?
443
+ #
444
444
  def self.png?(file)
445
- IO.read(file, 4, nil, :encoding => 'binary') == "\211PNG".force_encoding(Encoding::BINARY)
445
+ File.read(file, 4, nil, :encoding => 'binary') == "\211PNG".force_encoding(Encoding::BINARY)
446
446
  end
447
447
 
448
+ # Is the file a gif?
449
+ #
448
450
  def self.gif?(file)
449
- ['GIF89a', 'GIF97a'].include?(IO.read(file, 6))
451
+ %w[GIF89a GIF97a].include?(File.read(file, 6))
450
452
  end
451
453
 
454
+ # Is the file a tiff?
455
+ #
452
456
  def self.tiff?(file)
453
457
  return false if File.size(file) < 12
454
458
 
455
- bytes = IO.read(file, 4)
459
+ bytes = File.read(file, 4)
456
460
 
457
461
  # II is Intel, MM is Motorola
458
- if bytes[0..1] != 'II' && bytes[0..1] != 'MM'
459
- return false
460
- end
462
+ return false if bytes[0..1] != 'II' && bytes[0..1] != 'MM'
461
463
 
462
- if bytes[0..1] == 'II' && bytes[2..3].ord != 42
463
- return false
464
- end
464
+ return false if bytes[0..1] == 'II' && bytes[2..3].ord != 42
465
465
 
466
- if bytes[0..1] == 'MM' && bytes[2..3].reverse.ord != 42
467
- return false
468
- end
466
+ return false if bytes[0..1] == 'MM' && bytes[2..3].reverse.ord != 42
469
467
 
470
468
  true
471
469
  end
472
470
 
471
+ # Is the file an ico file?
472
+ #
473
473
  def self.ico?(file)
474
- ["\000\000\001\000", "\000\000\002\000"].include?(IO.read(file, 4, nil, :encoding => 'binary'))
474
+ ["\000\000\001\000", "\000\000\002\000"].include?(File.read(file, 4, nil, :encoding => 'binary'))
475
475
  end
476
476
  end
data/ptools.gemspec CHANGED
@@ -2,7 +2,7 @@ require 'rbconfig'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'ptools'
5
- spec.version = '1.4.1'
5
+ spec.version = '1.4.3'
6
6
  spec.license = 'Artistic-2.0'
7
7
  spec.author = 'Daniel J. Berger'
8
8
  spec.email = 'djberg96@gmail.com'
@@ -19,16 +19,19 @@ Gem::Specification.new do |spec|
19
19
  EOF
20
20
 
21
21
  spec.metadata = {
22
- 'homepage_uri' => 'https://github.com/djberg96/ptools',
23
- 'bug_tracker_uri' => 'https://github.com/djberg96/ptools/issues',
24
- 'changelog_uri' => 'https://github.com/djberg96/ptools/blob/master/CHANGES.md',
25
- 'documentation_uri' => 'https://github.com/djberg96/ptools/wiki',
26
- 'source_code_uri' => 'https://github.com/djberg96/ptools',
27
- 'wiki_uri' => 'https://github.com/djberg96/ptools/wiki'
22
+ 'homepage_uri' => 'https://github.com/djberg96/ptools',
23
+ 'bug_tracker_uri' => 'https://github.com/djberg96/ptools/issues',
24
+ 'changelog_uri' => 'https://github.com/djberg96/ptools/blob/main/CHANGES.md',
25
+ 'documentation_uri' => 'https://github.com/djberg96/ptools/wiki',
26
+ 'source_code_uri' => 'https://github.com/djberg96/ptools',
27
+ 'wiki_uri' => 'https://github.com/djberg96/ptools/wiki',
28
+ 'rubygems_mfa_required' => 'true'
28
29
  }
29
30
 
30
31
  spec.add_development_dependency('rake')
31
32
  spec.add_development_dependency('rspec', '~> 3.9')
33
+ spec.add_development_dependency('rubocop')
34
+ spec.add_development_dependency('rubocop-rspec')
32
35
 
33
36
  if File::ALT_SEPARATOR
34
37
  spec.platform = Gem::Platform.new(['universal', 'mingw32'])