| |
@@ -175,6 +175,7 @@
|
| |
|
| |
@contextlib.contextmanager
|
| |
def files_from_crate(cratef, crate, version):
|
| |
+ """Unpacks cratef and returns path to toml file, list of doc files, list of license files"""
|
| |
with tempfile.TemporaryDirectory() as tmpdir:
|
| |
target_dir = f"{tmpdir}/"
|
| |
with tarfile.open(cratef, "r") as archive:
|
| |
@@ -182,8 +183,7 @@
|
| |
if not os.path.abspath(os.path.join(target_dir, n)).startswith(target_dir):
|
| |
raise Exception("Unsafe filenames!")
|
| |
archive.extractall(target_dir)
|
| |
- toml_relpath = f"{crate}-{version}/Cargo.toml"
|
| |
- toml = f"{tmpdir}/{toml_relpath}"
|
| |
+ toml = f"{tmpdir}/{crate}-{version}/Cargo.toml"
|
| |
if not os.path.isfile(toml):
|
| |
raise IOError("crate does not contain Cargo.toml file")
|
| |
root_path = f"{tmpdir}/{crate}-{version}"
|
| |
@@ -191,8 +191,9 @@
|
| |
license_files = get_license_files(root_path)
|
| |
yield toml, doc_files, license_files
|
| |
|
| |
- def make_patch(toml, enabled=True, tmpfile=False):
|
| |
- if not enabled:
|
| |
+ def make_patch(args, toml, tmpfile=False):
|
| |
+ """Spawns editor on toml and returns a unified diff after editor closes"""
|
| |
+ if not args.patch:
|
| |
return []
|
| |
|
| |
editor = detect_editor()
|
| |
@@ -225,6 +226,7 @@
|
| |
|
| |
@sortify
|
| |
def get_license_files(path):
|
| |
+ """Heuristic match on file names to detect license files"""
|
| |
exclude = { "vendor", "example", "examples", "_example", "_examples",
|
| |
"testdata", "_testdata", ".github", "tests", "test" }
|
| |
for root, dirs, files in os.walk(path, topdown=True):
|
| |
@@ -235,6 +237,7 @@
|
| |
|
| |
@sortify
|
| |
def get_doc_files(path):
|
| |
+ """Heuristic match on file names to detect documentation files"""
|
| |
plus = re.compile(r"""
|
| |
.*\.(?:md|markdown|mdown|mkdn|rst|txt)|AUTHORS|
|
| |
AUTHORS[.-].*|CONTRIBUTORS|CONTRIBUTORS[.-].*|README|
|
| |
@@ -250,6 +253,18 @@
|
| |
yield os.path.relpath(os.path.join(root, f), path)
|
| |
|
| |
def get_package_info(package):
|
| |
+ """Download information about package from dist-git.
|
| |
+
|
| |
+ Returns JSON with package metadata, or None if the package is
|
| |
+ unnkown or the spec file is not present.
|
| |
+
|
| |
+ >>> rust2rpm.__main__.get_package_info('rust-alacritty')
|
| |
+ {...
|
| |
+ 'name': 'rust-alacritty',
|
| |
+ 'namespace': 'rpms',
|
| |
+ ...}
|
| |
+ """
|
| |
+
|
| |
url = requests.compat.urljoin(DIST_GIT_URL, f"rpms/{package}")
|
| |
req = requests.get(url, headers={"User-Agent": "rust2rpm"})
|
| |
json = req.json()
|
| |
@@ -268,17 +283,17 @@
|
| |
|
| |
return json
|
| |
|
| |
- def make_diff_metadata(crate, version, patch=False, store=False):
|
| |
+ def make_diff_metadata(args, crate, version):
|
| |
if _is_path(crate):
|
| |
# Only things that look like a paths are considered local arguments
|
| |
if crate.endswith(".crate"):
|
| |
cratef, crate, version = local_crate(crate, version)
|
| |
else:
|
| |
- if store:
|
| |
+ if args.store_crate:
|
| |
raise ValueError("--store-crate can only be used for a crate")
|
| |
|
| |
toml, crate, version, doc_files, license_files = local_toml(crate, version)
|
| |
- diff = make_patch(toml, enabled=patch, tmpfile=True)
|
| |
+ diff = make_patch(args, toml, tmpfile=True)
|
| |
metadata = Metadata.from_file(toml)
|
| |
if len(metadata) > 1:
|
| |
print(f"Warning: multiple metadata for {toml}")
|
| |
@@ -291,12 +306,12 @@
|
| |
if not license_files:
|
| |
print(f"Warning: no license files detected in {crate}")
|
| |
|
| |
- diff = make_patch(toml, enabled=patch)
|
| |
+ diff = make_patch(args, toml)
|
| |
metadata = Metadata.from_file(toml)
|
| |
if len(metadata) > 1:
|
| |
- print(f"Warning: multiple metadata for {toml}")
|
| |
+ print(f"Warning: multiple metadata for {toml}, ignoring everything except the first")
|
| |
metadata = metadata[0]
|
| |
- if store:
|
| |
+ if args.store_crate:
|
| |
shutil.copy2(cratef, os.path.join(os.getcwd(), f"{metadata.name}-{version}.crate"))
|
| |
return crate, diff, metadata, doc_files, license_files
|
| |
|
| |
@@ -306,6 +321,12 @@
|
| |
return list(filter(None, (l.strip() for l in s.splitlines())))
|
| |
|
| |
def detect_rpmautospec(default_target, spec_file):
|
| |
+ """Guess whether %autorelease+%autochangelog should be used
|
| |
+
|
| |
+ Returns False if we're not on Fedora or if the spec file exists and
|
| |
+ wasn't using rpmautospec already.
|
| |
+ """
|
| |
+
|
| |
# We default to on only for selected distros for now…
|
| |
if default_target not in {"fedora"}:
|
| |
return False
|
| |
@@ -346,9 +367,11 @@
|
| |
help="Print license mappings and exit")
|
| |
parser.add_argument("--translate-license", action="store_true",
|
| |
help="Print mapping for specified license and exit")
|
| |
- parser.add_argument("--no-auto-changelog-entry", action="store_true",
|
| |
+ parser.add_argument("--no-auto-changelog-entry", action="store_false",
|
| |
+ default=True, dest="auto_changelog_entry",
|
| |
help="Do not generate a changelog entry")
|
| |
- parser.add_argument("--no-existence-check", action="store_true",
|
| |
+ parser.add_argument("--no-existence-check", action="store_false",
|
| |
+ default=True, dest="existence_check",
|
| |
help="Do not check whether the package already exists in dist-git")
|
| |
parser.add_argument("-", "--stdout", action="store_true",
|
| |
help="Print spec and patches into stdout")
|
| |
@@ -363,15 +386,17 @@
|
| |
default=None,
|
| |
help="Use autorelease and autochangelog features")
|
| |
parser.add_argument("--no-rpmautospec", action="store_false",
|
| |
- default=None,
|
| |
+ dest="rpmautospec",
|
| |
help="Do not use rpmautospec")
|
| |
parser.add_argument("--relative-license-paths", action="store_true",
|
| |
help="Put all license files in main license directory")
|
| |
parser.add_argument("--all-features", action="store_true",
|
| |
help="Activate all available features")
|
| |
parser.add_argument("--dynamic-buildrequires", action="store_true",
|
| |
+ default=None,
|
| |
help="Use dynamic BuildRequires feature")
|
| |
- parser.add_argument("--no-dynamic-buildrequires", action="store_true",
|
| |
+ parser.add_argument("--no-dynamic-buildrequires", action="store_false",
|
| |
+ dest="dynamic_buildrequires",
|
| |
help="Do not use dynamic BuildRequires feature")
|
| |
parser.add_argument("--suffix", action="store",
|
| |
help="Package suffix")
|
| |
@@ -396,8 +421,7 @@
|
| |
if args.crate is None:
|
| |
parser.error("required crate/path argument missing")
|
| |
|
| |
- crate, diff, metadata, doc_files, license_files = make_diff_metadata(
|
| |
- args.crate, args.version, patch=args.patch, store=args.store_crate)
|
| |
+ crate, diff, metadata, doc_files, license_files = make_diff_metadata(args, args.crate, args.version)
|
| |
|
| |
JINJA_ENV.globals["normalize_deps"] = normalize_deps
|
| |
JINJA_ENV.globals["to_list"] = to_list
|
| |
@@ -436,7 +460,7 @@
|
| |
kwargs["pkg_suffix"] = suffix
|
| |
spec_file = pathlib.Path(f"rust-{metadata.name}{suffix}.spec")
|
| |
|
| |
- if args.target in {"fedora"} and not args.no_existence_check and not os.path.exists(spec_file):
|
| |
+ 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
|
| |
package_info = get_package_info(f"rust-{metadata.name}{suffix}")
|
| |
if package_info:
|
| |
@@ -444,10 +468,10 @@
|
| |
print("Re-run with --no-existence-check if you still want to convert it.")
|
| |
sys.exit(1)
|
| |
|
| |
- kwargs["auto_changelog_entry"] = not args.no_auto_changelog_entry
|
| |
+ kwargs["auto_changelog_entry"] = args.auto_changelog_entry
|
| |
|
| |
rpmautospec = args.rpmautospec
|
| |
- if args.rpmautospec is None:
|
| |
+ if rpmautospec is None:
|
| |
rpmautospec = detect_rpmautospec(args.target, spec_file)
|
| |
kwargs["rpmautospec"] = rpmautospec
|
| |
|
| |
@@ -476,8 +500,8 @@
|
| |
else:
|
| |
kwargs["pkg_release"] = "1%{?dist}"
|
| |
|
| |
- if args.target == "fedora" and not args.no_dynamic_buildrequires:
|
| |
- args.dynamic_buildrequires = True
|
| |
+ if args.dynamic_buildrequires is None:
|
| |
+ args.dynamic_buildrequires = args.target == "fedora"
|
| |
|
| |
kwargs["generate_buildrequires"] = args.dynamic_buildrequires
|
| |
|
| |
Preparatory changes split out of #183.