recls-ruby 2.8.2 → 2.11.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +57 -10
  3. data/examples/find_files_and_directories.md +77 -0
  4. data/examples/find_files_and_directories.rb +19 -0
  5. data/examples/find_files_and_directories.recursive.md +304 -0
  6. data/examples/find_files_and_directories.recursive.rb +19 -0
  7. data/examples/show_hidden_files.md +39 -0
  8. data/examples/show_hidden_files.rb +2 -2
  9. data/examples/show_readonly_files.md +35 -0
  10. data/examples/show_readonly_files.rb +2 -2
  11. data/lib/recls.rb +2 -0
  12. data/lib/recls/api.rb +70 -3
  13. data/lib/recls/combine_paths_1.rb +70 -0
  14. data/lib/recls/combine_paths_2plus.rb +76 -0
  15. data/lib/recls/entry.rb +40 -4
  16. data/lib/recls/file_search.rb +48 -14
  17. data/lib/recls/flags.rb +21 -4
  18. data/lib/recls/foreach.rb +45 -6
  19. data/lib/recls/obsolete.rb +119 -0
  20. data/lib/recls/recls.rb +27 -56
  21. data/lib/recls/stat.rb +96 -24
  22. data/lib/recls/util.rb +74 -23
  23. data/lib/recls/version.rb +10 -4
  24. data/lib/recls/ximpl/os.rb +29 -15
  25. data/lib/recls/ximpl/unix.rb +29 -16
  26. data/lib/recls/ximpl/util.rb +141 -39
  27. data/lib/recls/ximpl/windows.rb +56 -25
  28. data/test/fixtures/readonly/file-1 +0 -0
  29. data/test/fixtures/readonly/file-2 +0 -0
  30. data/test/scratch/test_display_parts.rb +9 -9
  31. data/test/scratch/test_entry.rb +11 -9
  32. data/test/scratch/test_files_and_directories.rb +17 -14
  33. data/test/scratch/test_foreach.rb +0 -3
  34. data/test/scratch/test_module_function.rb +10 -10
  35. data/test/scratch/test_pattern_arrays.rb +32 -0
  36. data/test/scratch/test_show_dev_and_ino.rb +1 -1
  37. data/test/scratch/test_show_hidden.rb +3 -3
  38. data/test/unit/tc_recls_util.rb +6 -0
  39. data/test/unit/tc_recls_ximpl_util.rb +156 -101
  40. data/test/unit/ts_all.rb +11 -9
  41. metadata +36 -11
@@ -4,11 +4,11 @@
4
4
  # Purpose: Defines the Recls::FileSearch class for the recls.Ruby library.
5
5
  #
6
6
  # Created: 24th July 2012
7
- # Updated: 13th June 2016
7
+ # Updated: 14th April 2019
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
11
- # Copyright (c) 2012-2015, Matthew Wilson and Synesis Software
11
+ # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
12
  # All rights reserved.
13
13
  #
14
14
  # Redistribution and use in source and binary forms, with or without
@@ -40,12 +40,33 @@ require 'recls/entry'
40
40
  require 'recls/flags'
41
41
  require 'recls/ximpl/os'
42
42
 
43
+ =begin
44
+ =end
45
+
46
+ class Object; end # :nodoc:
47
+
43
48
  module Recls
44
49
 
45
- class FileSearch
50
+ class FileSearch # :nodoc: all
46
51
 
47
52
  include Enumerable
48
53
 
54
+ # Initialises a +FileSearch+ instance, which acts as an +Enumerable+
55
+ # of Recls::Entry
56
+ #
57
+ # === Signature
58
+ #
59
+ # * *Parameters:*
60
+ # - +search_root+ (String, Recls::Entry) The root directory of the search. May be +nil+, in which case the current directory is assumed
61
+ # - +patterns+ (String, Array) The pattern(s) for which to search. May be +nil+, in which case +Recls::WILDCARDS_ALL+ is assumed
62
+ # - +options+ (Hash, Integer) Combination of flags (with behaviour as described below for the +flags+ option), or an options hash
63
+ #
64
+ # * *Options:*
65
+ # - +flags+ (Integer) Combination of flags - FILES, DIRECTORIES, RECURSIVE, etc. If the value modulo TYPEMASK is 0, then FILES is assumed
66
+ #
67
+ # === Return
68
+ # An instance of the class
69
+ #
49
70
  def initialize(search_root, patterns, options={})
