require 'set'
require 'debci/status'
require 'debci/package'
module Debci
class Repository
def initialize(path=nil) path ||= Debci.config.data_basedir
@path = path
@data_dirs = Dir.glob(File.join(path, '*-*')).reject { |d| d =~ /\.old$/ }
end
def suites
@suites ||= @data_dirs.map { |d| File.basename(d).split('-').first }.uniq.sort
end
def architectures
@architectures ||= @data_dirs.map { |d| File.basename(d).split('-').last }.uniq.sort
end
def packages
@packages ||= @data_dirs.map { |d| Dir.glob(File.join(d, 'packages/*/*')) }.flatten.map { |d| File.basename(d) }.to_set
end
def suites_for(package)
package = String(package)
data_dirs_for(package).map { |d| File.basename(d).split('-').first }.uniq
end
def architectures_for(package)
package = String(package)
data_dirs_for(package).map { |d| File.basename(d).split('-').last }.uniq
end
class PackageNotFound < Exception
end
def find_package(name)
if !packages.include?(name)
raise PackageNotFound.new(name)
end
Debci::Package.new(name, self)
end
def search(query)
match = packages.select { |p| p == query }
if match.empty?
re = Regexp.new(query)
match = packages.select { |p| p =~ re }
end
match.map { |p| Debci::Package.new(p, self)}
end
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
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
suite_arch = File.basename(File.expand_path(File.dirname(file) + '/../../..'))
suite, architecture = suite_arch.split('-')
status = load_status(file, suite, architecture)
if status.newsworthy?
news << status
end
if news.size >= n
break
end
end
news
end
private
def data_dir(suite, arch, package)
File.join(@path, "#{suite}-#{arch}", 'packages', prefix(package), package)
end
def prefix(package)
String(package).sub(/^((lib)?.).*/, '\1')
end
def load_status(status_file, suite, architecture)
status = Debci::Status.from_file(status_file)
status.suite = suite
status.architecture = architecture
status
end
def data_dirs_for(package)
@data_dirs.select { |d| File.exist?(File.join(d, 'packages', prefix(package), package)) }
end
end
end