106 lines
3.7 KiB
Python
106 lines
3.7 KiB
Python
"""
|
|
Copyright 2018 Oliver Smith
|
|
|
|
This file is part of pmbootstrap.
|
|
|
|
pmbootstrap is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
pmbootstrap is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
import logging
|
|
import pmb.chroot
|
|
import pmb.chroot.apk
|
|
import pmb.parse.apkindex
|
|
|
|
|
|
def recurse_error_message(pkgname, in_aports, in_apkindexes):
|
|
ret = "Could not find package '" + pkgname + "'"
|
|
if in_aports:
|
|
ret += " in the aports folder"
|
|
if in_apkindexes:
|
|
ret += " and could not find it"
|
|
if in_apkindexes:
|
|
ret += " in any APKINDEX"
|
|
return ret
|
|
|
|
|
|
def recurse(args, pkgnames, arch=None, in_apkindexes=True, in_aports=True,
|
|
strict=False):
|
|
"""
|
|
Find all dependencies of the given pkgnames.
|
|
|
|
:param in_apkindexes: look through all APKINDEX files (with the specified arch)
|
|
:param in_aports: look through the aports folder
|
|
:param strict: raise RuntimeError, when a dependency can not be found.
|
|
"""
|
|
logging.debug("Calculate depends of packages " + str(pkgnames) +
|
|
", arch: " + arch)
|
|
logging.verbose("Search in_aports: " + str(in_aports) + ", in_apkindexes: " +
|
|
str(in_apkindexes))
|
|
|
|
# Sanity check
|
|
if not in_apkindexes and not in_aports:
|
|
raise RuntimeError("Set at least one of in_apkindexes or in_aports to"
|
|
" True.")
|
|
|
|
# Iterate over todo-list until is is empty
|
|
todo = list(pkgnames)
|
|
ret = []
|
|
while len(todo):
|
|
# Skip already passed entries
|
|
pkgname_depend = todo.pop(0)
|
|
if pkgname_depend in ret:
|
|
continue
|
|
|
|
# Get depends and pkgname from aports
|
|
depends = None
|
|
pkgname = None
|
|
if in_aports:
|
|
aport = pmb.build.find_aport(args, pkgname_depend, False)
|
|
if aport:
|
|
logging.verbose(pkgname_depend + ": found aport: " + aport)
|
|
apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD")
|
|
depends = apkbuild["depends"]
|
|
if pkgname_depend in apkbuild["subpackages"]:
|
|
pkgname = pkgname_depend
|
|
else:
|
|
pkgname = apkbuild["pkgname"]
|
|
|
|
# Get depends and pkgname from APKINDEX
|
|
if depends is None and in_apkindexes:
|
|
index_data = pmb.parse.apkindex.read_any_index(args, pkgname_depend,
|
|
arch)
|
|
if index_data:
|
|
depends = index_data["depends"]
|
|
pkgname = index_data["pkgname"]
|
|
|
|
# Nothing found
|
|
if pkgname is None and strict:
|
|
raise RuntimeError(
|
|
recurse_error_message(
|
|
pkgname_depend,
|
|
in_aports,
|
|
in_apkindexes))
|
|
|
|
# Append to todo/ret (unless it is a duplicate)
|
|
if pkgname != pkgname_depend:
|
|
logging.verbose(pkgname_depend + ": provided by '" + pkgname + "'")
|
|
if pkgname in ret:
|
|
logging.verbose(pkgname + ": already found")
|
|
else:
|
|
logging.verbose(pkgname + ": depends on: " + ",".join(depends))
|
|
if depends:
|
|
todo += depends
|
|
ret.append(pkgname)
|
|
|
|
return ret
|