Class: Cliver::Dependency

Inherits:
Object
  • Object
show all
Defined in:
lib/cliver/dependency.rb

Overview

This is how a dependency is specified.

Constant Summary collapse

NotMet =

An exception class raised when assertion is not met

Class.new(ArgumentError)
VersionMismatch =

An exception that is raised when executable present, but no version that matches the requirements is present.

Class.new(Dependency::NotMet)
NotFound =

An exception that is raised when executable is not present at all.

Class.new(Dependency::NotMet)
PARSABLE_GEM_VERSION =

A pattern for extracting a Gem::Version-parsable version

/[0-9]+(.[0-9]+){0,4}(.[a-zA-Z0-9]+)?/.freeze

Instance Method Summary collapse

Constructor Details

#initialize(executables, *requirements, options = {}) {|executable_path| ... } ⇒ Dependency

Returns a new instance of Dependency.

Parameters:

  • executables (String, Array<String>)

    api-compatible executable names e.g, [‘python2’,‘python’]

  • requirements (Array<String>, String)

    splat of strings whose elements follow the pattern

    [<operator>] <version>
    

    Where <operator> is optional (default ‘=”) and in the set

    '=', '!=', '>', '<', '>=', '<=', or '~>'
    

    And <version> is dot-separated integers with optional alphanumeric pre-release suffix. See also Specifying Versions

  • options (Hash<Symbol,Object>) (defaults to: {})

Options Hash (options):

  • :detector (Cliver::Detector) — default: Detector.new
  • :detector (#to_proc, Object) — default: see Detector::generate
  • :filter (#to_proc) — default: {Cliver::Filter::IDENTITY}
  • :strict (Boolean) — default: false

    true - fail if first match on path fails

    to meet version requirements.
    This is used for Cliver::assert.
    

    false - continue looking on path until a

    sufficient version is found.
    
  • :path (String) — default: '*'

    the path on which to search for executables. If an asterisk (‘*`) is included in the supplied string, it is replaced with `ENV`

Yield Parameters:

  • executable_path (String)

    (see Detector#detect_version)

Yield Returns:

  • (String)

    containing a version that, once filtered, can be used for comparrison.



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/cliver/dependency.rb', line 51

def initialize(executables, *args, &detector)
  options = args.last.kind_of?(Hash) ? args.pop : {}
  @detector = Detector::generate(detector || options[:detector])
  @filter = options.fetch(:filter, Filter::IDENTITY).extend(Filter)
  @path = options.fetch(:path, '*')
  @strict = options.fetch(:strict, false)

  @executables = Array(executables).dup.freeze
  @requirement = args unless args.empty?

  check_compatibility!
end

Instance Method Details

#check_compatibility!void

This method returns an undefined value.

One of these things is not like the other ones… Some feature combinations just aren’t compatible. This method ensures the the features selected for this object are compatible with each-other.

Raises:

  • (ArgumentError)

    if incompatibility found



69
70
71
72
73
74
75
# File 'lib/cliver/dependency.rb', line 69

def check_compatibility!
  case
  when @executables.any? {|exe| exe[File::SEPARATOR] && !File.absolute_path?(exe) }
    # if the executable contains a path component, it *must* be absolute.
    raise ArgumentError, "Relative-path executable requirements are not supported."
  end
end

#detectsee #detect!

The non-raise variant of #detect!

Returns:

  • (see #detect!)

    or nil if no match found.



96
97
98
99
100
# File 'lib/cliver/dependency.rb', line 96

def detect
  detect!
rescue Dependency::NotMet
  nil
end

#detect!String

Detects an installed version of the executable that matches the requirements.

Returns:

  • (String)

    path to an executable that meets the requirements

Raises:



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cliver/dependency.rb', line 106

def detect!
  installed = {}
  installed_versions.each do |path, version|
    installed[path] = version
    return path if ENV['CLIVER_NO_VERIFY']
    return path if requirement_satisfied_by?(version)
    strict?
  end

  # dependency not met. raise the appropriate error.
  raise_not_found! if installed.empty?
  raise_version_mismatch!(installed)
end

#installed_versions {|executable_path, version| ... } ⇒ Hash<String,String>

Get all the installed versions of the api-compatible executables. If a block is given, it yields once per found executable, lazily.

Yield Parameters:

  • executable_path (String)
  • version (String)

Yield Returns:

  • (Boolean)
    • true if search should stop.

Returns:

  • (Hash<String,String>)

    executable_path, version



83
84
85
86
87
88
89
90
91
# File 'lib/cliver/dependency.rb', line 83

def installed_versions
  return enum_for(:installed_versions) unless block_given?

  find_executables.each do |executable_path|
    version = detect_version(executable_path)

    break(2) if yield(executable_path, version)
  end
end