Commit 953321a3 authored by mhellka's avatar mhellka
Browse files

Added 'rma' (remove archive) command.

parent c6e3cdf9
"""
Remove one or more archives.
"""
from contextlib import ExitStack
# TODO: Delete directories or glob patterns
from pycdstar3 import ApiError
def register(subparsers):
parser = subparsers.add_parser("rma", help=__doc__.strip().splitlines()[0], description=__doc__)
parser.add_argument("-f", "--force", action="store_true", help="Do not prompt and ignore missing archives"
" or access errors.")
parser.add_argument("-y", "--yes", action="store_true", help="Do not prompt")
parser.add_argument("ARCHIVE", nargs="+", help="Archive IDs. Repeat to delete multiple archives.")
parser.set_defaults(main=remove_files)
def remove_files(ctx, args):
client = ctx.client
vault = ctx.vault
archives = args.ARCHIVE
force = args.force
yes = args.yes
with ExitStack() as stack:
if len(archives) > 1:
stack.enter_context(client.begin(autocommit=True))
prompt = "Do you really want to delete {} archives? This cannot be undone!".format(len(archives))
if not (yes or force or ctx.ask_yes(prompt)):
return
for archive in archives:
try:
client.delete_archive(vault, archive)
ctx.print("Deleting: {}".format(archive))
except ApiError as e:
if force:
ctx.print(" Ignoring error (--force) {}", e)
continue
raise
......@@ -3,6 +3,12 @@ import os
import sys
import typing
try:
# Nicer input() behavior
import readline # noqa: F401
except ImportError:
pass
from pycdstar3 import CDStar, __url__ as help_url
from pycdstar3._utils import cached_property, url_split_auth
from pycdstar3.cli import CliError
......@@ -63,8 +69,8 @@ class CliContext:
def _get_setting(self, name) -> typing.Any:
""" Look for a setting in command-line arguments, environment variables or workspace configuration. """
return getattr(self.args, name, None) \
or os.environ.get(ENV_PREFIX + name.upper()) \
or (self.workspace and self.workspace.config.get(name))
or os.environ.get(ENV_PREFIX + name.upper()) \
or (self.workspace and self.workspace.config.get(name))
def _require_setting(self, name) -> typing.Any:
result = self._get_setting(name)
......@@ -78,6 +84,27 @@ class CliContext:
# Enter password for {url.scheme}://{url.netloc}/{url.path} (user={url.username})
raise RuntimeError("Asking for password not implemented yet")
def ask_yes(self, prompt, default="yes") -> bool:
""" Ask user for confirmation (Y|n)"""
def is_true(s):
return s.lower() in ('y', 'yes', 'ok', 'true')
def is_false(s):
return s.lower() in ('n', 'no', 'false')
while True:
if is_true(default):
val = input("{} (Y|n): ".format(prompt)).strip() or default
else:
val = input("{} (y|N): ".format(prompt)).strip() or default
if is_true(val):
return True
if is_false(val):
return False
self.print('Please answer "yes" or "no" (Ctrl+C to abort)')
def _find_workspace(start='.'):
for path in walk_up(os.path.abspath(start)):
......
......@@ -8,6 +8,6 @@ commands = pytest {posargs}
passenv = TEST_CDSTAR TEST_VAULT
[flake8]
ignore = E121,E123,E126,E133,E226,E241,E242,E704,W503,W504,W505
ignore = E121,E123,E126,E127,E133,E226,E241,E242,E704,W503,W504,W505,
max-line-length = 160
max-complexity = 10
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment