#!/usr/bin/env python3 """ Create source tarball, create rpm from it together with spec file. Create a source tarball that is compatbile with standard build pipelines. Then run rpmbuild on it to create an installable rpm. .. codeauthor:: Intra2net AG """ import sys from os.path import join, basename, dirname, expanduser from re import compile as re_compile import tarfile from shutil import copy from subprocess import run # path to spec file BASE_DIR = dirname(__file__) SPEC_FILE = join(BASE_DIR, 'pyi2ncommon.spec') # regular expressions extracting relevant information from spec file VERSION_REGEX = re_compile(r'^Version:\s*(\S+)\s*$') NAME_REGEX = re_compile(r'^Name:\s*(\S+)\s*$') SOURCE_REGEX = re_compile(r'^Source0:\s*(\S+)\s*$') # dir to contain tarball DIST_DIR = join(BASE_DIR, 'dist') # files and dirs to add to tarball; keep in sync with %files secion in spec DATA = ( 'COPYING.GPL', 'Linking-Exception.txt', 'README', 'CONTRIBUTING', 'setup.py', 'src', 'test', 'doc/about_docu.rst', 'doc/conf.py' ) # dir where rpmbuild expects its tarballs RPM_SOURCE_DIR = expanduser(join('~', 'rpmbuild', 'SOURCES')) def get_spec_info(): """Extract name, version and source0 from spec file.""" name = None version = None source = None with open(SPEC_FILE, 'rt') as reader: for line in reader: if name is not None and version is not None and source is not None: source = source.replace('%{name}', name)\ .replace('%{version}', version) return name, version, source match = NAME_REGEX.match(line) if match: name = match.group(1) continue match = VERSION_REGEX.match(line) if match: version = match.group(1) continue match = SOURCE_REGEX.match(line) if match: source = match.group(1) continue def tar_add_filter(tarinfo): """ Filter function for adding files to tarball Return `None` for pycache and pyc, meaning "do not add". Return input otherwise to add the file. """ if tarinfo.name.endswith('.pyc'): print(f'Skip {tarinfo.name}') return None if '__pycache__' in tarinfo.name: print(f'Skip {tarinfo.name}') return None print(f'Adding {tarinfo.name}') return tarinfo def create_tarball(): """Create tarball, return its full path.""" name, version, tarball_file = get_spec_info() tarball_path = join(DIST_DIR, tarball_file) print(f'Creating {tarball_path}') dirname = f'{name}-{version}' with tarfile.open(tarball_path, 'w:gz') as tarball: for entry in DATA: tarball.add(entry, join(dirname, entry), filter=tar_add_filter) return tarball_path def build_rpm(tarball_path): """Create rpm using rpmbuild with spec file and newly created tarball.""" copy(tarball_path, RPM_SOURCE_DIR) run(('rpmbuild', '-bb', SPEC_FILE)) def main(): """ Main function, called when running file as script. See module doc for more info. """ tarball_path = create_tarball() build_rpm(tarball_path) print(f'{basename(__file__)} finished successfully.') return 0 if __name__ == '__main__': sys.exit(main())