recls-ruby 2.11.0.3 → 2.12.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +24 -27
  3. data/README.md +1 -242
  4. data/examples/find_files_and_directories.md +30 -33
  5. data/examples/find_files_and_directories.recursive.md +254 -255
  6. data/examples/show_hidden_files.md +1 -4
  7. data/examples/show_hidden_files.rb +1 -1
  8. data/examples/show_readonly_files.md +1 -4
  9. data/examples/show_readonly_files.rb +1 -1
  10. data/lib/recls/api.rb +73 -76
  11. data/lib/recls/combine_paths_1.rb +23 -26
  12. data/lib/recls/combine_paths_2plus.rb +29 -32
  13. data/lib/recls/entry.rb +273 -277
  14. data/lib/recls/file_search.rb +193 -194
  15. data/lib/recls/flags.rb +45 -48
  16. data/lib/recls/foreach.rb +98 -105
  17. data/lib/recls/obsolete.rb +79 -80
  18. data/lib/recls/recls.rb +22 -16
  19. data/lib/recls/stat.rb +134 -137
  20. data/lib/recls/util.rb +92 -95
  21. data/lib/recls/version.rb +17 -22
  22. data/lib/recls/ximpl/os.rb +44 -46
  23. data/lib/recls/ximpl/unix.rb +35 -39
  24. data/lib/recls/ximpl/util.rb +596 -598
  25. data/lib/recls/ximpl/windows.rb +137 -141
  26. data/lib/recls.rb +9 -10
  27. data/test/scratch/test_display_parts.rb +33 -33
  28. data/test/scratch/test_entry.rb +6 -6
  29. data/test/scratch/test_files_and_directories.rb +8 -8
  30. data/test/scratch/test_foreach.rb +10 -10
  31. data/test/scratch/test_module_function.rb +33 -33
  32. data/test/scratch/test_pattern_arrays.rb +5 -5
  33. data/test/scratch/test_show_dev_and_ino.rb +1 -1
  34. data/test/scratch/test_show_hidden.rb +3 -3
  35. data/test/unit/tc_recls_entries.rb +31 -31
  36. data/test/unit/tc_recls_entry.rb +19 -19
  37. data/test/unit/tc_recls_file_search.rb +32 -32
  38. data/test/unit/tc_recls_module.rb +25 -25
  39. data/test/unit/tc_recls_util.rb +161 -161
  40. data/test/unit/tc_recls_ximpl_util.rb +676 -676
  41. data/test/unit/test_all_separately.sh +1 -1
  42. data/test/unit/ts_all.rb +4 -4
  43. metadata +7 -7
data/lib/recls/entry.rb CHANGED
@@ -1,14 +1,14 @@
1
- # ######################################################################## #
2
- # File: recls/entry.rb
1
+ # ######################################################################### #
2
+ # File: recls/entry.rb
3
3
  #
4
- # Purpose: Defines the Recls::Entry class for the recls.Ruby library.
4
+ # Purpose: Defines the Recls::Entry class for the recls.Ruby library.
5
5
  #
6
- # Created: 24th July 2012
7
- # Updated: 20th April 2024
6
+ # Created: 24th July 2012
7
+ # Updated: 25th May 2020
8
8
  #
9
- # Author: Matthew Wilson
9
+ # Author: Matthew Wilson
10
10
  #
11
- # Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems
11
+ # Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
12
12
  # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
13
13
  # All rights reserved.
14
14
  #
@@ -34,7 +34,7 @@
34
34
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
35
  # POSSIBILITY OF SUCH DAMAGE.
36
36
  #
37
- # ######################################################################## #
37
+ # ######################################################################### #
38
38
 
39
39
 
40
40
  require 'recls/ximpl/os'
@@ -42,361 +42,357 @@ require 'recls/ximpl/' + (Recls::Ximpl::OS::OS_IS_WINDOWS ? 'windows' : 'unix')
42
42
  require 'recls/ximpl/util'
43
43
  require 'recls/flags'
44
44
 
45
-
46
45
  =begin
47
46
  =end
48
47
 
49
- # @!visibility private
50
48
  class Object; end # :nodoc:
51
49
 
52
50
  module Recls
53
51
 
