
ZYpp bindings for Ruby.
Duncan Mac-Vicar <dmacvicar@suse.de>
Klaus Kaempf <kkaempf@suse.de>

0. Motivation & Concept

Access libzypp with a nice, object-oriented scripting language.

libzypp has four major components

- the target
  This is the representation of the system
- sources
  A source is the representation of a repository
- pool
  Pool is the collection of all resolvables, installed and uninstalled
- resolver
  The resolver operates on the pool


1. Accessing the bindings

The ruby-zypp bindings are in a loadable extension with the name of 'rzypp'

Just

  load 'rzypp'

in your ruby program and code away.

Everything is inside the module 'ZYpp'. Either prefix every class with 'ZYpp::'
or simply

  include 'ZYpp'


All rzypp class define the 'to_s' method which returns a string representation
of the object.


2. Basic classes

2.1. Kind

Kind defines the kind of a resolvable. The class 'ZYpp::Kind' defines
the following constants:

    ZYpp::Kind::Atom
    ZYpp::Kind::Package
    ZYpp::Kind::SrcPackage
    ZYpp::Kind::Patch
    ZYpp::Kind::Pattern
    ZYpp::Kind::Product
    ZYpp::Kind::Message
    ZYpp::Kind::Script
    ZYpp::Kind::Language
    ZYpp::Kind::SystemResObject


2.2 Dep

Dep defines different types of dependencies. The class 'ZYpp::Dep' defines
the following constants

    ZYpp::Dep::PreRequires
    ZYpp::Dep::Requires
    ZYpp::Dep::Provides
    ZYpp::Dep::Obsoletes
    ZYpp::Dep::Conflicts
    ZYpp::Dep::Freshens
    ZYpp::Dep::Enhances
    ZYpp::Dep::Supplements
    ZYpp::Dep::Recommends
    ZYpp::Dep::Suggests


2.3 Rel

Rel defines basic relational operators for use in capability expressions (see below).
The class 'ZYpp::Rel' defines the operator constants. It also define 'to_s' and
'to_symbol' methods for each constant. The following table lists the constants and
their 'to_s' and 'to_symbol' values:

    constant       | to_s | to_symbol
    ---------------+------+----------
    ZYpp::Rel::EQ  |  ==  | :EQ
    ZYpp::Rel::NE  |  !=  | :NE
    ZYpp::Rel::LT  |  <   | :LT
    ZYpp::Rel::GT  |  >   | :GT
    ZYpp::Rel::LE  |  <=  | :LE
    ZYpp::Rel::GE  |  >=  | :GE
    ZYpp::Rel::ANY | (any)| :ANY

ZYpp::Rel::ANY is the 'no relation' operator and treated as a wildcard.


2.4 Edition

Edition combines epoch, version, and release in a single object.

The constructor takes 0-3 arguments in the order of version (string),
release (string), and epoch (integer).

The default value for an edition is ZYpp::Edition::NoEdition.

    noedition = ZYpp::Edition::NoEdition
    edition = ZYpp::Edition.new()		# equals noedition
    edition = ZYpp::Edition.new("version")
    edition = ZYpp::Edition.new("version", "release")
    edition = ZYpp::Edition.new("version", "release", 42)

Edition defines the infix operator "<=>" for comparison. Its aliased to "compare".

    ZYpp::Edition.new("1.0") <=> ZYpp::Edition.new("2.0")		# == -1
    ZYpp::Edition.new("1.0").compare(ZYpp::Edition.new("2.0")) == -1	# == true 
    ZYpp::Edition.new("1.0") <=> ZYpp::Edition.new("1.0")		# == 0
    ZYpp::Edition.new("1.0", "1") <=> ZYpp::Edition.new("1.0", "0")	# == 1

There are three methods to access the attributes of an Edition.

    epoch	returns the epoch (fixnum)
    version	retuns the version (string)
    release	returns the release (string)


2.5 Capability

A capability is a combination of a kind (Kind), a name (string), a comparison
operator (ZYpp::Rel), and an edition (ZYpp::Edition).

The default value is 'no capability' (empty) which is expressed as the constant

    ZYpp::Capability::NoCap

The Capability constructor takes various arguments, depending on the capability.
The default constructor takes no arguments and returns the empty capability

    ZYpp::Capability.new()		# == ZYpp::Capability::NoCap

A string capability refers to Kind::Package by default.

    ZYpp::Capability.new( "capability" )			# matches a package providing 'capability' (in any edition)

Other kinds can be specified as

    ZYpp::Capability.new( ZYpp::Kind::Product, "capability" )	# matches a product providing 'capability' (in any edition)

