15 def initialize(name, type, attribs = {})
18 @attribs = attribs.dup
22 return @attribs['enabled'].to_i != 0
26 return @attribs['autorefresh'].to_i != 0
30 chksum = Solv::Chksum.new(Solv::REPOKEY_TYPE_SHA256)
35 def calc_cookie_file(filename)
36 chksum = Solv::Chksum.new(Solv::REPOKEY_TYPE_SHA256)
38 chksum.add_stat(filename)
42 def cachepath(ext = nil)
43 path = @name.sub(/^\./, '_')
44 path += ext ? "_#{ext}.solvx" : '.solv'
45 return '/var/cache/solv/' + path.gsub(/\//, '_')
49 @handle = pool.add_repo(@name)
50 @handle.appdata = self
51 @handle.priority = 99 - @attribs['priority'] if @attribs['priority']
52 dorefresh = autorefresh?
55 s = File.stat(cachepath)
56 dorefresh = false if s && Time.now - s.mtime < @attribs['metadata_expire']
57 rescue SystemCallError
61 if !dorefresh && usecachedrepo()
62 puts "repo: '#{@name}' cached"
65 return load_if_changed()
76 def download(file, uncompress, chksum, markincomplete = false)
80 def usecachedrepo(ext, mark = false)
81 cookie = ext ? @extcookie : @cookie
83 repopath = cachepath(ext)
84 @handle.add_solv(repopath)
94 def writecachedrepo(ext, info = nil)
99 class Repo_rpmmd < Repo_generic
102 print "rpmmd repo '#{@attribs['alias']}: "
103 f = download("repodata/repomd.xml", false, nil, nil)
105 puts "no repomd.xml file, skipped"
110 @cookie = calc_cookie_fp(f)
111 if usecachedrepo(nil, true)
121 class Repo_susetags < Repo_generic
124 print "susetags repo '#{@attribs['alias']}: "
125 f = download("content", false, nil, nil)
127 puts "no content file, skipped"
132 @cookie = calc_cookie_fp(f)
133 if usecachedrepo(nil, true)
143 class Repo_unknown < Repo_generic
145 puts "unsupported repo '#{@attribs['alias']}: skipped"
150 class Repo_system < Repo_generic
152 @handle = pool.add_repo(@name)
153 @handle.appdata = self
154 pool.installed = @handle
155 print "rpm database: "
156 @cookie = calc_cookie_file("/var/lib/rpm/Packages")
157 if usecachedrepo(nil)
162 @handle.add_products("/etc/products.d", Solv::Repo::REPO_NO_INTERNALIZE)
163 @handle.add_rpmdb(nil, Solv::Repo::REPO_REUSE_REPODATA)
169 def depglob(pool, name, globname, globdep)
170 id = pool.str2id(name, false)
173 providers = pool.providers(id)
174 if globname && providers.find {|s| s.nameid == id }
175 return [ pool.Job(Solv::Job::SOLVER_SOLVABLE_NAME, id) ]
178 puts "[using capability match for '#{name}']" if globname && globdep
179 return [ pool.Job(Solv::Job::SOLVER_SOLVABLE_PROVIDES, id) ]
182 return [] unless name =~ /[\[*?]/;
185 for d in pool.Dataiterator(0, Solv::SOLVABLE_NAME, name, Solv::Dataiterator::SEARCH_GLOB)
187 idmatches[s.nameid] = 1 if s.installable?
190 return idmatches.keys.sort.collect { |id| pool.Job(Solv::Job::SOLVER_SOLVABLE_NAME, id) }
194 idmatches = pool.matchprovidingids(name, Solv::Dataiterator::SEARCH_GLOB);
196 puts "[using capability match for '#{name}']"
197 return idmatches.sort.collect { |id| pool.Job(Solv::Job::SOLVER_SOLVABLE_PROVIDES, id) }
206 cmd = 'list' if cmd == 'li'
207 cmd = 'install' if cmd == 'in'
208 cmd = 'erase' if cmd == 'rm'
209 cmd = 'verify' if cmd == 've'
210 cmd = 'search' if cmd == 'se'
213 for reposdir in [ '/etc/zypp/repos.d' ] do
214 next unless FileTest.directory?(reposdir)
215 for reponame in Dir["#{reposdir}/*.repo"].sort do
216 cfg = IniFile.new(reponame)
217 cfg.each_section do |ali|
218 repoattr = { 'alias' => ali, 'enabled' => 0, 'priority' => 99, 'autorefresh' => 1, 'type' => 'rpm-md', 'metadata_expire' => 900}
219 repoattr.update(cfg[ali])
220 if repoattr['type'] == 'rpm-md'
221 repo = Repo_rpmmd.new(ali, 'repomd', repoattr)
222 elsif repoattr['type'] == 'yast2'
223 repo = Repo_susetags.new(ali, 'susetags', repoattr)
225 repo = Repo_unknown.new(ali, 'unknown', repoattr)
232 pool = Solv::Pool.new()
233 # require 'sys/uname' ; sysarch = Sys::Uname.machine
234 sysarch = `uname -p`.strip
235 pool.setarch(sysarch)
237 sysrepo = Repo_system.new('@System', 'system')
240 repo.load(pool) if repo.enabled?
245 for di in pool.Dataiterator(0, Solv::SOLVABLE_NAME, args[0], Solv::Dataiterator::SEARCH_SUBSTRING | Solv::Dataiterator::SEARCH_NOCASE)
246 matches[di.solvid] = true
248 for solvid in matches.keys.sort
249 s = pool.solvables[solvid]
250 puts "- #{s.str} [#{s.repo.name}]"
256 pool.createwhatprovides
260 njobs = depglob(pool, ARGV[0], true, true)
261 abort("nothing matches '#{arg}'") if njobs.empty?
266 job.how |= Solv::Job::SOLVER_ERASE
270 problems = solver.solve(jobs)
271 for problem in problems
272 puts "Problem #{problem.id}:"
273 puts problem.findproblemrule.info.problemstr
274 solutions = problem.solutions
275 for solution in solutions
276 puts " Solution #{solution.id}:"
277 elements = solution.elements
278 for element in elements:
279 puts " - type #{element.type}"