54
- # A file-system entry
55
- class Entry
56
-
57
- private
58
- # @!visibility private
59
- def self.get_compare_path_(path)
60
- return path.upcase if Recls::Ximpl::OS::OS_IS_WINDOWS
61
- path
62
- end
63
- public
64
-
65
- # initialises an entry instance from the given path,
66
- # file_stat, and search_dir
67
- def initialize(path, file_stat, search_dir, flags)
68
-
69
- @file_stat = file_stat
70
-
71
- @path = Recls::Ximpl.absolute_path path
72
- @short_path = nil
73
- @compare_path = Entry.get_compare_path_ @path
74
- @hash = @compare_path.hash
75
-
76
- windows_drive, directory, basename, file_name, file_ext = Recls::Ximpl::Util.split_path @path
77
-
78
- @drive = windows_drive
79
- @directory_path = "#{windows_drive}#{directory}"
80
- @directory = directory ? directory : ''
81
- @directory_parts = Recls::Ximpl.directory_parts_from_directory directory
82
- @file_full_name = basename ? basename : ''
83
- @file_short_name = nil
84
- @file_name_only = file_name ? file_name : ''
85
- @file_extension = file_ext ? file_ext : ''
86
-
87
- @search_directory = search_dir
88
- @search_relative_path = Recls::Ximpl.derive_relative_path search_dir, @path
89
- @search_relative_directory_path = Recls::Ximpl.derive_relative_path search_dir, @directory_path
90
- @search_relative_directory = @search_relative_directory_path
91
- @search_relative_directory_parts = Recls::Ximpl.directory_parts_from_directory @search_relative_directory
92
-
93
- if 0 != (Recls::MARK_DIRECTORIES & flags) && directory?
94
- @path = Recls::Ximpl::Util.append_trailing_slash @path
95
- @search_relative_path = Recls::Ximpl::Util.append_trailing_slash @search_relative_path
96
- end
97
-
98
- @dev = @file_stat.dev if @file_stat
99
- @ino = @file_stat.ino if @file_stat
100
- @nlink = @file_stat.nlink if @file_stat
101
-
102
- if Recls::Ximpl::OS::OS_IS_WINDOWS && @file_stat
103
-
104
- @dev = @file_stat.by_handle_information.volume_id
105
- @ino = @file_stat.by_handle_information.file_index
106
- @nlink = @file_stat.by_handle_information.num_links
107
- @short_path = @file_stat.short_path
108
- @file_short_name = Recls::Ximpl::Util.split_path(@short_path)[2]
109
- else
110
- end
111
- end
112
-
113
- # ##########################
114
- # Name-related attributes
115
-
116
- # (+String+) A normalised form of #path that can be used in comparisons
117
- attr_reader :compare_path
118
-
119
- # (+String+) The full-path of the instance
120
- attr_reader :path
121
- # (+String+) The (Windows) short-form of #path, or +nil+ if not on Windows
122
- attr_reader :short_path
123
- # (+String+) The (Windows) drive. +nil+ if does not exist
124
- attr_reader :drive
125
- # (+String+) The full path of the entry's directory (taking into account the
126
- # #drive if on Windows)
127
- attr_reader :directory_path
128
- alias_method :dirname, :directory_path
129
- # (+String+) The entry's directory (excluding the #drive if on Windows)
130
- attr_reader :directory
131
- # (+[ String ]+) An array of directory parts, where each part ends in Recls::PATH_NAME_SEPARATOR
132
- attr_reader :directory_parts
133
- # (+String+) The entry's file name (combination of #stem + #extension)
134
- attr_reader :file_full_name
135
- # (+String+) The (Windows) short-form of #basename, or +nil+ if not on Windows
136
- attr_reader :file_short_name
137
- alias_method :basename, :file_full_name
138
- # (+String+) The entry's file stem
139
- attr_reader :file_name_only
140
- alias_method :stem, :file_name_only
141
- # (+String+) The entry's file extension
142
- attr_reader :file_extension
143
- alias_method :extension, :file_extension
144
- # (+String+) The search directory if specified; +nil+ otherwise
145
- attr_reader :search_directory
146
- # (+String+) The #path relative to #search_directory; +nil+ if no search directory specified
147
- attr_reader :search_relative_path
148
- # (+String+) The #directory relative to #search_directory; +nil+ if no search directory specified
149
- attr_reader :search_relative_directory
150
- # (+String+) The #directory_path relative to #search_directory; +nil+ if no search directory specified
151
- attr_reader :search_relative_directory_path
152
- # (+[ String ]+) The #directory_parts relative to #search_directory; +nil+ if no search directory specified
153
- attr_reader :search_relative_directory_parts
154
-
155
- # ##########################
156
- # Nature attributes
157
-
158
- # indicates whether the given entry existed at the time the entry
159
- # instance was created
160
- def exist?
161
-
162
- return false if @file_stat.nil?
52
+ # A file-system entry
53
+ class Entry
54
+
55
+ private
56
+ # @!visibility private
57
+ def self.get_compare_path_(path)
58
+ return path.upcase if Recls::Ximpl::OS::OS_IS_WINDOWS
59
+ path
60
+ end
61
+ public
62
+
63
+ # initialises an entry instance from the given path,
64
+ # file_stat, and search_dir
65
+ def initialize(path, file_stat, search_dir, flags)
66
+
67
+ @file_stat = file_stat
68
+
69
+ @path = Recls::Ximpl.absolute_path path
70
+ @short_path = nil
71
+ @compare_path = Entry.get_compare_path_ @path
72
+ @hash = @compare_path.hash
73
+
74
+ windows_drive, directory, basename, file_name, file_ext = Recls::Ximpl::Util.split_path @path
75
+
76
+ @drive = windows_drive
77
+ @directory_path = "#{windows_drive}#{directory}"
78
+ @directory = directory ? directory : ''
79
+ @directory_parts = Recls::Ximpl.directory_parts_from_directory directory
80
+ @file_full_name = basename ? basename : ''
81
+ @file_short_name = nil
82
+ @file_name_only = file_name ? file_name : ''
83
+ @file_extension = file_ext ? file_ext : ''
84
+
85
+ @search_directory = search_dir
86
+ @search_relative_path = Recls::Ximpl.derive_relative_path search_dir, @path
87
+ @search_relative_directory_path = Recls::Ximpl.derive_relative_path search_dir, @directory_path
88
+ @search_relative_directory = @search_relative_directory_path
89
+ @search_relative_directory_parts = Recls::Ximpl.directory_parts_from_directory @search_relative_directory
90
+
91
+ if 0 != (Recls::MARK_DIRECTORIES & flags) && directory?
92
+ @path = Recls::Ximpl::Util.append_trailing_slash @path
93
+ @search_relative_path = Recls::Ximpl::Util.append_trailing_slash @search_relative_path
94
+ end
95
+
96
+ @dev = @file_stat.dev if @file_stat
97
+ @ino = @file_stat.ino if @file_stat
98
+ @nlink = @file_stat.nlink if @file_stat
99
+
100
+ if Recls::Ximpl::OS::OS_IS_WINDOWS && @file_stat
101
+
102
+ @dev = @file_stat.by_handle_information.volume_id
103
+ @ino = @file_stat.by_handle_information.file_index
104
+ @nlink = @file_stat.by_handle_information.num_links
105
+ @short_path = @file_stat.short_path
106
+ @file_short_name = Recls::Ximpl::Util.split_path(@short_path)[2]
107
+ else
108
+ end
109
+ end
110
+
111
+ # ##########################
112
+ # Name-related attributes
113
+
114
+ # (String) A normalised form of #path that can be used in comparisons
115
+ attr_reader :compare_path
116
+
117
+ # (String) The full-path of the instance
118
+ attr_reader :path
119
+ # (String) The (Windows) short-form of #path, or +nil+ if not on Windows
120
+ attr_reader :short_path
121
+ # (String) The (Windows) drive. +nil+ if does not exist
122
+ attr_reader :drive
123
+ # (String) The full path of the entry's directory (taking into account the
124
+ # #drive if on Windows)
125
+ attr_reader :directory_path
126
+ alias_method :dirname, :directory_path
127
+ # (String) The entry's directory (excluding the #drive if on Windows)
128
+ attr_reader :directory
129
+ # ([String]) An array of directory parts, where each part ends in Recls::PATH_NAME_SEPARATOR
130
+ attr_reader :directory_parts
131
+ # (String) The entry's file name (combination of #stem + #extension)
132
+ attr_reader :file_full_name
133
+ # (String) The (Windows) short-form of #basename, or +nil+ if not on Windows
134
+ attr_reader :file_short_name
135
+ alias_method :basename, :file_full_name
136
+ # (String) The entry's file stem
137
+ attr_reader :file_name_only
138
+ alias_method :stem, :file_name_only
139
+ # (String) The entry's file extension
140
+ attr_reader :file_extension
141
+ alias_method :extension, :file_extension
142
+ # (String) The search directory if specified; +nil+ otherwise
143
+ attr_reader :search_directory
144
+ # (String) The #path relative to #search_directory; +nil+ if no search directory specified
145
+ attr_reader :search_relative_path
146
+ # (String) The #directory relative to #search_directory; +nil+ if no search directory specified
147
+ attr_reader :search_relative_directory
148
+ # (String) The #directory_path relative to #search_directory; +nil+ if no search directory specified
149
+ attr_reader :search_relative_directory_path
150
+ # ([String]) The #directory_parts relative to #search_directory; +nil+ if no search directory specified
151
+ attr_reader :search_relative_directory_parts
163
152
 