50
71
 
51
72
  # for backwards compatibility, we allow for options to
@@ -101,19 +122,26 @@ module Recls
101
122
  end
102
123
 
103
124
  # now de-dup the patterns, to avoid duplicates in search
104
- patterns = patterns.flatten
105
- patterns = patterns.uniq
125
+ patterns = patterns.flatten
126
+ patterns = patterns.uniq
106
127
 
107
128
  @search_root = search_root
108
- @patterns = patterns
109
- @flags = flags
129
+ @patterns = patterns
130
+ @flags = flags
110
131
  end
111
132
 
133
+ # (String) The search root
112
134
  attr_reader :search_root
135
+ # (String) The search patterns
113
136
  attr_reader :patterns
137
+ # (Integer) The search flags
114
138
  attr_reader :flags
115
139
 
116
- def each(&blk)
140
+ # Calls the block once for each found file, passing a single
141
+ # parameter that is a Recls::Entry instance
142
+ #
143
+ # @!visibility private
144
+ def each(&blk) # :nodoc:
117
145
 
118
146
  search_root = @search_root
119
147
  search_root = Recls::Ximpl::absolute_path search_root
@@ -155,7 +183,8 @@ module Recls
155
183
  end
156
184
 
157
185
  private
158
- def FileSearch::is_dots(name)
186
+ # @!visibility private
187
+ def FileSearch.is_dots(name) # :nodoc:
159
188
 
160
189
  case name
161
190
  when '.', '..'
@@ -165,12 +194,13 @@ module Recls
165
194
  end
166
195
  end
167
196
 
168
- def FileSearch::stat_or_nil_(path, flags)
197
+ # @!visibility private
198
+ def FileSearch.stat_or_nil_(path, flags) # :nodoc:
169
199
 
170
200
  begin
171
201
 
172
202
  Recls::Ximpl::FileStat.stat path
173
- rescue Errno::ENOENT => x
203
+ rescue Errno::ENOENT, Errno::ENXIO
174
204
 
175
205
  nil
176
206
  rescue SystemCallError => x
@@ -193,7 +223,8 @@ module Recls
193
223
  # order to allow calculation of search_relative_path in the
194
224
  # entry.
195
225
 
196
- def FileSearch::search_directory_(search_root, dir, patterns, flags, &blk)
226
+ # @!visibility private
227
+ def FileSearch.search_directory_(search_root, dir, patterns, flags, &blk) # :nodoc:
197
228
 
198
229
  # array of FileStat instances
199
230
  entries = []
@@ -252,6 +283,8 @@ module Recls
252
283
 
253
284
  match = false
254
285
 
286
+ match ||= (0 == (Recls::TYPEMASK & flags))
287
+
255
288
  match ||= (0 != (Recls::FILES & flags) && fs.file?)
256
289
  match ||= (0 != (Recls::DIRECTORIES & flags) && fs.directory?)
257
290
  match ||= (0 != (Recls::DEVICES & flags) && fs.blockdev?)
@@ -286,8 +319,9 @@ module Recls
286
319
  FileSearch::search_directory_(search_root, fs.path, patterns, flags, &blk)
287
320
  end
288
321
  end
289
- end
290
- end
322
+ end # class FileSearch
323
+ end # module Recls
291
324
 
292
325
  # ############################## end of file ############################# #
293
326
 
327
+
@@ -4,11 +4,11 @@
4
4
  # Purpose: Defines the Recls::Flags module for the recls.Ruby library.
5
5
  #
6
6
  # Created: 24th July 2012
7
- # Updated: 27th August 2015
7
+ # Updated: 14th April 2019
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
11
- # Copyright (c) 2012-2015, Matthew Wilson and Synesis Software
11
+ # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
12
  # All rights reserved.
13
13
  #
14
14
  # Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,11 @@
36
36
  # ######################################################################### #
37
37
 
38
38
 
39
+ =begin
40
+ =end
41
+
42
+ class Object; end # :nodoc:
43
+
39
44
  module Recls
40
45
 
41
46
  # Specifies that files are to be listed
@@ -46,32 +51,44 @@ module Recls
46
51
  LINKS = 0x00000004
47
52
  # Specifies that devices are to be listed
48
53
  DEVICES = 0x00000008
54
+ # Type mask (combination of Recls::FILES, Recls::DIRECTORIES, Recls::LINKS, Recls::DEVICES)
49
55
  TYPEMASK = 0x000000ff
