Refactor python to rpm names conversion
Split convert_names_to_rpm method of py2rpm helper into two higher-level methods: - names_to_rpm_names, which returns a dict name -> rpm_name, which allows to get rid of unsafe zip(...) usage -- reqs and rpm names will never be out of sync again; - names_to_rpm_requires, which returns list of RPM-styled requirements with versions for usage in specfile rendering. Change-Id: I71faa244ae53bd2cefe872d0bf595c9aa4049812
This commit is contained in:
@@ -14,6 +14,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
|
||||
import six
|
||||
|
||||
from anvil import log as logging
|
||||
from anvil import settings
|
||||
from anvil import shell as sh
|
||||
@@ -62,36 +66,52 @@ class Helper(object):
|
||||
out_filename = sh.joinpths(self._log_dir, "%s.log" % sh.basename(filename))
|
||||
sh.execute_save_output(cmdline, cwd=marks_dir, out_filename=out_filename)
|
||||
|
||||
def convert_names_to_rpm(self, python_names, only_name=True):
|
||||
def _convert_names_to_rpm(self, python_names, only_name):
|
||||
if not python_names:
|
||||
return []
|
||||
return {}
|
||||
cmdline = self._start_cmdline() + ["--convert"] + python_names
|
||||
rpm_names = []
|
||||
receive_names = set()
|
||||
result = collections.defaultdict(set)
|
||||
current_source = None
|
||||
for line in sh.execute(cmdline)[0].splitlines():
|
||||
# NOTE(harlowja): format is "Requires: rpm-name <=> X" or when
|
||||
# the original requirement is denoted by the following comment
|
||||
# lines "# Source: python-requirement" (used to make sure all
|
||||
# requirements sent in come back out).
|
||||
# lines "# Source: python-requirement"
|
||||
if line.startswith("Requires:"):
|
||||
line = line[len("Requires:"):].strip()
|
||||
line = line[len("Requires:"):]
|
||||
if only_name:
|
||||
positions = [line.find(">"), line.find("<"), line.find("=")]
|
||||
positions = sorted([p for p in positions if p != -1])
|
||||
if positions:
|
||||
line = line[0:positions[0]].strip()
|
||||
if line:
|
||||
rpm_names.append(line)
|
||||
line = line[0:positions[0]]
|
||||
result[current_source].add(line.strip())
|
||||
elif line.startswith("# Source:"):
|
||||
line = line[len("# Source:"):].strip()
|
||||
if line:
|
||||
receive_names.add(line)
|
||||
current_source = line[len("# Source:"):].strip()
|
||||
|
||||
missing_names = set(python_names) - receive_names
|
||||
missing_names = set(python_names) - set(result.keys())
|
||||
if missing_names:
|
||||
raise AssertionError("%s package names were lost during"
|
||||
" conversion" % (missing_names))
|
||||
return rpm_names
|
||||
raise AssertionError("Python names were lost during conversion: %s"
|
||||
% ', '.join(sorted(missing_names)))
|
||||
extra_names = set(result.keys()) - set(python_names)
|
||||
if extra_names:
|
||||
raise AssertionError("Extra python names were found during conversion: %s"
|
||||
% ', '.join(sorted(extra_names)))
|
||||
return result
|
||||
|
||||
def names_to_rpm_names(self, python_names):
|
||||
mapping = self._convert_names_to_rpm(python_names, only_name=True)
|
||||
result = {}
|
||||
for k, v in six.iteritems(mapping):
|
||||
assert len(v) == 1, ('There should be exactly one RPM name for '
|
||||
'python module %s, but we have: %s'
|
||||
% (k, sorted(v)))
|
||||
result[k] = v.pop()
|
||||
return result
|
||||
|
||||
def names_to_rpm_requires(self, python_names):
|
||||
mapping = self._convert_names_to_rpm(python_names, only_name=False)
|
||||
return [req
|
||||
for value in six.itervalues(mapping)
|
||||
for req in value]
|
||||
|
||||
def build_all_srpms(self, package_files, tracewriter, jobs):
|
||||
(_fn, content) = utils.load_template(sh.joinpths("packaging", "makefiles"), "source.mk")
|
||||
|
||||
@@ -297,10 +297,11 @@ class YumDependencyHandler(base.DependencyHandler):
|
||||
req_to_install = [pip_helper.extract_requirement(line)
|
||||
for line in self.pips_to_install]
|
||||
requested_names = [req.key for req in req_to_install]
|
||||
rpm_to_install = self.py2rpm_helper.convert_names_to_rpm(requested_names)
|
||||
rpm_names = self.py2rpm_helper.names_to_rpm_names(requested_names)
|
||||
|
||||
satisfied_list = []
|
||||
for (req, rpm_name) in zip(req_to_install, rpm_to_install):
|
||||
for req in req_to_install:
|
||||
rpm_name = rpm_names[req.key]
|
||||
(version, repo) = self._find_yum_match(yum_map, req, rpm_name)
|
||||
if not repo:
|
||||
# We need the source requirement incase its a url.
|
||||
@@ -333,15 +334,15 @@ class YumDependencyHandler(base.DependencyHandler):
|
||||
|
||||
def _filter_package_files(package_files):
|
||||
package_reqs = []
|
||||
package_keys = []
|
||||
for filename in package_files:
|
||||
package_details = pip_helper.get_archive_details(filename)
|
||||
package_reqs.append(package_details['req'])
|
||||
package_keys.append(package_details['req'].key)
|
||||
package_rpm_names = self.py2rpm_helper.convert_names_to_rpm(package_keys)
|
||||
package_rpm_names = self.py2rpm_helper.names_to_rpm_names(
|
||||
[req.key for req in package_reqs])
|
||||
|
||||
filtered_files = []
|
||||
for (filename, req, rpm_name) in zip(package_files, package_reqs,
|
||||
package_rpm_names):
|
||||
for filename, req in zip(package_files, package_reqs):
|
||||
rpm_name = package_rpm_names[req.key]
|
||||
if req.key in no_pips:
|
||||
LOG.info(("Dependency %s was downloaded additionally "
|
||||
"but it is disallowed."), colorizer.quote(req))
|
||||
@@ -383,7 +384,7 @@ class YumDependencyHandler(base.DependencyHandler):
|
||||
if egg_info:
|
||||
def ei_names(key):
|
||||
requires_python = [str(req) for req in egg_info[key]]
|
||||
return self.py2rpm_helper.convert_names_to_rpm(requires_python, False)
|
||||
return self.py2rpm_helper.names_to_rpm_requires(requires_python)
|
||||
|
||||
requires_what.extend(ei_names('dependencies'))
|
||||
test_requires_what.extend(ei_names('test_dependencies'))
|
||||
@@ -605,9 +606,9 @@ class YumDependencyHandler(base.DependencyHandler):
|
||||
for line in [line.strip() for line in requires if line.strip()]:
|
||||
py_reqs.add(pip_helper.extract_requirement(line))
|
||||
|
||||
py_reqs = list(py_reqs)
|
||||
rpm_names = self.py2rpm_helper.convert_names_to_rpm(map(str, py_reqs))
|
||||
desired_rpms.extend(zip(rpm_names, py_reqs))
|
||||
rpm_names = self.py2rpm_helper.names_to_rpm_names([req.key
|
||||
for req in py_reqs])
|
||||
desired_rpms.extend((rpm_names[req.key], req) for req in py_reqs)
|
||||
|
||||
def _format_name(rpm_name, py_req):
|
||||
full_name = str(rpm_name).strip()
|
||||
|
||||
Reference in New Issue
Block a user