rust2rpm/rust2rpm/__main__.py
Fabio Valentini 2f1505daf2
conf: implement new TOML-based config file format
- does not rely on custom INI parsing
- can be validated automatically with the defined schema
- actual support for lists, multi-line strings, booleans

When a "rust2rpm.toml" file is found, it takes precedence. Otherwise,
rust2rpm will fall back to existing {,.,_}rust2rpm.conf files and
convert to the new format internally.
2023-10-05 20:03:08 +02:00

167 lines
5.7 KiB
Python

import os
import pathlib
import sys
from cargo2rpm.metadata import FeatureFlags, Version
from rust2rpm import log
from rust2rpm.cli import get_parser
from rust2rpm.conf import load_config
from rust2rpm.crate import process_project
from rust2rpm.cratesio import NoVersionsError
from rust2rpm.distgit import get_package_info
from rust2rpm.generator import spec_render_crate, spec_render_workspace
from rust2rpm.licensing import dump_sdpx_to_fedora_map, translate_license
from rust2rpm.metadata import guess_main_package, warn_if_package_uses_restrictive_dependencies
from rust2rpm.utils import (
detect_packager,
detect_rpmautospec,
exit_on_common_errors,
guess_crate_name,
package_name_compat,
package_name_suffixed,
)
@exit_on_common_errors()
def main():
parser = get_parser()
args = parser.parse_args()
if args.show_license_map:
dump_sdpx_to_fedora_map(sys.stdout)
return
if args.translate_license:
license_str, comments = translate_license(args.target, args.crate)
if comments:
for comment in comments.split("\n"):
log.info(comment)
print(license_str)
return
if args.crate is None:
args.crate = guess_crate_name()
if args.crate is None:
parser.error("crate/path argument missing and autodetection failed")
try:
project, version, diffs, metadata, doc_files, license_files = process_project(
args.crate, args.version, args.patch, args.patch_foreign, args.store_crate
)
except NoVersionsError:
log.error(f"No versions are available for crate {args.crate!r}.")
sys.exit(1)
if metadata.is_workspace():
base_name = project
rpm_name = project
else:
base_name = metadata.packages[0].name
if args.suffix:
log.warn("The '--suffix' argument is deprecated, use the '--compat' flag instead.")
rpm_name = package_name_suffixed(base_name, args.suffix)
elif args.compat:
rpm_name = package_name_compat(base_name, args.version)
else:
rpm_name = package_name_suffixed(base_name, None)
patch_files = (
f"{base_name}-fix-metadata-auto.diff" if diffs[0] else None,
f"{base_name}-fix-metadata.diff" if diffs[1] else None,
)
spec_file = pathlib.Path(f"{rpm_name}.spec")
if args.target in {"fedora"} and args.existence_check and not os.path.exists(spec_file):
# No specfile, so this is probably a new package
if package_info := get_package_info(rpm_name):
if args.suffix:
log.warn(
f"Version {args.suffix}.* of the crate {base_name!r} is already "
+ f"packaged for Fedora: {package_info['full_url']}"
)
else:
log.warn(f"Crate {base_name!r} is already packaged for Fedora: {package_info['full_url']}")
log.info("Re-run with --no-existence-check to create a new spec file from scratch.")
sys.exit(1)
if args.rpmautospec is None:
args.rpmautospec = detect_rpmautospec(args.target, spec_file)
packager = detect_packager()
if not metadata.is_workspace():
tomlconf = load_config(metadata.packages[0].get_feature_names(), args.target)
else:
tomlconf = load_config(set(), args.target)
if not metadata.is_workspace():
package = metadata.packages[0]
if build_meta := Version.parse(package.version).build:
log.error(f"Crate version {package.version!r} contains build metadata: '+{build_meta}'")
log.error(f"This is not supported by rust2rpm; remove the '+{build_meta}' suffix.")
sys.exit(1)
warn_if_package_uses_restrictive_dependencies(package)
spec_contents = spec_render_crate(
metadata=metadata,
upstream_version=version,
target=args.target,
rpm_name=rpm_name,
patch_file_automatic=patch_files[0],
patch_file_manual=patch_files[1],
license_files=license_files,
doc_files=doc_files,
tomlconf=tomlconf,
feature_flags=FeatureFlags(all_features=args.all_features),
relative_license_paths=args.relative_license_paths,
rpmautospec=args.rpmautospec,
auto_changelog_entry=args.auto_changelog_entry,
packager=packager,
)
else:
try:
main_package = guess_main_package(metadata, hint=project, interactive=args.interactive)
except ValueError:
sys.exit(1)
spec_contents = spec_render_workspace(
metadata=metadata,
main_package=main_package,
target=args.target,
rpm_name=rpm_name,
license_files=license_files,
doc_files=doc_files,
tomlconf=tomlconf,
feature_flags=FeatureFlags(all_features=args.all_features),
rpmautospec=args.rpmautospec,
auto_changelog_entry=args.auto_changelog_entry,
packager=packager,
)
if args.stdout:
print(f"# {spec_file}")
print(spec_contents)
for fname, diff in zip(patch_files, diffs):
if fname and diff:
print(f"# {fname}")
print("\n".join(diff) + "\n")
else:
with open(spec_file, "w") as fobj:
fobj.write(spec_contents)
log.success(f"Generated: {fobj.name}")
for fname, diff in zip(patch_files, diffs):
if fname and diff:
with open(fname, "w") as fobj:
fobj.write("\n".join(diff) + "\n")
log.success(f"Generated: {fobj.name}")
if __name__ == "__main__":
main()