Note that boolean methods have an added trailing ``?'', to be consistent with
other ruby modules:
- puts "empty repo" if repo.isempty?
+ puts "empty" if repo.isempty?
+Tcl Specifics
+-------------
+Libsolv's tcl bindings can be loaded with the following statement:
+
+ TCL package require solv
+
+Objects are either created by calling class name prefixed with ``new_'',
+or they are returned by calling methods on other objects.
+
+ TCL set pool [solv::new_Pool]
+ TCL set repo [$pool add_repo "my_first_repo"]
+
+Swig provides a ``cget'' method to read object attributes, and a
+``configure'' method to write them:
+
+ TCL $pool configure -appdata 42
+ TCL puts "appdata is [$pool cget -appdata]"
+
+The tcl bindings provide a little helper to work with iterators in
+a foreach style:
+
+ TCL set iter [$pool solvables_iter]
+ TCL solv::iter s $iter { ... }
+
+libsolv's arrays are mapped to tcl's lists:
+
+ TCL set jobs [list $job1 $job2]
+ TCL set problems [$solver solve $jobs]
+ TCL puts "We have [llength $problems] problems..."
+
+Stringification is done by calling the object's ``str'' method.
+
+ TCL puts [$dep str]
+
+There is one exception: you have to use ``stringify'' for Datamatch
+objects, as swig reports a clash with the ``str'' attribute.
+Some objects also support a ``=='' method for equality tests, and a
+``!='' method.
+
+Swig implements all constants as numeric variables, constants belonging
+to a libsolv class are prefixed with the class name:
+
+ TCL $pool set_flag $solv::Pool_POOL_FLAG_OBSOLETEUSESCOLORS 1
+ TCL puts [$solvable lookup_str $solv::SOLVABLE_SUMMARY]
+
+
The Solv Class
--------------
This is the main namespace of the library, you cannot create objects of this
pool = solv.Pool()
pool = Solv::Pool.new()
-Create a new pool instance. In most cases you just need
-one pool.
+Create a new pool instance. In most cases you just need one pool.
+Note that the returned object "owns" the pool, i.e. if the object is
+freed, the pool is also freed. You can use the disown method to
+break this ownership relation.
=== ATTRIBUTES ===
pool.free()
pool.free()
-Free a pool. This is currently done with a method instead of relying on
-reference counting or garbage collection because it's hard to track every
-reference to a pool.
+Force a free of the pool. After this call, you must not access any object
+that still references the pool.
+
+ void disown()
+ $pool->disown();
+ pool.disown()
+ pool.disown()
+
+Break the ownership relation betwen the binding object and the pool. After
+this call, the pool will not get freed even if the object goes out of
+scope. This also means that you must manually call the free method to free
+the pool data.
void setdebuglevel(int level)
$pool->setdebuglevel($level);
You can then load the data (maybe fetching it first from an remote server).
The callback should return true if the data has been made available.
+ /* bindings only */
+ $pool->appdata_disown()
+ pool.appdata_disown()
+ pool.appdata_disown()
+
+Decrement the reference count of the appdata object. This can be used to break
+circular references (e.g. if the pool's appdata value points to some meta data
+structure that contains a pool handle). If used incorrectly, this method can
+lead to application crashes, so beware. (This method is a no-op for ruby and tcl.)
+
=== DATA RETRIEVAL METHODS ===
In the following functions, the _keyname_ argument describes what to retrieve.
Lookup functions. Return the data element stored in the specified solvable.
You should probably use the methods of the Solvable class instead.
- Dataiterator Dataiterator(Id solvid, Id keyname, const char *match, int flags)
+ Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0)
+ my $di = $pool->Dataiterator($keyname, $match, $flags);
+ di = pool.Dataiterator(keyname, match, flags)
+ di = pool.Dataiterator(keyname, match, flags)
+
+ Dataiterator Dataiterator_solvid(Id solvid, Id keyname, const char *match = 0, int flags = 0)
my $di = $pool->Dataiterator($solvid, $keyname, $match, $flags);
di = pool.Dataiterator(solvid, keyname, match, flags)
di = pool.Dataiterator(solvid, keyname, match, flags)
for d in di
Iterate over the matching data elements. See the Dataiterator class for more
-information.
+information. The Dataiterator method iterates over all solvables in the pool,
+whereas the Dataiterator_solvid only iterates over the specified solvable.
=== ID METHODS ===
Create a Selection consisting of all packages in the repository.
- Dataiterator Dataiterator(Id p, Id key, const char *match, int flags)
- my $di = $repo->Dataiterator($solvid, $keyname, $match, $flags);
- di = repo.Dataiterator(solvid, keyname, match, flags)
- di = repo.Dataiterator(solvid, keyname, match, flags)
+ Dataiterator Dataiterator(Id key, const char *match = 0, int flags = 0)
+ my $di = $repo->Dataiterator($keyname, $match, $flags);
+ di = repo.Dataiterator(keyname, match, flags)
+ di = repo.Dataiterator(keyname, match, flags)
+
+ Dataiterator Dataiterator_meta(Id key, const char *match = 0, int flags = 0)
+ my $di = $repo->Dataiterator_meta($keyname, $match, $flags);
+ di = repo.Dataiterator_meta(keyname, match, flags)
+ di = repo.Dataiterator_meta(keyname, match, flags)
for my $d (@$di)
for d in di:
for d in di
Iterate over the matching data elements in this repository. See the
-Dataiterator class for more information.
+Dataiterator class for more information. The Dataiterator() method
+iterates over all solvables in a repository, whereas the Dataiterator_meta
+method only iterates over the repository's meta data.
<stringification>
my $str = $repo->str;
media number for multi-part repositories (e.g. repositories
spawning multiple DVDs).
+ Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0)
+ my $di = $solvable->Dataiterator($keyname, $match, $flags);
+ di = solvable.Dataiterator(keyname, match, flags)
+ di = solvable.Dataiterator(keyname, match, flags)
+
+ for my $d (@$di)
+ for d in di:
+ for d in di
+
+Iterate over the matching data elements. See the Dataiterator class for more
+information.
+
void add_deparray(Id keyname, DepId dep, Id marker = -1);
$solvable->add_deparray($keyname, $dep);
solvable.add_deparray(keyname, dep)
Return true if the solvable is installed on the system.
+ bool identical(Solvable *other)
+ $solvable->identical($other)
+ $solvable.identical(other)
+ $solvable.identical?(other)
+
+Return true if the two solvables are identical.
+
+ int evrcmp(Solvable *other)
+ $solvable->evrcmp(other)
+ $solvable.evrcmp(other)
+ $solvable.evrcmp(other)
+
+Returns -1 if the epoch/version/release of the solvable is less then the
+one from the other solvable, 1 if it is greater, and 0 if they are equal.
+Note that "equal" does not mean that the evr is identical.
+
Selection Selection(int setflags = 0)
my $sel = $solvable->Selection();
sel = solvable.Selection()
The id of the solvable that matched.
-=== METHODS ===
-
- Id key_id();
- $d->key_id()
- d.key_id()
- d.key_id()
+ Id key_id;
+ $d->{key_id}
+ d.key_id
+ d.key_id
- const char *key_idstr();
- $d->key_idstr()
- d.key_idstr()
- d.key_idstr()
+ const char *key_idstr;
+ $d->{key_idstr}
+ d.key_idstr
+ d.key_idstr
The keyname that matched, either as id or string.
- Id type_id();
- $d->type_id()
- d.type_id()
- d.type_id()
+ Id type_id;
+ $d->{type_id}
+ d.type_id
+ d.type_id
- const char *type_idstr();
- $d->type_idstr();
- d.type_idstr()
- d.type_idstr()
+ const char *type_idstr;
+ $d->{type_idstr};
+ d.type_idstr
+ d.type_idstr
The key type of the value that was matched, either as id or string.
- Id id();
- $d->id()
- d.id()
- d.id()
+ Id id;
+ $d->{id}
+ d.id
+ d.id
- Id idstr();
- $d->idstr()
- d.idstr()
- d.idstr()
+ Id idstr;
+ $d->{idstr}
+ d.idstr
+ d.idstr
The Id of the value that was matched (only valid for id types),
either as id or string.
- const char *str();
- $d->str()
- d.str()
- d.str()
+ const char *str;
+ $d->{str}
+ d.str
+ d.str
The string value that was matched (only valid for string types).
- unsigned long long num();
- $d->num()
- d.num()
- d.num()
+ unsigned long long num;
+ $d->{num}
+ d.num
+ d.num
The numeric value that was matched (only valid for numeric types).
- unsigned int num2();
- $d->num2()
- d.num2()
- d.num2()
+ unsigned int num2;
+ $d->{num2}
+ d.num2
+ d.num2
The secondary numeric value that was matched (only valid for types
containing two values).
+ unsigned int binary;
+ $d->{binary}
+ d.binary
+ d.binary
+
+The value in binary form, useful for checksums and other data
+that cannot be represented as a string.
+
+=== METHODS ===
+
Datapos pos();
my $pos = $d->pos();
pos = d.pos()
have no relation to the packages in the repositories, i.e. no package in the
repositories have the same name or obsolete the orphaned package.
This action brings the installed packages in sync with the ones in the
-repository. It also turns of arch/vendor/version locking for the affected
-packages to simulate a fresh installation. This means that distupgrade can
+repository. By default it also turns of arch/vendor/version locking for the
+affected packages to simulate a fresh installation. This means that distupgrade can
actually downgrade packages if only lower versions of a package are available
-in the repositories.
+in the repositories. You can tweak this behavior with the SOLVER_FLAG_DUP_
+solver flags.
*SOLVER_DROP_ORPHANED*::
Erase all the matching installed packages if they are orphaned. This only makes
the calculation of unneeded packages for jobs that have the
SOLVER_CLEANDEPS flag set.
+*SOLVER_ALLOWUNINSTALL*::
+Allow the solver to deinstall the matching installed packages if they get
+into the way of resolving a dependency. This is like the
+SOLVER_FLAG_ALLOW_UNINSTALL flag, but limited to a specific set of packages.
+
*SOLVER_JOBMASK*::
A mask containing all the above action bits.
better for the user to check the transaction overview instead of
approving every single package that needs to be erased.
+*SOLVER_FLAG_DUP_ALLOW_DOWNGRADE*::
+Like SOLVER_FLAG_ALLOW_DOWNGRADE, but used in distupgrade mode.
+
+*SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE*::
+Like SOLVER_FLAG_ALLOW_ARCHCHANGE, but used in distupgrade mode.
+
+*SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE*::
+Like SOLVER_FLAG_ALLOW_VENDORCHANGE, but used in distupgrade mode.
+
+*SOLVER_FLAG_DUP_ALLOW_NAMECHANGE*::
+Like SOLVER_FLAG_ALLOW_NAMECHANGE, but used in distupgrade mode.
+
*SOLVER_FLAG_NO_UPDATEPROVIDE*::
If multiple packages obsolete an installed package, the solver checks
the provides of every such package and ignores all packages that
Do not enable auto-targeting up update and distupgrade jobs. See
the section on targeted updates for more information.
+*SOLVER_FLAG_KEEP_ORPHANS*::
+Do not allow orphaned packages to be deinstalled if they get
+in the way of resolving other packages.
+
+*SOLVER_FLAG_BREAK_ORPHANS*::
+Ignore dependencies of orphaned packages that get in the way
+of resolving non-orphaned ones. Setting the flag might result
+in no longer working packages in case they are orphaned.
+
+*SOLVER_FLAG_FOCUS_INSTALLED*::
+Resolve installed packages before resolving the given job.
+Setting this flag means that the solver will prefer picking
+a package version that fits the other installed packages
+over updating installed packages.
+
Basic rule types:
*SOLVER_RULE_UNKNOWN*::
A rule of an unknown class. You should never encounter those.
-*SOLVER_RULE_RPM*::
-A package dependency rule, called rpm rule for historical reasons.
+*SOLVER_RULE_PKG*::
+A package dependency rule.
*SOLVER_RULE_UPDATE*::
A rule to implement the update policy of installed packages. Every
Special dependency rule types:
-*SOLVER_RULE_RPM_NOT_INSTALLABLE*::
+*SOLVER_RULE_PKG_NOT_INSTALLABLE*::
This rule was added to prevent the installation of a package of an
architecture that does not work on the system.
-*SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP*::
+*SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP*::
The package contains a required dependency which was not provided by
any package.
-*SOLVER_RULE_RPM_PACKAGE_REQUIRES*::
-Similar to SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, but in this case
+*SOLVER_RULE_PKG_REQUIRES*::
+Similar to SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP, but in this case
some packages provided the dependency but none of them could be
installed due to other dependency issues.
-*SOLVER_RULE_RPM_SELF_CONFLICT*::
+*SOLVER_RULE_PKG_SELF_CONFLICT*::
The package conflicts with itself. This is not allowed by older rpm
versions.
-*SOLVER_RULE_RPM_PACKAGE_CONFLICT*::
+*SOLVER_RULE_PKG_CONFLICTS*::
To fulfill the dependencies two packages need to be installed, but
one of the packages contains a conflict with the other one.
-*SOLVER_RULE_RPM_SAME_NAME*::
+*SOLVER_RULE_PKG_SAME_NAME*::
The dependencies can only be fulfilled by multiple versions of
a package, but installing multiple versions of the same package
is not allowed.
-*SOLVER_RULE_RPM_PACKAGE_OBSOLETES*::
+*SOLVER_RULE_PKG_OBSOLETES*::
To fulfill the dependencies two packages need to be installed, but
one of the packages obsoletes the other one.
-*SOLVER_RULE_RPM_IMPLICIT_OBSOLETES*::
+*SOLVER_RULE_PKG_IMPLICIT_OBSOLETES*::
To fulfill the dependencies two packages need to be installed, but
one of the packages has provides a dependency that is obsoleted
by the other one. See the POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES
flag.
-*SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES*::
+*SOLVER_RULE_PKG_INSTALLED_OBSOLETES*::
To fulfill the dependencies a package needs to be installed that is
obsoleted by an installed package. See the POOL_FLAG_NOINSTALLEDOBSOLETES
flag.
other package that has a different name.
+Reason constants
+
+*SOLVER_REASON_UNRELATED*::
+The package status did not change as it was not related to any job.
+
+*SOLVER_REASON_UNIT_RULE*::
+The package was installed/erased/kept because of a unit rule, i.e. a rule
+where all literals but one were false.
+
+*SOLVER_REASON_KEEP_INSTALLED*::
+The package was chosen when trying to keep as many packages installed as
+possible.
+
+*SOLVER_REASON_RESOLVE_JOB*::
+The decision happened to fulfill a job rule.
+
+*SOLVER_REASON_UPDATE_INSTALLED*::
+The decision happened to fulfill a package update request.
+
+*SOLVER_REASON_CLEANDEPS_ERASE*::
+The package was erased when cleaning up dependencies from other erased
+packages.
+
+*SOLVER_REASON_RESOLVE*::
+The package was installed to fulfill package dependencies.
+
+*SOLVER_REASON_WEAKDEP*::
+The package was installed because of a weak dependency (Recommends or
+Supplements).
+
+*SOLVER_REASON_RESOLVE_ORPHAN*::
+The decision about the package was made when deciding the fate of orphaned
+packages.
+
+*SOLVER_REASON_RECOMMENDED*::
+This is a special case of SOLVER_REASON_WEAKDEP.
+
+*SOLVER_REASON_SUPPLEMENTED*::
+This is a special case of SOLVER_REASON_WEAKDEP.
+
+
=== ATTRIBUTES ===
Pool *pool; /* read only */
=== METHODS ===
int set_flag(int flag, int value)
- my $oldvalue = $pool->set_flag($flag, $value);
- oldvalue = pool.set_flag(flag, value)
- oldvalue = pool.set_flag(flag, value)
+ my $oldvalue = $solver->set_flag($flag, $value);
+ oldvalue = solver.set_flag(flag, value)
+ oldvalue = solver.set_flag(flag, value)
int get_flag(int flag)
- my $value = $pool->get_flag($flag);
- value = pool.get_flag(flag)
- value = pool.get_flag(flag)
+ my $value = $solver->get_flag($flag);
+ value = solver.get_flag(flag)
+ value = solver.get_flag(flag)
Set/get a solver specific flag. The flags define the policies the solver has
to obey. The flags are explained in the CONSTANTS section of this class.
is available even if problems were found, this is useful for interactive user
interfaces that show both the job result and the problems.
+ int reason = describe_decision(Solvable *s, Rule *OUTPUT)
+ my ($reason, $rule) = $solver->describe_decision($solvable);
+ (reason, rule) = solver.describe_decision(solvable)
+ (reason, rule) = solver.describe_decision(solvable)
+
+Return the reason why a specific solvable was installed or erased. For most of
+the reasons the rule that triggered the decision is also returned.
+
The Problem Class
-----------------
Problems are the way of the solver to interact with the user. You can simply list
chksum = solv.Chksum(type, hex)
chksum = Solv::Chksum.new(type, hex)
-Create an already finalized checksum object.
+Create an already finalized checksum object from a hex string.
+
+ Chksum Chksum_from_bin(Id type, char *bin)
+ my $chksum = solv::Chksum->from_bin($type, $bin);
+ chksum = solv.Chksum.from_bin(type, bin)
+ chksum = Solv::Chksum.from_bin(type, bin)
+
+Create an already finalized checksum object from a binary checksum.
=== ATTRIBUTES ===
chksum.add(str)
chksum.add(str)
-Add a string to the checksum.
+Add a (binary) string to the checksum.
void add_fp(FILE *fp)
$chksum->add_fp($file);
Finalize the checksum and return the result as hex string.
+ const char *typestr()
+ my $typestr = $chksum->typestr();
+ typestr = chksum.typestr
+ typestr = chksum.typestr
+
+Return the type of the checksum as a string, e.g. "sha256".
+
<equality>
if ($chksum1 == $chksum2)
if chksum1 == chksum2:
Create a file handle from the specified file descriptor. The path argument is
only used to select the correct (de-)compression algorithm, use an empty path
-if you want to make sure to read/write raw data.
+if you want to make sure to read/write raw data. The file descriptor is dup()ed
+before the file handle is created.
=== METHODS ===
Return file file descriptor of the file. If the file is not open, `-1` is
returned.
+ void cloexec(bool state)
+ $file->cloexec($state)
+ file.cloexec(state)
+ file.cloexec(state)
+
+Set the close-on-exec flag of the file descriptor. The xfopen function
+returns files with close-on-exec turned on, so if you want to pass
+a file to some other process you need to call cloexec(0) before calling
+exec.
+
int dup()
my $fileno = $file->dup();
fileno = file.dup()
file.close()
file.close()
-Close the file. This is needed for languages like Ruby, that do not destruct
+Close the file. This is needed for languages like Ruby that do not destruct
objects right after they are no longer referenced. In that case, it is good
style to close open files so that the file descriptors are freed right away.
Returns false if there was an error.
Lookup functions. Note that the returned Ids are always translated into
the Ids of the global pool even if the repodata area contains its own pool.
+ Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0)
+ my $di = $datapos->Dataiterator($keyname, $match, $flags);
+ di = datapos.Dataiterator(keyname, match, flags)
+ di = datapos.Dataiterator(keyname, match, flags)
+
+ for my $d (@$di)
+ for d in di:
+ for d in di
+
+Iterate over the matching data elements. See the Dataiterator class for more
+information.
+
Author
------
Michael Schroeder <mls@suse.de>