Module: Recls

Defined in:
lib/recls/recls.rb,
lib/recls/api.rb,
lib/recls/stat.rb,
lib/recls/util.rb,
lib/recls/util.rb,
lib/recls/entry.rb,
lib/recls/flags.rb,
lib/recls/recls.rb,
lib/recls/foreach.rb,
lib/recls/version.rb,
lib/recls/obsolete.rb,
lib/recls/ximpl/os.rb,
lib/recls/ximpl/unix.rb,
lib/recls/ximpl/util.rb,
lib/recls/file_search.rb,
lib/recls/ximpl/windows.rb,
lib/recls/combine_paths_1.rb,
lib/recls/combine_paths_2plus.rb

Overview

The main recls module

Significant Components

Defined Under Namespace

Classes: Entry

Constant Summary collapse

FILES =

Specifies that files are to be listed

0x00000001
DIRECTORIES =

Specifies that directories are to be listed

0x00000002
0x00000004
DEVICES =

Specifies that devices are to be listed

0x00000008
TYPEMASK =

Type mask (combination of FILES, DIRECTORIES, LINKS, DEVICES)

0x000000ff
SHOW_HIDDEN =

Specifies that hidden items are to be shown and hidden directories are to be searched

0x00000100
DIR_PROGRESS =

(IGNORED) This for compatibility with recls libraries written in other languages

0x00001000
STOP_ON_ACCESS_FAILURE =

Causes search to terminate if a directory cannot be entered or an entry's file-system information cannot be obtained from the operating system

0x00002000
0000004000
NODE_INDEX =

(IGNORED) This for compatibility with recls libraries written in other languages

0x00008000
RECURSIVE =

Causes search to operate recursively

0x00010000
DIRECTORY_PARTS =

(IGNORED) In previous versions the Entry#directory_parts property was not obtained (for performance reasons) unless this flag was specified. In current version the parts are always obtained

0x00040000
DETAILS_LATER =

Causes operations (such as stat) to obtain a result even when no corresponding file-system entity does not exist

0x00080000
MARK_DIRECTORIES =

Causes the Entry#path and Entry#search_relative_path attributes to contain a trailing path-name-separator for directory entries

0x00200000
0x00100000
PATH_NAME_SEPARATOR =

The string sequence used to separate names in paths, e.g. "/" on UNIX

Recls::Ximpl::OS::PATH_NAME_SEPARATOR
PATH_SEPARATOR =

The string sequence used to separate paths, e.g. ";" on Windows

Recls::Ximpl::OS::PATH_SEPARATOR
WILDCARDS_ALL =

Represents the "all" wildcards string for the ambient operating system

Recls::Ximpl::OS::WILDCARDS_ALL
VERSION =

Current version of the recls.Ruby library

'2.13.4'

Class Method Summary collapse

Class Method Details

.absolute_path(path) ⇒ Object

Obtains the absolute form of the given path

Signature

  • Parameters:
    • path (+String+, Entry) The path;

Return

(+String+) The absolute form of the path.



60
61
62
63
# File 'lib/recls/util.rb', line 60

def self.absolute_path(path)

  Recls::Ximpl.absolute_path path
end

.absolute_path?(path) ⇒ Boolean

Indicates whether the given path is absolute

Signature

  • Parameters:
    • path (+String+, Entry, nil) The path to be evaluated;

Return

(boolean) true if path is absolute; false otherwise.

Returns:

  • (Boolean)


135
136
137
138
# File 'lib/recls/util.rb', line 135

def self.absolute_path?(path)

  Recls::Ximpl.absolute_path? path
end

.canonicalise_path(path) ⇒ Object

Canonicalises the given path, by removing dots directories, i.e. '.' and '..'

Signature

  • Parameters:
    • path (+String+, Entry) The path;

Return

(+String+) The canonical form of the path.



75
76
77
78
79
80
# File 'lib/recls/util.rb', line 75

def self.canonicalise_path(path)

  return path.path if ::Recls::Entry === path

  Recls::Ximpl.canonicalise_path path
end

.combine_paths(*paths, **options) ⇒ Object

Combines paths, optionally canonicalising them.

Unlike File::join(), this method takes account of relative vs absolute elements in the sequence. Specifically, the rightmost non-relative element, if it exists, anchors the combination, such that any arguments to the left are ignored. Furthermore, any entries (of type Recls::Entry) in the sequence are given special treatment as follows:

  • a rightmost #file? or #device? is returned as the complete result;
  • a rightmost #directory? causes all prior elements to be ignored and may be combined with subsequent elements;

Signature

  • Parameters:

    • paths ( String, Entry ) Array of 1 or more path elements to be combined;
    • options (+Hash+) Options that moderate the combination;
  • Options:

    • :canonicalise (boolean) Causes the evaluated path to be canonicalised - with Recls.canonicalise_path - before it is returned;
    • :clean (boolean) Causes the evaluated path to be cleaned (i.e. sent to cleanpath) before it is returned. Ignored if :canonicalise is specified;
    • :clean_path (boolean) Equivalent to :clean, but deprecated and may be removed in a future version;