164
- not @file_stat.nil?
165
- end
153
+ # ##########################
154
+ # Nature attributes
166
155
 
167
- # indicates whether the given entry is hidden
168
- def hidden?
156
+ # indicates whether the given entry existed at the time the entry
157
+ # instance was created
158
+ def exist?
169
159
 
170
- return false if @file_stat.nil?
160
+ return false if @file_stat.nil?
171
161
 
172
- @file_stat.hidden?
173
- end
162
+ not @file_stat.nil?
163
+ end
174
164
 
175
- # indicates whether the given entry is readonly
176
- def readonly?
165
+ # indicates whether the given entry is hidden
166
+ def hidden?
177
167
 
178
- return false if @file_stat.nil?
168
+ return false if @file_stat.nil?
179
169
 
180
- not @file_stat.writable?
181
- end
170
+ @file_stat.hidden?
171
+ end
182
172
 
183
- if Recls::Ximpl::OS::OS_IS_WINDOWS
173
+ # indicates whether the given entry is readonly
174
+ def readonly?
184
175
 
185
- # [WINDOWS-ONLY] Indicates whether the entry has the *system* bit
186
- def system?
176
+ return false if @file_stat.nil?
187
177
 
188
- return false if @file_stat.nil?
178
+ not @file_stat.writable?
179
+ end
189
180
 
