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



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

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



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/debci/repository.rb', line 152

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

#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



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/debci/repository.rb', line 177

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