From 61375b038c5c0f7fbd67e471b6f3991a3ce26fa3 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 18 Sep 2026 14:47:02 -0700 Subject: [PATCH 1/2] Require --db-server when publishing with embedded credentials PR #458 fixed the two publish crashes when using --db-username / --db-password / --save-db-password, but callers who omit --db-server still hit a raw ValueError from tableauserverclient's _add_connections_element. Fail fast in run_command with a clear, localizable message before we build the ConnectionItem, so users get an actionable error instead of an internal stack trace. - Restore the --db-server required-when-embedded guard on the workbook publish path. - Extract _require_db_server_for_workbook(args, filename, logger) helper so the duplicated guard cannot drift between the early pre-auth check and the in-loop per-file check. - Extend the English publish.options.db-server help text to warn about the silent-drop-on-mismatch footgun. - Fix Portuguese grammar: "banco de dado" -> "banco de dados" (plural); "associado a credenciais" -> "associado as credenciais" (crase). - Regenerate .mo catalogs to pick up the new keys. - Unit tests: db-username and oauth-username exit paths, plus datasource-not-blocked coverage. - E2E test: friendly exit when --db-server is missing. Comment on test_wb_publish_embedded clarifies it only proves not-crashing (a mismatched --db-server would still exit 0 while silently dropping the creds; tracked internally). Re-cut from the closed PR #470 stack. Previously PR C in the #467/#469/#470 backport chain; PR B's base branch was deleted after merge, orphaning PR #470. This lands the same content on a fresh branch off development. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../publish_command.py | 26 ++++- tabcmd/locales/en/LC_MESSAGES/tabcmd.mo | Bin 22763 -> 23120 bytes .../locales/en/tabcmd_messages_en.properties | 3 +- tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo | Bin 18896 -> 18898 bytes .../locales/pt/tabcmd_messages_pt.properties | 2 +- tests/commands/test_publish_command.py | 104 +++++++++++++++++- tests/e2e/online_tests.py | 47 +++++++- 7 files changed, 172 insertions(+), 10 deletions(-) diff --git a/tabcmd/commands/datasources_and_workbooks/publish_command.py b/tabcmd/commands/datasources_and_workbooks/publish_command.py index dfd26b28..0a94cacb 100644 --- a/tabcmd/commands/datasources_and_workbooks/publish_command.py +++ b/tabcmd/commands/datasources_and_workbooks/publish_command.py @@ -42,10 +42,27 @@ def define_args(publish_parser): set_append_replace_option(group) set_parent_project_arg(group) + @classmethod + def _require_db_server_for_workbook(cls, args, filename, logger): + """Fail fast if the caller is publishing a workbook with embedded + credentials but did not supply --db-server. Called both up front + (direct-file case) and inside the per-file publish loop (folder case).""" + if (args.db_username or args.oauth_username) and not args.db_server: + filename_lower = (filename or "").lower() + if filename_lower.endswith(".twb") or filename_lower.endswith(".twbx"): + Errors.exit_with_error(logger, _("publish.errors.db_server_required")) + @classmethod def run_command(cls, args): logger = log(cls.__name__, args.logging_level) logger.debug(_("tabcmd.launching")) + + # Fail fast before auth when the direct target is clearly a workbook file: + # TSC's workbook publish path requires ConnectionItem.server_address whenever + # embedded credentials are supplied. Datasource publishes never need it, so + # this check is deliberately scoped to workbook extensions. + PublishCommand._require_db_server_for_workbook(args, args.filename, logger) + session = Session() server = session.create_session(args, logger) @@ -88,6 +105,9 @@ def run_command(cls, args): source = PublishCommand.get_filename_extension_if_tableau_type(logger, str_filename) logger.info(_("publish.status").format(str_filename)) if source in ["twbx", "twb"]: + # TSC's workbook publish path requires ConnectionItem.server_address whenever + # embedded connection credentials are supplied; datasource publish does not. + PublishCommand._require_db_server_for_workbook(args, str_filename, logger) try: published_item = PublishCommand.publish_workbook_file( args=args, @@ -96,7 +116,7 @@ def run_command(cls, args): project_id=project_id, str_filename=str_filename, publish_mode=publish_mode, - credentials=workbook_connections, + connection=workbook_connections, ) except Exception as e: Errors.exit_with_error(logger, exception=e) @@ -172,7 +192,7 @@ def get_publish_mode(args, logger): return publish_mode @staticmethod - def publish_workbook_file(args, logger, server, project_id, str_filename, publish_mode, credentials): + def publish_workbook_file(args, logger, server, project_id, str_filename, publish_mode, connection): if args.thumbnail_group: raise AttributeError("Generating thumbnails for a group is not yet implemented.") if args.thumbnail_username and args.thumbnail_group: @@ -185,7 +205,7 @@ def publish_workbook_file(args, logger, server, project_id, str_filename, publis publish_mode, # args.thumbnail_username, not yet implemented in tsc # args.thumbnail_group, - connections=[credentials] if credentials else None, + connections=[connection] if connection else None, as_job=False, skip_connection_check=args.skip_connection_check, ) diff --git a/tabcmd/locales/en/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/en/LC_MESSAGES/tabcmd.mo index 7238ce249e974c5f16f0720ce49c643d155464fa..85c42d08ca58183281b31878b73bce0931b545ab 100644 GIT binary patch delta 4475 zcmZ|ReQ?yp9mnxKjXWoi1o8xFHi-m6AfR9(Bxr;LF$$pyls;H;mpjPekqfyCkG6*$ zS_cWXl}E=1Vy7|`M$rc3VH7(Rr6WT?#!l-X1tq{tD@7?1QS9{n$#0qVpJp!i+TGvp zxBK1i?r)QSyzV=($Cvn9TGA%N&%gN{#_xbWs{Qxp#z13osD6ulOx7S{@^K^%!CL$d z)}zG)W@5W@KMtmT0#ork>bY*r<#v-ytEHg?OYk97hs&`5x47#Ekq68vOvCG#hXbf+ zfYCS#??X)_f)>}Jp4;i#|Aahh&SO5~n{IbQcDmPbITmw6Eh?ZmYR2uDfqz5|^buxZ z5~C+$E^43>wD^E?k!xRv3}t?Y3j9qR%=qSG3X1p(RAedSM*~{a15rT zRH_fU`bpFhT|zzoEh^wVzJ_BN7UGXk1Ru=hZADB5bsKW)QnLUo$16yz?zJWz} z5|!fXs1#;0n(F0faSm$FEJaP|SycZ=Q2qSX)vqG4nA>v5KYf{8MjeY~$g-LRs1&Y5 zrT%%;o_H6Pk;|wKd+|kIrT|s1ZP_Q&~BYm1I7DfY% zN3B&YYDP_{)cqQ@#_eeFHPn3{peFJq@-Zo-MeQZdI@E+>XmJzrF^M-^;X~9KU%{T# z5Vq>MsKCad#RpMK5kYmh0r{A{d}+WBQEUAbD&StMliG)%GCL6!;0z=q3A4y6m^G*w zyy)DAitq$#Z~POLnI!9_b|@;)amXbz9rb)8YR#WO1^5i=t=faS?>*FnE?|b| zeUpV+qY0=RX5#G_cI{822Hb%b|KQp`L2b5ga5NUPUg~Eqs^4bRMA}gO?Q|Z;VT^CC zQqcREN}iO;a-=Ua7uCUXREHbg^;c0TJci21-%&I4(YpdqNA**RJ*h@*;zc+BH=r`q zjtQmYbqY%H2dD=xqEgw5sMKK|Dv(LoGc#9jcD6Zppq@L7y6-e9W8JPkkd34Mik;O( z{!~>=dfQuTcY~aY|{R64XR$Ts?%kKYba|^K(qNvB_|+VnL5=a2ez+g|;yc(M zk6~~82$S#=?1LAO3?gp+s>W*k0j@>OybIX|#y8dLxD2bP z*Wu6bSEwaR=i$5Y5zNL!8wI6$J1WI{-G$RQlzO)_op(!-kHrVD9-qRUsF~a~jqKn| z)MkDLbsn_4`YzOx9l%2D#PxdruTanoRHL3(BQStJ!6)!6 z=3{`UbpIOci@UKH51N;A? zWoK35J*fLuIbT8zd<1jwB64JyTV{GoT81Ri{1`KEJL&*>3ln+`Iw>esUDyXx>UbD4 zF$r@}naRUjaX4z`#i)!-!;x5zDYzB~;#O1!c3@xJjs5U|Yd>5^{uRkl8jA2^OvYPh zc{52xWneUN$;?8MVcMOSP^q8vUGJQD6cyOxn2yilK70i$FvO`-g)gCA$4?(7|Jrof zk9hCt9jFxl0(J1bgC)8VTQOy}cNDKdb#NJ#`XY9w0-S~lU^BL02P(5gbG`m%;aKWX zSKpSP@EaNq;iKsPp0^j?Mg?#REq;y4%+PsWy%>j3uSE@9k2Uxjmg6-{#nSJ4nW(}{ z>a$Uqh&b&I3Yu{jYM177s$^rCP8WYLxZ#Vmtd2f|mh?*t2Ij{?ElWc!^IJkoTEi`& zU`IG-L4Ns|F~PtX?}`n_?9GdIS!1ZlHn#>M;aFq1X`%JoWzm+$0@3JWc3C*yxMAGn zf=H>I6ARh@?I9kuvF1=ic)Kkg6sxyKDaL@l9Mtmj&2aUc{7hJv<%SVB$l zus;&BvBqd?BxnO6>yO2v4Pk$r8#G>NM`y)zzJ#688jIV-{&+)UPbUr0rlwFsJREJh zIYcZTr9T^P>bZV1<_h9p9FBPp#=;TCi>$E0mT2?;52n;q-weN%_?!HTLmjIoHxK;} DXvI2- delta 4143 zcmYM$dvwor9LMqZ7Hy_!ejB@4zGHqPxh%JtMN313RU;P3EM-S3m1y+Mx`?b?PZyUQ zoi0*3Y_cOd458E_`@@l27t&I6ILM`*FW=8O?fkaK=kxh}zn{;WX5J z@3`@570hM4n&co)o4z`7Ik6ph8wMBIBD-Kh1RKwlG7(CC2gqcZyeGw~|&u`m}YklRrG0%UG`#Es8z&ckHJ-$Qb+ z&8Q0PLsh6Ao8U#v#popJ&-PnBS82lGsLUp!&cG~8#SbuyHK-DwM3pd#)zr^K5A#uH zW;`mP*{Jz9pyt`-`oADC*tult&s-MEs+};5Y^M!JmAn*n78as1-;A1QKQf1%cKsLz zJ^Eo(=KWC#j6z*khFWm3^HcQb@9=3bhaE>P5W&W1kCITCowWAKmyxXBy>6XFLx*9EYmdOHO|!4ejj~RD?gcemyF%tLR}e>1YdbP!oss478Uq0)ODBfTB%u8hd3K=z_F+bO+r<~M_(m=mxgX!kJ^g;s0mM@0*U7B zp+GY5T4v57=M>a^3sBdsMpbNw>mNeRcitJ|An8nW2vdKLMjivos2B;}reR}Th6-#I zYQkNpg^r>Yx`@gop0}0yT~OB#Mh_>V4tE7AfEB1M`2w}xflTVJlAmTknT4pAF6@Y! z@Gj>#H$KDl-$Dhn4vE3OMlF2C_2YPHXrUg+?%FWad{eO_EiVxUn-`sG}OZVQI&ZZb=}Kud<81=FWtCbM?;aFM(s%q zM|la}gnHaIB5PPJ=HNf5E$T+pG;Jit;49b&=VN1Bf>HP(Ho(s?8mmwh+l+jC`-Q*X zFc6|H3gj?8h8M60j_19sK$fE_P>DLl2asK}-!UIUoz42-2-F#Q3$^!aF&4L@D!UIo zJclWI{+nk7k4YBlh9XoY9z&IGCf{{c+GH9e`nBHqbBGyDk^;RV#=6h)dUT^RNK5KO=l4B<4?n{FRce!FUYy3Z9BEYMwh$0TlJ3{(AnOVt_SmF_vL1@+jM&+~EI!Poqk?0$1Wr z*Dt*-*qZrR$M_K}#PyVcB3caP(pkwvEjSr$dH{xJzgDn2K653h3fZ1ZB-$*#tB$~71#n(`(1m3`j$;Yr?UWW z#^+EMypO}M28%I?6F3vgFdeU;u5URYc<~HG%~Ob4_<2mjg{Z{VqAL6?MqvtBHPrLp ziiQqdTlBC8s^lY3m05;uaRVx_qu2_sU`zA{29M+Ics>0xQ~>4Z;hRVfR*gE0|Dpnl zAH-Q;ed|O+kIgVtsTQG!)yO%s1K0+e6TZwvEnJK#SdP3RY#C;1phhhf~r7YY=i?b z1`FNz7>uJo9>e(T5b7UGV>tuLai2XaFW%}!Id}?N8@Fmh7Lo~@Zf?e=+R${s?6uEza5*={}r|H zCFDu6LH7s$*v!YK^mk)C9>hfa3ss4z5rKVC3Hz9UahqspPxqpYEh$+T5ua3<6!&CI U6JTk--)RFu6KFrf36M5q5uE@ diff --git a/tabcmd/locales/en/tabcmd_messages_en.properties b/tabcmd/locales/en/tabcmd_messages_en.properties index e5274230..88c40483 100644 --- a/tabcmd/locales/en/tabcmd_messages_en.properties +++ b/tabcmd/locales/en/tabcmd_messages_en.properties @@ -75,9 +75,10 @@ logout.short_description=Sign out from the server publish.description=Publish a workbook, data source, or extract to the server publish.errors.unexpected_server_response=Unexpected response from the server: {0} publish.errors.server_resource_not_found=The resource you specified does not exist, or you do not have permission to see it. Check your project name and permissions +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Append extract file to existing data source publish.options.db-password=Database password for all data sources -publish.options.db-server=Server address of the database to associate with the embedded connection credentials. Required when using --db-username or --oauth-username to publish a workbook. +publish.options.db-server=Server address of the database to associate with the embedded connection credentials. Required when using --db-username or --oauth-username to publish a workbook. Must match the connection server stored in the workbook; a mismatch silently drops the embedded credentials. publish.options.db-username=Database username for all data sources 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 diff --git a/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo index 8929f104fbb80f43797ea57afc70272e3cb6ebac..c50a872123a84149445af5b73fb3b33dd40d9707 100644 GIT binary patch delta 760 zcmXZaOGs346vy$Opu!-S;*^6qIi@5&vchNiXiP^N2qQ#=L}G9vl5mgX!HyGfOgRVTB(Y$A?H!G!*eFFpobNZ{QqG zcYF7g_0TrPgJ>=Kh$(wsO9aDAL?3$}T1M;XSF}?9MB1f)XbF`@C7yx$F@&>NifgD? hJf7Uo4XmH$>{jGDp_t<&MqbC_iO~1O^>p3I)pKSGX}JIZ delta 758 zcmXZaOGs2<7{>8Oj3f-ZsSS>o(WDW(Sd4ea8XI-0g(4c%B4U^kET};SFQ9NXx=?fx z0|nw@kX$JuxCnwaZd@oKE?lW#dD)4(T>5`Ku72QvA*k;2nWHq=AgpqsIhs~JA4%|a);8CO7KmzZup2GWf9~R@<<@KY>btZ?0*e}C0 z#_$$i2|ChEiu@o8^y3YDh`AWVBJ9EiOyFJg(p5eNuo7RRH86lhIEyj-g(Fz}j5Kiu zA7I6EQotUE;wr@?T6AC0i>v6tJ?zB)ScZ|1#7F59+H><*f{R#y8^|HseDi6uoP66ZnSftbgNo zoM?B?DUC=~tlyxGXdLJ4_xeHco{h*$_eJw)GyRDc^*S;x{X=W0%M3*nTUOi#uL8i%HP0g-Z_CwXOaK_ diff --git a/tabcmd/locales/pt/tabcmd_messages_pt.properties b/tabcmd/locales/pt/tabcmd_messages_pt.properties index c9dbfddd..ffccf710 100644 --- a/tabcmd/locales/pt/tabcmd_messages_pt.properties +++ b/tabcmd/locales/pt/tabcmd_messages_pt.properties @@ -77,7 +77,7 @@ publish.errors.unexpected_server_response=Resposta inesperada do servidor: {0} publish.errors.server_resource_not_found=O recurso especificado não existe ou você não tem permissão para vê-lo. Verifique o nome e as permissões do projeto publish.options.append=Anexe o arquivo de extração à fonte de dados existente publish.options.db-password=Senha do banco de dados para todas as fontes de dados -publish.options.db-server=Endereço do servidor do banco de dado associado as credenciais. Obrigatório ao usar --db-username ou --oauth-username. +publish.options.db-server=Endereço do servidor do banco de dados associado às credenciais. Obrigatório ao usar --db-username ou --oauth-username. publish.options.db-username=Nome de usuário do banco de dados para todas as fontes de dados publish.options.encrypt_extracts=Criptografar extrações no servidor publish.options.name=O nome da pasta de trabalho/fonte de dados no servidor. Se omitido, a pasta de trabalho/fonte de dados será nomeado de acordo com nome de arquivo, sem a extensão twb(x), tds(x) ou tde. Publicar um arquivo .tde criará uma fonte de dados diff --git a/tests/commands/test_publish_command.py b/tests/commands/test_publish_command.py index df4b7115..5c54bc6e 100644 --- a/tests/commands/test_publish_command.py +++ b/tests/commands/test_publish_command.py @@ -72,7 +72,7 @@ def test_publish_with_creds(self, mock_path, mock_glob, mock_session): self.assertEqual(len(connections), 1) self.assertEqual(connections[0].server_address, "db.example.com") - def test_publish_with_creds_no_db_server(self, mock_path, mock_glob, mock_session): + def test_publish_with_db_username_missing_db_server_exits(self, mock_path, mock_glob, mock_session): set_up_mock_server(mock_session) mock_path = set_up_mock_path(mock_path) @@ -87,7 +87,7 @@ def test_publish_with_creds_no_db_server(self, mock_path, mock_glob, mock_sessio mock_args.tabbed = True mock_args.db_username = "username" - mock_args.db_password = "oauth_u" + mock_args.db_password = "password" mock_args.db_server = None mock_args.save_db_password = True mock_args.oauth_username = None @@ -97,13 +97,111 @@ def test_publish_with_creds_no_db_server(self, mock_path, mock_glob, mock_sessio mock_args.thumbnail_group = None mock_args.skip_connection_check = False + with self.assertRaises(SystemExit): + PublishCommand.run_command(mock_args) + mock_session.internal_server.workbooks.publish.assert_not_called() + + def test_publish_with_oauth_username_missing_db_server_exits(self, mock_path, mock_glob, mock_session): + set_up_mock_server(mock_session) + mock_path = set_up_mock_path(mock_path) + + mock_args.overwrite = False + mock_args.append = True + mock_args.replace = False + + mock_args.filename = "existing_file.twbx" + mock_args.project_name = "project-name" + mock_args.parent_project_path = "projects" + mock_args.name = "" + mock_args.tabbed = True + + mock_args.db_username = None + mock_args.db_password = None + mock_args.db_server = None + mock_args.save_db_password = False + mock_args.oauth_username = "oauth_user" + mock_args.save_oauth = True + mock_args.embed = False + + mock_args.thumbnail_username = None + mock_args.thumbnail_group = None + mock_args.skip_connection_check = False + + with self.assertRaises(SystemExit): + PublishCommand.run_command(mock_args) + mock_session.internal_server.workbooks.publish.assert_not_called() + + def test_publish_with_oauth_creds(self, mock_path, mock_glob, mock_session): + set_up_mock_server(mock_session) + mock_path = set_up_mock_path(mock_path) + + mock_args.overwrite = False + mock_args.append = True + mock_args.replace = False + + mock_args.filename = "existing_file.twbx" + mock_args.project_name = "project-name" + mock_args.parent_project_path = "projects" + mock_args.name = "" + mock_args.tabbed = True + + mock_args.db_username = None + mock_args.db_password = None + mock_args.save_db_password = False + mock_args.oauth_username = "oauth_user" + mock_args.save_oauth = True + mock_args.db_server = "db.example.com" + mock_args.embed = False + + mock_args.thumbnail_username = None + mock_args.thumbnail_group = None + mock_args.skip_connection_check = False + PublishCommand.run_command(mock_args) mock_session.internal_server.workbooks.publish.assert_called() call_kwargs = mock_session.internal_server.workbooks.publish.call_args.kwargs connections = call_kwargs["connections"] self.assertEqual(len(connections), 1) - self.assertIsNone(connections[0].server_address) + self.assertEqual(connections[0].server_address, "db.example.com") + + def test_publish_datasource_with_db_username_no_db_server(self, mock_path, mock_glob, mock_session): + # Datasource publishes send credentials via _add_credentials_element on the TSC side, + # which does not require server_address. --db-server must not be required here. + set_up_mock_server(mock_session) + # set_up_mock_server only wires .workbooks on the mocked server (TSC.Server class-spec + # doesn't expose instance attributes from __init__); wire .datasources by hand. + mock_session.internal_server.datasources = mock.MagicMock() + mock_path = set_up_mock_path(mock_path) + # set_up_mock_path hardcodes splitext -> [_, 'twbx']; override so extension routing + # actually sees a datasource here. + mock_path.splitext = lambda x: ["file", "tdsx"] + + mock_args.overwrite = False + mock_args.append = True + mock_args.replace = False + + mock_args.filename = "existing_file.tdsx" + mock_args.project_name = "project-name" + mock_args.parent_project_path = "projects" + mock_args.name = "" + mock_args.tabbed = True + + mock_args.db_username = "username" + mock_args.db_password = "password" + mock_args.db_server = None + mock_args.save_db_password = True + mock_args.oauth_username = None + mock_args.embed = False + mock_args.use_tableau_bridge = False + + mock_args.thumbnail_username = None + mock_args.thumbnail_group = None + mock_args.skip_connection_check = False + + PublishCommand.run_command(mock_args) + mock_session.internal_server.datasources.publish.assert_called() + mock_session.internal_server.workbooks.publish.assert_not_called() def test_get_files_to_publish_twbx(self, mock_path, mock_glob, mock_session): set_up_mock_server(mock_session) diff --git a/tests/e2e/online_tests.py b/tests/e2e/online_tests.py index 741af663..ed631e0a 100644 --- a/tests/e2e/online_tests.py +++ b/tests/e2e/online_tests.py @@ -75,6 +75,8 @@ def get_publishable_name(file_value: str) -> str: TDS_FILE_LIVE = "live_mysql.tds" TWB_FILE_WITH_EMBEDDED_CONNECTION = "EmbeddedCredentials.twb" + # server_address baked into the workbook's element. + TWB_FILE_EMBEDDED_CONNECTION_SERVER = "see-internal-slack" USERS_DETAILS_FILE = "detailed_users.csv" USERNAMES_FILE = "usernames.csv" @@ -142,7 +144,9 @@ def _publish_args(file, name, optional_args=None): return arguments @staticmethod - def _publish_creds_args(arguments, db_user=None, db_pass=None, db_save=None, oauth_user=None, oauth_save=None): + def _publish_creds_args( + arguments, db_user=None, db_pass=None, db_save=None, oauth_user=None, oauth_save=None, db_server=None + ): if db_user: arguments.append("--db-username") arguments.append(db_user) @@ -156,6 +160,9 @@ def _publish_creds_args(arguments, db_user=None, db_pass=None, db_save=None, oau arguments.append(oauth_user) if oauth_save: arguments.append("--save-oauth") + if db_server: + arguments.append("--db-server") + arguments.append(db_server) return arguments @staticmethod @@ -468,14 +475,50 @@ def test_view_get_png(self): @pytest.mark.order(11) def test_wb_publish_embedded(self): + # NOTE: This asserts only that publish did not crash. It does NOT verify + # that credentials actually embedded on the server side - a mismatched + # --db-server would still exit 0 while silently dropping the creds at + # TSC's request-factory boundary. A stronger assertion would populate + # connections post-publish and check embed_password=True. file = os.path.join("tests", "assets", TestAssets.TWB_FILE_WITH_EMBEDDED_CONNECTION) name_on_server = TestAssets.get_publishable_name(TestAssets.TWB_FILE_WITH_EMBEDDED_CONNECTION) arguments = TabcmdCall._publish_args(file, name_on_server) - arguments = TabcmdCall._publish_creds_args(arguments, database_user, database_password, True) + arguments = TabcmdCall._publish_creds_args( + arguments, + database_user, + database_password, + True, + db_server=TestAssets.TWB_FILE_EMBEDDED_CONNECTION_SERVER, + ) arguments.append("--tabbed") arguments.append("--skip-connection-check") _test_command(arguments) + @pytest.mark.order(11) + def test_wb_publish_embedded_missing_db_server_fails(self): + # Publish with --db-username but no --db-server must exit non-zero with our + # friendly message rather than a raw tableauserverclient traceback. The guard + # short-circuits before any real work, so throwaway credentials are safe here. + file = os.path.join("tests", "assets", TestAssets.TWB_FILE_WITH_EMBEDDED_CONNECTION) + name_on_server = TestAssets.get_publishable_name(TestAssets.TWB_FILE_WITH_EMBEDDED_CONNECTION) + "-no-server" + arguments = TabcmdCall._publish_args(file, name_on_server) + arguments = TabcmdCall._publish_creds_args(arguments, "placeholder_user", "placeholder_pass", True) + arguments.append("--tabbed") + arguments.append("--skip-connection-check") + + login_args = setup_e2e.get_login_args() + if login_args is None: + pytest.skip("No credentials available (credentials.py not found)") + calling_args = ["python", "-m", "tabcmd"] + arguments + login_args + [debug_log] + ["--no-certcheck"] + result = subprocess.run(calling_args, capture_output=True, text=True) + + assert result.returncode != 0, "expected non-zero exit for missing --db-server" + # Localized string OR the raw key (if .mo has not been regenerated yet) both signal our guard. + combined = (result.stdout or "") + (result.stderr or "") + assert "publish.errors.db_server_required" in combined or "--db-server is required" in combined, ( + "expected guard message in output; got:\n" + combined + ) + @pytest.mark.order(12) def test_publish_ds(self): file = os.path.join("tests", "assets", TestAssets.TDSX_FILE_WITH_EXTRACT) From f6edc3b09d45c0c7443ca962d325eb4de1edb5c7 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 18 Sep 2026 17:48:53 -0700 Subject: [PATCH 2/2] i18n: add English fallback for publish.errors.db_server_required in all locales Copilot flagged the new key as English-only, so users in de/es/fr/ga/ it/ja/ko/pt/sv/zh would see the raw msgid (`publish.errors.db_server_required`) instead of any actual message. Adds the English placeholder text to each of the 10 non-EN properties catalogs and regenerates the .mo bundles via `doit localize` so the rendered guidance appears in every locale until real translations arrive. Tightens the e2e assertion to require the rendered English text (dropping the raw-msgid fallback path) so localization regressions fail loudly instead of silently. --- tabcmd/locales/de/LC_MESSAGES/tabcmd.mo | Bin 19849 -> 20097 bytes .../locales/de/tabcmd_messages_de.properties | 1 + tabcmd/locales/es/LC_MESSAGES/tabcmd.mo | Bin 19590 -> 19838 bytes .../locales/es/tabcmd_messages_es.properties | 1 + tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo | Bin 20033 -> 20281 bytes .../locales/fr/tabcmd_messages_fr.properties | 1 + tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo | Bin 19877 -> 20125 bytes .../locales/ga/tabcmd_messages_ga.properties | 1 + tabcmd/locales/it/LC_MESSAGES/tabcmd.mo | Bin 19743 -> 19991 bytes .../locales/it/tabcmd_messages_it.properties | 1 + tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo | Bin 22297 -> 22545 bytes .../locales/ja/tabcmd_messages_ja.properties | 1 + tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo | Bin 20047 -> 20295 bytes .../locales/ko/tabcmd_messages_ko.properties | 1 + tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo | Bin 18898 -> 19146 bytes .../locales/pt/tabcmd_messages_pt.properties | 1 + tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo | Bin 18383 -> 18631 bytes .../locales/sv/tabcmd_messages_sv.properties | 1 + tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo | Bin 17094 -> 17342 bytes .../locales/zh/tabcmd_messages_zh.properties | 1 + tests/e2e/online_tests.py | 8 +++++--- 21 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo index 30f3641a567ff848658726defeab0404fb80aa38..1e8df0671b7b4f80ea5fefb3590de3d907a77455 100644 GIT binary patch delta 3324 zcmYM#3vA727{~FaCe)=at$STww_>y#(-|vjZk^R_%tqW!dk*Jl_0ZF5%;v;`l5Eke z5k|@oGRBhWut*qYvc_x)5sM5XtTD4?=CaKt`~Ld>%j7tp|NFl@@AE$IbN*esIblUr zLi}=a{q@GbBmD2k|N0Fy`v2c=P0Ttlyp7ECY=^CJ2zJIv=rD?HvBLKgY{mE( zw#4(O=W4N&S==6T;5d<*WY!n6Pyxf(4a?Et9^?T#jmdZuyWk_#1Ra~1J&XNO3z>-y zm!h8Ak`4P%x|^+4UJfy0{6l`I0ThY5W8Xpw!!_ViE6MN-bHe-q!!*pspuFF z_MPFMUxteR5i0S$*oyh>I}VibRa9nAP!qObpa%wEZyb#di%?s#4pr(s{`drvi(NuJ ze;bu>bAt55H0+MKsQDIQTme4dARTw2R(1}1;S*GVv=lFqp{VgB)E>_F&%f(if$cfJ z1GObbP!&3hs?aT@*!B-*VPY%l&th#fcPrpD)XEA`Jy4FRxC_(p1ZppDqDt71hcxbm z4o9PUW*%xmYfp4tAlCx>35-vcM{(V$W96&yHg)arX zk6Lju(KPOd4s(zkErMFea@2iQ$j1)({-F9hPSm1So=7&DpgU@>hM-n78&$d$s6DPg zhaaQvJC1zp24C9SC;s_VX4UoKs0HPt!&Rut#drA!Cz0*8Yp4wG`Qs$AQeuuThcBZ7 z&BVHuq4u^4mEfnS2@j(xc^Q?^9VDbRr%bXBl4IOPdIvTWl~F0OJywaT#BNk6kD(Gf zkJ|g&s1+v>U3;8{N^B6)_%rsLG zQ_pOihPk)_^;8)$K|1$|@e{n)9 zctGcrV^3zEi2IP;vB%gCJMbFQR*gm7KOOV29OvRK)XH-yAMIgtx*<4h>)i?mFaRUB=YT8U@)%9_x zCM`p~Vb}QM>bQU6B&w(mAKRMo)rDLvpu0 zs29!!B!oRgC74c!IUJAVVnvvYTQLRqW14>dr#MjNxA7YsNc!9HUsT{KmdB#)II^ww zCtkn~FM0{wL6yGCAl@Mf#KKjKb6(BtFnwtY@fBQ;77l;E$(_F4+dZiHiy>f0pjgyq;BcVYq7U^mPh z7)CBezCo>L?^{yX8 zRjgf(*VI#xcCiRza(N3buf%`U|`Q086Ou=6++&tS@H-aGy(s`*;vdViF%aXaHV zI1B61AT4n&Y72_7Ev`n|!?vInb`fbSYc|1Ka1LtT#C#4c5DZpcZPu>(?q{XfY?Efzpz2`qOh6?u}T;yUh<@5_Pdfq5R0arLH6# za=}1JAa6{7oBZqKTO5kT>Mn*B=7oa6P|)R*X{e|q5-5zhSU6f*7<73d7l_58`H?^g OHz=Eo>V$!7+W!aT#GBRt delta 3097 zcmYM#4NO&a7{~F4$WlNMlnZht4`iZ<1}Y*3Ns6RKVo7G^8&ehytq~fjtAnW{tu!@D zB{!p~RMH&Rwwzk2(PpKMrZOX(wOneZy=}gP+4tu;TkLv2=YL-Q|L6Za&$%w!8n&uF z%sm}<`$pq$KmYphud|Cr|Ns3EX_myW17q+ireN17vv^F$yRZNqoQ(-s>$?eiG2V@_ z*n)bl4U^4W`;7yK6OrA`24Mzj!fBX_HR#|LpZHJ3EYNcnLK@pr;qeVAQw(Rl~>q^9y`yu{Y;8pi0t& z%FrQHhT4%N+j-2xt3Am-o3(82)`UfB__*3ZJ-!+UnTOfmA+fiVf?Z3uN|L6=CD6dHR?)K+DQf~WhJQE&O!&DLEX0& z`B;cA)$|+x{CVH*te(R8EOc-RDuWAs-Sr$$X4{RdZHN7FJ1VeC=wLSnnkXG_?F?1Z zN>qT0Q31Vz%HS?kK%XO1ScmTwRKT&M5nW5?KoN~as$gZPOw^!Kxds*3d#IZ4Lru_* zs_oyXz`C#+jc#ek8kUQirxeu-m8d{ABac`JWA*-j%Yh#F5w){U|BIrh�&9fF2_FQWo(LIr#rwQvkyx<3!~RxL&K zz&ihYBW_~s{=&gQ4r4Ab#kx-7v`EhjF)i==2OrrT!-rV za2jMRW+8oOi*O8X#ff+ZC*UAvpRDVs4Sk6{@d7GS|DraQnNR-dH+zDEKDZoN%eLW1 z*p5M5O(#X-4vfHN)Px66P1TC3^*MYWBSw2A*n?``6Q~VbMrAI!z`I^pK>pPn<(zl} zkKuZp{eTzYpGY|^$Tqv-BqZB54U=&#YKKi&iLIE5`J_o3nS*y=J@&;0Ou|D*)vaT! z>rD__=rvz9KF@{eSca{r%naid2!@eXe1!4*BJcXAsD+#dz1QqX)LT)7@8V9Z#|h)j z*o&P-1)fHoPT)9~gQFY-DIjm2okula;zQnlM&q%8@l!YxBZ|GZq5@TdC76I~kn-CO z)XsiF+Q`3N9#UPg;aYT$P}iuch){iCb8_hV@Vegr0qD9+ AJOBUy diff --git a/tabcmd/locales/de/tabcmd_messages_de.properties b/tabcmd/locales/de/tabcmd_messages_de.properties index 0faed37e..01efd21f 100644 --- a/tabcmd/locales/de/tabcmd_messages_de.properties +++ b/tabcmd/locales/de/tabcmd_messages_de.properties @@ -75,6 +75,7 @@ logout.short_description=Vom Server abmelden publish.description=Arbeitsmappe, Datenquelle oder Extrakt auf dem Server veröffentlichen publish.errors.unexpected_server_response=Unerwartete Antwort vom Server: {0} publish.errors.server_resource_not_found=Die von Ihnen angegebene Ressource exisitiert nicht oder Sie haben nicht die Berechtigung, sie einzusehen. Prüfen Sie Ihren Projektnamen und Ihre Berechtigungen. +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Extraktdatei an vorhandene Datenquelle anfügen publish.options.db-password=Datenbankkennwort für alle Datenquellen publish.options.db-server=Serveradresse der Datenbank, die den eingebetteten Verbindungsanmeldeinformationen zugeordnet werden soll. Erforderlich bei Verwendung von --db-username oder --oauth-username zum Veröffentlichen einer Arbeitsmappe. diff --git a/tabcmd/locales/es/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/es/LC_MESSAGES/tabcmd.mo index aef0790b028f4d8629e57907ccabfa93bd5bfc9f..f0ec35241ef54be0a1bb83628b05fafb9e1f757f 100644 GIT binary patch delta 3324 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 diff --git a/tabcmd/locales/es/tabcmd_messages_es.properties b/tabcmd/locales/es/tabcmd_messages_es.properties index 78a747af..b9ff11fd 100644 --- a/tabcmd/locales/es/tabcmd_messages_es.properties +++ b/tabcmd/locales/es/tabcmd_messages_es.properties @@ -75,6 +75,7 @@ logout.short_description=Cerrar sesión en el servidor publish.description=Publicar un libro de trabajo, una fuente de datos o una extracción en el servidor publish.errors.unexpected_server_response=Respuesta inesperada del servidor: {0} publish.errors.server_resource_not_found=El recurso que ha especificado no existe o no tiene permiso para verlo. Compruebe el nombre del proyecto y sus permisos +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Adjuntar archivo de extracción a fuente de datos existente publish.options.db-password=Contraseña de base de datos para todas las fuentes de datos publish.options.db-server=Dirección del servidor de la base de datos que se asociará con las credenciales de conexión incrustadas. Obligatorio cuando se usa --db-username o --oauth-username para publicar un libro de trabajo. diff --git a/tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo index b421c6f1772785f1cadd51e472c29fe8b8c01ae9..ebd31ac007c51d5798048f5fa750f50b46d2807d 100644 GIT binary patch delta 3324 zcmYM#3rv+|9LMp8NkS^3co)P+4bTz{FL}dzcmst^qrBw~oTKLia_}6GS<{mRYBQB( zYMN+eSzel%D@~)RQ;W2te_Ad7t<4Jpcdy`JdP0+oC?& z9u>Kq5WUgxSI563{zbRc=>NZ8S{u`yVI#(4Y#U>GVOQ*gBQP2B(P9w0V2$fL*pcxu zY>($r&)vWt#zf3N99T{y#u@VvW}znZV{crA7WW_zm@}Aw4cHU!q83PMYs`a~iArQH zT3m{HZmWC#Fg6E*y;$GeaBsMu^fYlA_QMgVfV|iXYp^rEk6Nf6yW*cn3?{Cfvrr;h z#=~7_yXT)l&A$Z|_&)5&`sOSLiufujvL@7m?HK5Rf!G(b(PAlTOV*=Gy~iD&Kw>eM zP|r7_0*+^r6imfFn2TDk3?rIgEeGlN7Amu^F%6qg6Qp)<0vUxG=cD#;p?iLrYYlee z{7%%C)S)VL4ppI_kz$+Mn1!(&sXxh@Z0^>C1*ptQP(82;6LA-&;tAAVHlRuv!$TUU zp~Y-e&n!SC^a5)BL#TN^bH~?EiQno({S{#xX$`DI1W3Kb1y=`*OC$g%pk3l6=gchq&m5c0h4^AT6ZGJ>Wc*`Bf5tRb7d|4cc znrJRIXNKC_T2z30Q41bHRq`?_pg)i)O+00i{g4wyla%rcO7 zlbMFR{LE}r01HqHFGo$Z87&?_Rqz~Yp6ke`c`^l%%%r-1h-)5pXMGcJPgJ26*pBM< z4_z;zCW89fVhHMdE=DxrLJqW7EAUm^ zhrn|cnd1iI?Th{I0C2eQqY7|I1KmVSiFY0n8M3K^Mp|E zjg{{BJ$HN(Rk5294w$n!EUIGq65cq>!8N!RtFasDD)SvU5f7odz6n{=#Ir9JhoJ(R zg*yKds?kl!=4%`_JWIG8dl3Q&^8{a6M@$(?rVf zD2~BwtilWUIp*T)L!J9>Vk6@O>R*dyxYL~5QO`A?#Q`+XD9p!6tZ&wFpsu`t%P@*G zp2rAI#THr4o=-jB#AAM{VInwD>!o!Gv+nR$ay(jGK_% zGfCsAznUj+yt8N3xPbB7Scz>(XB)0W`p)!WAE=_4f$_K&^(L&vBs_~+paJJ%3~Bd9 zFH&5y3R~g{?1}Z+5vLg%I6;4yXntFIU>K_T=3p7F#V|Ix*F%%|?K0ko`B+5*J%Q(u zs+$bzuZonQD*QBV#RI6`%4J_Ey7@N3K_?EnWv&!VyjSO49*lAi7@On0u>K-k{9Xe<4`Qd?G0SP}^P1EmYC$5sYI z#f8COv8@c0`)%`c6+Bq#S>&_95GR73igJJYy>l7%v9Qm%&7HnHXv1Z`qQHWsw%qTt zUQfBFaH5Bs-0Q>}@`c0A7k!HgeO|B6Ym11~S6UwMl!R^AAFL?x+Crc8gu}t2fTx@r N6ivp#O@sG#`w#AMowxu1 delta 3097 zcmYM$4~*Ak9S87-NIc~L58;qQ;CIL$1%xzDB8iSvR3d5K4Kau`(P$?v!*;`FKbBD_ zBu+gmlxmh)7G>O;F=(sM)l6uZVh%CeGP5CzkqS*luQ$K%*6nw{*YiC4exK*_d_K?j zd$;{N1AhDPfch)L-`iLG?DTuK-*-<*@Bcq94=$xm_W+0SDBIc8T*^pJXup5Vl*tyjWdujG1_pZJx)eOhDai=UTS%5oV$7Jd1y)7|L;G zp}}V~7Cx_X0W;pi%zqaX_`@7w{jyUd5$|OpJH#xQPHvdMbJ@Wfmop`)GpXKO^|w(B zWjAyG0Vd!RoWxd>ox?fIde^g_3GUE1pMA{Ec5w<1F%z_&*$Cu(rr*ib@Y-s8RpnZa zHhw=-lC4aJe#c~JKP9=m!8ts7ru^G%>2P%>oX_lR8FL1DIff5%GPg0Qe2GcnJ5_&_ zn``2|!fPO<$lmnITFaftnBkN_VMk2bDs!(oVGSSPV@*XCz?=v;u z!A!89sqKH5z)rE6gI=c48f7*!Pd9TGdYC}IO}CVOw&eN$lSXd%8?&=_>77)@h|0^Z zoXZ4o5wq|@W}=%|W1Y$1_n3M5=~MRjN&p9$>j#=Vj%BW!mA>`MH5ysq7Uq&vr#$W}3p`Vezs3YIu+|uFW9I8%J+)e-@eprhUKA%d zmy_gmF;{RpckmMalaf>>I-yDVJSGEO9K@SBkgM3lTX`{WXXgC{hYzr!3G$yv2ind9 z9LKBJ&qREjc`QeWDjB+rc_lC70U`L5}iL$b{GM16;#SZsS58Vdm-d(#U(G+gJKuuKM>e z8QV!ymOXV1*(h&w9!Cpv1DA3gUuSl{%C_fo9dqiRrM1cd);LIg63`T8{CZ}GcQKFY zADE|WUp0P^EA{KsoS+|QJiy(Y?S!RPr^0uv%AxObfb=iqRb0tVZlkHn z5vH{57pOnyFq!)qb68(!ST9F3avEDMY}`1FhRSu!_y#5ek5>Mgsr3s?3g2Q%HTM0D z_rP_Ol=3Bhn2#~{zs>}7f&yg$Z6~!}%oW_i zEcl)|jh#+rcK&Hz%Db5o>|siEmemr#D&{Qoa|~amn9EUSzL^fl$-nG~1JQ02ahSU0X}X1ySvGMHpW%4!WzN81 z<_t7nUT@scDPK8sH}doB<7y64hfH`o4{-}W&W#GWga;^_<>D(F8M%!~@mIK++nKY~ ztv-@jUgb!RSLbB7qpq=DD4KFJo2{8;0~GKDG8C3H+m z7qhcXOy+hm89L5M9CNj=8&<6N;_92euzJSomG>VTdPaX!^R1`%Kh!#7T>qwy$4CDU Db!Sq9 diff --git a/tabcmd/locales/fr/tabcmd_messages_fr.properties b/tabcmd/locales/fr/tabcmd_messages_fr.properties index 32744778..c7b616a0 100644 --- a/tabcmd/locales/fr/tabcmd_messages_fr.properties +++ b/tabcmd/locales/fr/tabcmd_messages_fr.properties @@ -75,6 +75,7 @@ logout.short_description=Se déconnecter du serveur publish.description=Publier un classeur, une source de données ou un extrait sur le serveur publish.errors.unexpected_server_response=Réponse imprévue du serveur : {0} publish.errors.server_resource_not_found=La ressource spécifiée n’existe pas, ou vous n’êtes pas autorisé à la voir. Consultez le nom de votre projet et les autorisations. +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Ajout d’un fichier d’extrait à une source de données existante publish.options.db-password=Mot de passe de base de données pour toutes les sources de données. publish.options.db-server=Adresse du serveur de la base de données à associer aux informations d’identification de connexion intégrées. Obligatoire lors de l’utilisation de --db-username ou --oauth-username pour publier un classeur. diff --git a/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo index 3bbbf4c24096ba0f4c32eca6948424a9c25514fd..d6eb5def1413be61b0a56e0e840783d48434b6e6 100644 GIT binary patch delta 3313 zcmYk;dr*{B7{~ErI_3>8fPkQQyg{bmr4&WHhgVD;l}RFXmwkm5WRV3KySUkSsWFX_ z98$wlNAp%qI*2*psH07eHIGUTA5MbANw}ttou3V-S>UY^E~J5>fRl# zYHC`Au0*!kYWP#n-=6$!(^j+p{`}n0n0ThQunV^9WK187!|s@li8u!>1~3*YUH4-& z^HbOjFQJ~hj=hWtnZFoVE+j-4GYB(K0SmA%Za|9%kq68LjKmw*8}FkQ=-JtrhjAFH zkX*F53iaG}_xf>cNd)__zPaw+(4O)XI2i|GIw~O__Q6Vw!6T@J&SM<@isWD-x`r1@ zK+AlzYmR&U8C3jjsKgIrH0zs>87SjxsLYyC3wC9q2ZrNAn28pPQCso~s?`VG`57b^ z(};Th7AoN`1Q~!y*blQ%>y=TU3MVoaHJ^jp!+iJpbFP)x zgX?=xTT+ke&_z^-ZX(S#e_#f-i>Ch+Ycjc80kct+6`{_+228+xn1p9gdwB!Z!UuUs z^JKJ`i8?b&Q3bt(ieHC{^N~CM0af^&?(|<7Mo`ueOhS?~*{BvSL$&^8)S0M7Ugj!q z3V0V)aU{_+AB+~KAvqd9s*u&F`)ZJvsdN2Q{kL4Wj;g#J*=T`&sJ%)@RkR4zx;3ah zu0)G(qV7A5yi5~s+S_LLdIGEJ^YN&H^3dWsROdqb+`(C7yUll~4DYz}2(nUQmN$!I zP=Ru>r83ms)}RtRgj(C!rEcLk_-Kh^%P}QE}Fz&O{9=feVMSg6jSeuCpTKwZzmkOJm2&|a;<9k>IRC|00;4-VsE{0vpd(BUl!hfFpD&VyNvEiFT3UXKd!i~D&J7j+hq52<9^V9 z9AwjaeAvOrvt|KSV-;$lK@-BKcP_>WzR{)*btoGq z(to;VqDWUa%tSAiV*oGXW}G%T+@UW~_qXLc7K7tZ6)!*~R*5R$7%s%C*cV4~g)2G91?}ZmsM8w3flvj*P=UOdgC8JY1QR=z|BT>NoQ55En}zd`9L+B5 zk4>l!ccA|-;AE`84^dk;E;NJxG%$D`>+o$PC*$y4Qj3~U3-)9q6EO>SVrh%;WWNkGlXFl{&#-%V*AVujBJM zKAT4_PH~yvQxvqpf;)2{IqL-`g{TtB~X5J)QIJA F{{ZCvn*aa+ delta 3097 zcmYM$53H6|9S87ZMv)-$_g(|JyccgE1ZcqpZjpe%weYrE!Yl|-5EgnfGjL3oy)1%Z zIM`woLS)&>6iwsK71Od3TQ;+3Eixq0!Hg+))!h6u%syY(9suKx&!@G0iLBOF~yy`0vl85nSWDIeq{X2Q>MEH|*mJ#<5Pj6?Yx$M98Vfq{br z!&WAdF4lMhbKf_r@gMVSAZ)dMIZ|ElCNpufG$(K(6VPI|awD5~FSF1=UdR&^LwTE7 zXu#mc!V@YNGUGkW{C6^ee}}`ZUmn*;#D|&4`j`dN$qi$93ENrY3T8{{OsV%&{R0$3 z`2%zRF(%-5_yIPV>|)Mh*1L}NOmK(BWbR@zdy?bX$4t;PtP#j$ray<-!_QRXH&t%r z`;G5pw&WqELcd`ubd-u*PH`6B7^eP`E$yz(gq=)g%a}8;fur~>j^hEQl+Q6Ge7)*7 zySb*{&YYQRn1pU)=D&}b=jT=bFHGVmN2q@yeA~dKY?7YfN+(nDrOa8_M4$4IuS|4^ z$@F;De~UH!CbNpE%wQ7eVy^3AQ~zZASDK^zo7toOqDm%{n38ofd%J=) zev!Fu2YpJfuk7hF)%dB(^R3=${6nm95mUkSmGy6G*yi#GtzDk1`bU|-`dH)pbTZLI zp3RKe(;gRo<&Zr8f7HkgFEW{(p?6XlB`Pnw zatRZ_G-ly0W}-E$vCdTRd(1q&^eNB!N&v4i*Pmy`VN ziT=#o_%BZ3dCJhn4koh|%yoCsr##>*3;ezsKgk4gZmlssl9{ia_3Tx*#$H~}l=2se{am?Pa#}g7Njn z4GWCc46I=;*y3w8f5KFtk00aZUJ425D@;bcOh&ITflu_Z$lAaQenE z`8-!~C1<;74!_R?^b)h+MLJpV3VxKgGLP|3d4u)KagDWH=!7g{FF(!qy8826!esnw z&gCo2#FHHumzG7mg4>y`I?PY7#fi;Ut>q~0U=rJ3jh|rM!7T%vh&YYL%5r|2dzpo% z&TgFAC2ZDTU-j=|w&p(C{_-^U@GU0bU2_^QswbGkc!G*mM#&<7Uo=<(&b~Azhl1un9$8xS`G1sl;dw37W@JAfU-!fbI;{1B! zl#W=?$e@Fn=teH(Av*YFOsD_Fu$v#}&?`&%BtJ)MmiyVp(@cqny69`XiW~SWVn;#w~2-9y%7~0FzlC9jh`{ vl&xIGar|ncUb%Ypt?Sl&dEJzCYj?gmXmD@;fw!F3ySM2VExj$%>lgkH#^X>} diff --git a/tabcmd/locales/ga/tabcmd_messages_ga.properties b/tabcmd/locales/ga/tabcmd_messages_ga.properties index 320638ea..04bb515a 100644 --- a/tabcmd/locales/ga/tabcmd_messages_ga.properties +++ b/tabcmd/locales/ga/tabcmd_messages_ga.properties @@ -75,6 +75,7 @@ logout.short_description=6dd8-表:Sign out from the server|桜 publish.description=60cd-表:Publish a workbook, data source, or extract to the server|桜 publish.errors.unexpected_server_response=dbf6-表:Unexpected response from the server: {0}|桜 publish.errors.server_resource_not_found=b7e8-表:The resource you specified does not exist, or you do not have permission to see it. Check your project name and permissions|桜 +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=6393-表:Append extract file to existing data source|桜 publish.options.db-password=ab47-表:Database password for all data sources|桜 publish.options.db-server=3166-表:Server address of the database to associate with the embedded connection credentials. Required when using --db-username or --oauth-username to publish a workbook.|桜 diff --git a/tabcmd/locales/it/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/it/LC_MESSAGES/tabcmd.mo index 58c7dab155a1f9f468337150c865a750603d5e57..1443fa3421a4d85e61f6c38315b68813f5bd2d76 100644 GIT binary patch delta 3324 zcmYM!32anF9LMp06|{goXbYt*(4j~RO1UZm6}1XQip48H0v2@J-FBBA+wQg^7+D(; z#AvJ{BBywR8s$(i9t4RR5Q7Fp5;;s&MAT|DLQoO?{<@FYZ1*!W@4cD-{QtA>>D5Uq z*Cxe}Wpr6#{JqbAKmNO1q~8C3Kld=}OSc2lF!>U*f!GIoVKENCThL(yv$4%{BWBUx zi9PWk>bVox-z;wb&~Oa+Qp_&L38)D}n1@Tz;mgPawih$-BEmv3gAF&!``?Rwa^~ygMT0~SW0?gAs;&W z<2`44+vZbwCS4z*x99X&7_hhQl>Y(SOdQBc}V>N zbXbZyGu5aKEkn(}9W~Exum2rtYQc91GVE6W><~#QGty`4!+Go*0fsGJWEh#VjU`gz39{L|2Pdjki_bGAQQE-;mEtm zrXepsn~e&f8ny5u)I=-M;TBW|_oL=Hj(j>NQvd^)RQHeZyczqlzJ_(fI1iPXM$~inV=2CyNB;k%k;I8n z3^Vy7KxOg+A1R)36BV;v{?=r{W+`))X#WloW^JxpQBQKA@AQ3%*7>mCkF5Y>Uue|sU#s(CSE|2WN#s{+hHuh3x*}m z$V9w~eiVD)Yp6ip!D}$Sk4BV63ftL=_u*Gq#0g_AOXamV2a9nkK7~ruIuI<})8_#Ji1vq_JxPe#25Do{IU zLcM4nK$UJ2-hjK218?a?iJ$36yq10$YW`)Y+ONi;`u%UAaWeyl@guyP!Y{_(P=VaV z0Z|IqAe**BxC1YykgR1NBjvU~@igYK{Tj>}N6^@c3Sc)Xu;lTHvoi#XSl?#S&;$=* z6K?Yy%*m>vzY=u_|HgTE4biC9n^5DQBgwK%4u%eGDc*z&Q6<}h%1jm~*M}9DgLh+` zYxXz|MfMr$XY(s^z^x}IM711`&tntz#@=iv6ALjLufsH)g?cWGdH5La!Z%P0&oA+6 zk2+hMOUS<(M;Pdj$=8|HV?HjzCvYQXvQ6Fh9+G|g0lVRViHY$c$WPyqIg`vT!s(ccw@->EUWNBCK>6)SRHUCE2iLyG2Qj;pNpS-z5Fdq2O(Ly$EB%?| zw+1&NYgzh~#9^I|Ix}H>1Xp1z7L+A2yD3gX3$^1;%%EVa@BnJO{>H=v>u~`6efTVP z;2dl#PrPV;L6thk1shyrOJ!X+7791iIKP`8 ziPly|BDHRQxH;rHpKIa427i6fMWPHu{4LF)!t-Op-Hcc;aho@NbHv3OgH_?`1+F<1 zbOC>}zjCslo4o798x6){ofm`kmBBzD7;sfY8f<6|`|DyZ7K*gg1zcs&`D3w2RoLIm O4T@&?wlhTqIsXAH0GAyA delta 3097 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�mGa&v+0?-r^^C7NV|u5$EAfEJF=G z0Od&4Z7tT}0o2xvXCE|Pg5>7f3K}{*Ey$wn2*Xxa9WVu z>=Y`&KFqF_W}zxniX(8HKfVw1=>LF~dj6y6on&A!l9A;xyAoK$*9`m+&*4SCe~hSF zK{yAYEQ}T52Kr6Z{c%j7zPf)gax83@-#>$VEQ*7p1Om8$`E8XNm^jsJ1qN|0j^*fT zyb(3w@af(jPs3sK*P#OKM(y?QSc2Jw>@PN=?mLM(gjY~!B$`!mj;#`1U9g%4=gfkr z3(lj?MCL=@;}Tos?OhR$V7wY5uo*c%wjPu5ICf(fD(-2rNW<&M?pV@H{&&D~RAn~J zr2gA!e8Iq0od1Z~=Xe8W;{l!--PngtH0GoBbT%qLGpZ7;ScBhSD&_{fEtrRQ(%*Mv*nf^0x!VGa#TF#C z9YsA}Q5=X>*oNBs8SIZL(|}#L$EEQpjkim^7t72t?+`Yj65EeEupRXn)|PvJ<$gpx zHGg0{-asuNrovlUG3snI`29B2#Fx<)R8=isws7gPtYy{fuMdn4g-5;kgNg5-GF%!+7q zq;b^DG$+d`O`SBe(NxmBWs{}jUxj6(qmE%tp_Zxj{jskTv+U=b_j1njJmmxho#@tMEJi;n)euVM# zYq1SpK;3s0I~x-=4`^5pcw&s{gITBn{n!<&(BgLF26G1E@H%$E`=|*LTN%?E2cQy} zi53^3?t8~Q{slG$g2~KpuDTbrAUzG7ioGxs6_5{;u?E}Y9@Ipqu_HDhF_@Uvk%>HL z=?`|D;T~U%8h-;S@J}$F`OUX96!9fgWDijjwx**S24YXlMvJAWC0UIs^>(*^6p6*u zq3*9o1suyDJun5kVJ>RE`54v!t7xR*hp5cXV=6vG4Up0{639?geg4zRB=)rB6f=5wnc^y^4=G>%y zDq74&?U}i#gsM^F??;Vu%I#l9C4Rdd^;d*3r1b=*AiTO1~1dC-xy9^D|!> z@D3{DI7U;yFIpUf#ApJjM3$kh+k||~e%G_AzvaMHROZn{qY1j9)+!T~(QH)dmZR3V z1}$zuUH298F<1D~+CFrTdze+{hocfIK#Q-TDi_}7Hoiud+x&`(@V48JAu0uC`LZ|! zHPB3K%nY@*n@|DnKuvf6RmqE}fc`*+G_jOP_CjI|n^BR5nTd+10$Coj233iVQKhU! z1$F_o_VuWYV;Eg)oPr8$5VG;jbYxCbj2h>4)SlRc3g8TS^!#6;p&O!@T{pBvW!4XQ zH<>)-J1aDv^OYo{M1(SV%)_wH!C% zTGRytsONCZ#R6Q3eeo9RY3a<)RO$0jKO3{%zJsdVLTrL7P6Q9*CL!dDd|rj>m71VweQ#C`Vuh z22khU!y$MRb$@TZ6!WZsVn=$+`-1( z&N`{Id3Y38qxQ!0Y#>eaHg<^OvBl~1zhk55`ktAQJyV29^glp~XpUhY<~I#A6tSgl ze$2sQ+>I}yhiB$FT!Mvo3N7|$VV}iGr~ucY20no~co)avFtVGB)z}&9P_0PNWaNz%#7g?B@eOP~ir)dOK?TyCbd}*WR0h>J7T2Q!zJ$s60E@5->!ZZp zM2c*7Vl%vkUGVqpaAbGJQZG%=8r@UQ}Y6ko{bUo>mJ1$>^X1P8 zIb{o-vN>hWf{H+y5^j9qVUb2sx3<+~LcEHZW1w`tUmIu5gAsg}sD@uGe-?83MC|D5imUDrk L>9==$MpVLoHteA& delta 3096 zcmYM$4Xl?{9S88k2qiBFc;Vgz#Q(*3@p3g4c@+&)uYm}WF9apw(3Ebn3AQ^{_NTD< zGP5DOiZ2m%*J=UI!ORMBg)!|#%+_EGX_b=0jHui|Lh1AM|7_j;xu0{+|9Q^&{eI^> z&*jApeO`I8PyJ74e5j}R+2P+v|4#Hv@BcrqHI*`4_W%d+7~9x?Kq#OhDJOjjP$h?=cJglpo<66hnEB zS*U4nW8rfvXEWnn%>4H=fj`Ni)-O9W67j1{WQUmr)5#5^Ii8bP<6>q@>P)F0ulidl zhVn9V{{bf8lN`eqlbypE%z8^$&jfdCoW~v}vllpyhnWdlnj3+f$Mk11d$^z)zoT+B z&osV{*^(_xg?2I(+D}C;hd6`Bn$=&jWs<8iVJDN>=a@6l%@KTrW4VS z$@I@v|2S*q8NZM}eMh;3_7d`!zvmMxRIG>8-2=dzY@UP%=LXu9?xQ~o07iu%cnK6z?Ya)eoy5l zW}-hZHy+{nJWUxs%4tkyi<#>lq)+*gUs>Qc)%ZaskiNCX_;6;vNvvnD=4m{^rOb^d z`Ed?c*QH#<4nEI3C4Xm1Kf(z;g&jvk;nPwX!TDfe|2&m z;i)>axq+$3AzsKnUSG*zBByXRZ{s(3E#IP;%2ef3q_T)fY!xr&x0rc$vc`8fmBYr> z8;{vsueJ+X%lVZ9vJ$a6n*V&jmtQi#<@p~hji(LFqjOQ-XHNMT^-W1{;7&fuoQXv? zE(>gAYadnPLj65XRIa~ZTH~y&U=HJEDq8t16X*#h(DBntx!w9@u0|K1;}V{uj@R%W z-p1dv#;Km6E4h#fa04^(Zg%n{XS37BU&pmfpa(gSeQms?%Mf}3ODFU4D$6uR@Lr}g zz5F@%vc?`qeK3E_Y{`pk;$9Br>m12r+|FS$8(aA*GynTlf28s_Zevbe zf%`b<6CNF|X9DTCqLJYeCWEz{#qTl!A7UH(Da#i*j>+s{DrR|>r|<}~;86}|t9{J; z7hP3vWbg$8*^{quKA++m{)bthTYcZ)W1PpYdDySzZYok4`N_r$>a)y?Wd*lz6PI(L zsB_&*9K}=Z)2}(UuCZ0)2%V$SYvZ%G`dNVI&E9cWODa)A5 zzE9_@?BiHAdq%TW)AOv}e9J9gUU}<^mFKU#ecijK58l>)z@4XUd!prUqk6BNeCGcE Dv)fZH diff --git a/tabcmd/locales/ko/tabcmd_messages_ko.properties b/tabcmd/locales/ko/tabcmd_messages_ko.properties index 3a764340..eb9e8057 100644 --- a/tabcmd/locales/ko/tabcmd_messages_ko.properties +++ b/tabcmd/locales/ko/tabcmd_messages_ko.properties @@ -75,6 +75,7 @@ logout.short_description=서버에서 로그아웃 publish.description=서버에 통합 문서, 데이터 원본 또는 추출 게시 publish.errors.unexpected_server_response=서버의 예기치 않은 응답: {0} publish.errors.server_resource_not_found=지정한 리소스가 존재하지 않거나 사용자에게 리소스를 볼 수 있는 권한이 없습니다. 프로젝트 이름 및 사용 권한을 확인하십시오. +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=기존 데이터 원본에 추출 파일 추가 publish.options.db-password=모든 데이터 원본에 대한 데이터베이스 비밀번호 publish.options.db-server=포함된 연결 자격 증명과 연결할 데이터베이스의 서버 주소입니다. 워크북을 게시할 때 --db-username 또는 --oauth-username을 사용하는 경우 필수입니다. diff --git a/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo index c50a872123a84149445af5b73fb3b33dd40d9707..808044198898b3d9c7858b0d090fc91fb11c9e34 100644 GIT binary patch delta 3324 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 diff --git a/tabcmd/locales/pt/tabcmd_messages_pt.properties b/tabcmd/locales/pt/tabcmd_messages_pt.properties index ffccf710..edc2443b 100644 --- a/tabcmd/locales/pt/tabcmd_messages_pt.properties +++ b/tabcmd/locales/pt/tabcmd_messages_pt.properties @@ -75,6 +75,7 @@ logout.short_description=Fazer logoff do servidor publish.description=Publique uma pasta de trabalho, fonte de dados ou extração no servidor publish.errors.unexpected_server_response=Resposta inesperada do servidor: {0} publish.errors.server_resource_not_found=O recurso especificado não existe ou você não tem permissão para vê-lo. Verifique o nome e as permissões do projeto +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Anexe o arquivo de extração à fonte de dados existente publish.options.db-password=Senha do banco de dados para todas as fontes de dados publish.options.db-server=Endereço do servidor do banco de dados associado às credenciais. Obrigatório ao usar --db-username ou --oauth-username. diff --git a/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo index e0e5059ea77f429a4c97a6edac195c67fd9c36ba..a8f6cf7890ee4389d2870dff33cce2d928ed531d 100644 GIT binary patch delta 3324 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 diff --git a/tabcmd/locales/sv/tabcmd_messages_sv.properties b/tabcmd/locales/sv/tabcmd_messages_sv.properties index ccf9ea64..7af17ff2 100644 --- a/tabcmd/locales/sv/tabcmd_messages_sv.properties +++ b/tabcmd/locales/sv/tabcmd_messages_sv.properties @@ -75,6 +75,7 @@ logout.short_description=Logga ut från servern publish.description=Publicera en arbetsbok, en datakälla eller ett extrakt på servern publish.errors.unexpected_server_response=Oväntat svar från servern: {0} publish.errors.server_resource_not_found=Den resurs du angav finns inte, eller så har du inte behörighet att se den. Kontrollera ditt projektnamn och dina behörigheter +publish.errors.db_server_required=--db-server is required when publishing a workbook with --db-username or --oauth-username. Use --db-server to specify the database server address the embedded credentials should be associated with. publish.options.append=Lägg till extraktfil till befintlig datakälla publish.options.db-password=Databaslösenord för alla datakällor publish.options.db-server=Serveradress för databasen som ska associeras med de inbäddade anslutningsuppgifterna. Krävs när --db-username eller --oauth-username används för att publicera en arbetsbok. diff --git a/tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo index 68a359d940a7a0dc188b269b8318ac4d423e0bd4..ff3767c3a6a425f366c615f9104fbb8a8377ced6 100644 GIT binary patch delta 3324 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