Skip to content

Add support for -c/--command option to execute commands and exit - #1542

Merged
j-bennet merged 11 commits into
dbcli:mainfrom
DiegoDAF:feature/command-option
Sep 9, 2026
Merged

Add support for -c/--command option to execute commands and exit#1542
j-bennet merged 11 commits into
dbcli:mainfrom
DiegoDAF:feature/command-option

Conversation

@DiegoDAF

@DiegoDAF DiegoDAF commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for the -c/--command option to pgcli, implementing psql-compatible behavior for executing SQL commands or internal commands from the command line.

This is PR #1530, cleaned.

Features

  • Single command execution: pgcli -c "SELECT 1"
  • Multiple commands: pgcli -c "SELECT 1" -c "SELECT 2"
  • Long form support: pgcli --command "SELECT 1"
  • Mixed usage: pgcli -c "cmd1" --command "cmd2"
  • Commands are executed sequentially
  • Pager is automatically disabled in command mode
  • Proper error handling and exit codes

Implementation Details

  • Added new click option -c/--command that accepts multiple values
  • Modified run_cli() to check for command mode and execute commands before entering interactive mode
  • Updated echo_via_pager() to disable pager when in command mode
  • Commands are executed using the existing handle_watch_command() method

Testing

Comprehensive BDD tests included covering:

  • Single command with -c flag
  • Single command with --command flag
  • Multiple statements in one command
  • Multiple -c options
  • Mixed -c and --command options
  • Error handling

Compatibility

This implementation follows psql's behavior and maintains backward compatibility with existing functionality.

Made with ❤️ and 🤖 Claude Code


Part of the feature list in discussion #1603: this is item 7 (-c/--command and -f/--file), the -c half. The -f half is #1543.

This commit adds support for the -c/--command option to pgcli, similar to
psql's behavior. Users can now execute SQL commands or internal commands
from the command line and exit immediately after execution.

Features:
- Single command execution: pgcli -c "SELECT 1"
- Multiple commands: pgcli -c "SELECT 1" -c "SELECT 2"
- Long form: pgcli --command "SELECT 1"
- Mixed usage: pgcli -c "cmd1" --command "cmd2"
- Commands are executed sequentially
- Pager is automatically disabled in command mode
- Proper error handling and exit codes

Tests included for all scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@DiegoDAF
DiegoDAF marked this pull request as ready for review December 5, 2025 18:22
Comment thread tests/features/steps/command_option.py Fixed
DiegoDAF added 2 commits July 20, 2026 12:23
Address review feedback: the step decoded cmd_output into `output` but never
used it (flagged by CodeQL as an unused local variable). It now asserts on the
\dt column headers, which are rendered whether or not any tables exist, so the
step verifies the special command actually produced its listing.

Also drop the unused `as e` bindings in the TimeoutExpired handlers (ruff F841)
and apply ruff format.
DiegoDAF and others added 4 commits August 27, 2026 10:25
behave's step registry is global, so now that -f landed and brought
tests/features/steps/file_option.py with it, the five steps this file
also defined ("we see the query result", "we see both query results",
"we see the command output", "we see an error message", "pgcli exits
successfully") raised AmbiguousStep and aborted the whole integration
run before any scenario executed.

Four of the five were byte-identical anyway; the fifth only differed in
a column name it looks for, and its assertion is an any() that already
matches on "SELECT". Dropping the duplicates here and reusing the ones
from file_option.py keeps every -c scenario passing.

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

j-bennet commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

@DiegoDAF There are conflicts to resolve.

@DiegoDAF

DiegoDAF commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Conflicts resolved, this is clean again and all checks are green.

Two things came out of the merge that are worth flagging, since -f landed in the meantime:

  • -c now runs one statement at a time through the same helper -f uses, so a \watch at the end of a -c block repeats only its own statement instead of the whole block.
  • -c and -f can now be given together and both run, the way psql does (psql -c ... -f file runs both). Before the merge -c exited first and the file was silently ignored.

Also dropped five behave steps this branch defined that file_option.py now defines too. behave keeps a single global step registry, so the duplicates raised AmbiguousStep and aborted the whole integration run before any scenario executed. Four of the five were byte-identical anyway.

DiegoDAF added a commit to DiegoDAF/pgcli.daf that referenced this pull request Sep 9, 2026
@j-bennet

j-bennet commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Sounds good, let's merge.

@j-bennet
j-bennet merged commit 924e7d4 into dbcli:main Sep 9, 2026
7 checks passed
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