Skip to content

fix: correct and standardize tabcmd 2 output messages to match tabcmd 1 - #432

Open
jacalata wants to merge 10 commits into
developmentfrom
jac/fix-output-messages
Open

jacalata wants to merge 10 commits into
developmentfrom
jac/fix-output-messages

Conversation

@jacalata

@jacalata jacalata commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Closes items 1-9 in #429 (item #10, logout redirect, is not applicable with PAT auth).

Motivation

#429 catalogued a set of output-message bugs where tabcmd 2 diverged from tabcmd 1. Fixing them one at a time would be nine small PRs; the changes all touch the same formatter or locale-key wiring, so a single PR is fine.

Behavior change

For users:

  • INFO log lines now render with tabcmd 1's ===== prefix by default
    (item Creategroup command  #8 in the issue). Users who prefer the plainer tabcmd 2 style can
    opt out with TABCMD_CLASSIC_OUTPUT=false.
  • listsites output shows human-readable SITEID instead of the site UUID.
  • deletegroup status message uses the group name, not a UUID.
  • createsiteusers error list shows human-readable messages, not the
    raw exception class name.
  • removeusers uses the correct locale key (removeusers.group).
  • Export save message and delete status message no longer render a
    double-space when content type is empty.
  • Login prints a Signing in... status line, matching tabcmd 1.
  • Saved X to 'Y' renders X = content name, Y = destination path
    (previously both slots rendered the destination).
  • Debug detail lines (Fetched user details, error-message detail)
    demoted from INFO to DEBUG.
  • The spurious logging: INFO line no longer appears before every
    command (type mismatch: namespace.logging_level is the string
    "INFO" but was compared against logging.INFO, integer 20; always
    truthy).

The ===== prefix is implemented via a single logger_config.py
formatter change so we don't have to edit every locale string.

Test plan

  • All 339 existing unit tests pass, plus 2 new save_to_file tests
    covering the content_name parameter
  • Manual: tabcmd login / tabcmd logout with default settings
    produce =====-prefixed output
  • Manual: TABCMD_CLASSIC_OUTPUT=false tabcmd login produces plain
    output without the prefix
  • tabcmd listsites shows human-readable SITEID
  • No logging: INFO line appears before command output

🤖 Generated with Claude Code

jacalata and others added 6 commits July 21, 2026 18:44
…esiteusers, removeusers

- listsites: show site content_url instead of internal UUID for SITEID
- deletegroup: log group name instead of UUID in delete status message
- export/save_to_file: pass filename as content name to fix double-space in "Saved  to '...'" message
- createsiteusers: append str(e) to error_list instead of e.__class__.__name__ so error details show readable messages
- removeusers: use new tabcmd.removeusers.group string key that includes the group name in the status message

Fixes #429

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ebug noise

- logger_config.py: add ===== prefix to INFO format so all action lines match tabcmd 1 style in one place
- session.py: remove hardcoded ===== from _print_server_info lines (now added by formatter); demote "Fetched user details from server" to debug
- constants.py: demote tabcmd.debug.error_message log call from info to debug so it no longer appears in normal output
- delete_command.py: default content_type to "workbook" in status message to fix double-space when type is undetected
- tabcmd_messages_en.properties: remove hardcoded ===== from tabcmd.listing.header (would double-prefix with formatter)

Closes remaining items from #429

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avoids the ===== prefix being applied to the version/help display.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Plain output is the default. Set TABCMD_CLASSIC_OUTPUT=true (or 1/yes) to
restore the ===== prefix on all INFO-level messages for backward compatibility
with tabcmd 1 output style.

Also moves the version banner in tabcmd_controller to print() so it is never
prefixed regardless of mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The condition compared logging_level string 'INFO' to the integer
logging.INFO (20), which was always True, causing the print to fire
on every invocation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
session.login string already existed; add logger.info call at the
start of _sign_in() to surface it as a distinct step after connecting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
tabcmd
   __main__.py121212 0%
   _version.py111111 0%
   tabcmd.py151515 0%
   version.py955 44%
tabcmd/commands
   commands.py101010 0%
   constants.py771818 77%
   server.py1351818 87%
tabcmd/commands/auth
   session.py3955050 87%
tabcmd/commands/datasources_and_workbooks
   datasources_and_workbooks_command.py1571818 89%
   datasources_workbooks_views_url_parser.py14255 96%
   delete_command.py611616 74%
   export_command.py1222525 80%
   get_url_command.py1274747 63%
   publish_command.py1252929 77%
   runschedule_command.py2177 67%
tabcmd/commands/extracts
   create_extracts_command.py4288 81%
   decrypt_extracts_command.py2722 93%
   delete_extracts_command.py3766 84%
   encrypt_extracts_command.py2722 93%
   extracts.py2022 90%
   reencrypt_extracts_command.py2722 93%
   refresh_extracts_command.py481010 79%
tabcmd/commands/group
   create_group_command.py2955 83%
   delete_group_command.py2722 93%
tabcmd/commands/project
   create_project_command.py4688 83%
   delete_project_command.py3544 89%
   publish_samples_command.py3044 87%
tabcmd/commands/site
   create_site_command.py3455 85%
   delete_site_command.py2722 93%
   edit_site_command.py3822 95%
   list_command.py771212 84%
   list_sites_command.py2922 93%
tabcmd/commands/user
   add_users_command.py2955 83%
   create_site_users.py581111 81%
   create_users_command.py5999 85%
   delete_site_users_command.py4355 88%
   user_data.py2223131 86%
tabcmd/execution
   _version.py222 0%
   global_options.py12688 94%
   localize.py661111 83%
   logger_config.py6266 90%
   tabcmd_controller.py4077 82%
TOTAL288045984% 

@bcantoni

Copy link
Copy Markdown
Contributor

@jacalata looks good - my only question, do we need tabcmd.removeusers.group added to the other language files too?

@jacalata

Copy link
Copy Markdown
Contributor Author

@jacalata looks good - my only question, do we need tabcmd.removeusers.group added to the other language files too?

good question. I thought we had a fallback, but we don't. I've implemented that now in #440

Two follow-up fixes for parity with tabcmd Classic output:

- save_to_file/save_to_data_file previously passed filename twice into
  the "Saved {0} to '{1}'" template, so both slots rendered the same
  path. Classic output was "Saved <content-name> to '<destination>'"
  where the two are distinct. Add a content_name parameter and thread
  export_item.name / get_url_item.name from all four callers.

- TABCMD_CLASSIC_OUTPUT default flipped to true. The stated goal of
  this PR is parity with tabcmd 1 output, and issue #429 item 8 lists
  the missing "=====" prefix as a bug. Users who prefer the plainer
  tabcmd 2 style can opt out with TABCMD_CLASSIC_OUTPUT=false.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Localization catalogs and delete/list output handling remain incomplete or incorrect.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 Medium severity · 1 Low severity

Open (4)
What changed in this PR

This PR standardizes tabcmd 2 output to match tabcmd 1, including classic prefixes, corrected identifiers, messages, logging levels, and export naming.

Changes:

  • Added configurable classic INFO formatting.
  • Corrected site, group, user, delete, login, and export messages.
  • Added export filename/content-name tests and localization updates.
File Description
tests/​commands/​test_geturl_utils.py Tests export success-message naming.
tabcmd/​locales/​en/​tabcmd_messages_en.properties Updates listing and remove-users messages.
tabcmd/​execution/​tabcmd_controller.py Removes spurious logging output.
tabcmd/​execution/​parent_parser.py Prints help directly.
tabcmd/​execution/​logger_config.py Adds configurable classic prefixes.
tabcmd/​commands/​user/​remove_users_command.py Uses group-specific message key.
tabcmd/​commands/​user/​create_site_users.py Reports readable exceptions.
tabcmd/​commands/​site/​list_sites_command.py Displays site content URLs.
tabcmd/​commands/​group/​delete_group_command.py Displays group names.
tabcmd/​commands/​datasources_and_workbooks/​get_url_command.py Passes content names to save helpers.
tabcmd/​commands/​datasources_and_workbooks/​export_command.py Tracks exported content names.
tabcmd/​commands/​datasources_and_workbooks/​delete_command.py Avoids empty delete content types.
tabcmd/​commands/​datasources_and_workbooks/​datasources_and_workbooks_command.py Supports content-aware save messages.
tabcmd/​commands/​constants.py Demotes error details to DEBUG.
tabcmd/​commands/​auth/​session.py Adjusts login and session output.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tabcmd/commands/datasources_and_workbooks/delete_command.py Outdated
Comment thread tabcmd/commands/datasources_and_workbooks/delete_command.py Outdated
tabcmd.refresh.options.bridge=Refresh datasource through Tableau Bridge
tabcmd.removeusers.help.group_name=The group to remove users from
tabcmd.removeusers.server=Removing users listed in {0} from the server...
tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''...
Comment thread tabcmd/locales/en/tabcmd_messages_en.properties Outdated
- delete_command.py: initialize item_to_delete before conditional;
  move delete.status log after item resolution so content_type/name
  are populated.
- dodo.py: fix NameError in uniquify_file - reference unique_lines
  (the sorted list actually printed) instead of undefined uniques.
- en properties: strip stray leading space in tabcmd.listing.header
  format string.
- locales: regenerated .mo/.properties for all languages.
Copilot AI review requested due to automatic review settings September 20, 2026 02:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Runtime gettext catalogs are not regenerated, so the locale output fixes are not active and may produce stale or raw-key messages.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Resolved since last review (3)

@bcantoni

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

…-messages

# Conflicts:
#	tabcmd/locales/de/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/en/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/es/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/it/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo
#	tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo

Co-authored-by: bcantoni <58372+bcantoni@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings October 14, 2026 05:40

Copilot AI commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merged development and resolved the gettext catalog conflicts by regenerating the catalogs from the merged locale sources. Merge commit: 7412ea1.

Copilot AI requested a review from bcantoni October 14, 2026 05:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Preserve classic INFO formatting for DEBUG configurations and add coverage for the formatter opt-out behavior.

2 open findings

🧠 Review effort: Lite

logging.ERROR: "%(asctime)s %(levelname)-5s:(%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s",
logging.WARN: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s",
logging.INFO: "%(message)-30s",
logging.INFO: _INFO_FORMAT,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jacalata please check this, I'm not sure the right answer

Co-authored-by: bcantoni <58372+bcantoni@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings October 14, 2026 05:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved moderate issues remain in localized error formatting, export content names, and logging behavior.

2 open findings

🧠 Review effort: Lite

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants