| |
@@ -83,6 +83,14 @@
|
| |
t = datetime.fromtimestamp(os.stat(path).st_mtime, timezone.utc)
|
| |
return t.astimezone().isoformat()
|
| |
|
| |
+ @contextlib.contextmanager
|
| |
+ def remove_on_error(path):
|
| |
+ try:
|
| |
+ yield
|
| |
+ except: # this is supposed to include ^C
|
| |
+ os.unlink(path)
|
| |
+ raise
|
| |
+
|
| |
def local_toml(toml, version):
|
| |
if os.path.isdir(toml):
|
| |
toml = os.path.join(toml, "Cargo.toml")
|
| |
@@ -110,7 +118,8 @@
|
| |
req = requests.get(url, stream=True)
|
| |
req.raise_for_status()
|
| |
total = int(req.headers["Content-Length"])
|
| |
- with open(cratef, "wb") as f:
|
| |
+ with remove_on_error(cratef), \
|
| |
+ open(cratef, "wb") as f:
|
| |
for chunk in tqdm.tqdm(req.iter_content(), "Downloading {}".format(cratef_base),
|
| |
total=total, unit="B", unit_scale=True):
|
| |
f.write(chunk)
|
| |
@@ -163,22 +172,29 @@
|
| |
def _is_path(path):
|
| |
return "/" in path or path in {".", ".."}
|
| |
|
| |
- def make_diff_metadata(crate, version, patch=False, store=False):
|
| |
+ def make_diff_metadata(crate, version, patch=False, store=False, *, enabled_features, disabled_features):
|
| |
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:
|
| |
+ raise ValueError('--store-crate can only be used for a crate')
|
| |
+
|
| |
toml, crate, version = local_toml(crate, version)
|
| |
diff = make_patch(toml, enabled=patch, tmpfile=True)
|
| |
- metadata = Metadata.from_file(toml)
|
| |
+ metadata = Metadata.from_file(toml,
|
| |
+ enabled_features=enabled_features,
|
| |
+ disabled_features=disabled_features)
|
| |
return metadata.name, diff, metadata
|
| |
else:
|
| |
cratef, crate, version = download(crate, version)
|
| |
|
| |
with toml_from_crate(cratef, crate, version) as toml:
|
| |
diff = make_patch(toml, enabled=patch)
|
| |
- metadata = Metadata.from_file(toml)
|
| |
+ metadata = Metadata.from_file(toml,
|
| |
+ enabled_features=enabled_features,
|
| |
+ disabled_features=disabled_features)
|
| |
if store:
|
| |
shutil.copy2(cratef, os.path.join(os.getcwd(), f"{crate}-{version}.crate"))
|
| |
return crate, diff, metadata
|
| |
@@ -197,6 +213,10 @@
|
| |
help="Do initial patching of Cargo.toml")
|
| |
parser.add_argument("-s", "--store-crate", action="store_true",
|
| |
help="Store crate in current directory")
|
| |
+ parser.add_argument("--with", nargs="*", dest="_with",
|
| |
+ help="Enable the specified features (default: all)")
|
| |
+ parser.add_argument("--without", nargs="*",
|
| |
+ help="Disable the specified features")
|
| |
parser.add_argument("crate", help="crates.io name\n"
|
| |
"path/to/local.crate\n"
|
| |
"path/to/project/",
|
| |
@@ -211,9 +231,15 @@
|
| |
if args.crate is None:
|
| |
parser.error('required crate/path argument missing')
|
| |
|
| |
+ confused = set(args._with or ()) & set(args.without or ())
|
| |
+ if confused:
|
| |
+ parser.error(f"Cannot both disable and enable features at the same time: {' '.join(confused)}")
|
| |
+
|
| |
crate, diff, metadata = make_diff_metadata(args.crate, args.version,
|
| |
patch=args.patch,
|
| |
- store=args.store_crate)
|
| |
+ store=args.store_crate,
|
| |
+ enabled_features=args._with,
|
| |
+ disabled_features=args.without)
|
| |
|
| |
template = JINJA_ENV.get_template("main.spec")
|
| |
|
| |
The first two commits are part of PR #58, please ignore them here.
The third commit adds ability to specify features to enable/disable on the rust2rpm command line. Unfortunately this gains us nothing, because cargo has no mechanism to ignore dependencies and requires all dependencies to be always present.
I think we should just wait for cargo to solve this. All distributions want/need this, so doing something like patching .toml files locally just doesn't seem worth the trouble. See upstream bug https://github.com/rust-lang/cargo/issues/4544.