ptools 1.5.0 → 1.5.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: 59d3894b0714ef0f4a355c42a93c358269507bf5de5762965b632ee1631a2de9
4
- data.tar.gz: 3650a31388b4207a99dc0145e599825c05fc9e412199c127f68133b8f98b4b1b
3
+ metadata.gz: 36d688bdf86ee95a0f1f6d422f75825903fc8ed26d821a69d617134d146a25e3
4
+ data.tar.gz: 574b230aff9a5b095f59cdbb6f1d7b65bc78b27970d4cc2ecc25a1fd67ecbaf0
5
5
  SHA512:
6
- metadata.gz: 50097a799553a489ee29cc183f4c89473a827b63c1c3b668e4b2f4b4128099c0b494b24967e2f870717a8cfe3d65e43316cb0fc5b1f78255108db1ac933d0e16
7
- data.tar.gz: 1e664973f17ec8b8c55515ffb1e6a8e24be2d3485203bccd5de9e812012fb5c6567a9d1ece397c9d62fbfb1f5fd8ff53dfcd5964c67ebb9670521494da9febe7
6
+ metadata.gz: 7a6ede88a24e97f927f6dcc81e9887a0d2b260013fe8e14931796489ec35723d9276651ddcd6ebd6d88cad32f65e0f1298234a0626af95b3b3c0ee157cc1c70a
7
+ data.tar.gz: 4bab6fdf21c8d7f0c3bae158319bb5b2131125d0d757e2d0c24b0d430345b7b7162bcf4b70e44d481c7d7c46aae7b3ead9545f4ad920038023511aa1190dc30d
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.5.1 - 27-Nov-2025
2
+ * Refactoring release.
3
+ * The wc('all') method now only does a single read instead of a double read.
4
+ * The nl_convert method simplified to use the block form of File.open.
5
+ * More consistent binary encoding calls.
6
+ * Some magic numbers were replaced with constants.
7
+ * Specs run in documentation mode.
8
+
1
9
  ## 1.5.0 - 5-Dec-2022
2
10
  * Change license to Apache-2.0.
3
11
  * Altered the File.binary? method. It no longer accepts a second argument,
data/Rakefile CHANGED
@@ -82,6 +82,7 @@ namespace 'spec' do
82
82
 
83
83
  RSpec::Core::RakeTask.new(:all) do |t|
84
84
  t.pattern = 'spec/*_spec.rb'
85
+ t.rspec_opts = '-f documentation'
85
86
  end
86
87
  end
87
88
 
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.5.0'.freeze
6
+ PTOOLS_VERSION = '1.5.1'.freeze
7
7
 
8
8
  # :stopdoc:
9
9
 
@@ -11,7 +11,7 @@ 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 = String.new(".{#{ENV['PATHEXT'].tr(';', ',').tr('.', '')}}").downcase
15
15
  else
16
16
  WIN32EXTS = '.{exe,com,bat}'.freeze
17
17
  end
@@ -26,6 +26,10 @@ class File
26
26
 
27
27
  IMAGE_EXT = %w[.bmp .gif .jpg .jpeg .png .ico].freeze
28
28
 
29
+ # Constants for file operations
30
+ BLOCK_SIZE = 512
31
+ TAIL_CHUNK_SIZE = 2**16 # 64k chunks
32
+
29
33
  # :startdoc:
30
34
 
31
35
  # Returns whether or not the file is an image. Only JPEG, PNG, BMP,
@@ -90,7 +94,7 @@ class File
90
94
  # File.which('ruby') # => '/usr/local/bin/ruby'
91
95
  # File.which('foo') # => nil
92
96
  #
93
- def self.which(program, path = ENV['PATH'])
97
+ def self.which(program, path = ENV.fetch('PATH', nil))
94
98
  raise ArgumentError, 'path cannot be empty' if path.nil? || path.empty?
95
99
 
96
100
  # Bail out early if an absolute path is provided.
@@ -143,7 +147,7 @@ class File
143
147
  # File.whereis('ruby') # => ['/usr/bin/ruby', '/usr/local/bin/ruby']
144
148
  # File.whereis('foo') # => nil
145
149
  #
146
- def self.whereis(program, path = ENV['PATH'])
150
+ def self.whereis(program, path = ENV.fetch('PATH', nil))
147
151
  raise ArgumentError, 'path cannot be empty' if path.nil? || path.empty?
148
152
 
149
153
  paths = []
@@ -232,13 +236,11 @@ class File
232
236
  # to be configured in the future as an optional 3rd argument.
233
237
  #
234
238
  def self.tail(filename, num_lines = 10, &block)
235
- tail_size = 2**16 # 64k chunks
236
-
237
239
  # MS Windows gets unhappy if you try to seek backwards past the
