Skip to content

Instantly share code, notes, and snippets.

@hkwi
Last active July 2, 2018 13:38
Show Gist options
  • Save hkwi/f95c6abb75a54939daae to your computer and use it in GitHub Desktop.
Save hkwi/f95c6abb75a54939daae to your computer and use it in GitHub Desktop.
Creates all dependency python rpms (bdist_rpm)
#!/usr/bin/python
'''
usage: bdist_rpm_r.py packagename [packagename ...]
You should use `pip wheel` command that creates whl deps.
Note: you should install rpmdevtools, python-devel, gcc, gcc-c++, etc.
that will be required during the rpmbuild process.
pbr will require git internally.
'''
import functools
import tempfile
import os
import os.path
import shutil
import subprocess
import sys
from glob import glob
from setuptools.package_index import PackageIndex
from setuptools.archive_util import unpack_archive
from pkg_resources import Requirement
required = set()
def update_required(str_or_list):
if isinstance(str_or_list,str):
required.add(str_or_list)
else:
required.update(str_or_list)
def setup_capture(f):
@functools.wraps(f)
def setup(*arg, **kwarg):
update_required(kwarg.get("requires",[]))
update_required(kwarg.get("install_requires",[]))
map(update_required, kwarg.get("extras_require",{}).values())
return f(*arg, **kwarg)
return setup
import distutils.core
distutils.core.setup = setup_capture(distutils.core.setup)
try:
import setuptools
setuptools.setup = setup_capture(setuptools.setup)
except ImportError:
pass
def pbr_capture(f):
@functools.wraps(f)
def parse(*arg, **kwarg):
ret = f(*arg, **kwarg)
update_required(ret)
return ret
return parse
try:
import pbr.packaging
pbr.packaging.parse_requirements = pbr_capture(pbr.packaging.parse_requirements)
except ImportError:
pass
processed = set()
class WorkingDir(object):
def __init__(self, dst):
self.dst = dst
def __enter__(self):
self.cwd = os.getcwd()
os.chdir(self.dst)
def __exit__(self, *args, **kwargs):
os.chdir(self.cwd)
def bdist_rpm(pkgspec):
pi=PackageIndex()
src = tempfile.mkdtemp(prefix="recursive_bdist_rpm-")
dst = tempfile.mkdtemp(prefix="recursive_bdist_rpm-")
req = Requirement.parse(pkgspec)
dist = pi.fetch_distribution(req, src, source=True)
jobid = dist.as_requirement()
if jobid in processed:
return
else:
processed.add(jobid)
unpack_archive(dist.location, dst)
contents = os.listdir(dst)
if len(contents)==1:
dst = os.path.join(dst, contents[0])
contents = os.listdir(dst)
if "setup.py" not in contents:
setup_script = glob(os.path.join(dst, "*", "setup.py"))
else:
setup_script = os.path.join(dst, "setup.py")
with WorkingDir(dst):
subprocess.call(("python", setup_script, "bdist_rpm"))
for rpm in glob(os.path.join(dst, "dist", "*.rpm")):
try:
shutil.move(rpm, ".")
except:
pass
ret = required.copy()
required.clear()
for dep in ret:
bdist_rpm(dep)
shutil.rmtree(src)
shutil.rmtree(dst)
for arg in sys.argv[1:]:
bdist_rpm(arg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment