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.
- checksums.yaml +4 -4
- data/LICENSE +24 -27
- data/README.md +1 -242
- data/examples/find_files_and_directories.md +30 -33
- data/examples/find_files_and_directories.recursive.md +254 -255
- data/examples/show_hidden_files.md +1 -4
- data/examples/show_hidden_files.rb +1 -1
- data/examples/show_readonly_files.md +1 -4
- data/examples/show_readonly_files.rb +1 -1
- data/lib/recls/api.rb +73 -76
- data/lib/recls/combine_paths_1.rb +23 -26
- data/lib/recls/combine_paths_2plus.rb +29 -32
- data/lib/recls/entry.rb +273 -277
- data/lib/recls/file_search.rb +193 -194
- data/lib/recls/flags.rb +45 -48
- data/lib/recls/foreach.rb +98 -105
- data/lib/recls/obsolete.rb +79 -80
- data/lib/recls/recls.rb +22 -16
- data/lib/recls/stat.rb +134 -137
- data/lib/recls/util.rb +92 -95
- data/lib/recls/version.rb +17 -22
- data/lib/recls/ximpl/os.rb +44 -46
- data/lib/recls/ximpl/unix.rb +35 -39
- data/lib/recls/ximpl/util.rb +596 -598
- data/lib/recls/ximpl/windows.rb +137 -141
- data/lib/recls.rb +9 -10
- data/test/scratch/test_display_parts.rb +33 -33
- data/test/scratch/test_entry.rb +6 -6
- data/test/scratch/test_files_and_directories.rb +8 -8
- data/test/scratch/test_foreach.rb +10 -10
- data/test/scratch/test_module_function.rb +33 -33
- data/test/scratch/test_pattern_arrays.rb +5 -5
- data/test/scratch/test_show_dev_and_ino.rb +1 -1
- data/test/scratch/test_show_hidden.rb +3 -3
- data/test/unit/tc_recls_entries.rb +31 -31
- data/test/unit/tc_recls_entry.rb +19 -19
- data/test/unit/tc_recls_file_search.rb +32 -32
- data/test/unit/tc_recls_module.rb +25 -25
- data/test/unit/tc_recls_util.rb +161 -161
- data/test/unit/tc_recls_ximpl_util.rb +676 -676
- data/test/unit/test_all_separately.sh +1 -1
- data/test/unit/ts_all.rb +4 -4
- metadata +7 -7
data/lib/recls/entry.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#
|
2
|
-
# File:
|
1
|
+
# ######################################################################### #
|
2
|
+
# File: recls/entry.rb
|
3
3
|
#
|
4
|
-
# Purpose:
|
4
|
+
# Purpose: Defines the Recls::Entry class for the recls.Ruby library.
|
5
5
|
#
|
6
|
-
# Created:
|
7
|
-
# Updated:
|
6
|
+
# Created: 24th July 2012
|
7
|
+
# Updated: 25th May 2020
|
8
8
|
#
|
9
|
-
# Author:
|
9
|
+
# Author: Matthew Wilson
|
10
10
|
#
|
11
|
-
# Copyright (c) 2019-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
165
|
-
|
153
|
+
# ##########################
|
154
|
+
# Nature attributes
|
166
155
|
|
167
|
-
|
168
|
-
|
156
|
+
# indicates whether the given entry existed at the time the entry
|
157
|
+
# instance was created
|
158
|
+
def exist?
|
169
159
|
|
170
|
-
|
160
|
+
return false if @file_stat.nil?
|
171
161
|
|
172
|
-
|
173
|
-
|
162
|
+
not @file_stat.nil?
|
163
|
+
end
|
174
164
|
|
175
|
-
|
176
|
-
|
165
|
+
# indicates whether the given entry is hidden
|
166
|
+
def hidden?
|
177
167
|
|
178
|
-
|
168
|
+
return false if @file_stat.nil?
|
179
169
|
|
180
|
-
|
181
|
-
|
170
|
+
@file_stat.hidden?
|
171
|
+
end
|
182
172
|
|
183
|
-
|
173
|
+
# indicates whether the given entry is readonly
|
174
|
+
def readonly?
|
184
175
|
|
185
|
-
|
186
|
-
def system?
|
176
|
+
return false if @file_stat.nil?
|
187
177
|
|
188
|
-
|
178
|
+
not @file_stat.writable?
|
179
|
+
end
|
189
180
|
|
190
|
-
|
191
|
-
|
181
|
+
# ##########################
|
182
|
+
# Comparison
|
192
183
|
|
193
|
-
|
194
|
-
def archive?
|
184
|
+
if Recls::Ximpl::OS::OS_IS_WINDOWS
|
195
185
|
|
196
|
-
|
186
|
+
# [WINDOWS-ONLY] Indicates whether the entry has the *system* bit
|
187
|
+
def system?
|
197
188
|
|
198
|
-
|
199
|
-
end
|
189
|
+
return false if @file_stat.nil?
|
200
190
|
|
201
|
-
|
202
|
-
|
191
|
+
@file_stat.system?
|
192
|
+
end
|
203
193
|
|
204
|
-
|
194
|
+
# [WINDOWS-ONLY] Indicates whether the entry has the *archive* bit
|
195
|
+
def archive?
|
205
196
|
|
206
|
-
|
207
|
-
end
|
197
|
+
return false if @file_stat.nil?
|
208
198
|
|
209
|
-
|
210
|
-
|
199
|
+
@file_stat.archive?
|
200
|
+
end
|
211
201
|
|
212
|
-
|
202
|
+
# [WINDOWS-ONLY] Indicates whether the entry is a device
|
203
|
+
def device?
|
213
204
|
|
214
|
-
|
215
|
-
end
|
205
|
+
return false if @file_stat.nil?
|
216
206
|
|
217
|
-
|
218
|
-
|
207
|
+
@file_stat.device?
|
208
|
+
end
|
219
209
|
|
220
|
-
|
210
|
+
# [WINDOWS-ONLY] Indicates whether the entry is *normal*
|
211
|
+
def normal?
|
221
212
|
|
222
|
-
|
223
|
-
end
|
213
|
+
return false if @file_stat.nil?
|
224
214
|
|
225
|
-
|
226
|
-
|
215
|
+
@file_stat.normal?
|
216
|
+
end
|
227
217
|
|
228
|
-
|
218
|
+
# [WINDOWS-ONLY] Indicates whether the entry has the *temporary* bit
|
219
|
+
def temporary?
|
229
220
|
|
230
|
-
|
231
|
-
end
|
221
|
+
return false if @file_stat.nil?
|
232
222
|
|
233
|
-
|
234
|
-
|
223
|
+
@file_stat.temporary?
|
224
|
+
end
|
235
225
|
|
236
|
-
|
226
|
+
# [WINDOWS-ONLY] Indicates whether the entry has the *compressed* bit
|
227
|
+
def compressed?
|
237
228
|
|
238
|
-
|
239
|
-
end
|
240
|
-
end
|
229
|
+
return false if @file_stat.nil?
|
241
230
|
|
242
|
-
|
243
|
-
|
231
|
+
@file_stat.compressed?
|
232
|
+
end
|
244
233
|
|
245
|
-
|
234
|
+
# [WINDOWS-ONLY] Indicates whether the entry has the *encrypted* bit
|
235
|
+
def encrypted?
|
246
236
|
|
247
|
-
|
248
|
-
end
|
237
|
+
return false if @file_stat.nil?
|
249
238
|
|
250
|
-
|
239
|
+
@file_stat.encrypted?
|
240
|
+
end
|
241
|
+
end
|
251
242
|
|
252
|
-
|
253
|
-
|
243
|
+
# indicates whether the given entry represents a directory
|
244
|
+
def directory?
|
254
245
|
|
255
|
-
|
246
|
+
return false if @file_stat.nil?
|
256
247
|
|
257
|
-
|
258
|
-
|
248
|
+
@file_stat.directory?
|
249
|
+
end
|
259
250
|
|
260
|
-
|
261
|
-
def link?
|
251
|
+
alias_method :dir?, :directory?
|
262
252
|
|
263
|
-
|
253
|
+
# indicates whether the given entry represents a file
|
254
|
+
def file?
|
264
255
|
|
265
|
-
|
266
|
-
end
|
256
|
+
return false if @file_stat.nil?
|
267
257
|
|
268
|
-
|
269
|
-
|
258
|
+
@file_stat.file?
|
259
|
+
end
|
270
260
|
|
271
|
-
|
261
|
+
# indicates whether the given entry represents a link
|
262
|
+
def link?
|
272
263
|
|
273
|
-
|
274
|
-
end
|
264
|
+
return false if @file_stat.nil?
|
275
265
|
|
276
|
-
|
277
|
-
|
266
|
+
@file_stat.link?
|
267
|
+
end
|
278
268
|
|
279
|
-
|
280
|
-
|
269
|
+
# indicates whether the given entry represents a socket
|
270
|
+
def socket?
|
281
271
|
|
282
|
-
|
272
|
+
return false if @file_stat.nil?
|
283
273
|
|
284
|
-
|
285
|
-
|
274
|
+
@file_stat.socket?
|
275
|
+
end
|
286
276
|
|
287
|
-
|
288
|
-
|
277
|
+
# ##########################
|
278
|
+
# Size attributes
|
289
279
|
|
290
|
-
|
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
|
-
|
297
|
-
end
|
283
|
+
return 0 if @file_stat.nil?
|
298
284
|
|
299
|
-
|
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
|
-
|
306
|
-
|
288
|
+
# ##########################
|
289
|
+
# File-system entry attributes
|
307
290
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
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
|
-
|
315
|
-
|
297
|
+
@dev
|
298
|
+
end
|
316
299
|
|
317
|
-
|
318
|
-
|
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
|
-
|
321
|
-
|
306
|
+
@ino
|
307
|
+
end
|
322
308
|
|
323
|
-
|
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
|
-
|
326
|
-
|
315
|
+
@nlink
|
316
|
+
end
|
327
317
|
|
328
|
-
|
329
|
-
|
318
|
+
# ##########################
|
319
|
+
# Time attributes
|
330
320
|
|
331
|
-
|
321
|
+
# indicates the last access time of the entry
|
322
|
+
def last_access_time
|
332
323
|
|
333
|
-
|
334
|
-
end
|
324
|
+
return nil if @file_stat.nil?
|
335
325
|
|
336
|
-
|
337
|
-
|
326
|
+
@file_stat.atime
|
327
|
+
end
|
338
328
|
|
339
|
-
|
340
|
-
|
341
|
-
def eql?(rhs)
|
329
|
+
# indicates the modification time of the entry
|
330
|
+
def modification_time
|
342
331
|
|
343
|
-
|
344
|
-
when self.class
|
332
|
+
return nil if @file_stat.nil?
|
345
333
|
|
346
|
-
|
347
|
-
|
334
|
+
@file_stat.mtime
|
335
|
+
end
|
348
336
|
|
349
|
-
|
350
|
-
|
351
|
-
end
|
337
|
+
# ##########################
|
338
|
+
# Comparison
|
352
339
|
|
353
|
-
|
354
|
-
|
340
|
+
# determines whether rhs is an instance of Entry and
|
341
|
+
# refers to the same path
|
342
|
+
def eql?(rhs)
|
355
343
|
|
356
|
-
|
357
|
-
|
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
|
-
|
360
|
-
|
352
|
+
# determines whether rhs refers to the same path
|
353
|
+
def ==(rhs)
|
361
354
|
|
362
|
-
|
363
|
-
|
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
|
-
|
366
|
-
|
367
|
-
end
|
365
|
+
# compares this instance with rhs
|
366
|
+
def <=>(rhs)
|
368
367
|
|
369
|
-
|
370
|
-
|
368
|
+
compare_path <=> rhs.compare_path
|
369
|
+
end
|
371
370
|
|
372
|
-
|
373
|
-
|
371
|
+
# the hash
|
372
|
+
def hash
|
374
373
|
|
375
|
-
|
376
|
-
|
374
|
+
@hash
|
375
|
+
end
|
377
376
|
|
378
|
-
|
379
|
-
|
377
|
+
# ##########################
|
378
|
+
# Conversion
|
380
379
|
|
381
|
-
|
382
|
-
|
380
|
+
# represents the entry as a string (in the form of
|
381
|
+
# the full path)
|
382
|
+
def to_s
|
383
383
|
|
384
|
-
|
385
|
-
|
386
|
-
def to_s
|
384
|
+
path
|
385
|
+
end
|
387
386
|
|
388
|
-
|
389
|
-
|
387
|
+
# represents the entry as a string (in the form of
|
388
|
+
# the full path)
|
389
|
+
def to_str
|
390
390
|
|
391
|
-
|
392
|
-
|
393
|
-
|
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
|
+
|