Class: Sevgi::Function::Locate

Inherits:
Object
  • Object
show all
Defined in:
lib/sevgi/function/locate.rb

Overview

Locates one of several candidate files by walking upward from an immutable configuration snapshot. Each call observes the filesystem again and returns an owned immutable Location snapshot.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paths, start = ::Dir.pwd, exclude: nil) ⇒ void

Builds an upward file locator.

Parameters:

  • paths (Array<String>, String)

    candidate file paths

  • start (String) (defaults to: ::Dir.pwd)

    directory where lookup starts, expanded without changing process cwd

  • exclude (Array<String>, String, nil) (defaults to: nil)

    paths ignored during lookup after absolute expansion



59
60
61
62
63
64
# File 'lib/sevgi/function/locate.rb', line 59

def initialize(paths, start = ::Dir.pwd, exclude: nil)
  @paths = Array(paths).map { it.dup.freeze }.freeze
  @start = ::File.expand_path(start).freeze
  @exclude = [*exclude].map { ::File.expand_path(it).freeze }.freeze unless exclude.nil?
  freeze
end

Instance Attribute Details

#excludeArray<String>? (readonly)

Returns the frozen owned paths ignored during lookup.

Returns:

  • (Array<String>, nil)

    frozen absolute path strings, or nil



52
53
54
# File 'lib/sevgi/function/locate.rb', line 52

def exclude
  @exclude
end

#pathsArray<String> (readonly)

Returns the frozen owned candidate paths.

Returns:

  • (Array<String>)

    frozen candidate path strings



44
45
46
# File 'lib/sevgi/function/locate.rb', line 44

def paths
  @paths
end

#startString (readonly)

Returns the frozen absolute start directory.

Returns:

  • (String)

    frozen absolute path



48
49
50
# File 'lib/sevgi/function/locate.rb', line 48

def start
  @start
end

Class Method Details

.call(paths, start = Dir.pwd, exclude: nil) {|path| ... } ⇒ Sevgi::Function::Location?

Builds a locator and runs it.

Parameters:

  • paths (Array<String>, String)

    candidate file paths

  • start (String) (defaults to: Dir.pwd)

    directory where lookup starts

  • exclude (Array<String>, String, nil) (defaults to: nil)

    paths ignored during lookup

Yields:

  • optional matcher used instead of built-in file checks

Yield Parameters:

  • path (String)

    candidate path

Yield Returns:

  • (Boolean)

Returns:

Raises:

  • (Errno::ENOENT)

    when the start directory does not exist

  • (Errno::ENOTDIR)

    when the start path is not a directory



40
# File 'lib/sevgi/function/locate.rb', line 40

def self.call(*, **, &block) = new(*, **).call(&block)

Instance Method Details

#call {|path| ... } ⇒ Sevgi::Function::Location?

Note:

Absolute exclusions are applied before the default or custom matcher.

Runs the upward lookup.

Yields:

  • optional matcher used instead of built-in file checks

Yield Parameters:

  • path (String)

    absolute candidate path

Yield Returns:

  • (Boolean)

Returns:

Raises:

  • (Errno::ENOENT)

    when the start directory does not exist

  • (Errno::ENOTDIR)

    when the start path is not a directory



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/sevgi/function/locate.rb', line 74

def call(&block)
  validate_start!

  each_parent(start) do |here|
    next unless (found = match(here, &block))

    slug, file = found

    return Location.new(file:, slug:, dir: here)
  end
end