Class: Ki::RepositoryFinder

Inherits:
Object show all
Defined in:
lib/data_access/repository_finder.rb

Overview

Collects components from multiple repositories and provides methods to find components and versions

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ RepositoryFinder

Returns a new instance of RepositoryFinder.



25
26
27
28
29
# File 'lib/data_access/repository_finder.rb', line 25

def initialize(source)
  @source = source
  @components = load_all_components
  @versions = HashCache.new
end

Instance Attribute Details

#componentsObject (readonly)

Returns the value of attribute components.



23
24
25
# File 'lib/data_access/repository_finder.rb', line 23

def components
  @components
end

#versionsObject (readonly)

Returns the value of attribute versions.



22
23
24
# File 'lib/data_access/repository_finder.rb', line 22

def versions
  @versions
end

Instance Method Details

#all_repositories(source = @source) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/data_access/repository_finder.rb', line 132

def all_repositories(source=@source)
  node = source
  repositories = []
  while (node)
    repositories.concat(node.repositories.to_a)
    if node.root?
      break
    end
    node = node.parent
  end
  repositories
end

#check_status_value(version_statuses, key, &block) ⇒ Object

locates first matching status for the key and checks if that is ok for the block



161
162
163
164
165
166
167
168
# File 'lib/data_access/repository_finder.rb', line 161

def check_status_value(version_statuses, key, &block)
  version_statuses.each do |status_key, status_value|
    if status_key == key
      return block.call(status_value)
    end
  end
  false
end

#component(component) ⇒ Component

Finds matching component by name

Returns:



33
34
35
# File 'lib/data_access/repository_finder.rb', line 33

def component(component)
  @components[component]
end

#find_dep_by_name(ver, dep_str) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/data_access/repository_finder.rb', line 123

def find_dep_by_name(ver, dep_str)
  ver..dependencies.each do |dep|
    if dep["name"] == dep_str
      return dep["version_id"]
    end
  end
  nil
end

#has_statuses(version_statuses_original, status_rules, component) ⇒ Object

Checks if version’s statuses match status_rules



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/data_access/repository_finder.rb', line 171

def has_statuses(version_statuses_original, status_rules, component)
  ret = true
  if status_rules.size > 0
    ret = false
    version_statuses = version_statuses_original.reverse # latest first
    status_info = component.status_info
                                                         # go through each rule and see if this version has matching status
    status_rules.each do |key, op, value|
      if order = status_info[key]
        rule_value_index = order.index(value)
      end
      op_action = {
          "=" => ->(status_value) { status_value == value },
          "!=" => ->(status_value) { status_value != value },
          "<" => ->(status_value) { order.index(status_value) < rule_value_index },
          ">" => ->(status_value) { order.index(status_value) > rule_value_index },
          ">=" => ->(status_value) { order.index(status_value) >= rule_value_index },
          "<=" => ->(status_value) { order.index(status_value) <= rule_value_index }
      }.fetch(op) do
        raise "Not supported status operation: '#{key}#{op}#{value}'"
      end
      ret = check_status_value(version_statuses, key) do |status_value|
        op_action.call(status_value)
      end
    end
  end
  ret
end

#load_all_components(source = @source) ⇒ Object

Loads all Component from all repositories

Parameters:



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/data_access/repository_finder.rb', line 147

def load_all_components(source=@source)
  components = HashCache.new
  all_repositories(source).each do |info|
    info.components.each do |component_info|
      component = components.cache(component_info.component_id) do
        Component.new.component_id(component_info.component_id).finder(self).components([])
      end
      component.components << component_info
    end
  end
  components
end

#version(*args, &block) ⇒ Version

Finds version matching arguments, goes through versions in chronological order from latest to oldest.

  • note: block form can be used to iterate through all available version

Supported search formats:

  • version(“test/comp”) -> latest version

  • version(“test/comp:Smoke=green”), version(“test/comp”,“Smoke”=>“green”) -> latest version with matching status

  • version(“test/comp”){|version| … } -> iterates all available versions and returns latest version where block returns true, block argument is a Version

  • version(“test/comp:maturity!=alpha”) ->

Component can define ordering for status values: [“alpha”,“beta”,“gamma”]

  • version(“test/comp:maturity>alpha”) -> returns first version where maturity is beta or gamma

  • version(“test/comp:maturity>=alpha”) -> returns first version where maturity is alpha, beta or gamma

  • version(“test/comp:maturity<beta”) -> returns first version where maturity is alpha

  • version(“test/comp:maturity<=beta”) -> returns first version where maturity is alpha or beta

Version supports also Component and Version parameters:

  • version(my_version) -> returns my_version

  • version(my_component, “Smoke:green”) -> finds Version matching other parameters

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/data_access/repository_finder.rb', line 53

def version(*args, &block)
  if args.empty?
    raise "no parameters!"
  end
  status_rules = []
  component_or_version = nil
  dep_navigation_arr = []
  args.each do |str|
    if str.kind_of?(String)
      dep_nav_arr = str.split("->")
      strings = dep_nav_arr.delete_at(0).split(":")
      dep_navigation_arr.concat(dep_nav_arr)
      if component_or_version.nil?
        component_or_version = strings.delete_at(0)
      end
      strings.each do |s|
        status_rules << s.match(/(.*?)([<=>!]+)(.*)/).captures
      end
    elsif str.kind_of?(Hash)
      str.each_pair do |k, v|
        status_rules << [k, "=", v]
      end
    elsif str.kind_of?(Version)
      return str
    elsif str.kind_of?(Component) && component_or_version.nil?
      component_or_version = str.component_id
    else
      raise "Not supported '#{str.inspect}'"
    end
  end
  if component = @components[component_or_version]
    if status_rules.size > 0 || block
      component.versions.each do |v|
        ver = component.version_by_id(v.name)
        ok = has_statuses(ver.statuses, status_rules, component)
        if ok && block
          ok = block.call(ver)
        end
        if ok
          return ver
        end
      end
    else
      # picking latest version
      version_name = component.versions.first.name
    end
  else
    # user has defined an exact version
    version_arr = component_or_version.split("/")
    version_name = version_arr.delete_at(-1)
    component_str = version_arr.join("/")
    component = @components[component_str]
  end
  if component && version_name
    ver = component.version_by_id(version_name)
    if dep_navigation_arr
      dep_navigation_arr.each do |dep_str|
        dep_version_str = find_dep_by_name(ver, dep_str)
        if dep_version_str.nil?
          raise "Could not locate dependency '#{dep_str}' from '#{ver.version_id}'"
        end
        ver = version(dep_version_str)
      end
    end
    ver
  else
    nil
  end
end