190
- @file_stat.system?
191
- end
181
+ # ##########################
182
+ # Comparison
192
183
 
193
- # [WINDOWS-ONLY] Indicates whether the entry has the *archive* bit
194
- def archive?
184
+ if Recls::Ximpl::OS::OS_IS_WINDOWS
195
185
 
196
- return false if @file_stat.nil?
186
+ # [WINDOWS-ONLY] Indicates whether the entry has the *system* bit
187
+ def system?
197
188
 
198
- @file_stat.archive?
199
- end
189
+ return false if @file_stat.nil?
200
190
 
201
- # [WINDOWS-ONLY] Indicates whether the entry is a device
202
- def device?
191
+ @file_stat.system?
192
+ end
203
193
 
204
- return false if @file_stat.nil?
194
+ # [WINDOWS-ONLY] Indicates whether the entry has the *archive* bit
195
+ def archive?
205
196
 
206
- @file_stat.device?
207
- end
197
+ return false if @file_stat.nil?
208
198
 
209
- # [WINDOWS-ONLY] Indicates whether the entry is *normal*
210
- def normal?
199
+ @file_stat.archive?
200
+ end
211
201
 
212
- return false if @file_stat.nil?
202
+ # [WINDOWS-ONLY] Indicates whether the entry is a device
203
+ def device?
213
204
 
214
- @file_stat.normal?
215
- end
205
+ return false if @file_stat.nil?
216
206
 
217
- # [WINDOWS-ONLY] Indicates whether the entry has the *temporary* bit
218
- def temporary?
207
+ @file_stat.device?
208
+ end
219
209
 
