diff --git a/.gitignore b/.gitignore
index 90521b3b..eae72589 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
# general dev/ide files
*.log
*.vscode
-*.csv
.idea
*.DS_Store
@@ -24,19 +23,20 @@ workon/
.coverage
pytest.xml
+*.txt
# content
# todo probably want to add a workbook and ds in /res for getting started easily
*.pdf
*.png
-*.twbx
-*.hyper
-*.twb
-*.twbr
-html
*.html
-*.twbr
+# *.twbx
+# *.hyper
+# *.twb
+# *.twbr
+# *.tdsx
**/credentials.py
-*.txt
+# exceptions
+!tests/assets/
# doit
.doit.*
@@ -48,6 +48,3 @@ site-packages
tabcmd-dev
workon
test.junit.xml
-
-# exceptions
-!tests/assets/detailed_users.csv
\ No newline at end of file
diff --git a/World Indicators.tdsx b/World Indicators.tdsx
deleted file mode 100644
index 7c8e53db..00000000
Binary files a/World Indicators.tdsx and /dev/null differ
diff --git a/WorldIndicators.tdsx b/WorldIndicators.tdsx
deleted file mode 100644
index 2df960cc..00000000
Binary files a/WorldIndicators.tdsx and /dev/null differ
diff --git a/pyproject.toml b/pyproject.toml
index f3348261..7a818c8f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,6 +9,7 @@ packages = ["tabcmd"]
tabcmd = ["tabcmd.locales/**/*.mo"]
[tool.black]
line-length = 120
+required-version = 22
target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
extend-exclude = '^/bin/*'
[tool.mypy]
diff --git a/tabcmd/commands/datasources_and_workbooks/publish_command.py b/tabcmd/commands/datasources_and_workbooks/publish_command.py
index 64189e9e..a4ff8c26 100644
--- a/tabcmd/commands/datasources_and_workbooks/publish_command.py
+++ b/tabcmd/commands/datasources_and_workbooks/publish_command.py
@@ -40,19 +40,17 @@ def run_command(args):
session = Session()
server = session.create_session(args, logger)
- if args.project_name:
- try:
- dest_project = Server.get_project_by_name_and_parent_path(
- logger, server, args.project_name, args.parent_project_path
- )
- project_id = dest_project.id
- except Exception as exc:
- logger.error(exc.__str__())
- Errors.exit_with_error(logger, _("publish.errors.server_resource_not_found"), exc)
- else:
- project_id = ""
- args.project_name = "default"
+ if not args.project_name:
+ args.project_name = "Default"
args.parent_project_path = ""
+ try:
+ dest_project = Server.get_project_by_name_and_parent_path(
+ logger, server, args.project_name, args.parent_project_path
+ )
+ project_id = dest_project.id
+ except Exception as exc:
+ logger.error(exc.__str__())
+ Errors.exit_with_error(logger, _("publish.errors.server_resource_not_found"), exc)
publish_mode = PublishCommand.get_publish_mode(args, logger)
@@ -82,7 +80,7 @@ def run_command(args):
# args.thumbnail_group,
connection_credentials=creds,
as_job=False,
- skip_connection_check=False,
+ skip_connection_check=args.skip_connection_check,
)
except Exception as e:
Errors.exit_with_error(logger, exception=e)
diff --git a/tabcmd/execution/global_options.py b/tabcmd/execution/global_options.py
index 695820db..6c972616 100644
--- a/tabcmd/execution/global_options.py
+++ b/tabcmd/execution/global_options.py
@@ -312,6 +312,11 @@ def set_publish_args(parser):
help="Encrypt extracts in the workbook, datasource, or extract being published to the server. "
"[N/a on Tableau Cloud: extract encryption is controlled by Site Admin]",
)
+ parser.add_argument(
+ "--skip-connection-check",
+ action="store_true",
+ help="Skip connection check: do not validate the workbook/datasource connection during publishing",
+ )
# These two only apply for a workbook, not a datasource
thumbnails = parser.add_mutually_exclusive_group()
diff --git a/tabcmd/execution/tabcmd_controller.py b/tabcmd/execution/tabcmd_controller.py
index 1a4544d2..6e06dfe1 100644
--- a/tabcmd/execution/tabcmd_controller.py
+++ b/tabcmd/execution/tabcmd_controller.py
@@ -37,14 +37,16 @@ def run(parser, user_input=None):
logger.debug(namespace)
if namespace.language:
set_client_locale(namespace.language, logger)
-
try:
+ func = namespace.func
# if a subcommand was identified, call the function assigned to it
# this is the functional equivalent of the call by reflection in the previous structure
# https://stackoverflow.com/questions/49038616/argparse-subparsers-with-functions
namespace.func.run_command(namespace)
+ except AttributeError:
+ parser.error("No command identified or too few arguments")
except Exception as e:
- # todo: use log_stack here for better presentation
+ # todo: use log_stack here for better presentation?
logger.exception(e)
# if no command was given, argparse will just not create the attribute
sys.exit(2)
diff --git a/tests/assets/EmbeddedCredentials.twb b/tests/assets/EmbeddedCredentials.twb
new file mode 100644
index 00000000..196f0924
--- /dev/null
+++ b/tests/assets/EmbeddedCredentials.twb
@@ -0,0 +1,977 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ 3
+ [ID]
+ [DBZ]
+ ID
+ 1
+ integer
+ Sum
+ 10
+ false
+
+ "SQL_INTEGER"
+ "SQL_C_SLONG"
+
+
+
+ Vendor
+ 130
+ [Vendor]
+ [DBZ]
+ Vendor
+ 2
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Database
+ 130
+ [Database]
+ [DBZ]
+ Database
+ 3
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ TDCName
+ 130
+ [TDCName]
+ [DBZ]
+ TDCName
+ 4
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Release
+ 130
+ [Release]
+ [DBZ]
+ Release
+ 5
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Release Notes
+ 130
+ [Release Notes]
+ [DBZ]
+ Release Notes
+ 6
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Status
+ 130
+ [Status]
+ [DBZ]
+ Status
+ 7
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Machine Type
+ 130
+ [Machine Type]
+ [DBZ]
+ Machine Type
+ 8
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ CName
+ 130
+ [CName]
+ [DBZ]
+ CName
+ 9
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ database/schema
+ 130
+ [database/schema]
+ [DBZ]
+ database/schema
+ 10
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ username
+ 130
+ [username]
+ [DBZ]
+ username
+ 11
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ password
+ 130
+ [password]
+ [DBZ]
+ password
+ 12
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Port/Service
+ 130
+ [Port/Service]
+ [DBZ]
+ Port/Service
+ 13
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ AD auth
+ 11
+ [AD auth]
+ [DBZ]
+ AD auth
+ 14
+ boolean
+ Count
+ true
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+
+
+ LDAP Auth
+ 11
+ [LDAP Auth]
+ [DBZ]
+ LDAP Auth
+ 15
+ boolean
+ Count
+ true
+
+ "SQL_BIT"
+ "SQL_C_BIT"
+
+
+
+ DBZ Host
+ 130
+ [DBZ Host]
+ [DBZ]
+ DBZ Host
+ 16
+ string
+ Count
+ 25
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ DBZ Node
+ 130
+ [DBZ Node]
+ [DBZ]
+ DBZ Node
+ 17
+ string
+ Count
+ 255
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ DBZ Internal IP
+ 130
+ [DBZ Internal IP]
+ [DBZ]
+ DBZ Internal IP
+ 18
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ GOLD IP
+ 130
+ [GOLD IP]
+ [DBZ]
+ GOLD IP
+ 19
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ LIVE IP
+ 130
+ [LIVE IP]
+ [DBZ]
+ LIVE IP
+ 20
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ TEST IP
+ 130
+ [TEST IP]
+ [DBZ]
+ TEST IP
+ 21
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ dvah IP
+ 130
+ [dvah IP]
+ [DBZ]
+ dvah IP
+ 22
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ tsah IP
+ 130
+ [tsah IP]
+ [DBZ]
+ tsah IP
+ 23
+ string
+ Count
+ 15
+ true
+ true
+
+
+ "SQL_WCHAR"
+ "SQL_C_WCHAR"
+
+
+
+ IP Address Locked
+ 130
+ [IP Address Locked]
+ [DBZ]
+ IP Address Locked
+ 24
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ Node Name Locked
+ 130
+ [Node Name Locked]
+ [DBZ]
+ Node Name Locked
+ 25
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ MAC Address Locked
+ 130
+ [MAC Address Locked]
+ [DBZ]
+ MAC Address Locked
+ 26
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ FirstBuiltDate
+ 7
+ [FirstBuiltDate]
+ [DBZ]
+ FirstBuiltDate
+ 27
+ date
+ Year
+ true
+
+ "SQL_TYPE_DATE"
+ "SQL_C_TYPE_DATE"
+ true
+
+
+
+ FirstBlessDate
+ 7
+ [FirstBlessDate]
+ [DBZ]
+ FirstBlessDate
+ 28
+ date
+ Year
+ true
+
+ "SQL_TYPE_DATE"
+ "SQL_C_TYPE_DATE"
+ true
+
+
+
+ ExternalDocURL
+ 130
+ [ExternalDocURL]
+ [DBZ]
+ ExternalDocURL
+ 29
+ string
+ Count
+ 250
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ InternalDocURL
+ 130
+ [InternalDocURL]
+ [DBZ]
+ InternalDocURL
+ 30
+ string
+ Count
+ 250
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+ DriverInfo
+ 129
+ [DriverInfo]
+ [DBZ]
+ DriverInfo
+ 31
+ string
+ Count
+ 250
+ true
+ true
+
+
+ "SQL_VARCHAR"
+ "SQL_C_CHAR"
+ "true"
+
+
+
+ Migration Group
+ 130
+ [Migration Group]
+ [DBZ]
+ Migration Group
+ 32
+ string
+ Count
+ 50
+ true
+ true
+
+
+ "SQL_WVARCHAR"
+ "SQL_C_WCHAR"
+ "true"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ([sqlserver.42493.565638564818].[none:LIVE IP:nk] / [sqlserver.42493.565638564818].[none:Status:nk])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [sqlserver.42493.565638564818].[none:Status:nk]
+
+
+
+
+
+
+ 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
+
+
+
diff --git a/tests/assets/SampleDS.tds b/tests/assets/SampleDS.tds
index 40b850ac..502e6a22 100644
--- a/tests/assets/SampleDS.tds
+++ b/tests/assets/SampleDS.tds
@@ -1,6 +1,6 @@
-
+
diff --git a/tests/assets/WorkbookWithExtract.twbx b/tests/assets/WorkbookWithExtract.twbx
new file mode 100644
index 00000000..b6025b36
Binary files /dev/null and b/tests/assets/WorkbookWithExtract.twbx differ
diff --git a/tests/assets/WorkbookWithoutExtract.twbx b/tests/assets/WorkbookWithoutExtract.twbx
new file mode 100644
index 00000000..49fc684a
Binary files /dev/null and b/tests/assets/WorkbookWithoutExtract.twbx differ
diff --git a/tests/assets/simple-data.twbx b/tests/assets/simple-data.twbx
new file mode 100644
index 00000000..bf8ad6df
Binary files /dev/null and b/tests/assets/simple-data.twbx differ
diff --git a/tests/assets/usernames.csv b/tests/assets/usernames.csv
new file mode 100644
index 00000000..b300c1c1
--- /dev/null
+++ b/tests/assets/usernames.csv
@@ -0,0 +1 @@
+anyoung@salesforce.com
\ No newline at end of file
diff --git a/tests/commands/test_publish_command.py b/tests/commands/test_publish_command.py
index 9f91a02e..0c9049a7 100644
--- a/tests/commands/test_publish_command.py
+++ b/tests/commands/test_publish_command.py
@@ -60,6 +60,7 @@ def test_publish(self, mock_session, mock_server):
mock_args.replace = False
mock_args.thumbnail_username = None
mock_args.thumbnail_group = None
+ mock_args.skip_connection_check = False
mock_server.projects = getter
publish_command.PublishCommand.run_command(mock_args)
mock_session.assert_called()
@@ -84,6 +85,7 @@ def test_publish_with_creds(self, mock_session, mock_server):
mock_args.thumbnail_username = None
mock_args.thumbnail_group = None
+ mock_args.skip_connection_check = False
mock_server.projects = getter
publish_command.PublishCommand.run_command(mock_args)
diff --git a/tests/commands/test_run_commands.py b/tests/commands/test_run_commands.py
index 9afd8b63..c29341d0 100644
--- a/tests/commands/test_run_commands.py
+++ b/tests/commands/test_run_commands.py
@@ -147,6 +147,7 @@ def test_publish(self, mock_session, mock_server):
mock_args.replace = False
mock_args.thumbnail_username = None
mock_args.thumbnail_group = None
+ mock_args.skip_connection_check = False
mock_server.projects = getter
publish_command.PublishCommand.run_command(mock_args)
mock_session.assert_called()
diff --git a/tests/e2e/online_tests.py b/tests/e2e/online_tests.py
index 3e70d78d..05a9b6a9 100644
--- a/tests/e2e/online_tests.py
+++ b/tests/e2e/online_tests.py
@@ -93,7 +93,7 @@ def _publish_samples(self, project_name):
arguments = [command, "--name", project_name]
_test_command(arguments)
- def _publish_args(self, file, name, tabbed=None):
+ def _publish_args(self, file, name):
command = "publish"
arguments = [command, file, "--name", name, "--overwrite"]
return arguments
@@ -201,11 +201,11 @@ def _list(self, item_type: str):
TDSX_WITH_EXTRACT_NAME = "WorldIndicators"
TDSX_FILE_WITH_EXTRACT = "World Indicators.tdsx"
# fill in
- TDS_FILE_LIVE_NAME = ""
- TDS_FILE_LIVE = ""
- # only works on linux servers or something
- TWB_WITH_EMBEDDED_CONNECTION = "embedded_connection_waremart.twb"
- EMBEDDED_TWB_NAME = "waremart"
+ TDS_FILE_LIVE_NAME = "SampleDS"
+ TDS_FILE_LIVE = "SampleDS.tds"
+
+ TWB_WITH_EMBEDDED_CONNECTION = "EmbeddedCredentials.twb"
+ EMBEDDED_TWB_NAME = "EmbeddedCredentials"
@pytest.mark.order(1)
def test_login(self):
@@ -333,7 +333,10 @@ def test_delete_projects(self):
def test_wb_publish(self):
file = os.path.join("tests", "assets", OnlineCommandTest.TWBX_FILE_WITH_EXTRACT)
arguments = self._publish_args(file, OnlineCommandTest.TWBX_WITH_EXTRACT_NAME)
- _test_command(arguments)
+ val = _test_command(arguments)
+ if val != 0:
+ print("publishing failed: cancel test run")
+ exit(val)
@pytest.mark.order(11)
def test_wb_get(self):
@@ -364,6 +367,8 @@ def test_wb_publish_embedded(self):
file = os.path.join("tests", "assets", OnlineCommandTest.TWB_WITH_EMBEDDED_CONNECTION)
arguments = self._publish_args(file, OnlineCommandTest.EMBEDDED_TWB_NAME)
arguments = self._publish_creds_args(arguments, database_user, database_password, True)
+ arguments.append("--tabbed")
+ arguments.append("--skip-connection-check")
_test_command(arguments)
@pytest.mark.order(12)