From: "Brian Dolbec" <brian.dolbec@gmail.com>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage:public_api commit in: pym/portage/api/
Date: Sat, 28 May 2011 06:53:48 +0000 (UTC) [thread overview]
Message-ID: <7f1c35149aa401e83828e27716d35c3ec2b13108.dol-sen@gentoo> (raw)
commit: 7f1c35149aa401e83828e27716d35c3ec2b13108
Author: dol-sen <brian.dolbec <AT> gmail <DOT> com>
AuthorDate: Sat May 28 06:52:42 2011 +0000
Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Sat May 28 06:52:42 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=7f1c3514
code cleanup, remove defunct fundtion(). Use set() to remove duplicate IUSE entries.
Signed-off-by: dol-sen <brian.dolbec <AT> gmail.com>
---
pym/portage/api/data_connect.py | 993 ++++++++++++++++++++-------------------
pym/portage/api/flag.py | 60 ++-
pym/portage/api/properties.py | 8 +-
pym/portage/api/settings.py | 57 +--
4 files changed, 566 insertions(+), 552 deletions(-)
diff --git a/pym/portage/api/data_connect.py b/pym/portage/api/data_connect.py
index 5c73632..cb41ce0 100644
--- a/pym/portage/api/data_connect.py
+++ b/pym/portage/api/data_connect.py
@@ -6,586 +6,609 @@
"""Portage API data connection for consumer apps. """
import os.path
+import logging
import portage
from portage import pkgsplit
from portage.api.settings import default_settings
from portage.dep import Atom
-from portage import manifest
+from portage import manifest #, catpkgsplit
from portage.api.flag import get_flags
from portage.api.properties import Properties
-from portage.util import writemsg_level, grabfile
+from portage.util import writemsg_level #, grabfile
def ensure_settings(root, settings):
- if settings is None:
- settings = default_settings
- if root is None:
- root = settings.settings["ROOT"]
- return root, settings
+ """Internal function to check that root and settings
+ are not None and if so, then return their default values"""
+ if settings is None:
+ settings = default_settings
+ if root is None:
+ root = settings.settings["ROOT"]
+ return root, settings
def get_path(cpv, file=None, vardb=True, root=None, settings=None):
- """Returns a path to the specified category/package-version in
- either the vardb or portdb
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type file: string
- @param file:
- @param vardb: bool, defaults to True
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype string
- @return '/path/to/file'
- """
- root, settings = ensure_settings(root, settings)
- if vardb:
- return settings.vardb[root].getpath(cpv, file)
- else:
- if '/' not in cpv:
- return ''
- try:
- dir,ovl = settings.portdb[root].findname2(cpv)
- except:
- dir = ''
- return dir
+ """Returns a path to the specified category/package-version in
+ either the vardb or portdb
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type file: string
+ @param file:
+ @param vardb: bool, defaults to True
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype string
+ @return '/path/to/file'
+ """
+ root, settings = ensure_settings(root, settings)
+ if vardb:
+ return settings.vardb[root].getpath(cpv, file)
+ else:
+ if '/' not in cpv:
+ return ''
+ try:
+ dir, ovl = settings.portdb[root].findname2(cpv)
+ except:
+ dir = ''
+ return dir
def xmatch(root, settings, *args, **kwargs):
- """Pass arguments on to portage's caching match function.
- xmatch('match-all',package-name) returns all ebuilds of <package-name> in a list,
- xmatch('match-visible',package-name) returns non-masked ebuilds,
- xmatch('match-list',package-name,mylist=list) checks for <package-name> in <list>
- There are more possible arguments.
- package-name may be, for example:
- gnome-base/control-center ebuilds for gnome-base/control-center
- control-center ebuilds for gnome-base/control-center
- >=gnome-base/control-center-2.8.2 only ebuilds with version >= 2.8.2
-
- @type root: string
- @param root: tree root to use
- @param settings: portage config settings instance.
- @param args: The arument to pass to the dbapi.xmatch()
- @param kwargs: the extra arguments to pass to dbapi.xmatch()
- @rtype list
- @return: list of matches
- """
- results = settings.portdb[root].xmatch(*args, **kwargs)
- return results
+ """Pass arguments on to portage's caching match function.
+ xmatch('match-all',package-name) returns all ebuilds of <package-name> in a list,
+ xmatch('match-visible',package-name) returns non-masked ebuilds,
+ xmatch('match-list',package-name,mylist=list) checks for <package-name> in <list>
+ There are more possible arguments.
+ package-name may be, for example:
+ gnome-base/control-center ebuilds for gnome-base/control-center
+ control-center ebuilds for gnome-base/control-center
+ >=gnome-base/control-center-2.8.2 only ebuilds with version >= 2.8.2
+
+ @type root: string
+ @param root: tree root to use
+ @param settings: portage config settings instance.
+ @param args: The arument to pass to the dbapi.xmatch()
+ @param kwargs: the extra arguments to pass to dbapi.xmatch()
+ @rtype list
+ @return: list of matches
+ """
+ results = settings.portdb[root].xmatch(*args, **kwargs)
+ return results
def get_versions(cp, include_masked=True, root=None, settings=None):
- """Returns all available ebuilds for the package
-
- @type cp: string
- @param cp: 'cat/pkg'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype
- @return
- """
- root, settings = ensure_settings(root, settings)
- # Note: this is slow, especially when include_masked is false
- criterion = include_masked and 'match-all' or 'match-visible'
- results = xmatch(root, settings, criterion, str(cp))
- #writemsg_level(
- # "DATA_CONNECT: get_versions(); criterion = %s, package = %s, results = %s" %(str(criterion),cp,str(results)),
- # level=logging.DEBUG)
- return results
+ """Returns all available ebuilds for the package
+
+ @type cp: string
+ @param cp: 'cat/pkg'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype
+ @return
+ """
+ root, settings = ensure_settings(root, settings)
+ # Note: this is slow, especially when include_masked is false
+ criterion = include_masked and 'match-all' or 'match-visible'
+ results = xmatch(root, settings, criterion, str(cp))
+ #writemsg_level("DATA_CONNECT: get_versions(); criterion = %s,
+ #package = %s, results = %s" %(str(criterion),cp,str(results)),
+ #level=logging.DEBUG)
+ return results
def get_hard_masked(cp, root=None, settings=None):
- """
-
- @type cp: string
- @param cp: 'cat/pkg'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype tuple
- @return (hard_masked_nocheck, hardmasked)
- """
- root, settings = ensure_settings(root, settings)
- cp = str(cp)
- hardmasked = []
- try: # newer portage
- pmaskdict = settings.portdb[root].settings.pmaskdict[cp]
- except KeyError:
- pmaskdict = {}
- for x in pmaskdict:
- m = xmatch(root, settings, "match-all", x)
- for n in m:
- if n not in hardmasked:
- hardmasked.append(n)
- hard_masked_nocheck = hardmasked[:]
- try: # newer portage
- punmaskdict = settings.portdb[root].settings.punmaskdict[cp]
- except KeyError:
- punmaskdict = {}
- for x in punmaskdict:
- m = xmatch(root, settings, "match-all",x)
- for n in m:
- while n in hardmasked: hardmasked.remove(n)
- return hard_masked_nocheck, hardmasked
+ """
+
+ @type cp: string
+ @param cp: 'cat/pkg'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype tuple
+ @return (hard_masked_nocheck, hardmasked)
+ """
+ root, settings = ensure_settings(root, settings)
+ cp = str(cp)
+ hardmasked = []
+ try: # newer portage
+ pmaskdict = settings.portdb[root].settings.pmaskdict[cp]
+ except KeyError:
+ pmaskdict = {}
+ for x in pmaskdict:
+ m = xmatch(root, settings, "match-all", x)
+ for n in m:
+ if n not in hardmasked:
+ hardmasked.append(n)
+ hard_masked_nocheck = hardmasked[:]
+ try: # newer portage
+ punmaskdict = settings.portdb[root].settings.punmaskdict[cp]
+ except KeyError:
+ punmaskdict = {}
+ for x in punmaskdict:
+ m = xmatch(root, settings, "match-all", x)
+ for n in m:
+ while n in hardmasked: hardmasked.remove(n)
+ return hard_masked_nocheck, hardmasked
def get_installed_files(cpv, root=None, settings=None):
- """Get a list of installed files for an ebuild, assuming it has
- been installed.
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype list of strings
- """
- root, settings = ensure_settings(root, settings)
- cat, pv = portage.versions.catsplit(cpv)
- db = portage.dblink(cat, pv, root,
- settings.settings, treetype="vartree",
- vartree=settings.vardb[root])
- contents = db.getcontents()
- if not contents:
- return ["None"]
- return sorted(contents)
+ """Get a list of installed files for an ebuild, assuming it has
+ been installed.
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype list of strings
+ """
+ root, settings = ensure_settings(root, settings)
+ cat, pv = portage.versions.catsplit(cpv)
+ db = portage.dblink(cat, pv, root,
+ settings.settings, treetype="vartree",
+ vartree=settings.vardb[root])
+ contents = db.getcontents()
+ if not contents:
+ return ["None"]
+ return sorted(contents)
def best(versions):
- """returns the best version in the list of supplied versions
+ """returns the best version in the list of supplied versions
- @type versions: list of strings
- @param versions: a list of cpv's
- @rtype str
- """
- return portage.best(versions)
+ @type versions: list of strings
+ @param versions: a list of cpv's
+ @rtype str
+ """
+ return portage.best(versions)
def get_best_ebuild(cp, root=None, settings=None):
- """returns the best available cpv
+ """returns the best available cpv
- @type cp: string
- @param cp: 'cat/pkg'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype str
- """
- root, settings = ensure_settings(root, settings)
- return xmatch(root, settings, "bestmatch-visible", cp)
+ @type cp: string
+ @param cp: 'cat/pkg'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype str
+ """
+ root, settings = ensure_settings(root, settings)
+ return xmatch(root, settings, "bestmatch-visible", cp)
def get_dep_ebuild(dep, root=None, settings=None):
- """Progresively checks for available ebuilds that match the dependency.
- returns what it finds as up to three options.
-
- @type dep: string
- @param dep: a valid dependency
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype set
- @return best_ebuild, keyworded_ebuild, masked_ebuild
- """
- root, settings = ensure_settings(root, settings)
- #writemsg_level("DATA_CONNECT: get_dep_ebuild(); dep = " + dep, level=logging.DEBUG)
- best_ebuild = keyworded_ebuild = masked_ebuild = ''
- best_ebuild = xmatch(root, settings, "bestmatch-visible", dep)
- if best_ebuild == '':
- #writemsg_level("DATA_CONNECT: get_dep_ebuild(); checking masked packages", level=logging.DEBUG)
- atomized_dep = Atom(dep)
- hardmasked_nocheck, hardmasked = get_hard_masked(atomized_dep.cpv)
- matches = xmatch(root, settings, "match-all", dep)[:]
- masked_ebuild = best(matches)
- keyworded = []
- for m in matches:
- if m not in hardmasked:
- keyworded.append(m)
- keyworded_ebuild = best(keyworded)
- #writemsg_level(
- #"DATA_CONNECT: get_dep_ebuild(); ebuilds = " + str([best_ebuild, keyworded_ebuild, masked_ebuild]),
- #level=logging.DEBUG)
- return best_ebuild, keyworded_ebuild, masked_ebuild
+ """Progresively checks for available ebuilds that match the dependency.
+ returns what it finds as up to three options.
+
+ @type dep: string
+ @param dep: a valid dependency
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype set
+ @return best_ebuild, keyworded_ebuild, masked_ebuild
+ """
+ root, settings = ensure_settings(root, settings)
+ #writemsg_level("DATA_CONNECT: get_dep_ebuild(); dep = " + \
+ #dep, level=logging.DEBUG)
+ best_ebuild = keyworded_ebuild = masked_ebuild = ''
+ best_ebuild = xmatch(root, settings, "bestmatch-visible", dep)
+ if best_ebuild == '':
+ #writemsg_level("DATA_CONNECT: get_dep_ebuild(); "
+ #"checking masked packages", level=logging.DEBUG)
+ atomized_dep = Atom(dep)
+ hardmasked_nocheck, hardmasked = get_hard_masked(atomized_dep.cpv)
+ matches = xmatch(root, settings, "match-all", dep)[:]
+ masked_ebuild = best(matches)
+ keyworded = []
+ for m in matches:
+ if m not in hardmasked:
+ keyworded.append(m)
+ keyworded_ebuild = best(keyworded)
+ #writemsg_level("DATA_CONNECT: get_dep_ebuild(); ebuilds = " + \
+ #str([best_ebuild, keyworded_ebuild, masked_ebuild]),
+ #level=logging.DEBUG)
+ return best_ebuild, keyworded_ebuild, masked_ebuild
def get_virtual_dep(atom, settings=None):
- """Returns the first (prefered) resolved virtual dependency
- if there is more than 1 possible resolution
+ """Returns the first (prefered) resolved virtual dependency
+ if there is more than 1 possible resolution
- @param atom: dependency string
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtpye: string
- @return 'cat/pkg-ver'
- """
- if settings is None:
- settings = default_settings
- return settings.settings.getvirtuals()[atom][0]
+ @param atom: dependency string
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtpye: string
+ @return 'cat/pkg-ver'
+ """
+ if settings is None:
+ settings = default_settings
+ return settings.settings.getvirtuals()[atom][0]
def get_masking_status(cpv):
- """Gets the current masking status
+ """Gets the current masking status
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @rtype str
- """
- try:
- status = portage.getmaskingstatus(cpv)
- except KeyError:
- status = ['unavailable']
- return status
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @rtype str
+ """
+ try:
+ status = portage.getmaskingstatus(cpv)
+ except KeyError:
+ status = ['unavailable']
+ return status
def get_masking_reason(cpv, root=None, settings=None):
- """Strips trailing \n from, and returns the masking reason given by portage
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype str
- """
- root, settings = ensure_settings(root, settings)
- reason, location = portage.getmaskingreason(
- cpv, settings=settings.settings, portdb=settings.portdb[root],
- return_location=True)
- if not reason:
- reason = 'No masking reason given.'
- status = get_masking_status(cpv)
- if 'profile' in status:
- reason = "Masked by the current profile."
- status.remove('profile')
- if status:
- reason += " from " + ', '.join(status)
- if location != None:
- reason += "in file: " + location
- if reason.endswith("\n"):
- reason = reason[:-1]
- return reason
+ """Strips trailing \n from, and returns the masking reason given by portage
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype str
+ """
+ root, settings = ensure_settings(root, settings)
+ reason, location = portage.getmaskingreason(
+ cpv, settings=settings.settings, portdb=settings.portdb[root],
+ return_location=True)
+ if not reason:
+ reason = 'No masking reason given.'
+ status = get_masking_status(cpv)
+ if 'profile' in status:
+ reason = "Masked by the current profile."
+ status.remove('profile')
+ if status:
+ reason += " from " + ', '.join(status)
+ if location != None:
+ reason += "in file: " + location
+ if reason.endswith("\n"):
+ reason = reason[:-1]
+ return reason
def get_size(cpv, formatted_string=True, root=None, settings=None):
- """ Returns size of package to fetch.
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @param formatted_string: defaults to True
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype str, or int
- """
- root, settings = ensure_settings(root, settings)
- #This code to calculate size of downloaded files was taken from /usr/bin/emerge - BB
- #writemsg_level( "DATA_CONNECT: get_size; cpv = " + cpv, level=logging.DEBUG)
- total = [0,'']
- ebuild = settings.portdb[root].findname(cpv)
- pkgdir = os.path.dirname(ebuild)
- mf = manifest.Manifest(pkgdir, settings.settings["DISTDIR"])
- iuse, final_use = get_flags(cpv, final_setting=True, root=root, settings=default_settings)
- #writemsg_level( "DATA_CONNECT: get_size; Attempting to get fetchlist final use= " + str(final_use),
- #level=logging.DEBUG)
- try:
- fetchlist = settings.portdb[root].getFetchMap(cpv, set(final_use))
- #writemsg_level( "DATA_CONNECT: get_size; fetchlist= " +str(fetchlist), level=logging.DEBUG)
- #writemsg_level( "DATA_CONNECT: get_size; mf.getDistfilesSize()", level=logging.DEBUG)
- total[0] = mf.getDistfilesSize(fetchlist)
- if formatted_string:
- total_str = str(total[0]/1024)
- #writemsg_level( "DATA_CONNECT: get_size; total_str = " + total_str, level=logging.DEBUG)
- count=len(total_str)
- while (count > 3):
- count-=3
- total_str=total_str[:count]+","+total_str[count:]
- total[1]=total_str+" kB"
- except KeyError, e:
- total[1] = "Unknown (missing digest)"
- total[0] = 0
- #writemsg_level( "DATA_CONNECT: get_size; Exception: " + str(e), level=logging.DEBUG)
- #writemsg_level( "DATA_CONNECT: get_size; cpv: " + str(cpv), level=logging.DEBUG)
- #writemsg_level( "DATA_CONNECT: get_size; fetchlist = " + str(fetchlist), level=logging.DEBUG)
- #writemsg_level( "DATA_CONNECT: get_size; returning total[1] = " + total[1], level=logging.DEBUG)
- if formatted_string:
- return total[1]
- return total[0]
+ """ Returns size of package to fetch.
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @param formatted_string: defaults to True
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype str, or int
+ """
+ root, settings = ensure_settings(root, settings)
+ #This code to calculate size of downloaded files
+ # was taken from /usr/bin/emerge - BB
+ #writemsg_level( "DATA_CONNECT: get_size; cpv = " + \
+ #cpv, level=logging.DEBUG)
+ total = [0,'']
+ ebuild = settings.portdb[root].findname(cpv)
+ pkgdir = os.path.dirname(ebuild)
+ mf = manifest.Manifest(pkgdir, settings.settings["DISTDIR"])
+ iuse, final_use = get_flags(cpv, final_setting=True,
+ root=root, settings=default_settings)
+ #writemsg_level( "DATA_CONNECT: get_size; Attempting to get "
+ #"fetchlist final use= " + str(final_use), level=logging.DEBUG)
+ try:
+ fetchlist = settings.portdb[root].getFetchMap(cpv, set(final_use))
+ #writemsg_level( "DATA_CONNECT: get_size; fetchlist= " + \
+ #str(fetchlist), level=logging.DEBUG)
+ #writemsg_level( "DATA_CONNECT: get_size; mf.getDistfilesSize()",
+ #level=logging.DEBUG)
+ total[0] = mf.getDistfilesSize(fetchlist)
+ if formatted_string:
+ total_str = str(total[0]/1024)
+ #writemsg_level( "DATA_CONNECT: get_size; total_str = " + \
+ #total_str, level=logging.DEBUG)
+ count = len(total_str)
+ while (count > 3):
+ count -= 3
+ total_str = total_str[:count]+","+total_str[count:]
+ total[1] = total_str+" kB"
+ except KeyError as e:
+ total[1] = "Unknown (missing digest)"
+ total[0] = 0
+ writemsg_level( "DATA_CONNECT: get_size; Exception: " + str(e),
+ level=logging.DEBUG)
+ writemsg_level( "DATA_CONNECT: get_size; cpv: " + str(cpv),
+ level=logging.DEBUG)
+ writemsg_level( "DATA_CONNECT: get_size; fetchlist = " + \
+ str(fetchlist), level=logging.DEBUG)
+ #writemsg_level( "DATA_CONNECT: get_size; returning total[1] = " \
+ #+ total[1], level=logging.DEBUG)
+ if formatted_string:
+ return total[1]
+ return total[0]
def get_properties(cpv, want_dict=False, root=None, settings=None):
- """Get all ebuild variables in one chunk.
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype
- @return all properties of cpv
- """
- root, settings = ensure_settings(root, settings)
- prop_dict = None
- if settings.portdb[root].cpv_exists(cpv): # if in portage tree
- try:
- #writemsg_level(" * DATA_CONNECT: get_properties()", level=logging.DEBUG)
- prop_dict = dict(zip(settings.keys, settings.portdb[root].aux_get(cpv, portage.auxdbkeys)))
- except IOError, e: # Sync being performed may delete files
- #writemsg_level(" * DATA_CONNECT: get_properties(): IOError: %s" % str(e), level=logging.DEBUG)
- pass
- except Exception, e:
- #writemsg_level(" * DATA_CONNECT: get_properties(): Exception: %s" %str( e), level=logging.DEBUG)
- pass
- else:
- if settings.vardb[root].cpv_exists(cpv): # elif in installed pkg tree
- prop_dict = dict(zip(settings.keys, settings.vardb[root].aux_get(cpv, portage.auxdbkeys)))
- if want_dict:
- # return an empty dict instead of None
- return prop_dict or {}
- return Properties(prop_dict)
+ """Get all ebuild variables in one chunk.
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype
+ @return all properties of cpv
+ """
+ root, settings = ensure_settings(root, settings)
+ prop_dict = None
+ if settings.portdb[root].cpv_exists(cpv): # if in portage tree
+ try:
+ #writemsg_level(" * DATA_CONNECT: get_properties()", level=logging.DEBUG)
+ prop_dict = dict(zip(settings.keys,
+ settings.portdb[root].aux_get(cpv, portage.auxdbkeys)))
+ except IOError as e: # Sync being performed may delete files
+ writemsg_level(" * DATA_CONNECT: get_properties(): IOError: %s"
+ % str(e), level=logging.DEBUG)
+ #pass
+ except Exception as e:
+ writemsg_level(" * DATA_CONNECT: get_properties(): Exception: %s"
+ %str( e), level=logging.DEBUG)
+ #pass
+ else:
+ if settings.vardb[root].cpv_exists(cpv): # elif in installed pkg tree
+ prop_dict = dict(zip(settings.keys,
+ settings.vardb[root].aux_get(cpv, portage.auxdbkeys)))
+ if want_dict:
+ # return an empty dict instead of None
+ return prop_dict or {}
+ return Properties(prop_dict)
def is_overlay(cpv, root=None, settings=None): # lifted from gentoolkit
- """Returns true if the package is in an overlay.
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype bool
- """
- root, settings = ensure_settings(root, settings)
- try:
- dir,ovl = settings.portdb[root].findname2(cpv)
- except:
- return False
- return ovl != settings.portdir
+ """Returns true if the package is in an overlay.
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype bool
+ """
+ root, settings = ensure_settings(root, settings)
+ try:
+ dir, ovl = settings.portdb[root].findname2(cpv)
+ except:
+ return False
+ return ovl != settings.portdir
def get_overlay(cpv, root=None, settings=None):
- """Returns a portage overlay id
-
- @type cpv: string
- @param cpv: 'cat/pkg-ver'
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype str
- @return portage overlay id. or 'Deprecated?
- '"""
- root, settings = ensure_settings(root, settings)
- if '/' not in cpv:
- return ''
- try:
- dir,ovl = settings.portdb[root].findname2(cpv)
- except:
- ovl = 'Deprecated?'
- return ovl
+ """Returns a portage overlay id
+
+ @type cpv: string
+ @param cpv: 'cat/pkg-ver'
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype str
+ @return portage overlay id. or 'Deprecated?
+ '"""
+ root, settings = ensure_settings(root, settings)
+ if '/' not in cpv:
+ return ''
+ try:
+ dir, ovl = settings.portdb[root].findname2(cpv)
+ except:
+ ovl = 'Deprecated?'
+ return ovl
def get_overlay_name(ovl_path=None, cpv=None, root=None, settings=None):
- """Returns the overlay name for either the overlay path or the cpv of a pkg
-
- @param ovl_path: optional portage overlay path
- @param cpv: optional cat/pkg-ver string
- @type root: string
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @param root: tree root to use
- @rtype str
- """
- root, settings = ensure_settings(root, settings)
- if not ovl_path and cpv:
- ovl_path= get_overlay(cpv, root)
- name = None
- name = settings.portdb[root].getRepositoryName(ovl_path)
- return name or "????"
+ """Returns the overlay name for either the overlay path or the cpv of a pkg
+
+ @param ovl_path: optional portage overlay path
+ @param cpv: optional cat/pkg-ver string
+ @type root: string
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @param root: tree root to use
+ @rtype str
+ """
+ root, settings = ensure_settings(root, settings)
+ if not ovl_path and cpv:
+ ovl_path = get_overlay(cpv, root)
+ name = None
+ name = settings.portdb[root].getRepositoryName(ovl_path)
+ return name or "????"
def get_repositories(root=None, settings=None):
- """Returns a list of all repositories for root
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- """
- root, settings = ensure_settings(root, settings)
- return self.portdb[root].getRepositories()
+ """Returns a list of all repositories for root
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].getRepositories()
def get_system_pkgs(root=None, settings=None): # lifted from gentoolkit
- """Returns a tuple of lists, first list is resolved system packages,
- second is a list of unresolved packages.
-
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype: tuple
- @return (resolved, unresolved) pkg lists
- """
- root, settings = ensure_settings(root, settings)
- pkglist = settings.settings.packages
- resolved = []
- unresolved = []
- for x in pkglist:
- cpv = x.strip()
- pkg = get_best_ebuild(cpv, root)
- if pkg:
- try:
- resolved.append(Atom(pkg).cp)
- except:
- resolved.append(pkgsplit(pkg)[0])
- else:
- unresolved.append(pkgsplit(cpv)[0])
- return (resolved, unresolved)
+ """Returns a tuple of lists, first list is resolved system packages,
+ second is a list of unresolved packages.
+
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype: tuple
+ @return (resolved, unresolved) pkg lists
+ """
+ root, settings = ensure_settings(root, settings)
+ pkglist = settings.settings.packages
+ resolved = []
+ unresolved = []
+ for x in pkglist:
+ cpv = x.strip()
+ pkg = get_best_ebuild(cpv, root)
+ if pkg:
+ try:
+ resolved.append(Atom(pkg).cp)
+ except:
+ resolved.append(pkgsplit(pkg)[0])
+ else:
+ unresolved.append(pkgsplit(cpv)[0])
+ return (resolved, unresolved)
def get_allnodes(root=None, settings=None):
- """Returns a list of all availabe cat/pkg's available from the tree
- and configured overlays. Subject to masking.
+ """Returns a list of all availabe cat/pkg's available from the tree
+ and configured overlays. Subject to masking.
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtpye: list
- @return: ['cat/pkg1', 'cat/pkg2',...]
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].cp_all()
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtpye: list
+ @return: ['cat/pkg1', 'cat/pkg2',...]
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].cp_all()
def get_installed_list(root=None, settings=None):
- """Returns a list of all installed cat/pkg-ver available from the tree
- and configured overlays. Subject to masking.
+ """Returns a list of all installed cat/pkg-ver available from the tree
+ and configured overlays. Subject to masking.
- @type root: string
- @param root: tree root to use
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtpye: list
- @return: ['cat/pkg1-ver', 'cat/pkg2-ver',...]
- """
- root, settings = ensure_settings(root, settings)
- return settings.vardb[root].cpv_all()
+ @type root: string
+ @param root: tree root to use
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtpye: list
+ @return: ['cat/pkg1-ver', 'cat/pkg2-ver',...]
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.vardb[root].cpv_all()
def is_installed(cpv, root=None, settings=None):
- root, settings = ensure_settings(root, settings)
- if settings.vardb[root].cpv_exists(cpv):
- return True
- return False
+ root, settings = ensure_settings(root, settings)
+ if settings.vardb[root].cpv_exists(cpv):
+ return True
+ return False
def get_cp_all(root=None, vardb=False, categories=None,
- trees=None, settings=None):
- """
- This returns a list of all keys in our tree or trees
- @param categories: optional list of categories to search or
- defaults to settings.portdb.settings.categories
- @param trees: optional list of trees to search the categories in or
- defaults to settings.portdb.porttrees
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @rtype list of [cat/pkg,...]
- """
- root, settings = ensure_settings(root, settings)
- if vardb:
- cp_all = settings.vardb[root].cp_all()
- if categories:
- d= {}
- for cp in cp_all:
- cp_split = catpkgsplit(cp)
- return sorted(d)
- return cp_all
- return settings.portdb[root].cp_all(categories, trees)
+ trees=None, settings=None):
+ """
+ This returns a list of all keys in our tree or trees
+ @param categories: optional list of categories to search or
+ defaults to settings.portdb.settings.categories
+ @param trees: optional list of trees to search the categories in or
+ defaults to settings.portdb.porttrees
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @rtype list of [cat/pkg,...]
+ """
+ root, settings = ensure_settings(root, settings)
+ if vardb:
+ raise NotImplementedError
+ '''cp_all = settings.vardb[root].cp_all()
+ if categories:
+ d= {}
+ for cp in cp_all:
+ cp_split = catpkgsplit(cp)
+ if cp_split[0] in categories and cp_split[0] not in d:
+ d[cp_split[0]] = []
+ d[cp_split[0]].append(p)
+ return sorted(d)
+ return cp_all'''
+ return settings.portdb[root].cp_all(categories, trees)
def get_cp_list(root=None, cp=None, trees=None, settings=None):
- """
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].cp_list(cp, trees)
+ """
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].cp_list(cp, trees)
def findLicensePath(license_name, root=None, settings=None):
- """@param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].findLicensePath(license_name)
-
-
-def getFetchMap(pkg, useflags=None, tree=None, settings=None):
- """
- Get the SRC_URI metadata as a dict which maps each file name to a
- set of alternative URIs.
-
- @param mypkg: cpv for an ebuild
- @type pkg: String
- @param useflags: a collection of enabled USE flags, for evaluation of
- conditionals
- @type useflags: set, or None to enable all conditionals
- @param tree: The canonical path of the tree in which the ebuild
- is located, or None for automatic lookup
- @type pkg: String
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- @returns: A dict which maps each file name to a set of alternative
- URIs.
- @rtype: dict
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].getfetchsizes(pkg, useflags, tree)
+ """@param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].findLicensePath(license_name)
+
+
+def getFetchMap(pkg, useflags=None, tree=None, root=None, settings=None):
+ """
+ Get the SRC_URI metadata as a dict which maps each file name to a
+ set of alternative URIs.
+
+ @param mypkg: cpv for an ebuild
+ @type pkg: String
+ @param useflags: a collection of enabled USE flags, for evaluation of
+ conditionals
+ @type useflags: set, or None to enable all conditionals
+ @param tree: The canonical path of the tree in which the ebuild
+ is located, or None for automatic lookup
+ @type pkg: String
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ @returns: A dict which maps each file name to a set of alternative
+ URIs.
+ @rtype: dict
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].getfetchsizes(pkg, useflags, tree)
def getfetchsizes(pkg, useflags=None, root=None, settings=None):
- """Returns a filename:size dictionnary of remaining downloads
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].getfetchsizes(pkg, useflags)
+ """Returns a filename:size dictionnary of remaining downloads
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].getfetchsizes(pkg, useflags)
def cpv_exists(cpv, root=None, settings=None):
- """Tells us whether an actual ebuild exists on disk (no masking)
- @param settings: optional portage config settings instance.
- defaults to portage.api.settings.default_settings
- """
- root, settings = ensure_settings(root, settings)
- return settings.portdb[root].cpv_exists(cpv)
+ """Tells us whether an actual ebuild exists on disk (no masking)
+ @param settings: optional portage config settings instance.
+ defaults to portage.api.settings.default_settings
+ """
+ root, settings = ensure_settings(root, settings)
+ return settings.portdb[root].cpv_exists(cpv)
def get_category_description(category, root=None, settings=None):
- root, settings = ensure_settings(root, settings)
- from xml.dom import minidom
- data = {}
- portdir = self.settings.settings['PORTDIR']
- myfile = os.path.join(portdir, category, "metadata.xml")
- if os.access(myfile, os.R_OK) and os.path.isfile(myfile):
- doc = minidom.parse(myfile)
- longdescs = doc.getElementsByTagName("longdescription")
- for longdesc in longdescs:
- data[longdesc.getAttribute("lang").strip()] = \
- ' '.join([x.strip() for x in \
- longdesc.firstChild.data.strip().split("\n")])
-
- # Only return in plain English since Portage doesn't support i18n/l10n
- return data.get('en', "No description")
+ root, settings = ensure_settings(root, settings)
+ from xml.dom import minidom
+ data = {}
+ portdir = settings.settings['PORTDIR']
+ myfile = os.path.join(portdir, category, "metadata.xml")
+ if os.access(myfile, os.R_OK) and os.path.isfile(myfile):
+ doc = minidom.parse(myfile)
+ longdescs = doc.getElementsByTagName("longdescription")
+ for longdesc in longdescs:
+ data[longdesc.getAttribute("lang").strip()] = \
+ ' '.join([x.strip() for x in \
+ longdesc.firstChild.data.strip().split("\n")])
+
+ # Only return in plain English since Portage doesn't support i18n/l10n
+ return data.get('en', "No description")
diff --git a/pym/portage/api/flag.py b/pym/portage/api/flag.py
index 52ea9be..a83ee1d 100644
--- a/pym/portage/api/flag.py
+++ b/pym/portage/api/flag.py
@@ -19,7 +19,7 @@ __all__ = (
)
-import sys
+#import sys
from portage.api.settings import default_settings
@@ -64,7 +64,7 @@ def get_installed_use(cpv, use="USE", root=None, settings=default_settings):
"""
if root is None:
root = settings.settings["ROOT"]
- return settings.vardb[root].aux_get(cpv,[use])[0].split()
+ return settings.vardb[root].aux_get(cpv, [use])[0].split()
def reduce_flag(flag):
@@ -89,13 +89,14 @@ def reduce_flags(the_list):
@rtype: list
@return absolute USE flags
"""
- r=[]
+ reduced = []
for member in the_list:
- r.append(reduce_flag(member))
- return r
+ reduced.append(reduce_flag(member))
+ return reduced
-def filter_flags(use, use_expand_hidden, usemasked, useforced, settings=default_settings):
+def filter_flags(use, use_expand_hidden, usemasked,
+ useforced, settings=default_settings):
"""Filter function to remove hidden or otherwise not normally
visible USE flags from a list.
@@ -114,21 +115,21 @@ def filter_flags(use, use_expand_hidden, usemasked, useforced, settings=default_
"""
# clean out some environment flags, since they will most probably
# be confusing for the user
- for f in use_expand_hidden:
- f=f.lower() + "_"
- for x in use:
- if f in x:
- use.remove(x)
+ for flag in use_expand_hidden:
+ flag = flag.lower() + "_"
+ for expander in use:
+ if flag in expander:
+ use.remove(expander)
# clean out any arch's
archlist = settings.settings["PORTAGE_ARCHLIST"].split()
- for a in use[:]:
- if a in archlist:
- use.remove(a)
+ for key in use[:]:
+ if key in archlist:
+ use.remove(key)
# dbl check if any from usemasked or useforced are still there
masked = usemasked + useforced
- for a in use[:]:
- if a in masked:
- use.remove(a)
+ for flag in use[:]:
+ if flag in masked:
+ use.remove(flag)
return use
@@ -181,11 +182,15 @@ def get_flags(cpv, final_setting=False, root=None, settings=default_settings):
@rtype: list or list, list
@return IUSE or IUSE, final_flags
"""
- final_use, use_expand_hidden, usemasked, useforced = get_all_cpv_use(cpv, root, settings)
- iuse_flags = filter_flags(get_iuse(cpv), use_expand_hidden, usemasked, useforced, settings)
- #flags = filter_flags(use_flags, use_expand_hidden, usemasked, useforced, settings)
+ (final_use, use_expand_hidden, usemasked, useforced) = \
+ get_all_cpv_use(cpv, root, settings)
+ iuse_flags = filter_flags(get_iuse(cpv), use_expand_hidden,
+ usemasked, useforced, settings)
+ #flags = filter_flags(use_flags, use_expand_hidden,
+ #usemasked, useforced, settings)
if final_setting:
- final_flags = filter_flags(final_use, use_expand_hidden, usemasked, useforced, settings)
+ final_flags = filter_flags(final_use, use_expand_hidden,
+ usemasked, useforced, settings)
return iuse_flags, final_flags
return iuse_flags
@@ -204,22 +209,23 @@ def get_use_flag_dict(portdir):
# process standard use flags
- List = portage.grabfile(portdir + '/profiles/use.desc')
- for item in List:
+ _list = portage.grabfile(portdir + '/profiles/use.desc')
+ for item in _list:
index = item.find(' - ')
use_dict[item[:index].strip().lower()] = ['global', '', item[index+3:]]
# process local (package specific) use flags
- List = portage.grabfile(portdir + '/profiles/use.local.desc')
- for item in List:
+ _list = portage.grabfile(portdir + '/profiles/use.local.desc')
+ for item in _list:
index = item.find(' - ')
data = item[:index].lower().split(':')
- try: # got an error once starting porthole==> added code to catch it, but it works again???
+ try:
use_dict[data[1].strip()] = ['local', data[0].strip(), item[index+3:]]
except:
pass
- #debug.dprint("FLAG: get_use_flag_dict(); error in index??? data[0].strip, item[index:]")
+ #debug.dprint("FLAG: get_use_flag_dict();"
+ #"error in index??? data[0].strip, item[index:]")
#debug.dprint(data[0].strip())
#debug.dprint(item[index:])
return use_dict
diff --git a/pym/portage/api/properties.py b/pym/portage/api/properties.py
index b885505..f282e76 100644
--- a/pym/portage/api/properties.py
+++ b/pym/portage/api/properties.py
@@ -20,8 +20,10 @@ class Properties(object):
self._dict = _dict
def __getattr__(self, name):
- try: return self._dict[name]
- except: return ''
+ try:
+ return self._dict[name]
+ except:
+ return ''
def __str__(self):
txt = []
@@ -30,9 +32,11 @@ class Properties(object):
return '\n'.join(txt)
def keys(self):
+ """Returns the availabel dictionary keys"""
return self.__slots__[:-3]
def get(self, name):
+ """Returns the value for the dictionary key"""
return getattr(self, name)
def get_slot(self):
diff --git a/pym/portage/api/settings.py b/pym/portage/api/settings.py
index ca81908..250917e 100644
--- a/pym/portage/api/settings.py
+++ b/pym/portage/api/settings.py
@@ -21,6 +21,14 @@ class PortageSettings:
# declare some globals
self.portdir = None
self.portdir_overlay = None
+ self.portdb = None
+ self.vardb = None
+ self.trees = None
+ self.root_config = None
+ self.bindb = None
+ self.configured_roots = None
+ self.arch = None
+ self.mtimedb = None
self.ACCEPT_KEYWORDS = None
self.user_config_dir = None
self._world = None
@@ -28,6 +36,7 @@ class PortageSettings:
self.virtuals = None
self.keys = None
self.UseFlagDict = None
+ self.settings = None
if config_root is None:
self.reset()
else:
@@ -67,38 +76,6 @@ class PortageSettings:
return
- def _load_config(trees=None, config_root=None):
- kwargs = {}
- if config_root:
- env_fetch = (("target_root", "ROOT"))
- kwargs['config_root'] = config_root
- else:
- env_fetch = (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT"))
- for k, envvar in env_fetch:
- v = os.environ.get(envvar, None)
- if v and v.strip():
- kwargs[k] = v
- trees = portage.create_trees(trees=trees, **kwargs)
-
- for root, root_trees in trees.items():
- settings = root_trees["vartree"].settings
- settings._init_dirs()
- setconfig = load_default_config(settings, root_trees)
- root_trees["root_config"] = RootConfig(settings, root_trees, setconfig)
-
- settings = trees["/"]["vartree"].settings
-
- for myroot in trees:
- if myroot != "/":
- settings = trees[myroot]["vartree"].settings
- break
-
- mtimedbfile = os.path.join(settings['EROOT'], portage.CACHE_PATH, "mtimedb")
- mtimedb = portage.MtimeDB(mtimedbfile)
- portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
- return settings, trees, mtimedb
-
-
def _load_dbapis(self):
"""handles loading all the trees dbapi's"""
self.portdb, self.vardb, self.bindb = {}, {}, {}
@@ -121,11 +98,12 @@ class PortageSettings:
#print("SETTINGS: reset_world();")
world = []
try:
- file = open(os.path.join(portage.root, portage.WORLD_FILE), "r")
- world = file.read().split()
- file.close()
+ _file = open(os.path.join(portage.root, portage.WORLD_FILE), "r")
+ world = _file.read().split()
+ _file.close()
except:
- print("SETTINGS: get_world(); Failure to locate file: '%s'" %portage.WORLD_FILE)
+ print("SETTINGS: get_world(); Failure to locate file: '%s'"
+ %portage.WORLD_FILE)
return False
self._world = world
return True
@@ -156,7 +134,7 @@ class PortageSettings:
default_settings = PortageSettings()
-def reload_portage():
+def reload_portage(settings=None):
"""Convienence function to re-import portage after a portage update.
Caution, it may not always work correctly due to python caching if
program files are added/deleted between versions. In those cases the
@@ -168,5 +146,8 @@ def reload_portage():
except ImportError:
return False
#print("SETTINGS: new portage version = " + portage.VERSION)
- settings.reset()
+ if settings is None:
+ default_settings.reset()
+ else:
+ settings.reset()
return True
next reply other threads:[~2011-05-28 6:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-28 6:53 Brian Dolbec [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-07-28 20:42 [gentoo-commits] proj/portage:public_api commit in: pym/portage/api/ Brian Dolbec
2011-05-28 6:53 Brian Dolbec
2011-05-25 15:43 Brian Dolbec
2011-05-25 14:45 Brian Dolbec
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7f1c35149aa401e83828e27716d35c3ec2b13108.dol-sen@gentoo \
--to=brian.dolbec@gmail.com \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox