Implement simple logging; ensure rust2rpm --stdout still works

This commit is contained in:
Fabio Valentini 2022-07-24 11:21:30 +02:00
parent a090caaa62
commit 67c878e32a
No known key found for this signature in database
GPG key ID: 5AC5F572E5D410AF
6 changed files with 81 additions and 51 deletions

View file

@ -1,4 +1,5 @@
jinja2
pyparsing
requests
termcolor
tqdm

View file

@ -18,7 +18,7 @@ import subprocess
import requests
import tqdm
from . import cfg, licensing, generator, util
from . import cfg, licensing, generator, log, util
from .core.metadata import Metadata
XDG_CACHE_HOME = os.getenv("XDG_CACHE_HOME", os.path.expanduser("~/.cache"))
@ -114,11 +114,11 @@ def query_newest_version(crate):
for struct in versions:
version = struct["num"]
if struct["yanked"]:
print(f'Ignoring yanked version {version}')
log.info(f'Ignoring yanked version {version}')
elif re.search('alpha|beta|rc|pre', version):
print(f'Ignoring pre-release version {version}')
log.info(f'Ignoring pre-release version {version}')
else:
print(f'Found version {version}')
log.success(f'Found version {version}')
return version
raise ValueError("Couldn't find any release versions. Specify a version explicitly.")
@ -180,29 +180,24 @@ def drop_foreign_dependencies(lines):
value = True
for line in lines:
# print(f'{line=}')
# [target.'cfg(not(any(target_os="windows", target_os="macos")))'.dependencies]
if m := TARGET_DEPENDENCY_LINE.match(line):
expr = m.group('cfg')
expr = ast.literal_eval(expr)
# print(f'matched: {expr=}')
try:
value = cfg.parse_and_evaluate(expr)
except (ValueError, cfg.ParseException):
print(f'Could not evaluate {expr!r}, treating as true')
log.warn(f'Could not evaluate {expr!r}, treating as true')
value = True
if not value:
feature = m.group('feature')
print(f'Skipping section {line.rstrip()} ({feature=})')
log.info(f'Skipping section {line.rstrip()} ({feature=})')
dropped_features.add(feature)
elif line.startswith('['):
# previous section ended, let's keep printing lines again
value = True
# print(f'→ {value}')
if value:
good_lines += [line]
else:
@ -349,7 +344,7 @@ def make_diff_metadata(args, crate, version):
diffs = make_patches(args, toml)
metadata = Metadata.from_file(toml)
if len(metadata) > 1:
print(f"Warning: multiple metadata for {toml}")
log.warn(f"More than one set of metadata found for {toml}, using the first one")
metadata = metadata[0]
return metadata.name, diffs, metadata, doc_files, license_files
else:
@ -357,12 +352,12 @@ def make_diff_metadata(args, crate, version):
with files_from_crate(cratef, crate, version) as (toml, doc_files, license_files):
if not license_files:
print(f"Warning: no license files detected in {crate}")
log.warn(f"No license files detected in {crate}")
diffs = make_patches(args, toml)
metadata = Metadata.from_file(toml)
if len(metadata) > 1:
print(f"Warning: multiple metadata for {toml}, ignoring everything except the first")
log.warn(f"More than one set of metadata found for {toml}, using the first one")
metadata = metadata[0]
if args.store_crate:
shutil.copy2(cratef, os.path.join(os.getcwd(), f"{metadata.name}-{version}.crate"))
@ -403,30 +398,36 @@ def guess_crate_name():
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')
log.error(f"Found multiple spec files; unable to determine crate name automatically.")
return None
if len(specs) == 1:
crate = None
for line in open(specs[0]):
spec = specs[0]
for line in open(spec):
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')
log.error(f'Found multiple definitions of the %crate macro in {spec}; ' +
f'unable to determine crate name automatically.')
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')
log.error(f'The value of the %crate macro appears to contain other macros and cannot be parsed.')
return None
if crate:
print(f'{specs[0]}: Found crate name {crate!r}')
log.success(f'Found valid spec file {spec!r} for the {crate!r} crate.')
else:
print(f'{specs[0]}: %crate define not found, cannot guess crate name')
log.error(f'Invalid spec file {spec!r}; unable to determine crate name automatically.')
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)
crate = m.group(1)
log.info(f'Using crate name {crate!r} based on the current working directory.')
return crate
return None
@ -496,7 +497,8 @@ def main():
if args.translate_license:
license, comments = licensing.translate_license(args.target, args.crate)
if comments:
print(comments)
for comment in comments.split("\n"):
log.info(comment)
print(license)
return
@ -518,14 +520,13 @@ def main():
# No specfile, so this is probably a new package
if package_info := get_package_info(pkg_name):
if args.suffix:
print(f"Versions {args.suffix}.* of the crate '{metadata.name}' are already")
print(f"packaged for Fedora: {package_info['full_url']}")
log.warn(f"Version {args.suffix}.* of the crate '{metadata.name}' is already " +
f"packaged for Fedora: {package_info['full_url']}")
else:
print(f"Crate '{metadata.name}' is already packaged for Fedora:")
print(f"{package_info['full_url']}")
log.warn(f"Crate '{metadata.name}' is already packaged for Fedora: " +
f"{package_info['full_url']}")
print("Re-run with --no-existence-check if you still want to start from scratch.")
log.info("Re-run with --no-existence-check to create a new spec file from scratch.")
sys.exit(1)
if args.rpmautospec is None:
@ -541,25 +542,25 @@ def main():
# clean up configuration files with deprecated names
if len(confs) > 1:
print("WARNING: More than one *rust2rpm.conf file is present in this directory.")
print(" Ensure that there is only one, and that it has the correct contents.")
log.error("More than one *rust2rpm.conf file is present in this directory. " +
"Ensure that there is only one, and that it has the correct contents.")
sys.exit(1)
if ".rust2rpm.conf" in confs and "rust2rpm.conf" not in confs:
os.rename(".rust2rpm.conf", "rust2rpm.conf")
print("Renamed deprecated, hidden .rust2rpm.conf file to rust2rpm.conf.")
log.info("Renamed deprecated, hidden .rust2rpm.conf file to rust2rpm.conf.")
if "_rust2rpm.conf" in confs and "rust2rpm.conf" not in confs:
os.rename("_rust2rpm.conf", "rust2rpm.conf")
print("Renamed deprecated _rust2rpm.conf file to rust2rpm.conf.")
log.info("Renamed deprecated _rust2rpm.conf file to rust2rpm.conf.")
if args.target not in conf:
conf.add_section(args.target)
conf_all_features = conf[args.target].getboolean("all-features")
if conf_all_features is False and args.all_features:
print("WARNING: Conflicting settings for enabling all features: The setting is \"false\"")
print(" in rust2rpm.conf but it was enabled with the \"--all-features\" CLI flag.")
log.warn("Conflicting settings for enabling all features: The setting is \"false\"" +
"in rust2rpm.conf but it was enabled with the \"--all-features\" CLI flag.")
spec_contents = generator.spec_file_render(
args = args,
@ -585,12 +586,12 @@ def main():
else:
with open(spec_file, "w") as fobj:
fobj.write(spec_contents)
print(f'Wrote {fobj.name}')
log.success(f'Generated: {fobj.name}.')
for fname, diff in zip(patch_files, diffs):
if fname:
with open(fname, "w") as fobj:
fobj.writelines(diff)
print(f'Wrote {fobj.name}')
log.success(f'Generated: {fobj.name}')
if __name__ == "__main__":
main()

View file

@ -7,6 +7,8 @@ import sys
import pyparsing as pp
from pyparsing import ParseException
from . import log
pp.ParserElement.enablePackrat()
# ConfigurationPredicate :
@ -59,7 +61,6 @@ def cfg_grammar():
@functools.cache
def evaluate_variable(name):
# print(f'evaluate_variable: {expr}')
match name:
case 'target_arch':
return platform.machine()
@ -91,11 +92,10 @@ def evaluate_variable(name):
return 'unknown'
case _:
print(f'Unknown variable {name}, assuming False')
log.warn(f'Unknown variable {name}, assuming False')
return False
def evaluate(expr, nested=False):
# print(f'evaluate: {expr}')
if hasattr(expr, 'asList'):
expr = expr.asList() # compat with pyparsing 2.7.x
match expr:

View file

@ -1,22 +1,22 @@
import os as _os
import sys as _sys
import csv as _csv
import functools as _functools
import os
import csv
import functools
SPDX_TO_FEDORA_CSV = _os.path.dirname(__file__) + '/spdx_to_fedora.csv'
from . import log
SPDX_TO_FEDORA_CSV = os.path.dirname(__file__) + '/spdx_to_fedora.csv'
def translate_slashes(license):
"Replace all slashes with OR, emit warning"
split = [l.strip() for l in license.split("/")]
if len(split) > 1:
print('Upstream uses deprecated "/" syntax. Replacing with "OR"',
file=_sys.stderr)
log.info('Upstream uses deprecated "/" syntax. Replacing with "OR"')
return ' OR '.join(split)
@_functools.lru_cache()
@functools.lru_cache()
def spdx_to_fedora_map():
with open(SPDX_TO_FEDORA_CSV, newline='') as f:
reader = _csv.DictReader(f)
reader = csv.DictReader(f)
return {line['SPDX License Identifier']: line['Fedora Short Name']
for line in reader
if line['SPDX License Identifier']}
@ -52,8 +52,7 @@ def translate_license_fedora(license):
else:
final.append(mapped)
if mapped != tag:
print(f'Upstream license tag {fulltag} translated to {mapped}',
file=_sys.stderr)
log.info(f'Upstream license tag {fulltag} translated to {mapped}')
return (' '.join(final), '\n'.join(comments) or None)
def translate_license(target, license):

28
rust2rpm/log.py Normal file
View file

@ -0,0 +1,28 @@
import sys
import textwrap
from termcolor import colored
def _eprint(message):
print(message, file=sys.stderr)
def _wrap(message, prefix):
return textwrap.wrap(message, 80, initial_indent=f"{prefix} ", subsequent_indent=" "*(len(prefix) + 1))
def success(message):
_eprint(colored("\n".join(_wrap(message, "")), "green"))
def info(message):
_eprint(colored("\n".join(_wrap(message, "")), "white"))
def warn(message):
_eprint(colored("\n".join(_wrap(message, "WARNING")), "yellow"))
def error(message):
_eprint(colored("\n".join(_wrap(message, "ERROR")), "red", attrs=["dark"]))

View file

@ -27,6 +27,7 @@ install_requires =
jinja2
pyparsing
requests
termcolor
tqdm
[options.package_data]