Module: Kettle::Dev::Paths
- Defined in:
- lib/kettle/dev/paths.rb
Overview
Filesystem path operations shared by Kettle tools.
Class Method Summary collapse
-
.canonical(path, base: nil) ⇒ Object
Expands a path and resolves its longest existing ancestor.
- .comparable_parts(path) ⇒ Object
- .path_parts(path) ⇒ Object
-
.same?(left, right, base: nil) ⇒ Boolean
Uses filesystem identity for existing paths, so symlink aliases and platform-specific aliases are compared by the operating system.
-
.within?(path, root, base: nil) ⇒ Boolean
Tests containment by path components, not by a string prefix.
Class Method Details
.canonical(path, base: nil) ⇒ Object
Expands a path and resolves its longest existing ancestor. This keeps comparisons useful for generated paths that do not exist yet.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/kettle/dev/paths.rb', line 11 def canonical(path, base: nil) = File.(path, base) existing = suffix = [] until File.exist?(existing) || File.symlink?(existing) parent = File.dirname(existing) return if parent == existing suffix.unshift(File.basename(existing)) existing = parent end suffix.reduce(File.realpath(existing)) { |resolved, component| File.join(resolved, component) } rescue Errno::EACCES, Errno::ENOENT end |
.comparable_parts(path) ⇒ Object
59 60 61 62 |
# File 'lib/kettle/dev/paths.rb', line 59 def comparable_parts(path) parts = path_parts(path) Gem.win_platform? ? parts.map(&:downcase) : parts end |
.path_parts(path) ⇒ Object
55 56 57 |
# File 'lib/kettle/dev/paths.rb', line 55 def path_parts(path) path.tr("\\", "/").split("/").reject(&:empty?) end |
.same?(left, right, base: nil) ⇒ Boolean
Uses filesystem identity for existing paths, so symlink aliases and platform-specific aliases are compared by the operating system.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/kettle/dev/paths.rb', line 30 def same?(left, right, base: nil) left_path = canonical(left, base: base) right_path = canonical(right, base: base) return true if left_path == right_path return File.identical?(left_path, right_path) if File.exist?(left_path) && File.exist?(right_path) comparable_parts(left_path) == comparable_parts(right_path) rescue Errno::EACCES, Errno::ENOENT, Errno::ENOTDIR, NotImplementedError comparable_parts(left_path || left) == comparable_parts(right_path || right) end |
.within?(path, root, base: nil) ⇒ Boolean
Tests containment by path components, not by a string prefix.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/kettle/dev/paths.rb', line 43 def within?(path, root, base: nil) candidate = canonical(path, base: base) boundary = canonical(root, base: base) return true if same?(candidate, boundary) candidate_parts = comparable_parts(candidate) boundary_parts = comparable_parts(boundary) candidate_parts[0, boundary_parts.length] == boundary_parts rescue Errno::EACCES, Errno::ENOENT, Errno::ENOTDIR false end |