From c5969d1227e04f0e9e18d5ba1ded8799b0685c17 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 3 Aug 2026 18:08:09 -0700 Subject: [PATCH] Fix #436: add --description/-d to publish tabcmd Classic accepts --description/-d when publishing to set the workbook or data source description. tabcmd 2 was missing the flag, so users had to publish and then run a separate update to set the description. Add --description/-d to set_publish_args and set it on the WorkbookItem or DatasourceItem before calling server.workbooks.publish or server.datasources.publish. TSC's _generate_xml already includes description in the publish request body when the attribute is set. Fixes #436. --- .../datasources_and_workbooks/publish_command.py | 4 ++++ tabcmd/execution/global_options.py | 1 + tabcmd/locales/en/tabcmd_messages_en.properties | 1 + tests/parsers/test_parser_publish.py | 15 +++++++++++++++ 4 files changed, 21 insertions(+) diff --git a/tabcmd/commands/datasources_and_workbooks/publish_command.py b/tabcmd/commands/datasources_and_workbooks/publish_command.py index 1dd2bfc1..854c20e4 100644 --- a/tabcmd/commands/datasources_and_workbooks/publish_command.py +++ b/tabcmd/commands/datasources_and_workbooks/publish_command.py @@ -177,6 +177,8 @@ def publish_workbook_file(args, logger, server, project_id, str_filename, publis raise AttributeError("Cannot specify both a user and group for thumbnails.") new_workbook = TSC.WorkbookItem(project_id, name=args.name, show_tabs=args.tabbed) + if getattr(args, "description", None): + new_workbook.description = args.description new_workbook = server.workbooks.publish( new_workbook, str_filename, @@ -193,6 +195,8 @@ def publish_workbook_file(args, logger, server, project_id, str_filename, publis def publish_datasource_file(args, logger, server, project_id, str_filename, publish_mode, credentials): new_datasource = TSC.DatasourceItem(project_id, name=args.name) new_datasource.use_remote_query_agent = args.use_tableau_bridge + if getattr(args, "description", None): + new_datasource.description = args.description new_datasource = server.datasources.publish( new_datasource, str_filename, publish_mode, connection_credentials=credentials ) diff --git a/tabcmd/execution/global_options.py b/tabcmd/execution/global_options.py index 1a24133c..d3db7c0c 100644 --- a/tabcmd/execution/global_options.py +++ b/tabcmd/execution/global_options.py @@ -252,6 +252,7 @@ def set_destination_filename_arg(parser): def set_publish_args(parser): parser.add_argument("-n", "--name", help=_("publish.options.name")) + parser.add_argument("-d", "--description", help=_("publish.options.description")) creds = parser.add_mutually_exclusive_group() creds.add_argument("--oauth-username", help=_("publish.options.oauth-username")) diff --git a/tabcmd/locales/en/tabcmd_messages_en.properties b/tabcmd/locales/en/tabcmd_messages_en.properties index 7eda4bff..50b2f168 100644 --- a/tabcmd/locales/en/tabcmd_messages_en.properties +++ b/tabcmd/locales/en/tabcmd_messages_en.properties @@ -78,6 +78,7 @@ publish.errors.server_resource_not_found=The resource you specified does not exi publish.options.append=Append extract file to existing data source publish.options.db-password=Database password for all data sources publish.options.db-username=Database username for all data sources +publish.options.description=Description for the workbook or data source, sent with the publish request publish.options.encrypt_extracts=Encrypt extracts in the workbook or datasource being published to the server. publish.options.name=Workbook or data source name on the server. If omitted, the workbook or data source will be named after the file name, without the twb(x), tds(x), or tde extension. Publishing a .tde file will create a data source publish.options.oauth-username=Use the credentials saved on the server keychain associated with USERNAME to publish diff --git a/tests/parsers/test_parser_publish.py b/tests/parsers/test_parser_publish.py index b26f911d..728eb8e7 100644 --- a/tests/parsers/test_parser_publish.py +++ b/tests/parsers/test_parser_publish.py @@ -105,3 +105,18 @@ def test_publish_parser_deprecated_options(self): def test_publish_parser_use_bridge_option(self): mock_args = [commandname, "filename.twbx", "--use-tableau-bridge"] args = self.parser_under_test.parse_args(mock_args) + + def test_publish_parser_description_long_flag(self): + mock_args = [commandname, "filename.twbx", "--description", "My workbook description"] + args = self.parser_under_test.parse_args(mock_args) + assert args.description == "My workbook description", args + + def test_publish_parser_description_short_flag(self): + mock_args = [commandname, "filename.twbx", "-d", "Short desc"] + args = self.parser_under_test.parse_args(mock_args) + assert args.description == "Short desc", args + + def test_publish_parser_description_optional(self): + mock_args = [commandname, "filename.twbx"] + args = self.parser_under_test.parse_args(mock_args) + assert args.description is None, args