Capability expressions can be specified by adding a relation operator and an edition.
The relation operator can either be expressed as a Rel:: constant, a symbol, or a string according to the
table listed above for the Rel class.
The edition can be expressed as a string ("epoch:version-release", 'epoch:' and '-release' being optional)
or as ZYpp::Edition object.
The following constructor calls all return the same capability:


    ZYpp::Capability.new( "capability", "==, "42-1" )
    ZYpp::Capability.new( "capability", :EQ, "42-1" )
    ZYpp::Capability.new( "capability", ZYpp::Rel::EQ, ZYpp::Edition.new( "42", "1" ) )

There are four methods to access the attributes of a Capability.

    refers	returns the ZYpp::Kind the capability refers to
    index	returns the index (string representation without relational operator and edition)
    op		returns the relational operator (ZYpp::Rel)
    edition	returns the edition

    ZYpp::Capability.new().refers	# == ZYpp::Kind::Package
    ZYpp::Capability.new().index	# == ""
    ZYpp::Capability.new().op		# == ZYpp::Rel::ANY
    ZYpp::Capability.new().edition	# == ZYpp::Edition::NoEdition

The 'matches' method compares two editions if their respection edition ranges match.
All of the following comparions return true:

    ZYpp::Capability.new( "foo" ).matches( ZYpp::Capability.new( "foo" ) )

    ZYpp::Capability.new( "foo", :GE, "1" ).matches( ZYpp::Capability.new( "foo", "==", "1") )

    ZYpp::Capability.new( "foo", :GE, "1" ).matches( ZYpp::Capability.new( "foo", "<", "2") )



3. Resolvable

The Resolvable is the base class for objects within zypp. A resolvable has

 - a kind (ZYpp::Kind)
 - a name (string)
 - an edition (ZYpp::Edition)
 - an architecture (string)
 - dependencies (hash of ZYpp::Capability arrays, indexed by ZYpp::Dep)

Resolvables are created internally from libzypp, there is no public constructor available.

Assumed foo representing a resolvable foo-1.42-27.i686 of kind package which provides "bar",
requires package "baz >= 8-15", and conflicts with (package) "foobar":

    foo.kind == ZYpp::Kind::Package
    foo.name == "foo"
    foo.edition.version == "1.42"
    foo.edition.release == "27"
    foo.edition.arch == "i686"
    foo.dep( Dep::Provides ) == ZYpp::Capability.new( "bar" )
    foo.dep( Dep::Requires ) == ZYpp::Capability.new( "baz", Rel::GE, "8-15" )
    foo.dep( Dep::Conflicts ) == ZYpp::Capability.new( "foobar" )


4. ResObject

ResObject is derived from Resolvable and add summary (string) and description (string)
methods.


5. Package

Package is derived from ResObject.


6. Patch

Patch is derived from ResObject.


7. Pattern

Pattern is derived from ResObject.

  default? : bool
  user_visible? : bool
  order : integer
  icon : string
  script : string
  category : string

8. Product

Product is derived from ResObject.

  category : string
  vendor : string
  release_notes_url : string

9. ResStatus

ResStatus represents the status of a resolvable in the pool. Its internal
implementation is a bitmask.

The general status is either installed or uninstalled.

Status changes are represented as 'transactions'. Removals are 'installed + transacts',
Installs are 'uninstalled + transacts'.

A transaction is always accompanied by a 'causer', representing 'who' triggered
the transaction.

There are four causers defined as constants:

    ZYpp::ResStatus::USER	user initiated
    ZYpp::ResStatus::APPL_HIGH	application initiated (i.e. service configuration requesting
				addtional packages
    ZYpp::ResStatus::APPL_LOW	application initiated
    ZYpp::ResStatus::SOLVER	triggered during dependency resolving

The above list is ordered by priority. A user initiated change can override a solver initiated
one but not vice versa.

10. PoolItem

A combination of ResStatus and ResObject

Its status can be accessed by the "status" method

    status : ResStatus

Its resolvable can be accessed by the "resolvable" method

    resolvable : Resolvable

Methods of derived resolvables can also be accessed. PoolItem has "method_missing" defined
and will delegate any unknown method to the Class representing the resolvable.

If PoolItem.resolvable.kind == Kind::Product then the product attribute can
be accessed directly, e.g.

    item.release_notes_url


Each PoolItem has an associated status which can be tested or manipulated by one
of the following methods.

ResStatus methods

    license_confirmed? : bool
    license_confirmed! ( bool ) : bool

General installed/uninstalled query
    installed? : bool
    uninstalled? : bool

Ensure that it does not transact
    stays_installed? : bool
    stays_uninstalled? : bool

Ensure that is transacts
    to_be_installed? : bool		# equal to uninstalled? && transacts?
    to_be_uninstalled? : bool		# equal to installed? && transacts?

Install or uninstall, with causer
    install! ( causer )
    uninstall! ( causer ) : bool

Transaction
    transacts? : bool
    transact! ( bool value, causer ) : bool

Locks
    locked? : bool
    locked! : ( bool value, causer )

Prevent transaction
    keep? : bool
    keep! : ( bool value, causer )

Clear transact/lock/keep, if causer has equal or higher priority than current causer
    reset_transact! ( causer )


11. Pool

Representation of all resolvables currently known to zypp.

Pool is enumerable. (include the 'enumerable' module)

The size of the pool can get rather big, therefore the pool is only accessible
via iterators and filters.
The default filter is empty, all resolvables are allowed by the empty filter.

    each		# iterates over all resolvables according to the current filter

    pool = ZYpp::Pool.new()
    pool.each { |item| ... }

    by_name		# iterates over resolvables with a specific name

    pool.by_name( "foo" ).each { |item| ... }

    by_kind		# iterates over resolvables with a specific kind

    pool.by_kind( ZYpp::Kind::Pattern ).each { |item| ... }

    by_capindex		# iterates over resolvables with a specific dependency

    pool.by_capindex( "bar", ZYpp::Dep::Provides ).each { |capability,item| ... }

    size		# number of resolvables matching the current filter
    empty?		# true if no resolvable matches the current filter

---------------


Questions

- filter ?
- blocks ?
- callbacks ?

----
