Class: Invar::FileLocator

Inherits:
Object
  • Object
show all
Defined in:
lib/invar/file_locator.rb

Overview

Locates a config file within XDG standard location(s) and namespace subdirectory.

Defined Under Namespace

Classes: FileNotFoundError, InvalidNamespaceError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(namespace) ⇒ FileLocator

Builds a new instance that will search in the namespace.

Parameters:

  • namespace (String)

    Name of the subdirectory within the XDG standard location(s)

Raises:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/invar/file_locator.rb', line 38

def initialize(namespace)
   raise InvalidNamespaceError, 'namespace cannot be nil' if namespace.nil?
   raise InvalidNamespaceError, 'namespace cannot be an empty string' if namespace.empty?

   @namespace = namespace

   home_config_dir = ENV.fetch('XDG_CONFIG_HOME', XDG::Defaults::CONFIG_HOME)
   alt_config_dirs = ENV.fetch('XDG_CONFIG_DIRS', XDG::Defaults::CONFIG_DIRS).split(':')

   source_dirs = alt_config_dirs
   source_dirs.unshift(home_config_dir) if ENV.key? 'HOME'
   @search_paths = source_dirs.collect { |path| Pathname.new(path) / @namespace }.collect(&:expand_path)

   freeze
end

Instance Attribute Details

#search_pathsObject (readonly)

Returns the value of attribute search_paths.



32
33
34
# File 'lib/invar/file_locator.rb', line 32

def search_paths
  @search_paths
end

Instance Method Details

#find(basename, ext = nil) ⇒ PrivateFile

Locates the file with the given name. You may optionally provide an extension as a second argument.

These are equivalent:

find('config.yml')
find('config', 'yml')

Parameters:

  • basename (String)

    The file’s basename

  • ext (String) (defaults to: nil)

    the file extension, excluding the dot.

Returns:

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/invar/file_locator.rb', line 65

def find(basename, ext = nil)
   basename = [basename, ext].join('.') if ext

   full_paths = search_paths.collect { |dir| dir / basename }
   files      = full_paths.select(&:exist?)

   if files.size > 1
      msg = "Found more than 1 #{ basename } file: #{ files.join(', ') }."
      raise AmbiguousSourceError, "#{ msg } #{ AmbiguousSourceError::HINT }"
   end

   PrivateFile.new(files.first || raise(FileNotFoundError, "Could not find #{ basename }"))
end