Return

(+String+) The combined path.

Raises:

  • (ArgumentError)


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
# File 'lib/recls/combine_paths_1.rb', line 67

def self.combine_paths(*paths)

  paths.reject! { |p| p.nil? }

  raise ArgumentError, 'must specify one or more path elements' if paths.empty?

  ix_last_entry = paths.rindex { |path| ::Recls::Entry === path }

  if ix_last_entry

    fe = paths[ix_last_entry]

    if fe.directory?

      paths = paths[ix_last_entry..-1]
    else

      return fe
    end
  end

  paths = paths.map { |path| path.to_str }

  return Recls::Ximpl.combine_paths paths, {}
end

.derive_relative_path(origin, path) ⇒ Object

Derives a given path relative to an origin, unless the path is absolute

Signature

  • Parameters:
    • origin (+String+, Entry) The path against which path will be evaluated;
    • path (+String+, Entry) The path to evaluate;

Return

(+String+) The relative form of the path.



93
94
95
96
# File 'lib/recls/util.rb', line 93

def self.derive_relative_path(origin, path)

  Recls::Ximpl.derive_relative_path origin, path
end

.directory?(path, *args) ⇒ Boolean

Equivalent to stat but only returns (a non-+nil+ value) if the path exists and represents a directory

This has two advantages over File.directory?: it obtains a Entry in the case where the path represents a directory; and it does '~' interpretation

Signature

  • Parameters:
    • path (+String+, Entry) The path;

Return

(Entry, nil) The entry if path exists and is a directory; nil otherwise.

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
73
74
# File 'lib/recls/stat.rb', line 64

def self.directory?(path, *args)

  fe = self.stat(path, *args)

  if fe

    return nil unless fe.directory?
  end

  fe
end

.exist?(path) ⇒ Boolean

Indicates whether the given path exists, obtaining a Entry instance if so

Signature

  • Parameters:
    • path (+String+, Entry) The path;

Return

(Entry, nil) The entry if path exists; nil otherwise.

Returns:

  • (Boolean)


119
120
121
122
123
124
# File 'lib/recls/util.rb', line 119

def self.exist?(path)

  return nil if path.nil?

  Recls.stat(path)
end

.file?(path, *args) ⇒ Boolean

Equivalent to stat but only returns (a non-+nil+ value) if the path exists and represents a file

This has two advantages over File.file?: it obtains a Entry in the case where the path represents a file; and it does '~' interpretation

Signature

  • Parameters:
    • path (+String+, Entry) The path;

Return

(Entry, nil) The entry if path exists and is a file; nil otherwise.

Returns:

  • (Boolean)


90
91
92
93
94
95
96
97
98
99
100
# File 'lib/recls/stat.rb', line 90

def self.file?(path, *args)

  fe = self.stat(path, *args)

  if fe

    return nil unless fe.file?
  end

  fe
end

.file_rsearch(search_root, patterns, options = {}) ⇒ Object

(DEPRECATED) Use rsearch



57
58
59
60
# File 'lib/recls/api.rb', line 57

def self.file_rsearch(search_root, patterns, options = {})

  self.rsearch(search_root, patterns, options)
end

.file_search(search_root, patterns, options = {}) ⇒ Object

(DEPRECATED) Use search



63
64
65
66
# File 'lib/recls/api.rb', line 63

def self.file_search(search_root, patterns, options = {})

  self.search(search_root, patterns, options)
end

.FileSearch(search_root, patterns, options = {}) ⇒ Object

(DEPRECATED) Use search



51
52
53
54
# File 'lib/recls/api.rb', line 51

def self.FileSearch(search_root, patterns, options = {})

  self.search(search_root, patterns, options)
end

.foreach(*args, &block) ⇒ Object

Performs an optionally-recursive search and enumerates the lines of all files found

Signature

  • Parameters:

    • searchable A searchable instance obtained from search or rsearch;
    • search_root (+String+, Entry) The root directory of the search. May be nil, in which case the current directory is assumed;
    • patterns (+String+, Array) The pattern(s) for which to search. May be nil, in which case WILDCARDS_ALL is assumed;
    • options (+Hash+) An options hash;
    • flags (+Integer+) Combination of flags (with behaviour as described below for the flags option);
  • Block: An optional block that will be executed once for each line in each file found, where the block must take 1, 2, or 3 parameters, representing the line [, file_line_index [, entry ]]. If no block is given, an enumerator is returned.

Parameter Ordering

The parameters may be expressed in any of the following permutations:

  • searchable
  • search_root, patterns, flags
  • search_root, patterns, options

Return

nil if a block is given; otherwise, an instance of the FileSearchLineEnumerator.



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
# File 'lib/recls/foreach.rb', line 115

def self.foreach(*args, &block)

  fs = nil

  case args.length
  when 1

    raise ArgumentError "Single argument must be of type #{Recls::FileSearch}" unless args[0].kind_of? Recls::FileSearch

    fs = args[0]
  when 3

    fs = Recls::FileSearch.new(args[0], args[1], args[2])
  else

    raise ArgumentError "Function requires single argument (#{Recls::FileSearch}) or three arguments (directory, patterns, flags)"
  end

  if block_given?

    FileSearchLineEnumerator.new(fs).each(block)

    return nil
  else

    return FileSearchLineEnumerator.new(fs)
  end
end

.rsearch(search_root, patterns, options = {}) ⇒ Object

Initialises a FileSearch instance, which acts recursively, as an Enumerable of Entry

Signature

  • Parameters:

    • search_root (+String+, Entry) The root directory of the search. May be nil, in which case the current directory is assumed;
    • patterns (+String+, Array) The pattern(s) for which to search. May be nil, in which case WILDCARDS_ALL is assumed;
    • options (+Hash+, Integer) Combination of flags (with behaviour as described below for the flags option), or an options hash;
  • Options:

    • flags (+Integer+) Combination of flags - FILES, DIRECTORIES, etc. If the value modulo TYPEMASK is 0, then FILES is assumed. The value RECURSIVE is added by the function, and so need not be added by the caller; it cannot be removed;

Return

An instance of a class implementing Enumerable whose value type is Entry.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/recls/api.rb', line 85

def self.rsearch(search_root, patterns, options = {})

  case options
  when ::NilClass

    options = { flags: RECURSIVE }
  when ::Integer

    options |= RECURSIVE
  when ::Hash

    flags =   options[:flags] || 0
    flags |=  RECURSIVE

    options[:flags] = flags
  else

    # this is handled by the FileSearch initialiser
  end

  Recls::FileSearch.new(search_root, patterns, options)
end

.search(search_root, patterns, options = {}) ⇒ Object

Initialises a FileSearch instance, which acts as an Enumerable of Entry

Signature

  • Parameters:

    • search_root (+String+, Entry) The root directory of the search. May be nil, in which case the current directory is assumed;
    • patterns (+String+, Array) The pattern(s) for which to search. May be nil, in which case WILDCARDS_ALL is assumed;
    • options (+Hash+, Integer) Combination of flags (with behaviour as described below for the flags option), or an options hash;
  • Options:

Return

An instance of a class implementing Enumerable whose value type is Entry.



124
125
126
127
# File 'lib/recls/api.rb', line 124

def self.search(search_root, patterns, options = {})

  Recls::FileSearch.new(search_root, patterns, options)
end

.stat(path, *args) ⇒ Object

Obtains a single Entry instance from a path, according to the given arguments, which can be any combination of search-root and flags, as discussed below

Signature

  • Parameters:
    • path (+String+) A path to evaluate. May not be nil;
    • search_root (+String+, Entry) A directory from which the returned Entry instance's search-relative attributes are evaluated;
    • flags (+Integer+) A bit-combined set of flags (such as DIRECTORIES, FILES, RECURSIVE, DETAILS_LATER, and so on);

Parameter Ordering

The parameters may be expressed in any of the following permutations:

  • path
  • path, flags
  • path, search_root
  • path, flags, search_root
  • path, search_root, flags

Return

(Entry) An entry representing the path on the file-system, or nil if the path does not refer to an existing entity. If the DETAILS_LATER flag is included, then an entry is returned regardless of its existence.

Raises:

  • (ArgumentError)


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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/recls/stat.rb', line 127

def self.stat(path, *args)

  flags       = 0
  search_root = nil
  message     = nil

  path_is_entry = ::Recls::Entry === path

  unless path_is_entry

    path = File.expand_path(path) if path =~ /^~[\\\/]*/
  end

  case args.size
  when 0

    return path if path_is_entry
  when 1

    case args[0]
    when ::Integer

      flags = args[0]
    when ::String

      search_root = args[0]
    else

      message = "argument '#{args[0]}' (of type `#{args[0].class}`) not valid"
    end
  when 2

    if false
    elsif ::Integer === args[0] && ::String === args[1]

      flags       = args[0]
      search_root = args[1]
    elsif ::String === args[0] && ::Integer === args[1]

      search_root = args[0]
      flags       = args[1]
    else

      message = "invalid combination of arguments"
    end
  else

    message = "too many arguments"
  end

  raise ArgumentError, "#{message}: `Recls.stat()` takes one (path), two (path+flags or path+search_root), or three (path+search_root+flags) arguments" if message

  Recls::Ximpl.stat_prep(path, search_root, flags)
end

.windows?Boolean

Indicates whether the operating system is a variant of Windows

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/recls/recls.rb', line 84

def self.windows?

  Recls::Ximpl::OS::OS_IS_WINDOWS
end