Class: Debci::Repository

Inherits:
Object
  • Object
show all
Defined in:
lib/debci/repository.rb

Overview

This class implements the backend access to the debci data files. Normally you should access the data through objects of the Debci::Package class, which you can obtain by calling this class' find_package method.

>> repository = Debci::Repository.new
>> package = repository.find_package('mypackage')

Defined Under Namespace

Classes: PackageNotFound

Instance Method Summary collapse

Constructor Details

#initialize(path = nil) ⇒ Repository

:nodoc:



17
18
19
20
21
# File 'lib/debci/repository.rb', line 17

def initialize(path=nil) # :nodoc:
  path ||= Debci.config.data_basedir
  @path = path
  @data_dirs = Dir.glob(File.join(path, 'packages', '*', '*')).reject { |d| d =~ /\.old$/ }
end

Instance Method Details

#architecturesObject

Returns an Array of architectures known to this debci instance



29
30
31
# File 'lib/debci/repository.rb', line 29

def architectures
  @architectures ||= @data_dirs.map { |d| File.basename(d) }.uniq.sort
end

#architectures_for(package) ⇒ Object

Returns an Array of architectures for which there is data for package.



71
72
73
74
# File 'lib/debci/repository.rb', line 71

def architectures_for(package)
  package = String(package)
  data_dirs_for(package).map { |d| File.basename(d) }.uniq
end

#each_packageObject

Iterates over all packages

For each package in the repostory, a Debci::Package object will be passed in to the block passed.

Example:

repository.each_package do |pkg| puts pkg end



102
103
104
105
106
107
# File 'lib/debci/repository.rb', line 102

def each_package
  packages.sort.each do |pkgname|
    pkg = Debci::Package.new(pkgname, self)
    yield pkg
  end
end

#find_package(name) ⇒ Object

Returns a single package by its names.

Raises a Debci::PackageNotFound is there is no package with that name.



83
84
85
86
87
88
89
# File 'lib/debci/repository.rb', line 83

def find_package(name)
  if !packages.include?(name)
    raise PackageNotFound.new(name)
  end

  Debci::Package.new(name, self)
end

#history_for(package, suite, architecture) ⇒ Object

Backend implementation for Debci::Package#history



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/debci/repository.rb', line 150

def history_for(package, suite, architecture)
  return unless File.exists?(file = File.join(data_dir(suite, architecture, package), 'history.json'))

  entries = nil

  File.open(file) do |f|
    entries = JSON.load(f)
  end

  entries.map { |test| Debci::Status.from_data(test, suite, architecture) }
end

#news_for(package, n = 10) ⇒ Object

Backend implementation for Debci::Package#news



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/debci/repository.rb', line 163

def news_for(package, n=10)
  suites = '{' + self.suites.join(',') + '}'
  architectures = '{' + self.architectures.join(',') + '}'
  history = Dir.glob(File.join(data_dir(suites, architectures, package), '[0-9]*.json')).sort_by { |f| File.basename(f) }

  news = []

  while !history.empty?
    file = history.pop
    dir = File.expand_path(File.dirname(file) + '/../..')
    suite = File.basename(File.dirname(dir))
    architecture = File.basename(dir)
    status = load_status(file, suite, architecture)
    if status.newsworthy?
      news << status
    end
    if news.size >= n
      break
    end
  end

  news
end

#packagesObject

Returns a Set of packages known to this debci instance



34
35
36
# File 'lib/debci/repository.rb', line 34

def packages
  @packages ||= (@data_dirs.map { |d| Dir.glob(File.join(d, '*/*')) }.flatten.map { |d| File.basename(d) } + Debci.blacklist.packages.keys).to_set
end

#platform_specific_issuesObject



138
139
140
141
142
143
144
145
146
147
# File 'lib/debci/repository.rb', line 138

def platform_specific_issues
  result = {}
  packages.each do |package|
    statuses = status_for(package).flatten
    if statuses.map(&:status).reject { |s| [:no_test_data, :tmpfail].include?(s) }.uniq.size > 1
      result[package] = statuses
    end
  end
  result
end

#prefixesObject

Returns an Array of package prefixes known to this debci instance



39
40
41
# File 'lib/debci/repository.rb', line 39

def prefixes
  @prefixes ||= @data_dirs.map { |d| Dir.glob(File.join(d, '*/')) }.flatten.map { |d| File.basename(d) }.uniq.sort
end

#search(query) ⇒ Object

Searches packages by name.

Returns a sorted Array of Debci::Package objects. On an exact match, it will return an Array with a single element. Otherwise all packages that match the query (which is converted into a regular expression) are returned.



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/debci/repository.rb', line 115

def search(query)
  # first try exact match
  match = packages.select { |p| p == query }

  # then try regexp match
  if match.empty?
    re = Regexp.new(query)
    match = packages.select { |p| p =~ re }
  end

  match.sort.map { |p| Debci::Package.new(p, self) }
end

#status_for(package) ⇒ Object

Backend implementation for Debci::Package#status



129
130
131
132
133
134
135
136
# File 'lib/debci/repository.rb', line 129

def status_for(package)
  architectures.map do |arch|
    suites.map do |suite|
      status_file = File.join(data_dir(suite, arch, package), 'latest.json')
      load_status(status_file, suite, arch)
    end
  end
end

#status_history(suite, architecture) ⇒ Object

Returns the status history for this debci instance



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/debci/repository.rb', line 188

def status_history(suite, architecture)
  return unless File.exists?(file = File.join(status_dir(suite, architecture), 'history.json'))

  data = nil

  begin
    File.open(file, 'r') do |f|
      data = JSON.load(f)
    end
  rescue JSON::ParserError
    true
  end

  data
end

#suitesObject

Returns an Array of suites known to this debci instance



24
25
26
# File 'lib/debci/repository.rb', line 24

def suites
  @suites ||= Dir.glob(File.join(@path, 'packages', '*')).reject { |d| d =~ /\.old$/ }.map { |d| File.basename(d) }.sort
end

#suites_for(package) ⇒ Object

Returns an Array of suites for which there is data for package.



65
66
67
68
# File 'lib/debci/repository.rb', line 65

def suites_for(package)
  package = String(package)
  data_dirs_for(package).map { |d| File.basename(File.dirname(d)) }.uniq
end

#tmpfail_packagesObject

Returns a Set of packages known to this debci instance that are temporarily failing. If no packages are temporarily failing, nothing is returned.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/debci/repository.rb', line 46

def tmpfail_packages
  tmpfail_packages = Set.new

  packages.each do |package|
    suites.each do |suite|
      architectures.each do |arch|
        status = load_status(File.join(data_dir(suite, arch, package), "latest.json"), suite, arch)

        if status.status == :tmpfail
          tmpfail_packages << package
        end
      end
    end
  end

  tmpfail_packages.sort.map { |p| Debci::Package.new(p, self) }
end