|12594 |Remove support for deprecated 2_pre* EAPI values. |
|zmedico| |
|12595 |Keep 2_pre* EAPI values in the deprecated list so that uninstalls still work |
|zmedico|normally. |
|12596 |Add new EAPI 3_pre1 value, and disable unpack() support for *.xz for earlier EAPI |
|zmedico|values. |
|12597 |Document EAPI 3_pre1. |
|zmedico| |
|12598 |Bug #258433 - Note FETCHCOMMAND and RESUMECOMMAND requirements wrt ${FILE} for |
|zmedico|compatibility with EAPI 2. |
|12599 |Inside depgraph._select_atoms(), only trigger the circular dependency avoidance |
|zmedico|code for buildtime dependencies. This solves a problem with virtual/mysql |
| |inappropriately pulling in mysql-community from PDEPEND when satisfying deps of |
| |plain mysql. Thanks to Krzysiek Pawlik <nelchael@g.o> for reporting this issue: |
| |http://archives.gentoo.org/gentoo-dev/msg_efce154d642fe6ede38d084a33c7f949.xml |
|12600 |Bug #258433 - In portage.fetch(), check for missing ${FILE} parameter in |
|zmedico|FETCHCOMMAND or RESUMECOMMAND and bail out early if necessary. |
|12601 |Inside portage.fetch(), check for the case where FETCOMMAND creates a directory |
|zmedico|where a file is expected. This can happen if FETCHCOMMAND erroneously contains |
| |wget's -P option where it should instead have -O, as reported in bug #258433, |
| |comment #16. |
|12602 |* Remove outdated comment about qa_source() return value (with typo). * Update |
|zmedico|copyright header. Thanks to Jeremy Olexa <darkside@g.o> for reporting. |
|12603 |Add a new "portage.internal" warning for prepalldocs usage since the council ruled|
|zmedico|that it shouldn't be used in ebuilds. Thanks to Petteri Räty <betelgeuse@g.o> for|
| |the initial patch. |
|12604 |Fix Scheduler._prevent_builddir_collisions() to skip non-Package instances when |
|zmedico|necessary. |
|12605 |In depgraph._serialize_tasks(), verify that an uninstall task has at least one |
|zmedico|theoretically mergeable parent before choosing to reverse it's edges. |
svn path=/main/branches/prefix/; revision=12608
force digests to be updated, run `ebuild --force <ebuild file> manifest`.
This is a safety measure which protects valid distfiles digests from being
accidentally replaced by invalid digests.
+* If you have overridden FETCHCOMMAND or RESUMECOMMAND variables, for
+ compatibility with EAPI 2, you must ensure that these variables are written
+ such that the downloaded file will be placed at \"\${DISTDIR}/\${FILE}\".
+ Refer to make.conf(5) for information about FETCHCOMMAND and RESUMECOMMAND.
portage-2.1.5
==================================
#!@PORTAGE_BASH@
-# Copyright 1999-2007 Gentoo Foundation
+# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$
# These two functions wrap sourcing and calling respectively. At present they
# perform a qa check to make sure eclasses and ebuilds and profiles don't mess
# with shell opts (shopts). Ebuilds/eclasses changing shopts should reset them
-# when they are done. Note: For now these shoudl always return success.
+# when they are done.
qa_source() {
local shopts=$(shopt) OLDIFS="$IFS"
local y
local myfail
local tar_opts=""
+ local eapi=${EAPI:-0}
[ -z "$*" ] && die "Nothing passed to the 'unpack' command"
for x in "$@"; do
fi
;;
xz)
- if [ "${y}" == "tar" ]; then
- xz -dc "${srcdir}${x}" | tar xof - ${tar_opts}
- assert "$myfail"
+ if hasq $eapi 0 1 2 ; then
+ vecho "unpack ${x}: file format not recognized. Ignoring."
else
- xz -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
+ if [ "${y}" == "tar" ]; then
+ xz -dc "${srcdir}${x}" | tar xof - ${tar_opts}
+ assert "$myfail"
+ else
+ xz -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
+ fi
fi
;;
*)
phase_func=src_unpack
;;
prepare)
- ! hasq $eapi 0 1 2_pre1 2_pre2 && \
+ ! hasq $eapi 0 1 && \
phase_func=src_prepare
;;
configure)
- ! hasq $eapi 0 1 2_pre1 && \
+ ! hasq $eapi 0 1 && \
phase_func=src_configure
;;
compile)
case $eapi in
- 0|1|2_pre1)
+ 0|1)
if [[ $(type -t src_compile) != function ]] ; then
case $eapi in
"metadata.missing":"Missing metadata.xml files",
"metadata.bad":"Bad metadata.xml files",
"metadata.warning":"Warnings in metadata.xml files",
+ "portage.internal":"The ebuild uses an internal Portage function",
"virtual.versioned":"PROVIDE contains virtuals with versions",
"virtual.exists":"PROVIDE contains existing package names",
"virtual.unavailable":"PROVIDE contains a virtual which contains no profile default",
&package_ebuild_eapi_0;
&package_ebuild_eapi_1;
&package_ebuild_eapi_2;
+&package_ebuild_eapi_3;
</section>
</chapter>
--- /dev/null
+<section id='package-ebuild-eapi-3_pre1'>
+<title>EAPI 3_pre1</title>
+<section id='package-ebuild-eapi-3_pre1-helpers'>
+<title>Helpers</title>
+<section id='package-ebuild-eapi-3_pre1-helpers-unpack'>
+<title>unpack</title>
+<section id='package-ebuild-eapi-3_pre1-helpers-unpack-xz'>
+<title>Support for the xz file extension</title>
+<para>
+The xz file extension is now supported.
+</para>
+</section>
+</section>
+</section>
+</section>
<!ENTITY package_ebuild_eapi_0 SYSTEM "package/ebuild/eapi/0.docbook">
<!ENTITY package_ebuild_eapi_1 SYSTEM "package/ebuild/eapi/1.docbook">
<!ENTITY package_ebuild_eapi_2 SYSTEM "package/ebuild/eapi/2.docbook">
+ <!ENTITY package_ebuild_eapi_3 SYSTEM "package/ebuild/eapi/3.docbook">
<!ENTITY qa SYSTEM "qa.docbook">
<!ENTITY config SYSTEM "config.docbook">
<!ENTITY config_bashrc SYSTEM "config/bashrc.docbook">
.B metadata.warning
Warnings in metadata.xml files
.TP
+.B portage.internal
+The ebuild uses an internal Portage function
+.TP
.B upstream.workaround
The ebuild works around an upstream bug, an upstream bug should be filed and
tracked in bugs.gentoo.org
pkg = self.pkg
phases = self._phases
eapi = pkg.metadata["EAPI"].replace(EAPIPREFIX, "").strip()
- if eapi in ("0", "1", "2_pre1"):
+ if eapi in ("0", "1"):
# skip src_prepare and src_configure
phases = phases[2:]
- elif eapi in ("2_pre2",):
- # skip src_prepare
- phases = phases[1:]
for phase in phases:
ebuild_phases.add(EbuildPhase(background=self.background,
vardb = self.roots[dep_root].trees["vartree"].dbapi
try:
selected_atoms = self._select_atoms(dep_root,
- dep_string, myuse=myuse, parent=pkg, strict=strict)
+ dep_string, myuse=myuse, parent=pkg, strict=strict,
+ priority=dep_priority)
except portage.exception.InvalidDependString, e:
show_invalid_depstring_notice(jbigkey, dep_string, str(e))
return 0
return self._select_atoms_highest_available(*pargs, **kwargs)
def _select_atoms_highest_available(self, root, depstring,
- myuse=None, parent=None, strict=True, trees=None):
+ myuse=None, parent=None, strict=True, trees=None, priority=None):
"""This will raise InvalidDependString if necessary. If trees is
None then self._filtered_trees is used."""
pkgsettings = self.pkgsettings[root]
if trees is None:
trees = self._filtered_trees
+ if not getattr(priority, "buildtime", False):
+ # The parent should only be passed to dep_check() for buildtime
+ # dependencies since that's the only case when it's appropriate
+ # to trigger the circular dependency avoidance code which uses it.
+ # It's important not to trigger the same circular dependency
+ # avoidance code for runtime dependencies since it's not needed
+ # and it can promote an incorrect package choice.
+ parent = None
if True:
try:
if parent is not None:
runtime_deps.update(atom for atom in portage_rdepend \
if not atom.startswith("!"))
+ def gather_deps(ignore_priority, mergeable_nodes,
+ selected_nodes, node):
+ """
+ Recursively gather a group of nodes that RDEPEND on
+ eachother. This ensures that they are merged as a group
+ and get their RDEPENDs satisfied as soon as possible.
+ """
+ if node in selected_nodes:
+ return True
+ if node not in mergeable_nodes:
+ return False
+ if node == replacement_portage and \
+ mygraph.child_nodes(node,
+ ignore_priority=DepPriority.MEDIUM_SOFT):
+ # Make sure that portage always has all of it's
+ # RDEPENDs installed first.
+ return False
+ selected_nodes.add(node)
+ for child in mygraph.child_nodes(node,
+ ignore_priority=ignore_priority):
+ if not gather_deps(ignore_priority,
+ mergeable_nodes, selected_nodes, child):
+ return False
+ return True
+
+ def ignore_uninst_or_med(priority):
+ if priority is BlockerDepPriority.instance:
+ return True
+ return priority <= DepPriority.MEDIUM
+
+ def ignore_uninst_or_med_soft(priority):
+ if priority is BlockerDepPriority.instance:
+ return True
+ return priority <= DepPriority.MEDIUM_SOFT
+
ignore_priority_soft_range = [None]
ignore_priority_soft_range.extend(
xrange(DepPriority.MIN, DepPriority.MEDIUM_SOFT + 1))
if not selected_nodes:
nodes = get_nodes(ignore_priority=DepPriority.MEDIUM)
if nodes:
- """Recursively gather a group of nodes that RDEPEND on
- eachother. This ensures that they are merged as a group
- and get their RDEPENDs satisfied as soon as possible."""
- def gather_deps(ignore_priority,
- mergeable_nodes, selected_nodes, node):
- if node in selected_nodes:
- return True
- if node not in mergeable_nodes:
- return False
- if node == replacement_portage and \
- mygraph.child_nodes(node,
- ignore_priority=DepPriority.MEDIUM_SOFT):
- # Make sure that portage always has all of it's
- # RDEPENDs installed first.
- return False
- selected_nodes.add(node)
- for child in mygraph.child_nodes(node,
- ignore_priority=ignore_priority):
- if not gather_deps(ignore_priority,
- mergeable_nodes, selected_nodes, child):
- return False
- return True
mergeable_nodes = set(nodes)
if prefer_asap and asap_nodes:
nodes = asap_nodes
if not selected_nodes and not myblocker_uninstalls.is_empty():
# An Uninstall task needs to be executed in order to
# avoid conflict if possible.
+
+ mergeable_nodes = get_nodes(
+ ignore_priority=ignore_uninst_or_med)
+
min_parent_deps = None
uninst_task = None
for task in myblocker_uninstalls.leaf_nodes():
# best possible choice, but the current algorithm
# is simple and should be near optimal for most
# common cases.
+ mergeable_parent = False
parent_deps = set()
for parent in mygraph.parent_nodes(task):
parent_deps.update(mygraph.child_nodes(parent,
ignore_priority=DepPriority.MEDIUM_SOFT))
+ if parent in mergeable_nodes and \
+ gather_deps(ignore_uninst_or_med_soft,
+ mergeable_nodes, set(), parent):
+ mergeable_parent = True
+
+ if not mergeable_parent:
+ continue
+
parent_deps.remove(task)
if min_parent_deps is None or \
len(parent_deps) < min_parent_deps:
"""
cpv_map = {}
for pkg in self._mergelist:
+ if not isinstance(pkg, Package):
+ # a satisfied blocker
+ continue
if pkg.installed:
continue
if pkg.cpv not in cpv_map:
if listonly:
can_fetch = False
- for var_name in ("FETCHCOMMAND", "RESUMECOMMAND"):
- if not mysettings.get(var_name, None):
- can_fetch = False
-
if can_fetch and not fetch_to_ro:
global _userpriv_test_write_file_cache
dirmode = 02070
pass
if mystat is not None:
+ if stat.S_ISDIR(mystat.st_mode):
+ portage.util.writemsg_level(
+ ("!!! Unable to fetch file since " + \
+ "a directory is in the way: \n" + \
+ "!!! %s\n") % myfile_path,
+ level=logging.ERROR, noiselevel=-1)
+ return 0
+
if mystat.st_size == 0:
if distdir_writable:
try:
continue
# allow different fetchcommands per protocol
protocol = loc[0:loc.find("://")]
- if "FETCHCOMMAND_" + protocol.upper() in mysettings:
- fetchcommand=mysettings["FETCHCOMMAND_"+protocol.upper()]
- else:
- fetchcommand=mysettings["FETCHCOMMAND"]
- if "RESUMECOMMAND_" + protocol.upper() in mysettings:
- resumecommand=mysettings["RESUMECOMMAND_"+protocol.upper()]
- else:
- resumecommand=mysettings["RESUMECOMMAND"]
+
+ missing_file_param = False
+ fetchcommand_var = "FETCHCOMMAND_" + protocol.upper()
+ fetchcommand = mysettings.get(fetchcommand_var)
+ if fetchcommand is None:
+ fetchcommand_var = "FETCHCOMMAND"
+ fetchcommand = mysettings.get(fetchcommand_var)
+ if fetchcommand is None:
+ portage.util.writemsg_level(
+ ("!!! %s is unset. It should " + \
+ "have been defined in\n!!! %s/make.globals.\n") \
+ % (fetchcommand_var,
+ portage.const.GLOBAL_CONFIG_PATH),
+ level=logging.ERROR, noiselevel=-1)
+ return 0
+ if "${FILE}" not in fetchcommand:
+ portage.util.writemsg_level(
+ ("!!! %s does not contain the required ${FILE}" + \
+ " parameter.\n") % fetchcommand_var,
+ level=logging.ERROR, noiselevel=-1)
+ missing_file_param = True
+
+ resumecommand_var = "RESUMECOMMAND_" + protocol.upper()
+ resumecommand = mysettings.get(resumecommand_var)
+ if resumecommand is None:
+ resumecommand_var = "RESUMECOMMAND"
+ resumecommand = mysettings.get(resumecommand_var)
+ if resumecommand is None:
+ portage.util.writemsg_level(
+ ("!!! %s is unset. It should " + \
+ "have been defined in\n!!! %s/make.globals.\n") \
+ % (resumecommand_var,
+ portage.const.GLOBAL_CONFIG_PATH),
+ noiselevel=-1)
+ return 0
+ if "${FILE}" not in resumecommand:
+ portage.util.writemsg_level(
+ ("!!! %s does not contain the required ${FILE}" + \
+ " parameter.\n") % resumecommand_var,
+ level=logging.ERROR, noiselevel=-1)
+ missing_file_param = True
+
+ if missing_file_param:
+ portage.util.writemsg_level(
+ "!!! Refer to the make.conf(5) man page for " + \
+ "information about how to\n!!! correctly specify " + \
+ "FETCHCOMMAND and RESUMECOMMAND.\n",
+ level=logging.ERROR, noiselevel=-1)
+ if myfile != os.path.basename(loc):
+ return 0
if not can_fetch:
if fetched != 2:
else:
writemsg(("!!! File %s is incorrect size, " + \
"but unable to retry.\n") % myfile, noiselevel=-1)
- for var_name in ("FETCHCOMMAND", "RESUMECOMMAND"):
- if not mysettings.get(var_name, None):
- writemsg(("!!! %s is unset. It should " + \
- "have been defined in /etc/make.globals.\n") \
- % var_name, noiselevel=-1)
return 0
else:
continue
#resume mode:
writemsg(">>> Resuming download...\n")
locfetch=resumecommand
+ command_var = resumecommand_var
else:
#normal mode:
locfetch=fetchcommand
+ command_var = fetchcommand_var
writemsg_stdout(">>> Downloading '%s'\n" % \
re.sub(r'//(.+):.+@(.+)/',r'//\1:*password*@\2/', loc))
variables = {
del e
fetched = 0
else:
+
+ if stat.S_ISDIR(mystat.st_mode):
+ # This can happen if FETCHCOMMAND erroneously
+ # contains wget's -P option where it should
+ # instead have -O.
+ portage.util.writemsg_level(
+ ("!!! The command specified in the " + \
+ "%s variable appears to have\n!!! " + \
+ "created a directory instead of a " + \
+ "normal file.\n") % command_var,
+ level=logging.ERROR, noiselevel=-1)
+ portage.util.writemsg_level(
+ "!!! Refer to the make.conf(5) " + \
+ "man page for information about how " + \
+ "to\n!!! correctly specify " + \
+ "FETCHCOMMAND and RESUMECOMMAND.\n",
+ level=logging.ERROR, noiselevel=-1)
+ return 0
+
# no exception? file exists. let digestcheck() report
# an appropriately for size or checksum errors
eapi = mysettings["EAPI"]
- if mydo == "configure" and eapi in ("0", "1", "2_pre1"):
+ if mydo == "configure" and eapi in ("0", "1"):
return os.EX_OK
- if mydo == "prepare" and eapi in ("0", "1", "2_pre1", "2_pre2"):
+ if mydo == "prepare" and eapi in ("0", "1"):
return os.EX_OK
kwargs = actionmap[mydo]["args"]
eerror(l, phase=mydo, key=mysettings.mycpv)
return rval
+_testing_eapis = frozenset(["3_pre1"])
_deprecated_eapis = frozenset(["2_pre3", "2_pre2", "2_pre1"])
def _eapi_is_deprecated(eapi):
eapi.remove(prop)
# now check if what's left is supported (can)
- properties = set(_deprecated_eapis) # another clumpsy solution
+ properties = set(_testing_eapis) # another clumpsy solution
for i in range(portage.const.EAPI + 1):
properties.add(str(i))
return 'WANT_AUTO' + m.group(1) + \
' redundantly set to default value "latest" on line: %d'
+class PortageInternal(LineCheck):
+ """
+ In February 2009 the Gentoo council ruled that
+ prepalldocs is a Portage internal.
+ """
+ repoman_check_name = 'portage.internal'
+ re = re.compile(r'[^#]*\bprepalldocs\b')
+ error = errors.PREPALLDOCS_ERROR
+
_constant_checks = tuple((c() for c in (
EbuildHeader, EbuildWhitespace, EbuildQuote,
EbuildAssignment, EbuildUselessDodoc,
EbuildPatches, EbuildQuotedA,
IUseUndefined, ImplicitRuntimeDeps, InheritAutotools,
EMakeParallelDisabled, DeprecatedBindnowFlags,
- WantAutoDefaultValue)))
+ WantAutoDefaultValue, PortageInternal)))
def run_checks(contents, pkg):
checks = _constant_checks
REDUNDANT_CD_S_ERROR = 'Ebuild has redundant cd ${S} statement on line: %d'
EMAKE_PARALLEL_DISABLED = 'Upstream parallel compilation bug (ebuild calls emake -j1 on line: %d)'
DEPRECATED_BINDNOW_FLAGS = 'Deprecated bindnow-flags call on line: %d'
+PREPALLDOCS_ERROR = 'prepalldocs called on line: %d'