238
240
  # end of the file, so we have some extra checks here and later.
239
241
  file_size = File.size(filename)
240
- read_bytes = file_size % tail_size
241
- read_bytes = tail_size if read_bytes == 0
242
+ read_bytes = file_size % TAIL_CHUNK_SIZE
243
+ read_bytes = TAIL_CHUNK_SIZE if read_bytes == 0
242
244
 
243
245
  line_sep = File::ALT_SEPARATOR ? "\r\n" : "\n"
244
246
 
@@ -252,7 +254,7 @@ class File
252
254
  while buf.scan(line_sep).size <= num_lines and position >= 0
253
255
  fh.seek(position, IO::SEEK_SET)
254
256
  buf = fh.read(read_bytes) + buf
255
- read_bytes = tail_size
257
+ read_bytes = TAIL_CHUNK_SIZE
256
258
  position -= read_bytes
257
259
  end
258
260
  end
@@ -288,24 +290,23 @@ class File
288
290
  if old_file == new_file
289
291
  require 'tempfile'
290
292
  temp_name = Time.new.strftime('%Y%m%d%H%M%S')
291
- nf = Tempfile.new("ruby_temp_#{temp_name}")
292
- else
293
- nf = File.new(new_file, 'w')
294
- end
295
-
296
- begin
297
- nf.open if old_file == new_file
298
- File.foreach(old_file) do |line|
299
- line.chomp!
300
- nf.print("#{line}#{format}")
301
- end
302
- ensure
303
- nf.close if nf && !nf.closed?
304
- if old_file == new_file
293
+ Tempfile.open("ruby_temp_#{temp_name}") do |nf|
294
+ File.foreach(old_file) do |line|
295
+ line.chomp!
296
+ nf.print("#{line}#{format}")
297
+ end
298
+ nf.close
305
299
  require 'fileutils'
306
300
  File.delete(old_file)
307
301
  FileUtils.mv(nf.path, old_file)
308
302
  end
303
+ else
304
+ File.open(new_file, 'w') do |nf|
305
+ File.foreach(old_file) do |line|
306
+ line.chomp!
307
+ nf.print("#{line}#{format}")
308
+ end
309
+ end
309
310
  end
310
311
 
311
312
  self
@@ -358,13 +359,13 @@ class File
358
359
  n
359
360
  else
360
361
  bytes, chars, lines, words = 0, 0, 0, 0
361
- File.foreach(filename) do |line|
362
- lines += 1
363
- words += line.split.length
364
- chars += line.chars.length
365
- end
366
362
  File.open(filename) do |f|
367
- bytes += 1 while f.getc
363
+ while (line = f.gets)
364
+ lines += 1
365
+ words += line.split.length
366
+ chars += line.chars.length
367
+ bytes += line.bytesize
368
+ end
368
369
  end
369
370
  [bytes, chars, words, lines]
370
371
  end
@@ -382,7 +383,7 @@ class File
382
383
  #
383
384
  def self.sparse?(file)
384
385
  stats = File.stat(file)
385
- stats.size > stats.blocks * 512
386
+ stats.size > stats.blocks * BLOCK_SIZE
386
387
  end
387
388
  end
388
389
 
@@ -423,25 +424,25 @@ class File
423
424
  #
424
425
  def self.bmp?(file)
425
426
  data = File.read(file, 6, nil, :encoding => 'binary')
426
- data[0,2] == 'BM' && File.size(file) == data[2,4].unpack('i').first
427
+ data[0, 2] == 'BM' && File.size(file) == data[2, 4].unpack1('i')
427
428
  end
428
429
 
429
430
  # Is the file a jpeg file?
430
431
  #
431
432
  def self.jpg?(file)
432
- File.read(file, 10, nil, :encoding => 'binary') == "\377\330\377\340\000\020JFIF".force_encoding(Encoding::BINARY)
433
+ File.read(file, 10, nil, :encoding => 'binary') == "\xFF\xD8\xFF\xE0\x00\x10JFIF".force_encoding(Encoding::BINARY)
433
434
  end
434
435
 
435
436
  # Is the file a png file?
436
437
  #
437
438
  def self.png?(file)
438
- File.read(file, 4, nil, :encoding => 'binary') == "\211PNG".force_encoding(Encoding::BINARY)
439
+ File.read(file, 4, nil, :encoding => 'binary') == "\x89PNG".force_encoding(Encoding::BINARY)
439
440
  end
440
441
 
441
442
  # Is the file a gif?
442
443
  #
443
444
  def self.gif?(file)
444
- %w[GIF89a GIF97a].include?(File.read(file, 6))
445
+ %w[GIF89a GIF97a].include?(File.read(file, 6, nil, :encoding => 'binary'))
445
446
  end
