Skip to content

Add non-interactive CLI support and pre-commit hooks#109

Closed
natefikru wants to merge 7 commits intomainfrom
nate/tvc-non-interactive
Closed

Add non-interactive CLI support and pre-commit hooks#109
natefikru wants to merge 7 commits intomainfrom
nate/tvc-non-interactive

Conversation

@natefikru
Copy link
Copy Markdown

@natefikru natefikru commented Mar 26, 2026

Summary

This PR adds non-interactive support to the TVC CLI while keeping the interface simple and predictable for both humans and autonomous agents.

Current behavior:

  • tvc has two global flags: --no-input and --quiet
  • commands that require interaction fail clearly under --no-input unless all required inputs are provided explicitly
  • tvc login supports a non-interactive setup flow with --org-id, --alias, and --api-env
  • tvc deploy approve uses --yes / -y for explicit non-interactive approval, with --dangerous-skip-interactive kept as a backward-compatible alias
  • interactive prompts and progress output go to stderr, while command results stay on stdout
  • a repo pre-commit hook is available via make install-hooks and runs cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test

The CLI surface in this branch is intentionally small:

  • no implicit approval in non-interactive mode
  • no partially implemented global JSON mode
  • no shared output abstraction beyond straightforward command-local handling
  • no extra login flag for skipping the API-key wait; --no-input is the non-interactive path

Test Plan

  • cargo test -p tvc
  • smoke tested tvc --help
  • smoke tested tvc --no-input login failure path
  • smoke tested tvc --no-input login --org-id ... through real network verification outside the sandbox
  • smoke tested tvc --no-input deploy approve ... failure without --yes
  • smoke tested tvc --no-input deploy approve ... --yes --skip-post
  • pre-commit hook passed on commit (cargo fmt --check, cargo clippy, and cargo test)

Pre-commit hooks:
- Add scripts/pre-commit hook (cargo fmt --check + clippy)
- Add make install-hooks and make check targets

Global flags infrastructure:
- Add GlobalOpts struct with --json, --no-input, --quiet flags
- Create Output module for stderr/stdout separation
- Thread GlobalOpts through all command signatures

Non-interactive login:
- Add --org-id, --alias, --api-env, --skip-api-key-wait flags
- Bail with clear error when --no-input is set without required args
- Move prompts and status messages to stderr

Rename --dangerous-skip-interactive to --yes/-y:
- Old flag preserved as hidden alias for backward compatibility
- --no-input also auto-skips interactive approval prompts

Tests (8 -> 16):
- Global flags recognition tests
- --yes, -y, backward compat tests for deploy approve
- --no-input skips interactive tests
- Non-interactive login tests
- Remove unused is_no_input() method and IsTerminal import from
  GlobalOpts. Non-interactive mode is controlled exclusively by the
  --no-input flag / TVC_NO_INPUT env var. No magic TTY detection.

- Move all interactive approve output (review sections, confirm
  prompts, approval status) to stderr. This keeps stdout clean for
  the approval JSON when piping output.

- Update tests to assert interactive content on stderr instead of
  stdout, and approval JSON on stdout.
Remove Output::result() method since no command in this PR uses it
(belongs in PR B where JSON output structs are added). Remove unused
serde import.

Add tests for all API environment values:
- login_api_env_dev, login_api_env_preprod, login_api_env_local
- login_api_env_invalid_rejected (clap validation)
- login_api_env_defaults_to_prod (omitted flag)
- login_quiet_suppresses_status (behavioral --quiet test)

Test count: 16 -> 22
@natefikru natefikru requested review from emostov and r-n-o March 26, 2026 21:53
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.

My opinion is we should keep this not checked in and add to gitignore if you like using it. Pre-commit hooks are a bit more of personal pref that I don't want to push on people

println!("========================================\n");
eprintln!("\n========================================");
eprintln!(" MANIFEST APPROVAL");
eprintln!("========================================\n");
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.

why stderr?

}

fn notice(message: &str) {
eprintln!("{message}");
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.

why wrap eprintln with this function but in other places use it directly?

@emostov
Copy link
Copy Markdown
Contributor

emostov commented Mar 27, 2026

Can we break this up into separate PRs by functionality

  • Non-interactive login
  • Non-interactive deploy approve
  • Remove hooks

@natefikru natefikru marked this pull request as draft March 30, 2026 14:49
@natefikru natefikru marked this pull request as draft March 30, 2026 14:49
@natefikru
Copy link
Copy Markdown
Author

Superseded by #111, #112, and #114 which split this into focused PRs.

@natefikru natefikru closed this Mar 31, 2026
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.

2 participants