220
- return false if @file_stat.nil?
210
+ # [WINDOWS-ONLY] Indicates whether the entry is *normal*
211
+ def normal?
221
212
 
222
- @file_stat.temporary?
223
- end
213
+ return false if @file_stat.nil?
224
214
 
225
- # [WINDOWS-ONLY] Indicates whether the entry has the *compressed* bit
226
- def compressed?
215
+ @file_stat.normal?
216
+ end
227
217
 
228
- return false if @file_stat.nil?
218
+ # [WINDOWS-ONLY] Indicates whether the entry has the *temporary* bit
219
+ def temporary?
229
220
 
230
- @file_stat.compressed?
231
- end
221
+ return false if @file_stat.nil?
232
222
 
233
- # [WINDOWS-ONLY] Indicates whether the entry has the *encrypted* bit
234
- def encrypted?
223
+ @file_stat.temporary?
224
+ end
235
225
 
236
- return false if @file_stat.nil?
226
+ # [WINDOWS-ONLY] Indicates whether the entry has the *compressed* bit
227
+ def compressed?
237
228
 
238
- @file_stat.encrypted?
239
- end
240
- end
229
+ return false if @file_stat.nil?
241
230
 
242
- # indicates whether the given entry represents a directory
243
- def directory?
231
+ @file_stat.compressed?
232
+ end
244
233
 
245
- return false if @file_stat.nil?
234
+ # [WINDOWS-ONLY] Indicates whether the entry has the *encrypted* bit
235
+ def encrypted?
246
236
 
247
- @file_stat.directory?
248
- end
237
+ return false if @file_stat.nil?
249
238
 
250
- alias_method :dir?, :directory?
239
+ @file_stat.encrypted?
240
+ end
241
+ end
251
242
 
252
- # indicates whether the given entry represents a file
253
- def file?
243
+ # indicates whether the given entry represents a directory
244
+ def directory?
254
245
 
255
- return false if @file_stat.nil?
246
+ return false if @file_stat.nil?
256
247
 
257
- @file_stat.file?
258
- end
248
+ @file_stat.directory?
249
+ end
259
250
 
260
- # indicates whether the given entry represents a link
261
- def link?
251
+ alias_method :dir?, :directory?
262
252
 
263
- return false if @file_stat.nil?
253
+ # indicates whether the given entry represents a file
254
+ def file?
264
255
 
265
- @file_stat.link?
266
- end
256
+ return false if @file_stat.nil?
267
257
 
268
- # indicates whether the given entry represents a socket
269
- def socket?
258
+ @file_stat.file?
259
+ end
270
260
 
271
- return false if @file_stat.nil?
261
+ # indicates whether the given entry represents a link
262
+ def link?
272
263
 
273
- @file_stat.socket?
274
- end
264
+ return false if @file_stat.nil?
275
265
 
276
- # ##########################
277
- # Size attributes
266
+ @file_stat.link?
267
+ end
278
268
 
279
- # indicates the size of the given entry
280
- def size
269
+ # indicates whether the given entry represents a socket
270
+ def socket?
281
271
 
282
- return 0 if @file_stat.nil?
272
+ return false if @file_stat.nil?
283
273
 
284
- @file_stat.size
285
- end
274
+ @file_stat.socket?
275
+ end
286
276
 
287
- # ##########################
288
- # File-system entry attributes
277
+ # ##########################
278
+ # Size attributes
289
279
 
290
- # indicates the device of the given entry
291
- #
292
- # On Windows, this will be 0 if the entry cannot be
293
- # opened
294
- def dev
280
+ # indicates the size of the given entry
281
+ def size
295
282
 
296
- @dev
297
- end
283
+ return 0 if @file_stat.nil?
298
284
 
299
- # indicates the ino of the given entry
300
- #
301
- # On Windows, this will be 0 if the entry cannot be
302
- # opened
303
- def ino
285
+ @file_stat.size
286
+ end
304
287
 
305
- @ino
306
- end
288
+ # ##########################
289
+ # File-system entry attributes
307
290
 
