The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.
Difference between revisions of "Portage API"
(21 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
This page is the beginning of the missing documentation on the Portage Python API. | This page is the beginning of the missing documentation on the Portage Python API. | ||
== Introduction == | == Introduction == | ||
Portage has always had a Python API | Portage has always had a Python API. This page represents an initial effort to document the API that is available for querying packages, etc. The API described on the page was created by Daniel Robbins and is still used internally by Portage. While Portage's API has evolved and grown over the years as various abstractions have been added to Portage's design, these fundamental API calls remain at the heart of Portage's functionality, and can be used by third-party Python applications to query and interact with the package database. | ||
== Portage DBAPI == | == Portage DBAPI == | ||
The API that exists in Portage to query this is called the DBAPI | The API that exists in Portage to query this is called the DBAPI. The "porttree" is the nickname used to describe the Portage tree, which is typically stored in {{f|/usr/portage}}. In these examples, we will use Portage's python DBAPI to query the porttree using the interactive {{c|python}} interpreter. | ||
{{console|body= | {{console|body= | ||
Line 14: | Line 14: | ||
[GCC 4.9.3] on linux | [GCC 4.9.3] on linux | ||
Type "help", "copyright", "credits" or "license" for more information. | Type "help", "copyright", "credits" or "license" for more information. | ||
>>> ##i##import portage | |||
>>> ##i##portage.root | >>> ##i##portage.root | ||
'/' | '/' | ||
>>> ##i##p = portage.db[portage.root]["porttree"].dbapi | >>> ##i##p = portage.db[portage.root]["porttree"].dbapi | ||
>>> | >>> | ||
}} | }} | ||
{{Note|"porttree" contains every ebuild and "vartree" the installed ones. "bintree" is also available }} | |||
{{c|p}} now contains a reference to the DBAPI associated with the Portage tree associated with the system installed at {{c|portage.root}}, which is typically {{f|/usr/portage}}. We can now perform various queries using this variable. | {{c|p}} now contains a reference to the DBAPI associated with the Portage tree associated with the system installed at {{c|portage.root}}, which is typically {{f|/usr/portage}}. We can now perform various queries using this variable. | ||
Line 42: | Line 44: | ||
{{console|body= | {{console|body= | ||
>>> p.xmatch("match-visible", "=sys-apps/portage-2*") | >>> ##i##p.xmatch("match-visible", "=sys-apps/portage-2*") | ||
['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8'] | ['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8'] | ||
}} | }} | ||
Line 56: | Line 58: | ||
<tr><td>{{c|minimum-visible}}</td><td>Find the lowest match for the dependency, respecting masks.</td><td>single string</td></tr> | <tr><td>{{c|minimum-visible}}</td><td>Find the lowest match for the dependency, respecting masks.</td><td>single string</td></tr> | ||
{{TableEnd}} | {{TableEnd}} | ||
=== Querying Package Metadata === | |||
Portage is designed to extract and cache a certain set of data from each ebuild, called metadata, and this metadata is queryable and used for dependency calculations, fetching sources, etc. Querying of metadata for a particular ebuild can be performed using the {{c|aux_get()}} DBAPI method: | |||
{{console|body= | |||
>>> ##i##p.aux_get("sys-apps/portage-2.3.8", ["EAPI", "SRC_URI"]) | |||
['5-progress', 'https://www.github.com/funtoo/portage-funtoo/tarball/funtoo-2.3.8 -> portage-funtoo-2.3.8.tar.gz'] | |||
}} | |||
The parameters of the {{c|aux_get()}} method are, first, the name of a package in "catpkg-v" format, which is a reference to a specific version of a package in "category/packagename-version(-revision)" format. The second argument is a list or tuple of metadata to return. A list is returned containing the queried metadata in the order specified in the first argument. If necessary, Portage will evaluate the contents of the ebuild to extract and cache this metadata. For porttrees, the following metadata is available (and this may vary by EAPI): | |||
{{TableStart}} | |||
<tr><th>Metadata</th><th>Description</th></tr> | |||
<tr><td>{{c|DEFINED_PHASES}}</td><td>String containing all phases (see [[Ebuild Functions]]) defined in the ebuild, delimited by spaces.</td></tr> | |||
<tr><td>{{c|DEPEND}}</td><td>Build dependencies</td></tr> | |||
<tr><td>{{c|EAPI}}</td><td>Ebuild API version</td></tr> | |||
<tr><td>{{c|HDEPEND}}</td><td>Host Build Dependencies (EAPI 5-hdepend only)</td></tr> | |||
<tr><td>{{c|INHERITED}}</td><td>A complete list of eclasses used by this ebuild, directly or indirectly (via eclasses inheriting other eclasses)</td></tr> | |||
<tr><td>{{c|IUSE}}</td><td>{{c|IUSE}} variable from ebuild</td></tr> | |||
<tr><td>{{c|KEYWORDS}}</td><td>{{c|KEYWORDS}} (masking) setting</td></tr> | |||
<tr><td>{{c|LICENSE}}</td><td>{{c|LICENSE}} variable from ebuild</td></tr> | |||
<tr><td>{{c|PDEPEND}}</td><td>{{c|PDEPEND}} variable from ebuild</td></tr> | |||
<tr><td>{{c|PROPERTIES}}</td><td>{{c|PROPERTIES}} variable from ebuild</td></tr> | |||
<tr><td>{{c|PROVIDE}}</td><td>{{c|PROVIDE}} variable from ebuild</td></tr> | |||
<tr><td>{{c|RDEPEND}}</td><td>Runtime dependencies</td></tr> | |||
<tr><td>{{c|REQUIRED_USE}}</td><td>{{c|REQUIRED_USE}} variable from ebuild</td></tr> | |||
<tr><td>{{c|repository}}</td><td>Repository name ("gentoo" in main Gentoo or Funtoo Portage tree)</td></tr> | |||
<tr><td>{{c|RESTRICT}}</td><td>{{c|RESTRICT}} variable from ebuild</td></tr> | |||
<tr><td>{{c|SLOT}}</td><td>{{c|SLOT}} variable from ebuild</td></tr> | |||
{{TableEnd}} | |||
== Manipulating and Comparing Package Strings == | |||
Portage's API contains a number of functions that are used to manipulate, split and compare Portage's various types of package strings, and these functions are defined in {{f|/usr/lib/python3.7/site-packages/portage/versions.py}}. Here is a list of the various functions available: | |||
{{TableStart}} | |||
<tr><th>Function name</th><th>Description</th><th>Example</th><th>Result</th></tr> | |||
<tr><td>{{c|catpkgsplit(cpv_string)}}</td><td>Takes a complete catpkg-version string, and splits into category, package name, package version, package revision. Will return {{c|None}} if argument string is invalid -- such as missing a version, or category.</td><td>{{console|body=portage.catpkgsplit("foo-bar/oni-1.0-r1")}}</td><td>{{console|body=('foo-bar', 'oni', '1.0', 'r1')}}</td></tr> | |||
<tr><td>{{c|catsplit(catpkg_string)}}</td><td>Takes a string in catpkg or catpkg-version format, and splits into category and "other" part (list of length 2) at the initial "/" separator. Equivalent to {{c|1=string.split(catpkg_string, "/", maxsplit=1)}}. No validation of the package or package-version part is performed.</td><td>{{console|body=portage.catsplit("foo-bar/oni-1.0-r1") | |||
portage.catsplit("foo-bar/oni-2asdfz00")}}</td><td>{{console|body=['foo-bar', 'oni-1.0'] | |||
['foo-bar', 'oni-2asdfz00'] | |||
}}</td></tr> | |||
<tr><td>{{c|pkgsplit(pv_or_cpv_string)}}</td><td>Takes a complete catpkg-version string or a pkg-version string, and splits into catpkg (or package, if pkg-version specified), package version, package revision. Will return {{c|None}} if argument string is invalid -- such as missing a version, or category.</td><td>{{console|body=portage.pkgsplit("foo-bar/oni-1.0-r1") | |||
portage.pkgsplit("oni-1.0-r1")}}</td><td>{{console|body=('foo-bar/oni', '1.0', 'r1') | |||
('oni', '1.0', 'r1') | |||
}}</td></tr> | |||
<tr><td>{{c|ververify(version_string)}}</td><td>Takes a version string (can include revision,) and uses regexes to determine if it is valid and supported by Portage. Returns True or False.</td><td>{{console|body=portage.ververify("1.0-r1")}}</td><td>{{console|body=True}}</td></tr> | |||
<tr><td>{{c|vercmp(version_string_1, version_string_2)}}</td><td>Compares two version strings and determines which string is greater. If first string is a higher version, then a positive number is returned. If the second string is a higher version, a negative number is returned. If the versions are considered to be equal, then zero is returned.</td><td>{{console|body=portage.vercmp("1.0-r1", "1.0-r2")}}</td><td>{{console|body=-1}}</td></tr> | |||
<tr><td>{{c|pkgcmp(pkgsplit_1, pkgsplit_2)}}</td><td>Compares two packages in {{c|pkgsplit()}} format. If first package is a higher version, then a positive number is returned. If the second package is a higher version, a negative number is returned. If the versions are considered to be equal, then zero is returned. Note that the package or catpkg atoms used for each pkgsplit call must match exactly (although the versions can of course differ) or the packages will be considered to be different and incomparable and {{c|None}} will be returned.</td><td>{{console|body=pkgcmp(pkgsplit("oni-1.0-r1"), pkgsplit("oni-1.0-r2")) | |||
pkgcmp(pkgsplit("oni-1.0-r1"), pkgsplit("boni-1.0-r2")) | |||
}}</td><td>{{console|body=-1 | |||
None}}</td></tr> | |||
{{TableEnd}} | |||
[[Category:Portage]] | |||
[[Category:Internals]] |
Latest revision as of 03:18, July 8, 2020
This page is the beginning of the missing documentation on the Portage Python API.
Introduction
Portage has always had a Python API. This page represents an initial effort to document the API that is available for querying packages, etc. The API described on the page was created by Daniel Robbins and is still used internally by Portage. While Portage's API has evolved and grown over the years as various abstractions have been added to Portage's design, these fundamental API calls remain at the heart of Portage's functionality, and can be used by third-party Python applications to query and interact with the package database.
Portage DBAPI
The API that exists in Portage to query this is called the DBAPI. The "porttree" is the nickname used to describe the Portage tree, which is typically stored in /usr/portage
. In these examples, we will use Portage's python DBAPI to query the porttree using the interactive python
interpreter.
w520 drobbins # python Python 3.3.5 (default, Sep 21 2015, 23:01:43) [GCC 4.9.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import portage >>> portage.root '/' >>> p = portage.db[portage.root]["porttree"].dbapi >>>
"porttree" contains every ebuild and "vartree" the installed ones. "bintree" is also available
p
now contains a reference to the DBAPI associated with the Portage tree associated with the system installed at portage.root
, which is typically /usr/portage
. We can now perform various queries using this variable.
>>> p.cp_list("sys-apps/portage")
['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8']
Above, cp_list
takes what is called a "catpkg", which is a reference to a particular ebuild in a repository in "category/packagename" format. We can also get lists of specific available packages, using other functions:
>>> p.match("sys-apps/portage") ['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8'] >>> p.match("=sys-apps/portage-2*") ['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8']
While at first the match()
method looks no different than the cp_list()
method, you can see that it accepts any valid dependency atom, which is any individual dependency reference to a particular package. The match()
method is actually a shortcut for the more sophisticated xmatch()
method -- it matches all visible (non-masked) packages that satisfy the dependency.
Using xmatch()
, more sophisticated matching can be performed:
>>> p.xmatch("match-visible", "=sys-apps/portage-2*")
['sys-apps/portage-2.3.6-r9', 'sys-apps/portage-2.3.8']
As you can see, xmatch()
with the "match_visible" gives us the identical results as match()
. In fact, match()
is a shortcut for this particular xmatch()
call. However, xmatch()
has other matching methods, detailed below:
match mode | Description | Return Type |
---|---|---|
bestmatch-visible | Find the best (highest) visible (unmasked) match for the dependency. | single string |
match-all | Find all matches, masked or unmasked. | list of strings |
match-visible | Find all visible (unmasked) matches for the dependency. | list of strings |
minimum-all | Find the lowest match for the dependency, ignoring masks. | single string |
minimum-visible | Find the lowest match for the dependency, respecting masks. | single string |
Querying Package Metadata
Portage is designed to extract and cache a certain set of data from each ebuild, called metadata, and this metadata is queryable and used for dependency calculations, fetching sources, etc. Querying of metadata for a particular ebuild can be performed using the aux_get()
DBAPI method:
>>> p.aux_get("sys-apps/portage-2.3.8", ["EAPI", "SRC_URI"])
['5-progress', 'https://www.github.com/funtoo/portage-funtoo/tarball/funtoo-2.3.8 -> portage-funtoo-2.3.8.tar.gz']
The parameters of the aux_get()
method are, first, the name of a package in "catpkg-v" format, which is a reference to a specific version of a package in "category/packagename-version(-revision)" format. The second argument is a list or tuple of metadata to return. A list is returned containing the queried metadata in the order specified in the first argument. If necessary, Portage will evaluate the contents of the ebuild to extract and cache this metadata. For porttrees, the following metadata is available (and this may vary by EAPI):
Metadata | Description |
---|---|
DEFINED_PHASES | String containing all phases (see Ebuild Functions) defined in the ebuild, delimited by spaces. |
DEPEND | Build dependencies |
EAPI | Ebuild API version |
HDEPEND | Host Build Dependencies (EAPI 5-hdepend only) |
INHERITED | A complete list of eclasses used by this ebuild, directly or indirectly (via eclasses inheriting other eclasses) |
IUSE | IUSE variable from ebuild |
KEYWORDS | KEYWORDS (masking) setting |
LICENSE | LICENSE variable from ebuild |
PDEPEND | PDEPEND variable from ebuild |
PROPERTIES | PROPERTIES variable from ebuild |
PROVIDE | PROVIDE variable from ebuild |
RDEPEND | Runtime dependencies |
REQUIRED_USE | REQUIRED_USE variable from ebuild |
repository | Repository name ("gentoo" in main Gentoo or Funtoo Portage tree) |
RESTRICT | RESTRICT variable from ebuild |
SLOT | SLOT variable from ebuild |
Manipulating and Comparing Package Strings
Portage's API contains a number of functions that are used to manipulate, split and compare Portage's various types of package strings, and these functions are defined in /usr/lib/python3.7/site-packages/portage/versions.py
. Here is a list of the various functions available:
Function name | Description | Example | Result |
---|---|---|---|
catpkgsplit(cpv_string) | Takes a complete catpkg-version string, and splits into category, package name, package version, package revision. Will return None if argument string is invalid -- such as missing a version, or category. | portage.catpkgsplit("foo-bar/oni-1.0-r1") | ('foo-bar', 'oni', '1.0', 'r1') |
catsplit(catpkg_string) | Takes a string in catpkg or catpkg-version format, and splits into category and "other" part (list of length 2) at the initial "/" separator. Equivalent to string.split(catpkg_string, "/", maxsplit=1) . No validation of the package or package-version part is performed. | portage.catsplit("foo-bar/oni-1.0-r1") portage.catsplit("foo-bar/oni-2asdfz00") | ['foo-bar', 'oni-1.0'] ['foo-bar', 'oni-2asdfz00'] |
pkgsplit(pv_or_cpv_string) | Takes a complete catpkg-version string or a pkg-version string, and splits into catpkg (or package, if pkg-version specified), package version, package revision. Will return None if argument string is invalid -- such as missing a version, or category. | portage.pkgsplit("foo-bar/oni-1.0-r1") portage.pkgsplit("oni-1.0-r1") | ('foo-bar/oni', '1.0', 'r1') ('oni', '1.0', 'r1') |
ververify(version_string) | Takes a version string (can include revision,) and uses regexes to determine if it is valid and supported by Portage. Returns True or False. | portage.ververify("1.0-r1") | True |
vercmp(version_string_1, version_string_2) | Compares two version strings and determines which string is greater. If first string is a higher version, then a positive number is returned. If the second string is a higher version, a negative number is returned. If the versions are considered to be equal, then zero is returned. | portage.vercmp("1.0-r1", "1.0-r2") | -1 |
pkgcmp(pkgsplit_1, pkgsplit_2) | Compares two packages in pkgsplit() format. If first package is a higher version, then a positive number is returned. If the second package is a higher version, a negative number is returned. If the versions are considered to be equal, then zero is returned. Note that the package or catpkg atoms used for each pkgsplit call must match exactly (although the versions can of course differ) or the packages will be considered to be different and incomparable and None will be returned. | pkgcmp(pkgsplit("oni-1.0-r1"), pkgsplit("oni-1.0-r2")) pkgcmp(pkgsplit("oni-1.0-r1"), pkgsplit("boni-1.0-r2")) | -1 None |