50
56
 
51
57
  # Specifies that hidden items are to be shown and hidden directories are
52
58
  # to be searched
53
59
  SHOW_HIDDEN = 0x00000100
54
60
 
61
+ # [IGNORED] This for compatibility with *recls* libraries written in other languages
55
62
  DIR_PROGRESS = 0x00001000
56
63
  # Causes search to terminate if a directory cannot be entered or an
57
64
  # entry's information cannot be stat()'d
58
65
  STOP_ON_ACCESS_FAILURE = 0x00002000
66
+ # [IGNORED] This for compatibility with *recls* libraries written in other languages
59
67
  LINK_COUNT = 0000004000
68
+ # [IGNORED] This for compatibility with *recls* libraries written in other languages
60
69
  NODE_INDEX = 0x00008000
61
70
 
71
+ # Causes search to operate recursively
62
72
  RECURSIVE = 0x00010000
63
73
  private
64
- NO_SEARCH_LINKS = 0x00020000
74
+ NO_SEARCH_LINKS = 0x00020000 # :nodoc:
65
75
  public
76
+ # [IGNORED] In previous versions the Recls::Entry#directory_parts property was not obtained (for performance reasons) unless this flag was specified. In current version the parts are always obtained
66
77
  DIRECTORY_PARTS = 0x00040000
78
+ # Causes operations (such as Recls::stat()) to obtain a result even when
79
+ # no corresponding file-system entity does not exist
67
80
  DETAILS_LATER = 0x00080000
68
81
 
82
+ # Causes the Recls::Entry#path and Recls::Entry#search_relative_path
83
+ # attributes to contain a trailing path-name-separator for directory
84
+ # entries
69
85
  MARK_DIRECTORIES = 0x00200000
70
86
 
71
87
  # Causes sub-directories that are links to be searched; default is not
72
88
  # to search through links
73
89
  SEARCH_THROUGH_LINKS = 0x00100000
74
- end
90
+ end # module Recls
75
91
 
76
92
  # ############################## end of file ############################# #
77
93
 
94
+
@@ -4,11 +4,11 @@
4
4
  # Purpose: Definition of Recls::foreach() utility function
5
5
  #
6
6
  # Created: 22nd October 2014
7
- # Updated: 9th June 2016
7
+ # Updated: 26th May 2020
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
11
- # Copyright (c) 2012-2016, Matthew Wilson and Synesis Software
11
+ # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
12
  # All rights reserved.
13
13
  #
14
14
  # Redistribution and use in source and binary forms, with or without
@@ -38,23 +38,31 @@
38
38
 
39
39
  require 'recls/file_search'
40
40
 
41
+ =begin
42
+ =end
43
+
44
+ class Object; end # :nodoc:
45
+
41
46
  module Recls
42
47
 
43
48
  private
44
- class FileSearchLineEnumerator
49
+ # @!visibility private
50
+ class FileSearchLineEnumerator # :nodoc: all
45
51
 
46
52
  include Enumerable
47
53
 
54
+ # @!visibility private
48
55
  def initialize(fs)
49
56
 
50
57
  @fs = fs
51
58
  end
52
59
 
60
+ # @!visibility private
53
61
  def each(&block)
54
62
 
55
63
  @fs.each do |fe|
56
64
 
57
- IO::readlines(fe).each_with_index do |line, index|
65
+ IO.readlines(fe).each_with_index do |line, index|
58
66
 
59
67
  case block.arity
60
68
  when 1
@@ -69,21 +77,51 @@ module Recls
69
77
  end
70
78
  end
71
79
  end
72
- end
80
+ end # class FileSearchLineEnumerator
73
81
  public
74
82
 
83
+ # Performs a recursive search and enumerates the lines of all files
84
+ # found
85
+ #
86
+ # === Signature
87
+ #
88
+ # * *Parameters:*
89
+ # - +searchable+ A searchable instance obtained from Recls::file_search() or Recls::file_rsearch()
90
+ # - +search_root+ (String, Recls::Entry) The root directory of the search. May be +nil+, in which case the current directory is assumed
91
+ # - +patterns+ (String, Array) The pattern(s) for which to search. May be +nil+, in which case Recls::WILDCARDS_ALL is assumed
92
+ # - +options+ (Hash) An options hash
93
+ # - +flags+ (Integer) Combination of flags (with behaviour as described below for the +flags+ option)
94
+ #
95
+ # * *Block:*
96
+ # An optional block that will be executed once for each line in each file
97
+ # found, where the block must take 1, 2, or 3 parameters, representing the
98
+ # line [ + file-line-index [ + entry ]]. If no block is given, an
99
+ # enumerator is returned.
100
+ #
101
+ # ==== Parameter Ordering
102
+ #
103
+ # The parameters may be expressed in any of the following permutations:
104
+ # - +searchable+
105
+ # - +search_root+, +patterns+, +flags+
106
+ # - +search_root+, +patterns+, +options+
107
+ #
108
+ # === Return
109
+ #
75
110
  def self.foreach(*args, &block)
