Module: Modulation::Paths

Defined in:
lib/modulation/paths.rb

Overview

Implements methods for expanding relative or incomplete module file names

Constant Summary collapse

CALLER_FILE_REGEXP =

Regexp for extracting filename from caller reference

/^([^\:]+)\:?/.freeze
TAGGED_REGEXP =
/^@([^\/]+)(\/.+)?$/.freeze
RE_TAG =
/^@([^\/]+)/.freeze
GEM_NAME_RE =
/^([^\/]+)/.freeze

Class Method Summary collapse

Class Method Details

.absolute_dir_path(path, caller_location) ⇒ String

Computes and verifies the absolute directory path

Parameters:

  • path

    String] unqualified path

  • caller_location (String)

    caller location

Returns:

  • (String)

    absolute directory path



62
63
64
65
66
67
68
69
# File 'lib/modulation/paths.rb', line 62

def absolute_dir_path(path, caller_location)
  path = expand_tag(path)
  caller_file = caller_location[CALLER_FILE_REGEXP, 1]
  return nil unless caller_file

  path = File.expand_path(path, File.dirname(caller_file))
  File.directory?(path) ? path : (raise "Invalid directory #{path}")
end

.absolute_path(path, caller_location) ⇒ String

Resolves the absolute path to the provided reference. If the file is not found, will try to resolve to a gem

Parameters:

  • path (String)

    unqualified file name

  • caller_location (String)

    caller location

Returns:

  • (String)

    absolute file name



50
51
52
53
54
55
56
# File 'lib/modulation/paths.rb', line 50

def absolute_path(path, caller_location)
  caller_file = caller_location[CALLER_FILE_REGEXP, 1]
  return nil unless caller_file

  path = File.expand_path(path, File.dirname(caller_file))
  check_path(path)
end

.add_tags(new_tags, caller_location) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/modulation/paths.rb', line 27

def add_tags(new_tags, caller_location)
  caller_file = caller_location[CALLER_FILE_REGEXP, 1]
  caller_dir = caller_file ? File.dirname(caller_file) : nil

  new_tags.each do |k, path|
    tags[k.to_s] = caller_dir ? File.expand_path(path, caller_dir) : path
  end
end

.check_path(path) ⇒ String?

Checks that the given path references an existing file, adding the .rb extension if needed

Parameters:

  • path (String)

    absolute file path (with/without .rb extension)

Returns:

  • (String, nil)

    path of file or nil if not found



75
76
77
78
79
80
81
# File 'lib/modulation/paths.rb', line 75

def check_path(path)
  if File.file?("#{path}.rb")
    path + '.rb'
  elsif File.file?(path)
    path
  end
end

.expand_tag(path) ⇒ Object



38
39
40
41
42
43
# File 'lib/modulation/paths.rb', line 38

def expand_tag(path)
  path.sub RE_TAG do
    tag = Regexp.last_match[1]
    tags[tag] || (raise "Invalid tag #{tag}")
  end
end

.find_gem_based_path(gemspec, path) ⇒ String

Finds full path for gem file based on gem’s require paths

Parameters:

  • gemspec (Gem::Specification)

    gem spec

  • path (String)

    given import path

Returns:

  • (String)

    full path



115
116
117
118
119
120
121
# File 'lib/modulation/paths.rb', line 115

def find_gem_based_path(gemspec, path)
  gemspec.full_require_paths.each do |p|
    full_path = check_path(File.join(p, path))
    return full_path if full_path
  end
  nil
end

.gem_uses_modulation?(gemspec) ⇒ Boolean

Returns true if given gemspec depends on modulation, which means it can be loaded using ‘import`

Parameters:

  • gemspec (Gem::Specification)

    gem spec

Returns:

  • (Boolean)

    does gem depend on modulation?



107
108
109
# File 'lib/modulation/paths.rb', line 107

def gem_uses_modulation?(gemspec)
  gemspec.dependencies.map(&:name).include?('modulation')
end

.lookup_gem_path(name) ⇒ String, Symbol

Resolves the provided path by looking for a corresponding gem. If no gem is found, returns nil. If the corresponding gem does not use modulation, returns :require_gem, which signals that the gem must be required.

Parameters:

  • name (String)

    gem name

Returns:

  • (String, Symbol)

    absolute path or :require_gem



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

def lookup_gem_path(name)
  gem = name[GEM_NAME_RE, 1] || name
  spec = Gem::Specification.find_by_name(gem)

  if gem_uses_modulation?(spec)
    find_gem_based_path(spec, name)
  else
    :require_gem
  end
rescue Gem::MissingSpecError
  nil
end

.modules_pathObject



23
24
25
# File 'lib/modulation/paths.rb', line 23

def modules_path
  File.join(Modulation::DIR, 'modulation/modules')
end

.process(path, caller_location) ⇒ Object



7
8
9
10
11
# File 'lib/modulation/paths.rb', line 7

def process(path, caller_location)
  path = expand_tag(path)
  absolute_path(path, caller_location) ||
    lookup_gem_path(path)
end

.tagsObject



17
18
19
20
21
# File 'lib/modulation/paths.rb', line 17

def tags
  @tags ||= {
    'modulation' => modules_path
  }
end