From 4e2a9e2adbc1e06dd1bd1bb49d67eae55e4b8a7d Mon Sep 17 00:00:00 2001 From: Georg Pfuetzenreuter Date: Sun, 27 Aug 2023 22:28:27 +0200 Subject: [PATCH] Write files - create spec and service files - other miscellaneous improvements Signed-off-by: Georg Pfuetzenreuter --- opam2rpm.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/opam2rpm.py b/opam2rpm.py index 2eccb58..b932392 100755 --- a/opam2rpm.py +++ b/opam2rpm.py @@ -18,21 +18,37 @@ import requests from bs4 import BeautifulSoup import re import jinja2 +import os import sys +from contextlib import contextmanager +import subprocess +from time import sleep argparser = ArgumentParser() argparser.add_argument('--debug', help='Print verbose output', action='store_const', dest='loglevel', const=logging.DEBUG, default=logging.INFO) argparser.add_argument('--package', help='Name of the OPAM package', required=True) -argparser.add_argument('--prefixed', help='Create package with "ocaml-" prefix', action='store_true', default=True) +argparser.add_argument('--prefixed', help='Create RPM package with "ocaml-" prefix', action='store_true', default=True) argparser.add_argument('--opam-web', help='URL pointing to the OPAM web interface', default='https://opam.ocaml.org/') +argparser.add_argument('--obs-project-dir', help='Path to a local checkout of the desired target project') args = argparser.parse_args() downstream_prefixed = args.prefixed +mydir = os.path.dirname(os.path.realpath(sys.argv[0])) def _fail(msg): log.error(msg) sys.exit(1) +# https://gist.github.com/howardhamilton/537e13179489d6896dd3 +@contextmanager +def pushd(new_dir): + old_dir = os.getcwd() + os.chdir(new_dir) + try: + yield + finally: + os.chdir(old_dir) + def query_opam(package): url = f'{args.opam_web}/packages/{package}' result = requests.get(url) @@ -99,31 +115,80 @@ def parse_dependencies(dependencies): log.debug(f'Constructed OCAML build dependencies: {buildrequires}') return buildrequires -def render(name, url, license, buildrequires, prefixed, vcs_url=None): +def manglesrcname(name): + if name.startswith('ocaml-') and prefixed: # where is "prefixed" defined ? + return name.lstrip('ocaml-') + else: + return name + +def manglepkgname(srcname, add_prefix): + if add_prefix: + pkgname = f'ocaml-{srcname}' + else: + pkgname = srcname + return pkgname + +def render(name, srcname, url, license, buildrequires, prefixed, vcs_url=None): if not vcs_url: vcs_url = url - templenv = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath='/home/georg/Work/templates')) + templenv = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=f'{mydir}/templates')) template_service = templenv.get_template('service') template_spec = templenv.get_template('ultimate.spec') log.debug(f'Rendering {template_spec}') - #if downstream_prefixing: - # name = f'ocaml-{name}' rendered_service = template_service.render(pkgname=name, url=vcs_url) - if name.startswith('ocaml-') and prefixed: - name = name.lstrip('ocaml-') - rendered_spec = template_spec.render(pkgname=name, url=url, buildrequires=buildrequires, license=license, mode='dune', do_prefix=prefixed) + rendered_spec = template_spec.render(pkgname=srcname, url=url, buildrequires=buildrequires, license=license, mode='dune', do_prefix=prefixed) log.debug(f'Service: {rendered_service}') log.debug(f'Spec: {rendered_spec}') return rendered_service, rendered_spec +def mkpac(pkgdir): + if os.path.isdir(pkgdir): + log.warning(f'Package directory {pkgdir} already exists') + else: + subprocess.run(['osc', 'mkpac', pkgdir], check=True) + +def mkfile(file, data): + if os.path.isfile(file): + log.warning(f'File {file} already exists, overwriting in 10 seconds ...') + sleep(10) + with open(file, 'w') as fh: + fh.write(data) + +def spec_cleaner(file): + subprocess.run(['spec-cleaner', '-i', file], check=True) + + # spec-cleaner thinks "Development/Languages/OCaml" is an invalid group + with open(file, 'r') as fh: + lines = fh.readlines() + with open(file, 'w') as fh: + for line in lines: + if not 'FIXME' in line: + fh.write(line) + def main(): opam_package = parse_opam(query_opam(args.package)) info = opam_package.get_info() - repository_url, repository_name, is_prefixed = parse_homepage(info['Homepage']) + repository_url, name, is_prefixed = parse_homepage(info['Homepage']) add_prefix = evaluate_prefixing(is_prefixed) dependencies = parse_dependencies(info['Dependencies']) - render(repository_name, info['Homepage'], info['License'], dependencies, add_prefix, repository_url) + srcname = manglesrcname(name) + pkgname = manglepkgname(name, add_prefix) + data_service, data_spec = render(name, srcname, info['Homepage'], info['License'], dependencies, add_prefix, repository_url) + prjdir = args.obs_project_dir + if prjdir: + if not os.path.isfile(f'{prjdir}/.osc/_project'): + _fail(f'Invalid project directory: {prjdir}') + specfile = f'{pkgname}.spec' + with pushd(prjdir): + mkpac(pkgname) + with pushd(pkgname): + mkfile('_service', data_service) + mkfile(specfile, data_spec) + spec_cleaner(specfile) + else: + log.warning('Will not create package, --obs-project-dir was not declared') + logging.basicConfig(format='%(asctime)s %(levelname)s - %(funcName)s: %(message)s', datefmt='%H:%M:%S') log = logging.getLogger(__name__)