446
447
 
447
448
  # Is the file a tiff?
@@ -449,7 +450,7 @@ class File
449
450
  def self.tiff?(file)
450
451
  return false if File.size(file) < 12
451
452
 
452
- bytes = File.read(file, 4)
453
+ bytes = File.read(file, 4, nil, :encoding => 'binary')
453
454
 
454
455
  # II is Intel, MM is Motorola
455
456
  return false if bytes[0..1] != 'II' && bytes[0..1] != 'MM'
@@ -464,6 +465,6 @@ class File
464
465
  # Is the file an ico file?
465
466
  #
466
467
  def self.ico?(file)
467
- ["\000\000\001\000", "\000\000\002\000"].include?(File.read(file, 4, nil, :encoding => 'binary'))
468
+ ["\x00\x00\x01\x00".force_encoding(Encoding::BINARY), "\x00\x00\x02\x00".force_encoding(Encoding::BINARY)].include?(File.read(file, 4, nil, :encoding => 'binary'))
468
469
  end
469
470
  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.5.0'
5
+ spec.version = '1.5.1'
6
6
  spec.license = 'Apache-2.0'
7
7
  spec.author = 'Daniel J. Berger'
8
8
  spec.email = 'djberg96@gmail.com'
@@ -25,7 +25,9 @@ Gem::Specification.new do |spec|
25
25
  'documentation_uri' => 'https://github.com/djberg96/ptools/wiki',
26
26
  'source_code_uri' => 'https://github.com/djberg96/ptools',
27
27
  'wiki_uri' => 'https://github.com/djberg96/ptools/wiki',
28
- 'rubygems_mfa_required' => 'true'
28
+ 'rubygems_mfa_required' => 'true',
29
+ 'github_repo' => 'https://github.com/djberg96/ptools',
30
+ 'funding_uri' => 'https://github.com/sponsors/djberg96'
29
31
  }
30
32
 
31
33
  spec.add_development_dependency('rake')
data/spec/binary_spec.rb CHANGED
@@ -10,7 +10,7 @@ require 'ptools'
10
10
 
11
11
  RSpec.describe File, :binary do
12
12
  let(:dirname) { described_class.dirname(__FILE__) }
13
- let(:bin_file) { File::ALT_SEPARATOR ? described_class.join(ENV['windir'], 'notepad.exe') : '/bin/ls' }
13
+ let(:bin_file) { File::ALT_SEPARATOR ? described_class.join(ENV.fetch('windir', nil), 'notepad.exe') : '/bin/ls' }
14
14
 
15
15
  before do
16
16
  @txt_file = described_class.join(dirname, 'txt', 'english.txt')
@@ -13,7 +13,7 @@ RSpec.describe File, :constants do
13
13
  let(:windows) { File::ALT_SEPARATOR }
14
14
 
15
15
  example 'PTOOLS_VERSION constant is set to expected value' do
16
- expect(File::PTOOLS_VERSION).to eq('1.5.0')
16
+ expect(File::PTOOLS_VERSION).to eq('1.5.1')
17
17
  expect(File::PTOOLS_VERSION.frozen?).to be true
18
18
  end
19
19
 
data/spec/head_spec.rb CHANGED
@@ -29,7 +29,7 @@ RSpec.describe File, :head do
29
29
  end
30
30
 
31
31
  example 'head method returns the expected results' do
32
- expect(described_class.head(test_file)).to be_kind_of(Array)
32
+ expect(described_class.head(test_file)).to be_a(Array)
33
33
  expect(described_class.head(test_file)).to eq(@expected_head1)
34
34
  expect(described_class.head(test_file, 5)).to eq(@expected_head2)
35
35
  end
data/spec/tail_spec.rb CHANGED
@@ -74,7 +74,7 @@ RSpec.describe File, :tail do
74
74
  end
75
75
 
76
76
  example 'tail returns the expected values' do
77
- expect(described_class.tail(test_file1)).to be_kind_of(Array)
77
+ expect(described_class.tail(test_file1)).to be_a(Array)
78
78
  expect(described_class.tail(test_file1)).to eq(@expected_tail1)
79
79
  expect(described_class.tail(test_file1, 5)).to eq(@expected_tail2)
80
80
  end
data/spec/wc_spec.rb CHANGED
@@ -35,7 +35,7 @@ RSpec.describe File, :wc do
35
35
  end
36
36
 
37
37
  example 'wc with no option returns expected results' do
38
- expect(described_class.wc(test_file)).to be_kind_of(Array)
38
+ expect(described_class.wc(test_file)).to be_a(Array)
39
39
  expect(described_class.wc(test_file)).to eq([166, 166, 25, 25])
40
40
  end
41
41
 
data/spec/whereis_spec.rb CHANGED
@@ -34,7 +34,7 @@ RSpec.describe File, :whereis do
34
34
  example 'whereis basic functionality' do
35
35
  expect(described_class).to respond_to(:whereis)
36
36
  expect{ described_class.whereis('ruby') }.not_to raise_error
37
- expect(described_class.whereis('ruby')).to be_kind_of(Array).or be_nil
37
+ expect(described_class.whereis('ruby')).to be_a(Array).or be_nil
38
38
  end
39
39
 
40
40
  example 'whereis accepts an optional second argument' do
@@ -43,7 +43,7 @@ RSpec.describe File, :whereis do
43
43
 
44
44
  example 'whereis returns expected values' do
45
45
  expect{ @actual_locs = described_class.whereis(ruby) }.not_to raise_error
46
- expect(@actual_locs).to be_kind_of(Array)
46
+ expect(@actual_locs).to be_a(Array)
47
47
  expect((@expected_locs & @actual_locs).size > 0).to be true
48
48
  end
49
49
 
data/spec/which_spec.rb CHANGED
@@ -18,8 +18,8 @@ describe File, :which do
18
18
 
19
19
  Dir.mkdir(@dir) unless described_class.exist?(@dir)
20
20
  FileUtils.touch(@non_exe)
21
- described_class.chmod(775, @dir)
22
- described_class.chmod(644, @non_exe)
21
+ described_class.chmod(0775, @dir)
22
+ described_class.chmod(0644, @non_exe)
23
23
 
24
24
  @exe = described_class.join(
25
25
  RbConfig::CONFIG['bindir'],
@@ -40,7 +40,7 @@ describe File, :which do
40
40
  example 'which method basic functionality' do
41
41
  expect(described_class).to respond_to(:which)
42
42
  expect{ described_class.which(@ruby) }.not_to raise_error
43
- expect(described_class.which(@ruby)).to be_kind_of(String)
43
+ expect(described_class.which(@ruby)).to be_a(String)
44
44
  end
45
45
 
46
46
  example 'which accepts an optional path to search' do
@@ -92,10 +92,10 @@ describe File, :which do
92
92
  end
93
93
 
94
94
  example 'resolves with with ~', :unix_only => true do
95
- old_home = ENV['HOME']
95
+ old_home = Dir.home
96
96
  ENV['HOME'] = Dir::Tmpname.tmpdir
97
97
  program = Tempfile.new(['program', '.sh'])
98
- described_class.chmod(755, program.path)
98
+ described_class.chmod(0755, program.path)
99
99
 
100
100
  expect(described_class.which(described_class.basename(program.path), '~/')).not_to be_nil
101
101
  ensure
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,11 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ptools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain:
11
10
  - |
@@ -35,7 +34,7 @@ cert_chain:
35
34
  ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
36
35
  WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
37
36
  -----END CERTIFICATE-----
38
- date: 2022-12-05 00:00:00.000000000 Z
37
+ date: 1980-01-02 00:00:00.000000000 Z
39
38
  dependencies:
40
39
  - !ruby/object:Gem::Dependency
41
40
  name: rake
@@ -145,7 +144,8 @@ metadata:
145
144
  source_code_uri: https://github.com/djberg96/ptools
146
145
  wiki_uri: https://github.com/djberg96/ptools/wiki
147
146
  rubygems_mfa_required: 'true'
148
- post_install_message:
147
+ github_repo: https://github.com/djberg96/ptools
148
+ funding_uri: https://github.com/sponsors/djberg96
149
149
  rdoc_options: []
150
150
  require_paths:
151
151
  - lib
@@ -160,8 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  - !ruby/object:Gem::Version
161
161
  version: '0'
162
162
  requirements: []
163
- rubygems_version: 3.3.26
164
- signing_key:
163
+ rubygems_version: 3.6.9
165
164
  specification_version: 4
166
165
  summary: Extra methods for the File class
167
166
  test_files: []
metadata.gz.sig CHANGED
@@ -1,2 +1 @@
1
- �ڏ-pY���0�STb��w�����t�Q�+��ǟIU��(b�,�YTfSB���iL�&�)���A��lׄ��EE���:y�ۮ���b�*��B
2
- �������v� �k>���N�R'7��QaO�Y��#�D���@� 0w�J4�R����4�>�F��]#�d�}�h��s�Kģ���!?���9�E��ʟDD
1
+ AՇK����p�֑H H]C��Q�m�,hL��e;�ҟ�zƱS�qѶ�[�X���S���WD�sg��NUXm�2��?rDx�& o=�9��a�*X0�8Ӏ��Aml���磰k$5 o�S�S���NZ���c+X͙��j�3�=���I{���_�`W���i�r�Qb���* ��i=�r���Y