76
111
 
77
112
  fs = nil
78
113
 
79
114
  case args.length
80
115
  when 1
116
+
81
117
  raise ArgumentError "Single argument must be of type #{Recls::FileSearch}" unless args[0].kind_of? Recls::FileSearch
82
118
 
83
119
  fs = args[0]
84
120
  when 3
121
+
85
122
  fs = Recls::FileSearch.new(args[0], args[1], args[2])
86
123
  else
124
+
87
125
  raise ArgumentError "Function requires single argument (#{Recls::FileSearch}) or three arguments (directory, patterns, flags)"
88
126
  end
89
127
 
@@ -97,7 +135,8 @@ module Recls
97
135
  return FileSearchLineEnumerator.new(fs)
98
136
  end
99
137
  end
100
- end
138
+ end # module Recls
101
139
 
102
140
  # ############################## end of file ############################# #
103
141
 
142
+
@@ -0,0 +1,119 @@
1
+ # ######################################################################### #
2
+ # File: recls/obsolete.rb
3
+ #
4
+ # Purpose: Obsolete elements
5
+ #
6
+ # Created: 19th July 2012
7
+ # Updated: 14th April 2019
8
+ #
9
+ # Author: Matthew Wilson
10
+ #
11
+ # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
+ # All rights reserved.
13
+ #
14
+ # Redistribution and use in source and binary forms, with or without
15
+ # modification, are permitted provided that the following conditions are met:
16
+ #
17
+ # * Redistributions of source code must retain the above copyright notice,
18
+ # this list of conditions and the following disclaimer.
19
+ #
20
+ # * Redistributions in binary form must reproduce the above copyright notice,
21
+ # this list of conditions and the following disclaimer in the documentation
22
+ # and/or other materials provided with the distribution.
23
+ #
24
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
+ # POSSIBILITY OF SUCH DAMAGE.
35
+ #
36
+ # ######################################################################### #
37
+
38
+
39
+
40
+ # ######################################################################### #
41
+ # Obsolete symbols
42
+
43
+ if not defined? RECLS_NO_OBSOLETE
44
+
45
+ module Recls # :nodoc: all
46
+
47
+ # @!visibility private
48
+ def self.pathNameSeparator
49
+
50
+ PATH_NAME_SEPARATOR
51
+ end
52
+
53
+ # @!visibility private
54
+ def self.pathSeparator
55
+
56
+ PATH_SEPARATOR
57
+ end
58
+
59
+ # @!visibility private
60
+ def self.wildcardsAll
61
+
62
+ WILDCARDS_ALL
63
+ end
64
+
65
+ class FileSearch # :nodoc:
66
+
67
+ # @!visibility private
68
+ alias_method :searchRoot, :search_root
69
+ # @!visibility private
70
+ alias_method :pattern, :patterns
71
+ end
72
+
73
+ class Entry # :nodoc:
74
+
75
+ # @!visibility private
76
+ alias_method :uncDrive, :drive
77
+ # @!visibility private
78
+ alias_method :directoryPath, :directory_path
79
+ # @!visibility private
80
+ alias_method :directoryParts, :directory_parts
81
+ # @!visibility private
82
+ alias_method :file, :file_full_name
83
+ # @!visibility private
84
+ alias_method :shortFile, :file_short_name
85
+ # @!visibility private
86
+ alias_method :fileBaseName, :file_name_only
87
+ # @!visibility private
88
+ alias_method :fileName, :file_name_only
89
+ # @!visibility private
90
+ alias_method :fileExt, :file_extension
91
+ # @!visibility private
92
+ alias_method :searchDirectory, :search_directory
93
+ # @!visibility private
94
+ alias_method :searchRelativePath, :search_relative_path
95
+
96
+ # @!visibility private
97
+ alias_method :isDirectory, :directory?
98
+ # @!visibility private
99
+ alias_method :isFile, :file?
100
+ #alias_method :isLink, :link?
101
+ # @!visibility private
102
+ alias_method :isReadOnly, :readonly?
103
+ # @!visibility private
104
+ def isUNC
105
+
106
+ d = drive
107
+
108
+ d and d.size > 2
109
+ end
110
+
111
+ # @!visibility private
112
+ alias_method :creationTime, :modification_time
113
+ end
114
+ end # module Recls
115
+ end
116
+
117
+ # ############################## end of file ############################# #
118
+
119
+
@@ -4,11 +4,11 @@
4
4
  # Purpose: Main source file for recls library
