Remove forgotten multilib module for yum
There's no more yum anymore. This was also the only user of the pathmatch module, which is thus also removed. Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com> (cherry picked from commit 989a9c2565ab9466b55d6edc056973c3080dfeae)
This commit is contained in:
parent
4ff13b1993
commit
e98dd56fce
@ -1,295 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# This program 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; version 2 of the License.
|
|
||||||
#
|
|
||||||
# This program 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 Library General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, see <https://gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
import fnmatch
|
|
||||||
|
|
||||||
import pungi.pathmatch
|
|
||||||
import pungi.gather
|
|
||||||
import pungi.util
|
|
||||||
|
|
||||||
|
|
||||||
LINE_PATTERN_RE = re.compile(r"^\s*(?P<line>[^#]+)(:?\s+(?P<comment>#.*))?$")
|
|
||||||
RUNTIME_PATTERN_SPLIT_RE = re.compile(
|
|
||||||
r"^\s*(?P<path>[^\s]+)\s+(?P<pattern>[^\s]+)(:?\s+(?P<comment>#.*))?$"
|
|
||||||
)
|
|
||||||
SONAME_PATTERN_RE = re.compile(r"^(.+\.so\.[a-zA-Z0-9_\.]+).*$")
|
|
||||||
|
|
||||||
|
|
||||||
def read_lines(lines):
|
|
||||||
result = []
|
|
||||||
for i in lines:
|
|
||||||
i = i.strip()
|
|
||||||
|
|
||||||
if not i:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# skip comments
|
|
||||||
if i.startswith("#"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = LINE_PATTERN_RE.match(i)
|
|
||||||
if match is None:
|
|
||||||
raise ValueError("Couldn't parse line: %s" % i)
|
|
||||||
gd = match.groupdict()
|
|
||||||
result.append(gd["line"])
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def read_lines_from_file(path):
|
|
||||||
lines = open(path, "r").readlines()
|
|
||||||
lines = read_lines(lines)
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def read_runtime_patterns(lines):
|
|
||||||
result = []
|
|
||||||
for i in read_lines(lines):
|
|
||||||
match = RUNTIME_PATTERN_SPLIT_RE.match(i)
|
|
||||||
if match is None:
|
|
||||||
raise ValueError("Couldn't parse pattern: %s" % i)
|
|
||||||
gd = match.groupdict()
|
|
||||||
result.append((gd["path"], gd["pattern"]))
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def read_runtime_patterns_from_file(path):
|
|
||||||
lines = open(path, "r").readlines()
|
|
||||||
return read_runtime_patterns(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def expand_runtime_patterns(patterns):
|
|
||||||
pm = pungi.pathmatch.PathMatch()
|
|
||||||
for path, pattern in patterns:
|
|
||||||
for root in ("", "/opt/*/*/root"):
|
|
||||||
# include Software Collections: /opt/<vendor>/<scl_name>/root/...
|
|
||||||
if "$LIBDIR" in path:
|
|
||||||
for lib_dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64"):
|
|
||||||
path_pattern = path.replace("$LIBDIR", lib_dir)
|
|
||||||
path_pattern = "%s/%s" % (root, path_pattern.lstrip("/"))
|
|
||||||
pm[path_pattern] = (path_pattern, pattern)
|
|
||||||
else:
|
|
||||||
path_pattern = "%s/%s" % (root, path.lstrip("/"))
|
|
||||||
pm[path_pattern] = (path_pattern, pattern)
|
|
||||||
return pm
|
|
||||||
|
|
||||||
|
|
||||||
class MultilibMethodBase(object):
|
|
||||||
"""a base class for multilib methods"""
|
|
||||||
|
|
||||||
name = "base"
|
|
||||||
|
|
||||||
def __init__(self, config_path):
|
|
||||||
self.config_path = config_path
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def skip(self, po):
|
|
||||||
if (
|
|
||||||
pungi.gather.is_noarch(po)
|
|
||||||
or pungi.gather.is_source(po)
|
|
||||||
or pungi.util.pkg_is_debug(po)
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_kernel(self, po):
|
|
||||||
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
|
|
||||||
if p_name == "kernel":
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_kernel_devel(self, po):
|
|
||||||
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
|
|
||||||
if p_name == "kernel-devel":
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_kernel_or_kernel_devel(self, po):
|
|
||||||
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
|
|
||||||
if p_name in ("kernel", "kernel-devel"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class NoneMultilibMethod(MultilibMethodBase):
|
|
||||||
"""multilib disabled"""
|
|
||||||
|
|
||||||
name = "none"
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class AllMultilibMethod(MultilibMethodBase):
|
|
||||||
"""all packages are multilib"""
|
|
||||||
|
|
||||||
name = "all"
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
if self.skip(po):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class RuntimeMultilibMethod(MultilibMethodBase):
|
|
||||||
"""pre-defined paths to libs"""
|
|
||||||
|
|
||||||
name = "runtime"
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(RuntimeMultilibMethod, self).__init__(*args, **kwargs)
|
|
||||||
self.blacklist = read_lines_from_file(
|
|
||||||
self.config_path + "runtime-blacklist.conf"
|
|
||||||
)
|
|
||||||
self.whitelist = read_lines_from_file(
|
|
||||||
self.config_path + "runtime-whitelist.conf"
|
|
||||||
)
|
|
||||||
self.patterns = expand_runtime_patterns(
|
|
||||||
read_runtime_patterns_from_file(self.config_path + "runtime-patterns.conf")
|
|
||||||
)
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
if self.skip(po):
|
|
||||||
return False
|
|
||||||
if po.name in self.blacklist:
|
|
||||||
return False
|
|
||||||
if po.name in self.whitelist:
|
|
||||||
return True
|
|
||||||
if self.is_kernel(po):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# gather all *.so.* provides from the RPM header
|
|
||||||
provides = set()
|
|
||||||
for i in po.provides:
|
|
||||||
match = SONAME_PATTERN_RE.match(i[0])
|
|
||||||
if match is not None:
|
|
||||||
provides.add(match.group(1))
|
|
||||||
|
|
||||||
for path in po.returnFileEntries() + po.returnFileEntries("ghost"):
|
|
||||||
dirname, filename = path.rsplit("/", 1)
|
|
||||||
dirname = dirname.rstrip("/")
|
|
||||||
|
|
||||||
patterns = self.patterns[dirname]
|
|
||||||
if not patterns:
|
|
||||||
continue
|
|
||||||
for dir_pattern, file_pattern in patterns:
|
|
||||||
if file_pattern == "-":
|
|
||||||
return True
|
|
||||||
if fnmatch.fnmatch(filename, file_pattern):
|
|
||||||
if ".so.*" in file_pattern:
|
|
||||||
if filename in provides:
|
|
||||||
# return only if the lib is provided in RPM header
|
|
||||||
# (some libs may be private, hence not exposed in Provides)
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class KernelMultilibMethod(MultilibMethodBase):
|
|
||||||
"""kernel and kernel-devel"""
|
|
||||||
|
|
||||||
name = "kernel"
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(KernelMultilibMethod, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
if self.is_kernel_or_kernel_devel(po):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class YabootMultilibMethod(MultilibMethodBase):
|
|
||||||
"""yaboot on ppc"""
|
|
||||||
|
|
||||||
name = "yaboot"
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(YabootMultilibMethod, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
if po.arch in ["ppc"]:
|
|
||||||
if po.name.startswith("yaboot"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class DevelMultilibMethod(MultilibMethodBase):
|
|
||||||
"""all -devel and -static packages"""
|
|
||||||
|
|
||||||
name = "devel"
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(DevelMultilibMethod, self).__init__(*args, **kwargs)
|
|
||||||
self.blacklist = read_lines_from_file(self.config_path + "devel-blacklist.conf")
|
|
||||||
self.whitelist = read_lines_from_file(self.config_path + "devel-whitelist.conf")
|
|
||||||
|
|
||||||
def select(self, po):
|
|
||||||
if self.skip(po):
|
|
||||||
return False
|
|
||||||
if po.name in self.blacklist:
|
|
||||||
return False
|
|
||||||
if po.name in self.whitelist:
|
|
||||||
return True
|
|
||||||
if self.is_kernel_devel(po):
|
|
||||||
return False
|
|
||||||
# HACK: exclude ghc*
|
|
||||||
if po.name.startswith("ghc-"):
|
|
||||||
return False
|
|
||||||
if po.name.endswith("-devel"):
|
|
||||||
return True
|
|
||||||
if po.name.endswith("-static"):
|
|
||||||
return True
|
|
||||||
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
|
|
||||||
if p_name.endswith("-devel"):
|
|
||||||
return True
|
|
||||||
if p_name.endswith("-static"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_METHODS = ["devel", "runtime"]
|
|
||||||
METHOD_MAP = {}
|
|
||||||
|
|
||||||
|
|
||||||
def init(config_path="/usr/share/pungi/multilib/"):
|
|
||||||
global METHOD_MAP
|
|
||||||
|
|
||||||
if not config_path.endswith("/"):
|
|
||||||
config_path += "/"
|
|
||||||
|
|
||||||
for cls in (
|
|
||||||
AllMultilibMethod,
|
|
||||||
DevelMultilibMethod,
|
|
||||||
KernelMultilibMethod,
|
|
||||||
NoneMultilibMethod,
|
|
||||||
RuntimeMultilibMethod,
|
|
||||||
YabootMultilibMethod,
|
|
||||||
):
|
|
||||||
method = cls(config_path)
|
|
||||||
METHOD_MAP[method.name] = method
|
|
||||||
|
|
||||||
|
|
||||||
def po_is_multilib(po, methods):
|
|
||||||
for method_name in methods:
|
|
||||||
if not method_name:
|
|
||||||
continue
|
|
||||||
method = METHOD_MAP[method_name]
|
|
||||||
if method.select(po):
|
|
||||||
return method_name
|
|
||||||
return None
|
|
@ -1,73 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
# This program 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; version 2 of the License.
|
|
||||||
#
|
|
||||||
# This program 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 Library General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, see <https://gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
import fnmatch
|
|
||||||
|
|
||||||
|
|
||||||
def head_tail_split(name):
|
|
||||||
name_split = name.strip("/").split("/", 1)
|
|
||||||
if len(name_split) == 2:
|
|
||||||
head = name_split[0]
|
|
||||||
tail = name_split[1].strip("/")
|
|
||||||
else:
|
|
||||||
head, tail = name_split[0], None
|
|
||||||
return head, tail
|
|
||||||
|
|
||||||
|
|
||||||
class PathMatch(object):
|
|
||||||
def __init__(self, parent=None, desc=None):
|
|
||||||
self._patterns = {}
|
|
||||||
self._final_patterns = {}
|
|
||||||
self._values = []
|
|
||||||
|
|
||||||
def __setitem__(self, name, value):
|
|
||||||
head, tail = head_tail_split(name)
|
|
||||||
|
|
||||||
if tail is not None:
|
|
||||||
# recursion
|
|
||||||
if head not in self._patterns:
|
|
||||||
self._patterns[head] = PathMatch(parent=self, desc=head)
|
|
||||||
self._patterns[head][tail] = value
|
|
||||||
else:
|
|
||||||
if head not in self._final_patterns:
|
|
||||||
self._final_patterns[head] = PathMatch(parent=self, desc=head)
|
|
||||||
if value not in self._final_patterns[head]._values:
|
|
||||||
self._final_patterns[head]._values.append(value)
|
|
||||||
|
|
||||||
def __getitem__(self, name):
|
|
||||||
result = []
|
|
||||||
head, tail = head_tail_split(name)
|
|
||||||
for pattern in self._patterns:
|
|
||||||
if fnmatch.fnmatch(head, pattern):
|
|
||||||
if tail is None:
|
|
||||||
values = self._patterns[pattern]._values
|
|
||||||
else:
|
|
||||||
values = self._patterns[pattern][tail]
|
|
||||||
for value in values:
|
|
||||||
if value not in result:
|
|
||||||
result.append(value)
|
|
||||||
|
|
||||||
for pattern in self._final_patterns:
|
|
||||||
if tail is None:
|
|
||||||
x = head
|
|
||||||
else:
|
|
||||||
x = "%s/%s" % (head, tail)
|
|
||||||
if fnmatch.fnmatch(x, pattern):
|
|
||||||
values = self._final_patterns[pattern]._values
|
|
||||||
for value in values:
|
|
||||||
if value not in result:
|
|
||||||
result.append(value)
|
|
||||||
return result
|
|
@ -1,64 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from pungi.pathmatch import PathMatch, head_tail_split
|
|
||||||
|
|
||||||
|
|
||||||
class TestHeadTailSplit(unittest.TestCase):
|
|
||||||
def test_1(self):
|
|
||||||
head, tail = head_tail_split("a")
|
|
||||||
self.assertEqual(head, "a")
|
|
||||||
self.assertEqual(tail, None)
|
|
||||||
|
|
||||||
head, tail = head_tail_split("/*")
|
|
||||||
self.assertEqual(head, "*")
|
|
||||||
self.assertEqual(tail, None)
|
|
||||||
|
|
||||||
head, tail = head_tail_split("///*")
|
|
||||||
self.assertEqual(head, "*")
|
|
||||||
self.assertEqual(tail, None)
|
|
||||||
|
|
||||||
head, tail = head_tail_split("///*//")
|
|
||||||
self.assertEqual(head, "*")
|
|
||||||
self.assertEqual(tail, None)
|
|
||||||
|
|
||||||
head, tail = head_tail_split("///*//-")
|
|
||||||
self.assertEqual(head, "*")
|
|
||||||
self.assertEqual(tail, "-")
|
|
||||||
|
|
||||||
|
|
||||||
class TestPathMatch(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.pm = PathMatch()
|
|
||||||
|
|
||||||
def test_1(self):
|
|
||||||
self.pm["/*"] = "/star1"
|
|
||||||
self.assertEqual(list(self.pm._final_patterns.keys()), ["*"])
|
|
||||||
self.assertEqual(self.pm._values, [])
|
|
||||||
self.assertEqual(self.pm._final_patterns["*"]._values, ["/star1"])
|
|
||||||
self.assertEqual(sorted(self.pm["/lib"]), ["/star1"])
|
|
||||||
|
|
||||||
self.pm["/*"] = "/star2"
|
|
||||||
self.assertEqual(sorted(self.pm["/lib"]), ["/star1", "/star2"])
|
|
||||||
|
|
||||||
self.pm["/lib"] = "/lib"
|
|
||||||
self.assertEqual(sorted(self.pm["/lib"]), ["/lib", "/star1", "/star2"])
|
|
||||||
|
|
||||||
self.pm["/lib64"] = "/lib64"
|
|
||||||
self.assertEqual(sorted(self.pm["/lib64"]), ["/lib64", "/star1", "/star2"])
|
|
||||||
|
|
||||||
def test_2(self):
|
|
||||||
self.pm["/*/*"] = "/star/star1"
|
|
||||||
self.assertEqual(list(self.pm._patterns.keys()), ["*"])
|
|
||||||
self.assertEqual(list(self.pm._patterns["*"]._final_patterns.keys()), ["*"])
|
|
||||||
self.assertEqual(
|
|
||||||
self.pm._patterns["*"]._final_patterns["*"]._values, ["/star/star1"]
|
|
||||||
)
|
|
||||||
self.assertEqual(sorted(self.pm["/lib/asd"]), ["/star/star1"])
|
|
||||||
|
|
||||||
self.pm["/*"] = "/star2"
|
|
||||||
self.assertEqual(sorted(self.pm["/lib"]), ["/star2"])
|
|
||||||
|
|
||||||
self.assertEqual(sorted(self.pm["/lib/foo"]), ["/star/star1", "/star2"])
|
|
Loading…
Reference in New Issue
Block a user