From 598c5e3972d072d46fd0a7c9914dd84de7fc000f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 3 Jul 2022 17:03:50 +0200 Subject: [PATCH] Guess crate name based on %crate or directory name This makes is much nicer to work with dist-git: the same command without modifications can be used for different crates. --- rust2rpm/__main__.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/rust2rpm/__main__.py b/rust2rpm/__main__.py index 61e5567..d0e7661 100644 --- a/rust2rpm/__main__.py +++ b/rust2rpm/__main__.py @@ -6,6 +6,7 @@ from datetime import datetime, timezone import difflib import functools import itertools +import glob import os import pathlib import re @@ -356,6 +357,44 @@ def detect_rpmautospec(default_target, spec_file): return any(re.match(autochangelog_re, line) for line in text.splitlines()) +def guess_crate_name(): + """Guess crate name from directory name and/or spec file name + + If a spec file is present, we use the %crate variable. This is the best + option. But if we're in a new directory, and don't have a spec file yet, + let's assume that this is a dist-git directory and extract the crate name. + For compat packages, the directory name will contain a version suffix, + but a compat package would almost always be created from an existing + dist-git directory, hence there'd be a spec file, so we can ignore this. + """ + specs = glob.glob('*.spec') + if len(specs) > 1: + print('Multiple spec files found, cannot guess crate name') + return None + if len(specs) == 1: + crate = None + for line in open(specs[0]): + if m := re.match(r'^%(?:global|define)\s+crate\s+(\S+)\s+', line): + if crate: + print(f'{specs[0]}: Found duplicated %crate define, cannot guess crate name') + return None + crate = m.group(1) + if '%' in crate: + print(f'{specs[0]}: Crate name appears to use a macro, and evaluation is not implemented') + return None + if crate: + print(f'{specs[0]}: Found crate name {crate!r}') + else: + print(f'{specs[0]}: %crate define not found, cannot guess crate name') + return crate + + dirname = os.path.basename(os.getcwd()) + if m := re.match('^rust-([a-z+0-9_-]+)$', dirname): + print(f'Using crate name {m.group(1)!r} based on the directory name') + return m.group(1) + + return None + @contextlib.contextmanager def exit_on_common_errors(): """Suppress tracebacks on common "expected" exceptions""" @@ -432,7 +471,9 @@ def main(): return if args.crate is None: - parser.error("required crate/path argument missing") + args.crate = guess_crate_name() + if args.crate is None: + parser.error("crate/path argument missing and autodetection failed") crate, diff, metadata, doc_files, license_files = make_diff_metadata(args, args.crate, args.version)