5
5
  #
6
6
  # Created: 19th July 2012
7
- # Updated: 9th June 2016
7
+ # Updated: 14th April 2019
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
11
- # Copyright (c) 2012-2015, Matthew Wilson and Synesis Software
11
+ # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
12
  # All rights reserved.
13
13
  #
14
14
  # Redistribution and use in source and binary forms, with or without
@@ -39,76 +39,47 @@
39
39
  require 'recls/version'
40
40
 
41
41
  require 'recls/api'
42
+ require 'recls/entry'
42
43
  require 'recls/file_search'
43
44
  require 'recls/foreach'
44
45
  require 'recls/stat'
45
46
  require 'recls/util'
46
47
  require 'recls/ximpl/os'
47
48
 
49
+ # The *recls* module
50
+ #
51
+ # == Significant Components
52
+ # - Recls::Entry
53
+ # - Recls::absolute_path
54
+ # - Recls::absolute_path?
55
+ # - Recls::canonicalise_path
56
+ # - Recls::derive_relative_path
57
+ # - Recls::directory?
58
+ # - Recls::exist?
59
+ # - Recls::file?
60
+ # - Recls::file_rsearch
61
+ # - Recls::file_search
62
+ # - Recls::foreach
63
+ # - Recls::stat
64
+ module Recls
65
+
66
+ end # module Recls
67
+
48
68
  module Recls
49
69
 
50
70
  # Represents the "all" wildcards string for the ambient operating
51
71
  # system
52
72
  WILDCARDS_ALL = Recls::Ximpl::OS::WILDCARDS_ALL
53
73
 
74
+ # The string sequence used to separate names in paths, e.g. "/" on UNIX
54
75
  PATH_NAME_SEPARATOR = Recls::Ximpl::OS::PATH_NAME_SEPARATOR
55
76
 
77
+ # The string sequence used to separate paths, e.g. ":" on UNIX
56
78
  PATH_SEPARATOR = Recls::Ximpl::OS::PATH_SEPARATOR
57
- end
58
-
59
- # ######################################################################### #
60
- # Obsolete symbols
61
-
62
- if not defined? RECLS_NO_OBSOLETE
63
-
64
- module Recls
65
-
66
- def self.pathNameSeparator
67
- PATH_NAME_SEPARATOR
68
- end
69
-
70
- def self.pathSeparator
71
- PATH_SEPARATOR
72
- end
79
+ end # module Recls
73
80
 
74
- def self.wildcardsAll
75
- WILDCARDS_ALL
76
- end
77
-
78
- class FileSearch
79
-
80
- alias_method :searchRoot, :search_root
81
- alias_method :pattern, :patterns
82
- end
83
-
84
- class Entry
85
-
86
- alias_method :uncDrive, :drive
87
- alias_method :directoryPath, :directory_path
88
- alias_method :directoryParts, :directory_parts
89
- alias_method :file, :file_full_name
90
- alias_method :shortFile, :file_short_name
91
- alias_method :fileBaseName, :file_name_only
92
- alias_method :fileName, :file_name_only
93
- alias_method :fileExt, :file_extension
94
- alias_method :searchDirectory, :search_directory
95
- alias_method :searchRelativePath, :search_relative_path
96
-
97
- alias_method :isDirectory, :directory?
98
- alias_method :isFile, :file?
99
- #alias_method :isLink, :link?
100
- alias_method :isReadOnly, :readonly?
101
- def isUNC
102
-
103
- d = drive
104
-
105
- d and d.size > 2
106
- end
107
-
108
- alias_method :creationTime, :modification_time
109
- end
110
- end
111
- end
81
+ require 'recls/obsolete'
112
82
 
113
83
  # ############################## end of file ############################# #
114
84
 
85
+