diff options
-rwxr-xr-x | examples/p5solv | 67 | ||||
-rwxr-xr-x | examples/pysolv | 66 | ||||
-rwxr-xr-x | examples/rbsolv | 201 | ||||
-rw-r--r-- | examples/solv.i | 216 |
4 files changed, 410 insertions, 140 deletions
diff --git a/examples/p5solv b/examples/p5solv index 1b5be22..a1bf8ad 100755 --- a/examples/p5solv +++ b/examples/p5solv @@ -527,8 +527,9 @@ sub depglob { } sub limitjobs { - my ($pool, $jobs, $flags, $evr) = @_; + my ($pool, $jobs, $flags, $evrstr) = @_; my @jobs; + my $evr = $pool->str2id($evrstr); for my $j (@$jobs) { my $how = $j->{'how'}; my $sel = $how & $solv::Job::SOLVER_SELECTMASK; @@ -536,21 +537,20 @@ sub limitjobs { if ($flags == $solv::REL_ARCH) { $how |= $solv::Job::SOLVER_SETARCH; } elsif ($flags == $solv::REL_EQ && $sel == $solv::Job::SOLVER_SOLVABLE_NAME) { - $how |= $pool->id2str($evr) =~ /-/ ? $solv::Job::SOLVER_SETEVR : $solv::Job::SOLVER_SETEV; + $how |= $evrstr =~ /-/ ? $solv::Job::SOLVER_SETEVR : $solv::Job::SOLVER_SETEV; } push @jobs, $pool->Job($how, $what); } return @jobs; } -sub limitjobs_arch { +sub limitjobs_evrarch { my ($pool, $jobs, $flags, $evrstr) = @_; if ($evrstr =~ /^(.+)\.(.+?)$/ && validarch($pool, $2)) { - my $evr = $pool->str2id($1); - my @jobs = limitjobs($pool, $jobs, $solv::REL_ARCH, $pool->str2id($2)); - return limitjobs($pool, \@jobs, $flags, $evr); + $evrstr = $1; + $jobs = [ limitjobs($pool, $jobs, $solv::REL_ARCH, $2) ]; } - return limitjobs($pool, $jobs, $flags, $pool->str2id($evrstr)); + return limitjobs($pool, $jobs, $flags, $evrstr); } sub mkjobs_rel { @@ -560,13 +560,13 @@ sub mkjobs_rel { $flags |= $solv::REL_EQ if $rel =~ /=/; $flags |= $solv::REL_GT if $rel =~ />/; my @jobs = depglob($pool, $name, 1, 1); - return limitjobs($pool, \@jobs, $flags, $pool->str2id($evr)) if @jobs; + return limitjobs($pool, \@jobs, $flags, $evr) if @jobs; if (($name =~ /^(.+)\.(.+?)$/s) && validarch($pool, $2)) { my $arch = $2; @jobs = depglob($pool, $1, 1, 1); if (@jobs) { - @jobs = limitjobs($pool, \@jobs, $solv::REL_ARCH, $pool->str2id($arch)); - return limitjobs($pool, \@jobs, $flags, $pool->str2id($evr)); + @jobs = limitjobs($pool, \@jobs, $solv::REL_ARCH, $arch); + return limitjobs($pool, \@jobs, $flags, $evr); } } return (); @@ -579,17 +579,17 @@ sub mkjobs_nevra { if (($arg =~ /^(.+)\.(.+?)$/s) && validarch($pool, $2)) { my $arch = $2; @jobs = depglob($pool, $1, 1, 1); - return limitjobs($pool, \@jobs, $solv::REL_ARCH, $pool->str2id($arch)) if @jobs; + return limitjobs($pool, \@jobs, $solv::REL_ARCH, $arch) if @jobs; } if ($arg =~ /^(.+)-(.+?)$/s) { my $evr = $2; @jobs = depglob($pool, $1, 1, 0); - return limitjobs_arch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs; + return limitjobs_evrarch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs; } if ($arg =~ /^(.+)-(.+?-.+?)$/s) { my $evr = $2; @jobs = depglob($pool, $1, 1, 0); - return limitjobs_arch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs; + return limitjobs_evrarch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs; } return (); } @@ -707,7 +707,7 @@ for my $arg (@ARGV) { if ($cmd eq 'list' || $cmd eq 'info') { die("no package matched.\n") unless @jobs; for my $job (@jobs) { - for my $s ($pool->jobsolvables($job)) { + for my $s ($job->solvables()) { if ($cmd eq 'info') { printf "Name: %s\n", $s->str(); printf "Repo: %s\n", $s->{'repo'}->{'name'}; @@ -736,7 +736,7 @@ if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cm } for my $job (@jobs) { if ($cmd eq 'up') { - if ($job->{'how'} == $solv::Job::SOLVER_SOLVABLE_ALL || grep {$_->isinstalled()} $pool->jobsolvables($job)) { + if ($job->{'how'} == $solv::Job::SOLVER_SOLVABLE_ALL || grep {$_->isinstalled()} $job->solvables()) { $job->{'how'} |= $solv::Job::SOLVER_UPDATE; } else { $job->{'how'} |= $solv::Job::SOLVER_INSTALL; @@ -830,28 +830,27 @@ if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cm } print "\nTransaction summary:\n\n"; for my $c ($trans->classify()) { - my ($ctype, $pkgs, $fromid, $toid) = @$c; - if ($ctype == $solv::Transaction::SOLVER_TRANSACTION_ERASE) { - printf "%d erased packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_INSTALL) { - printf "%d installed packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_REINSTALLED) { - printf "%d reinstalled packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED) { - printf "%d downgraded packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_CHANGED) { - printf "%d changed packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_UPGRADED) { - printf "%d upgraded packages:\n", scalar(@$pkgs); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_VENDORCHANGE) { - printf "%d vendor changes from '%s' to '%s':\n", scalar(@$pkgs), $pool->id2str($fromid), $pool->id2str($toid); - } elsif ($ctype == $solv::Transaction::SOLVER_TRANSACTION_ARCHCHANGE) { - printf "%d arch changes from '%s' to '%s':\n", scalar(@$pkgs), $pool->id2str($fromid), $pool->id2str($toid); + if ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_ERASE) { + print "$c->{'count'} erased packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_INSTALL) { + print "$c->{'count'} installed packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_REINSTALLED) { + print "$c->{'count'} reinstalled packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED) { + print "$c->{'count'} downgraded packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_CHANGED) { + print "$c->{'count'} changed packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_UPGRADED) { + print "$c->{'count'} upgraded packages:\n"; + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_VENDORCHANGE) { + printf "$c->{'count'} vendor changes from '%s' to '%s':\n", $pool->id2str($c->{'fromid'}), $pool->id2str($c->{'toid'}); + } elsif ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_ARCHCHANGE) { + printf "$c->{'count'} arch changes from '%s' to '%s':\n", $pool->id2str($c->{'fromid'}), $pool->id2str($c->{'toid'}); } else { next; } - for my $p (@$pkgs) { - if ($ctype == $solv::Transaction::SOLVER_TRANSACTION_UPGRADED || $ctype == $solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED) { + for my $p ($c->solvables()) { + if ($c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_UPGRADED || $c->{'type'} == $solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED) { my $other = $trans->othersolvable($p); printf " - %s -> %s\n", $p->str(), $other->str(); } else { diff --git a/examples/pysolv b/examples/pysolv index d3541b2..f2f78be 100755 --- a/examples/pysolv +++ b/examples/pysolv @@ -570,8 +570,9 @@ def validarch(pool, arch): return False return pool.isknownarch(id) -def limitjobs(pool, jobs, flags, evr): +def limitjobs(pool, jobs, flags, evrstr): njobs = [] + evr = pool.str2id(evrstr) for j in jobs: how = j.how sel = how & Job.SOLVER_SELECTMASK @@ -579,20 +580,19 @@ def limitjobs(pool, jobs, flags, evr): if flags == solv.REL_ARCH: how |= Job.SOLVER_SETARCH elif flags == solv.REL_EQ and sel == Job.SOLVER_SOLVABLE_NAME: - if pool.id2str(evr).find('-') >= 0: + if evrstr.find('-') >= 0: how |= Job.SOLVER_SETEVR else: how |= Job.SOLVER_SETEV njobs.append(pool.Job(how, what)) return njobs -def limitjobs_arch(pool, jobs, flags, evr): - m = re.match(r'(.+)\.(.+?)$', evr) +def limitjobs_evrarch(pool, jobs, flags, evrstr): + m = re.match(r'(.+)\.(.+?)$', evrstr) if m and validarch(pool, m.group(2)): - jobs = limitjobs(pool, jobs, solv.REL_ARCH, pool.str2id(m.group(2))) - return limitjobs(pool, jobs, flags, pool.str2id(m.group(1))) - else: - return limitjobs(pool, jobs, flags, pool.str2id(evr)) + jobs = limitjobs(pool, jobs, solv.REL_ARCH, m.group(2)) + evrstr = m.group(1) + return limitjobs(pool, jobs, flags, evrstr) def mkjobs_filelist(pool, cmd, arg): if re.search(r'[[*?]', arg): @@ -624,13 +624,13 @@ def mkjobs_rel(pool, cmd, name, rel, evr): if rel.find('>') >= 0: flags |= solv.REL_GT jobs = depglob(pool, name, True, True) if jobs: - return limitjobs(pool, jobs, flags, pool.str2id(evr)) + return limitjobs(pool, jobs, flags, evr) m = re.match(r'(.+)\.(.+?)$', name) if m and validarch(pool, m.group(2)): jobs = depglob(pool, m.group(1), True, True) if jobs: - jobs = limitjobs(pool, jobs, solv.REL_ARCH, pool.str2id(m.group(2))) - return limitjobs(pool, jobs, flags, pool.str2id(evr)) + jobs = limitjobs(pool, jobs, solv.REL_ARCH, m.group(2)) + return limitjobs(pool, jobs, flags, evr) return [] def mkjobs_nevra(pool, cmd, arg): @@ -641,17 +641,17 @@ def mkjobs_nevra(pool, cmd, arg): if m and validarch(pool, m.group(2)): jobs = depglob(pool, m.group(1), True, True) if jobs: - return limitjobs(pool, jobs, solv.REL_ARCH, pool.str2id(m.group(2))) + return limitjobs(pool, jobs, solv.REL_ARCH, m.group(2)) m = re.match(r'(.+)-(.+?)$', arg) if m: jobs = depglob(pool, m.group(1), True, False) if jobs: - return limitjobs_arch(pool, jobs, solv.REL_EQ, m.group(2)) + return limitjobs_evrarch(pool, jobs, solv.REL_EQ, m.group(2)) m = re.match(r'(.+)-(.+?-.+?)$', arg) if m: jobs = depglob(pool, m.group(1), True, False) if jobs: - return limitjobs_arch(pool, jobs, solv.REL_EQ, m.group(2)) + return limitjobs_evrarch(pool, jobs, solv.REL_EQ, m.group(2)) return [] def mkjobs(pool, cmd, arg): @@ -834,7 +834,7 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == ' for job in jobs: if cmd == 'up': # up magic: use install instead of update if no installed package matches - if job.how == Job.SOLVER_SOLVABLE_ALL or filter(lambda s: s.isinstalled(), pool.jobsolvables(job)): + if job.how == Job.SOLVER_SOLVABLE_ALL or filter(lambda s: s.isinstalled(), job.solvables()): job.how |= Job.SOLVER_UPDATE else: job.how |= Job.SOLVER_INSTALL @@ -936,26 +936,26 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == ' print print "Transaction summary:" print - for ctype, pkgs, fromid, toid in trans.classify(): - if ctype == Transaction.SOLVER_TRANSACTION_ERASE: - print "%d erased packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_INSTALL: - print "%d installed packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_REINSTALLED: - print "%d reinstalled packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_DOWNGRADED: - print "%d downgraded packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_CHANGED: - print "%d changed packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_UPGRADED: - print "%d upgraded packages:" % len(pkgs) - elif ctype == Transaction.SOLVER_TRANSACTION_VENDORCHANGE: - print "%d vendor changes from '%s' to '%s':" % (len(pkgs), pool.id2str(fromid), pool.id2str(toid)) - elif ctype == Transaction.SOLVER_TRANSACTION_ARCHCHANGE: - print "%d arch changes from '%s' to '%s':" % (len(pkgs), pool.id2str(fromid), pool.id2str(toid)) + for cl in trans.classify(): + if cl.type == Transaction.SOLVER_TRANSACTION_ERASE: + print "%d erased packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_INSTALL: + print "%d installed packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_REINSTALLED: + print "%d reinstalled packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_DOWNGRADED: + print "%d downgraded packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_CHANGED: + print "%d changed packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_UPGRADED: + print "%d upgraded packages:" % cl.count + elif cl.type == Transaction.SOLVER_TRANSACTION_VENDORCHANGE: + print "%d vendor changes from '%s' to '%s':" % (cl.count, pool.id2str(cl.fromid), pool.id2str(cl.toid)) + elif cl.type == Transaction.SOLVER_TRANSACTION_ARCHCHANGE: + print "%d arch changes from '%s' to '%s':" % (cl.count, pool.id2str(cl.fromid), pool.id2str(cl.toid)) else: continue - for p in pkgs: + for p in cl.solvables(): if ctype == Transaction.SOLVER_TRANSACTION_UPGRADED or ctype == Transaction.SOLVER_TRANSACTION_DOWNGRADED: op = trans.othersolvable(p) print " - %s -> %s" % (p.str(), op.str()) diff --git a/examples/rbsolv b/examples/rbsolv index 3ab58f2..6c8afbe 100755 --- a/examples/rbsolv +++ b/examples/rbsolv @@ -399,6 +399,11 @@ class Repo_system < Repo_generic end +def validarch?(pool, arch) + return false unless arch && arch != '' + id = pool.str2id(arch, false) + return id != 0 && pool.isknownarch?(id) +end def depglob(pool, name, globname, globdep) id = pool.str2id(name, false) @@ -434,6 +439,69 @@ def depglob(pool, name, globname, globdep) return [] end +def limitjobs(pool, jobs, flags, evrstr) + njobs = [] + evr = pool.str2id(evrstr) + for j in jobs + how = j.how + sel = how & Solv::Job::SOLVER_SELECTMASK + what = pool.rel2id(j.what, evr, flags) + if flags == Solv::REL_ARCH + how |= Solv::Job::SOLVER_SETARCH + elsif flags == Solv::REL_EQ && sel == Solv::Job::SOLVER_SOLVABLE_NAME + how |= evrstr.include?(?-) ? Solv::Job::SOLVER_SETEVR : Solv::Job::SOLVER_SETEV + end + njobs << pool.Job(how, what) + end + return njobs +end + +def limitjobs_evrarch(pool, jobs, flags, evrstr) + if evrstr =~ /^(.+)\.(.+?)$/ && validarch?(pool, $2) + evrstr = $1 + jobs = limitjobs(pool, jobs, Solv::REL_ARCH, $2) + end + return limitjobs(pool, jobs, flags, evrstr) +end + +def mkjobs_rel(pool, cmd, name, rel, evr) + flags = 0 + flags |= Solv::REL_LT if rel.include?(?<) + flags |= Solv::REL_EQ if rel.include?(?=) + flags |= Solv::REL_GT if rel.include?(?>) + jobs = depglob(pool, name, true, true) + return limitjobs(pool, jobs, flags, evr) unless jobs.empty? + if (name =~ /^(.+)\.(.+?)$/) && validarch?(pool, $2) + arch = $2 + jobs = depglob(pool, name, true, true) + return [] if jobs.empty? + jobs = limitjobs(pool, jobs, Solv::REL_ARCH, arch) + return limitjobs(pool, jobs, flags, evr) + end + return [] +end + +def mkjobs_nevra(pool, cmd, arg) + jobs = depglob(pool, arg, true, true) + return jobs unless jobs.empty? + if ((arg =~ /^(.+)\.(.+?)$/) && validarch?(pool, $2)) + arch = $2 + jobs = depglob(pool, $1, true, true) + return limitjobs(pool, jobs, Solv::REL_ARCH, arch) unless jobs.empty? + end + if (arg =~ /^(.+)-(.+?)$/) + evr = $2 + jobs = depglob(pool, $1, true, false) + return limitjobs_evrarch(pool, jobs, Solv::REL_EQ, evr) unless jobs.empty? + end + if (arg =~ /^(.+)-(.+?-.+?)$/) + evr = $2 + jobs = depglob(pool, $1, true, false) + return limitjobs_evrarch(pool, jobs, Solv::REL_EQ, evr) unless jobs.empty? + end + return [] +end + def mkjobs_filelist(pool, cmd, arg) type = Solv::Dataiterator::SEARCH_STRING type = Solv::Dataiterator::SEARCH_GLOB if arg =~ /[\[*?]/ @@ -463,7 +531,11 @@ def mkjobs(pool, cmd, arg) jobs = mkjobs_filelist(pool, cmd, arg) return jobs unless jobs.empty? end - return depglob(pool, arg, true, true) + if (arg =~ /^(.+?)\s*([<=>]+)\s*(.+?)$/) + return mkjobs_rel(pool, cmd, $1, $2, $3) + else + return mkjobs_nevra(pool, cmd, arg) + end end args = ARGV @@ -532,21 +604,122 @@ for arg in args jobs += njobs end -for job in jobs - job.how |= Solv::Job::SOLVER_ERASE +if cmd == 'list' || cmd == 'info' + abort("no package matched.") if jobs.empty? + for job in jobs + for s in job.solvables() + if cmd == 'info' + puts "Name: #{s.str}" + puts "Repo: #{s.repo.name}" + puts "Summary: #{s.lookup_str(Solv::SOLVABLE_SUMMARY)}" + str = s.lookup_str(Solv::SOLVABLE_URL) + puts "Url: #{str}" if str + str = s.lookup_str(Solv::SOLVABLE_LICENSE) + puts "License: #{str}" if str + puts "Description:\n#{s.lookup_str(Solv::SOLVABLE_DESCRIPTION)}" + puts + else + puts " - #{s.str} [#{s.repo.name}]" + puts " #{s.lookup_str(Solv::SOLVABLE_SUMMARY)}" + end + end + end + exit end -solver = pool.Solver -problems = solver.solve(jobs) -for problem in problems - puts "Problem #{problem.id}:" - puts problem.findproblemrule.info.problemstr - solutions = problem.solutions - for solution in solutions - puts " Solution #{solution.id}:" - elements = solution.elements - for element in elements - puts " - type #{element.type}" +if cmd == 'install' || cmd == 'erase' || cmd == 'up' || cmd == 'dup' || cmd == 'verify' + if jobs.empty? + if cmd == 'up' || cmd == 'verify' + jobs = [ pool.Job(Solv::Job::SOLVER_SOLVABLE_ALL, 0) ] + elsif cmd != 'dup' + abort("no package matched.") + end + end + for job in jobs + if cmd == 'up' + if job.how == Solv::Job::SOLVER_SOLVABLE_ALL || job.solvables.any? {|s| s.isinstalled?} + job.how |= Solv::Job::SOLVER_UPDATE + else + job.how |= Solv::Job::SOLVER_INSTALL + end + elsif cmd == 'install' + job.how |= Solv::Job::SOLVER_INSTALL + elsif cmd == 'erase' + job.how |= Solv::Job::SOLVER_ERASE + elsif cmd == 'dup' + job.how |= Solv::Job::SOLVER_DISTUPGRADE + elsif cmd == 'verify' + job.how |= Solv::Job::SOLVER_VERIFY + end + end + + solver = nil + #pool.set_debuglevel(1) + while true + solver = pool.Solver + solver.ignorealreadyrecommended = true + solver.allowuninstall = true if cmd == 'erase' + if cmd == 'dup' && jobs.empty? + solver.distupgrade = true + solver.updatesystem = true + solver.allowdowngrade = true + solver.allowvendorchange = true + solver.allowarchchange = true + solver.dosplitprovides = true + elsif cmd == 'up' && jobs.length == 1 && jobs[0].how == (Solv::Job::SOLVER_UPDATE | Solv::Job::SOLVER_SOLVABLE_ALL) + solver.dosplitprovides = true + end + problems = solver.solve(jobs) + break if problems.empty? + for problem in problems + puts "Problem #{problem.id}:" + puts problem.findproblemrule.info.problemstr + solutions = problem.solutions + for solution in solutions + puts " Solution #{solution.id}:" + elements = solution.elements(true) + for element in elements + puts " - #{element.str}" + end + end + exit + end + end + trans = solver.transaction + solver = nil + if trans.isempty? + puts "Nothing to do." + exit + end + puts "\nTransaction summary:\n" + for cl in trans.classify() + if cl.type == Solv::Transaction::SOLVER_TRANSACTION_ERASE + puts "#{cl.count} erased packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_INSTALL + puts "#{cl.count} installed packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_REINSTALLED + puts "#{cl.count} reinstalled packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED + puts "#{cl.count} downgraded packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_CHANGED + puts "#{cl.count} changed packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_UPGRADED + puts "#{cl.count} upgraded packages:" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_VENDORCHANGE + puts "#{cl.count} vendor changes from '#{pool.id2str(cl.fromid)}' to '#{pool.id2str(cl.toid)}':" + elsif cl.type == Solv::Transaction::SOLVER_TRANSACTION_ARCHCHANGE + puts "#{cl.count} arch changes from '#{pool.id2str(cl.fromid)}' to '#{pool.id2str(cl.toid)}':" + else + next + end + for p in cl.solvables + if cl.type == Solv::Transaction::SOLVER_TRANSACTION_UPGRADED || cl.type == Solv::Transaction::SOLVER_TRANSACTION_DOWNGRADED + puts " - #{p.str} -> #{trans.othersolvable(p).str}" + else + puts " - #{p.str}" + end end + puts end + puts "install size change: #{trans.calc_installsizechange()} K\n\n" end diff --git a/examples/solv.i b/examples/solv.i index 9ea64f2..fd38fdb 100644 --- a/examples/solv.i +++ b/examples/solv.i @@ -352,8 +352,12 @@ typedef VALUE AppObjectPtr; #define true 1 #define false 1 -#define SOLVER_SOLUTION_ERASE -100 -#define SOLVER_SOLUTION_REPLACE -101 +#define SOLVER_SOLUTION_ERASE -100 +#define SOLVER_SOLUTION_REPLACE -101 +#define SOLVER_SOLUTION_REPLACE_DOWNGRADE -102 +#define SOLVER_SOLUTION_REPLACE_ARCHCHANGE -103 +#define SOLVER_SOLUTION_REPLACE_VENDORCHANGE -104 + typedef struct chksum Chksum; typedef int bool; typedef void *AppObjectPtr; @@ -430,6 +434,15 @@ typedef struct { Id dep; } Ruleinfo; +typedef struct { + Transaction *transaction; + int mode; + Id type; + int count; + Id fromid; + Id toid; +} TransactionClass; + typedef Dataiterator Datamatch; %} @@ -591,6 +604,13 @@ typedef struct { Pool * const pool; } Transaction; +typedef struct { + Transaction * const transaction; + Id const type; + Id const fromid; + Id const toid; + int const count; +} TransactionClass; %extend Job { @@ -976,6 +996,9 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { Id towhatprovides(Queue q) { return pool_queuetowhatprovides($self, &q); } +#ifdef SWIGRUBY + %rename("isknownarch?") isknownarch; +#endif bool isknownarch(Id id) { Pool *pool = $self; if (!id || id == ID_EMPTY) @@ -1010,7 +1033,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { repo_empty($self, reuseids); } #ifdef SWIGRUBY - %rename("isempty?") isempty(); + %rename("isempty?") isempty; #endif bool isempty() { return !$self->nsolvables; @@ -1122,7 +1145,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { repodata_create_stubs(data); } #ifdef SWIGRUBY - %rename("iscontiguous?") iscontiguous(); + %rename("iscontiguous?") iscontiguous; #endif bool iscontiguous() { int i; @@ -1478,11 +1501,14 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { return solvable_get_location($self->pool->solvables + $self->id, OUTPUT); } #ifdef SWIGRUBY - %rename("installable?") installable(); + %rename("installable?") installable; #endif bool installable() { return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id)); } +#ifdef SWIGRUBY + %rename("isinstalled?") isinstalled; +#endif bool isinstalled() { Pool *pool = $self->pool; return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed; @@ -1612,37 +1638,105 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { int element_count() { return solver_solutionelement_count($self->solv, $self->problemid, $self->id); } + %newobject elements; - %typemap(out) Queue elements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1, id)); - Queue elements() { + %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3])); + Queue elements(bool expandreplaces=0) { Queue q; int i, cnt; queue_init(&q); - cnt = solver_solution_count($self->solv, $self->id); + cnt = solver_solutionelement_count($self->solv, $self->problemid, $self->id); for (i = 1; i <= cnt; i++) - queue_push(&q, i); + { + Id p, rp, type; + solver_next_solutionelement($self->solv, $self->problemid, $self->id, i - 1, &p, &rp); + if (p > 0) { + type = rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE; + } else { + type = p; + p = rp; + rp = 0; + } + if (type == SOLVER_SOLUTION_REPLACE && expandreplaces) { + int illegal = policy_is_illegal(self->solv, self->solv->pool->solvables + p, self->solv->pool->solvables + rp, 0); + if (illegal) { + if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) { + queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_DOWNGRADE); + queue_push2(&q, p, rp); + } + if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) { + queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_ARCHCHANGE); + queue_push2(&q, p, rp); + } + if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) { + queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE); + queue_push2(&q, p, rp); + } + continue; + } + } + queue_push2(&q, i, type); + queue_push2(&q, p, rp); + } return q; } } %extend Solutionelement { - Solutionelement(Solution *s, Id id) { + Solutionelement(Solver *solv, Id problemid, Id solutionid, Id id, Id type, Id p, Id rp) { Solutionelement *e; e = sat_calloc(1, sizeof(*e)); - e->solv = s->solv; - e->problemid = s->problemid; - e->solutionid = s->id; + e->solv = solv; + e->problemid = problemid; + e->solutionid = id; e->id = id; - solver_next_solutionelement(e->solv, e->problemid, e->solutionid, e->id - 1, &e->p, &e->rp); - if (e->p > 0) { - e->type = e->rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE; - } else { - e->type = e->p; - e->p = e->rp; - e->rp = 0; - } + e->type = type; + e->p = p; + e->rp = rp; return e; } + const char *str() { + Id p = $self->type; + Id rp = $self->p; + if (p == SOLVER_SOLUTION_ERASE) + { + p = rp; + rp = 0; + } + else if (p == SOLVER_SOLUTION_REPLACE) + { + p = rp; + rp = $self->rp; + } + else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE) + return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_DOWNGRADE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0); + else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE) + return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_ARCHCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0); + else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE) + return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_VENDORCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0); + return solver_solutionelement2str($self->solv, p, rp); + } + %newobject replaceelements; + %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp)); + Queue replaceelements() { + Queue q; + int illegal; + + queue_init(&q); + if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0) + illegal = 0; + else + illegal = policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0); + if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) + queue_push(&q, SOLVER_SOLUTION_REPLACE_DOWNGRADE); + if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) + queue_push(&q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE); + if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) + queue_push(&q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE); + if (!q.count) + queue_push(&q, $self->type); + return q; + } int illegalreplace() { if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0) return 0; @@ -1668,7 +1762,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { Job *Job() { if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE) return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->p); - if ($self->type == SOLVER_SOLUTION_REPLACE) + if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE) return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->rp); if ($self->type == SOLVER_SOLUTION_ERASE) return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE, $self->p); @@ -1702,6 +1796,9 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) { static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE; static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE; static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE; + static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE; + static const int SOLVER_SOLUTION_REPLACE_ARCHCHANGE = SOLVER_SOLUTION_REPLACE_ARCHCHANGE; + static const int SOLVER_SOLUTION_REPLACE_VENDORCHANGE = SOLVER_SOLUTION_REPLACE_VENDORCHANGE; static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE; static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE; @@ -1794,55 +1891,35 @@ rb_eval_string( sat_free($self); } #ifdef SWIGRUBY - %rename("isempty?") isempty(); + %rename("isempty?") isempty; #endif bool isempty() { return $self->steps.count == 0; } - Queue classify_helper(int mode) { + + %newobject othersolvable; + XSolvable *othersolvable(XSolvable *s) { + Id op = transaction_obs_pkg($self, s->id); + return new_XSolvable($self->pool, op); + } + + %newobject allothersolvables; + %typemap(out) Queue allothersolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id)); + Queue allothersolvables(XSolvable *s) { Queue q; queue_init(&q); - transaction_classify($self, mode, &q); + transaction_all_obs_pkgs($self, s->id, &q); return q; } - Queue classify_pkgs_helper(int mode, Id cl, Id from, Id to) { + + %typemap(out) Queue classify Queue2Array(TransactionClass *, 4, new_TransactionClass(arg1, arg2, id, idp[1], idp[2], idp[3])); + %newobject classify; + Queue classify(int mode = 0) { Queue q; queue_init(&q); - transaction_classify_pkgs($self, mode, cl, from, to, &q); + transaction_classify($self, mode, &q); return q; } - %newobject othersolvable; - XSolvable *othersolvable(XSolvable *s) { - Id op = transaction_obs_pkg($self, s->id); - return new_XSolvable($self->pool, op); - } -#if defined(SWIGPYTHON) - %pythoncode { - def classify(self, mode = 0): - r = [] - cr = self.classify_helper(mode) - for type, cnt, fromid, toid in zip(*([iter(cr)] * 4)): - if type != self.SOLVER_TRANSACTION_IGNORE: - r.append([ type, [ self.pool.solvables[j] for j in self.classify_pkgs_helper(mode, type, fromid, toid) ], fromid, toid ]) - return r - } -#endif -#if defined(SWIGPERL) - %perlcode { - sub solv::Transaction::classify { - my ($self, $mode) = @_; - $mode ||= 0; - my @r = $self->classify_helper($mode); - my @res; - while (@r) { - my ($type, $cnt, $fromid, $toid) = splice(@r, 0, 4); - next if $type == $solv::Transaction::SOLVER_TRANSACTION_IGNORE; - push @res, [$type, [ map {$self->{'pool'}->{'solvables'}->[$_]} $self->classify_pkgs_helper($mode, $type, $fromid, $toid) ], $fromid, $toid]; - } - return @res; - } - } -#endif %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id)); %newobject newpackages; @@ -1886,6 +1963,27 @@ rb_eval_string( } } +%extend TransactionClass { + TransactionClass(Transaction *trans, int mode, Id type, int count, Id fromid, Id toid) { + TransactionClass *cl = sat_calloc(1, sizeof(*cl)); + cl->transaction = trans; + cl->mode = mode; + cl->type = type; + cl->count = count; + cl->fromid = fromid; + cl->toid = toid; + return cl; + } + %newobject solvables; + %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->transaction->pool, id)); + Queue solvables() { + Queue q; + queue_init(&q); + transaction_classify_pkgs($self->transaction, $self->mode, $self->type, $self->fromid, $self->toid, &q); + return q; + } +} + %extend XRule { XRule(Solver *solv, Id id) { if (!id) |