Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion tabcmd/commands/datasources_and_workbooks/delete_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class DeleteCommand(DatasourcesAndWorkbooks):
@staticmethod
def define_args(delete_parser):
group = delete_parser.add_argument_group(title=DeleteCommand.name)
group.add_argument("name", help=_("tabcmd.delete.target.name"))
# nargs="?" so `tabcmd delete --workbook "Name"` (Classic) also works,
# where the name is carried by the --workbook/--datasource value.
group.add_argument("name", nargs="?", default=None, help=_("tabcmd.delete.target.name"))
set_ds_xor_wb_options(group)
set_project_r_arg(group)
set_parent_project_arg(group)
Expand All @@ -33,7 +35,20 @@ def run_command(cls, args):
logger.debug(_("tabcmd.launching"))
session = Session()
server = session.create_session(args, logger)
# Resolve target from either form:
# tabcmd 2: delete "Name" --workbook -> args.name="Name", args.workbook=True
# Classic: delete --workbook "Name" -> args.name=None, args.workbook="Name"
content_type: str = ""
if isinstance(args.workbook, str):
if args.name is None:
args.name = args.workbook
args.workbook = True
if isinstance(args.datasource, str):
if args.name is None:
args.name = args.datasource
args.datasource = True
if args.name is None:
Errors.exit_with_error(logger, _("delete.errors.requires_workbook_datasource"))
if args.workbook:
content_type = "workbook"
elif args.datasource:
Expand Down
14 changes: 12 additions & 2 deletions tabcmd/execution/global_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,19 @@ def set_resource_url_arg(parser):


def set_ds_xor_wb_options(parser):
# Classic parity for `delete`: `tabcmd delete --workbook "Name"` treats
# --workbook's value as the target name. tabcmd 2 originally shipped as
# `tabcmd delete "Name" --workbook` (bare flag). Accept both forms by
# letting the flag take an optional value: bare -> True, with value ->
# value string. The command's run_command resolves which arg carries the
# name. See DeleteCommand.
target_type_group = parser.add_mutually_exclusive_group(required=False)
target_type_group.add_argument("-d", "--datasource", action="store_true", help=_("tabcmd.options.datasource"))
target_type_group.add_argument("-w", "--workbook", action="store_true", help=_("tabcmd.options.workbook"))
target_type_group.add_argument(
"-d", "--datasource", nargs="?", const=True, default=False, help=_("tabcmd.options.datasource")
)
target_type_group.add_argument(
"-w", "--workbook", nargs="?", const=True, default=False, help=_("tabcmd.options.workbook")
)
return parser


Expand Down
36 changes: 30 additions & 6 deletions tests/parsers/test_parser_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,42 @@ class DeleteParserTest(ParserTest):
def setUpClass(cls):
cls.parser_under_test = initialize_test_pieces(commandname, DeleteCommand)

def test_delete_parser_no_object(self):
def test_delete_parser_no_object_parses(self):
# With Classic-parity support (positional name optional so `--workbook Name`
# works), a bare `delete` now parses; the command-level check enforces that
# a name arrived via either form.
mock_args = [commandname]
with self.assertRaises(SystemExit):
args = self.parser_under_test.parse_args(mock_args)
args = self.parser_under_test.parse_args(mock_args)
assert args.name is None, args
assert args.workbook is False, args
assert args.datasource is False, args

def test_delete_parser(self):
mock_args = [commandname, "ds", "-r", "proj"]
args = self.parser_under_test.parse_args(mock_args)
assert args.name == "ds", args
assert args.project_name == "proj", args

def test_delete_parser_missing_args(self):
mock_args = [commandname, "--datasource"]
def test_delete_parser_bare_datasource_flag(self):
# tabcmd 2 form: `delete "Name" --datasource`. Bare --datasource -> True.
mock_args = [commandname, "ds", "--datasource"]
args = self.parser_under_test.parse_args(mock_args)
assert args.name == "ds", args
assert args.datasource is True, args

def test_delete_parser_classic_workbook_form(self):
# Classic form: `delete --workbook "Name"`. The value is the target name.
mock_args = [commandname, "--workbook", "MyWorkbook"]
args = self.parser_under_test.parse_args(mock_args)
assert args.workbook == "MyWorkbook", args

def test_delete_parser_classic_datasource_form(self):
mock_args = [commandname, "--datasource", "MyDatasource"]
args = self.parser_under_test.parse_args(mock_args)
assert args.datasource == "MyDatasource", args

def test_delete_parser_mutually_exclusive_still_holds(self):
# --workbook and --datasource are still mutually exclusive.
mock_args = [commandname, "--workbook", "A", "--datasource", "B"]
with self.assertRaises(SystemExit):
args = self.parser_under_test.parse_args(mock_args)
self.parser_under_test.parse_args(mock_args)