308
- # number of links to the given entry
309
- #
310
- # On Windows, this will be 0 if the entry cannot be
311
- # opened
312
- def nlink
291
+ # indicates the device of the given entry
292
+ #
293
+ # On Windows, this will be 0 if the entry cannot be
294
+ # opened
295
+ def dev
313
296
 
314
- @nlink
315
- end
297
+ @dev
298
+ end
316
299
 
317
- # ##########################
318
- # Time attributes
300
+ # indicates the ino of the given entry
301
+ #
302
+ # On Windows, this will be 0 if the entry cannot be
303
+ # opened
304
+ def ino
319
305
 
320
- # indicates the last access time of the entry
321
- def last_access_time
306
+ @ino
307
+ end
322
308
 
323
- return nil if @file_stat.nil?
309
+ # number of links to the given entry
310
+ #
311
+ # On Windows, this will be 0 if the entry cannot be
312
+ # opened
313
+ def nlink
324
314
 
325
- @file_stat.atime
326
- end
315
+ @nlink
316
+ end
327
317
 
328
- # indicates the modification time of the entry
329
- def modification_time
318
+ # ##########################
319
+ # Time attributes
330
320
 
331
- return nil if @file_stat.nil?
321
+ # indicates the last access time of the entry
322
+ def last_access_time
332
323
 
333
- @file_stat.mtime
334
- end
324
+ return nil if @file_stat.nil?
335
325
 
336
- # ##########################
337
- # Comparison
326
+ @file_stat.atime
327
+ end
338
328
 
339
- # determines whether rhs is an instance of Entry and
340
- # refers to the same path
341
- def eql?(rhs)
329
+ # indicates the modification time of the entry
330
+ def modification_time
342
331
 
343
- case rhs
344
- when self.class
332
+ return nil if @file_stat.nil?
345
333
 
346
- return compare_path == rhs.compare_path
347
- else
334
+ @file_stat.mtime
335
+ end
348
336
 
349
- return false
350
- end
351
- end
337
+ # ##########################
338
+ # Comparison
352
339
 
353
- # determines whether rhs refers to the same path
354
- def ==(rhs)
340
+ # determines whether rhs is an instance of Entry and
341
+ # refers to the same path
342
+ def eql?(rhs)
355
343
 
356
- case rhs
357
- when String
344
+ case rhs
345
+ when self.class
346
+ return compare_path == rhs.compare_path
347
+ else
348
+ return false
349
+ end
350
+ end
358
351
 
359
- return compare_path == Entry.get_compare_path_(rhs)
360
- when self.class
352
+ # determines whether rhs refers to the same path
353
+ def ==(rhs)
361
354
 
362
- return compare_path == rhs.compare_path
363
- else
355
+ case rhs
356
+ when String
357
+ return compare_path == Entry.get_compare_path_(rhs)
358
+ when self.class
359
+ return compare_path == rhs.compare_path
360
+ else
361
+ return false
362
+ end
363
+ end
364
364
 
365
- return false
366
- end
367
- end
365
+ # compares this instance with rhs
366
+ def <=>(rhs)
368
367
 
369
- # compares this instance with rhs
370
- def <=>(rhs)
368
+ compare_path <=> rhs.compare_path
369
+ end
371
370
 
372
- compare_path <=> rhs.compare_path
373
- end
371
+ # the hash
372
+ def hash
374
373
 
375
- # the hash
376
- def hash
374
+ @hash
375
+ end
377
376
 
378
- @hash
379
- end
377
+ # ##########################
378
+ # Conversion
380
379
 
381
- # ##########################
382
- # Conversion
380
+ # represents the entry as a string (in the form of
381
+ # the full path)
382
+ def to_s
383
383
 
384
- # represents the entry as a string (in the form of
385
- # the full path)
386
- def to_s
384
+ path
385
+ end
387
386
 
388
- path
389
- end
387
+ # represents the entry as a string (in the form of
388
+ # the full path)
389
+ def to_str
390
390
 
391
- # represents the entry as a string (in the form of
392
- # the full path)
393
- def to_str
394
-
395
- path
396
- end
397
- end # class Entry
391
+ path
392
+ end
393
+ end # class Entry
398
394
  end # module Recls
399
395
 
400
-
401
396
  # ############################## end of file ############################# #
402
397
 
398
+