Skip to content

Refactor formatters to standalone module and prepare v1.0.0 release - #1

Merged
cptfinch merged 3 commits into
mainfrom
claude/kq-package-evaluation-ws9gi4
Jul 7, 2026
Merged

cptfinch merged 3 commits into
mainfrom
claude/kq-package-evaluation-ws9gi4

Conversation

@cptfinch

@cptfinch cptfinch commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

This PR extracts output formatters into a dedicated Azure-free module, adds comprehensive test coverage, and prepares the project for its first public release on PyPI as kql-cli.

Key Changes

Code Organization

  • New module src/kq/formatters.py: Extracted format_table(), format_json(), and format_csv() from client.py into a standalone module with no Azure SDK dependencies, enabling unit testing in isolation
  • Re-export from client.py: Maintains backward compatibility by re-exporting formatters with explicit __all__
  • Test infrastructure: Added tests/conftest.py with FakeResultTable and FakeColumn fixtures to mock Azure Kusto result objects

Test Coverage

  • tests/test_formatters.py (77 lines): Comprehensive tests for all three formatters covering:
    • Table formatting with headers, row limits, and cell truncation
    • JSON serialization with datetime handling
    • CSV quoting and escaping (RFC 4180 compliance)
    • Edge cases (None results, wide cells, embedded newlines)
  • tests/test_config.py: Configuration resolution and query-path precedence
  • tests/test_registry.py: Query parameter rendering and validation

Release Preparation

  • Version bump: 0.1.0 → 1.0.0 in src/kq/__init__.py
  • Package metadata: Updated pyproject.toml:
    • Renamed package to kql-cli (PyPI name) while command remains kq
    • Added dynamic version reading from __init__.py
    • Expanded classifiers (Production/Stable, added Intended Audience)
    • Added ruff and build to dev dependencies
    • Configured pytest and ruff tool settings
  • CI/CD workflows:
    • .github/workflows/ci.yml: Lint + test matrix (Python 3.9–3.13)
    • .github/workflows/release.yml: Trusted Publishing (OIDC) to PyPI on version tags
  • Documentation:
    • CHANGELOG.md: First release notes with feature summary
    • LICENSE: MIT license file
    • README.md: Enhanced with badges, installation clarification, and development/release instructions
  • Project files: Added .gitignore refinements and tests/__init__.py

Code Quality

  • Linting: Integrated ruff with E, F, I, UP, B rule sets
  • Import organization: Sorted and grouped imports across modified files (cli.py, auth.py)
  • Constants: Extracted magic numbers (MAX_TABLE_ROWS=50, MAX_CELL_WIDTH=30) in formatters module

Notable Implementation Details

  • Formatters use duck typing (expect .columns, .rows_count, .to_dict()) rather than importing Azure types, enabling pure-Python testing
  • CSV formatter properly handles RFC 4180 quoting: commas, quotes, and newlines trigger quoting; embedded quotes are doubled
  • Table formatter truncates wide cells to 30 chars with ellipsis and notes remaining rows when exceeding max_rows limit
  • JSON formatter uses isoformat() for datetime serialization via a custom default handler

https://claude.ai/code/session_01B777V3WPGhuCdFuZiHYds4

Turn the tool into a polished, publishable package with tests and CI/CD.

Packaging:
- Rename PyPI distribution to `kql-cli` (the `kq` name is taken on PyPI by
  an unrelated project); the installed command stays `kq`.
- Add a real LICENSE file and fix placeholder author metadata.
- Single-source the version from src/kq/__init__.py via hatch dynamic version.
- Bump to 1.0.0; drop the redundant License classifier now that the SPDX
  license expression is used.
- Anchor the .gitignore `queries/` rule to the repo root so it no longer
  excludes the bundled src/kq/queries package data from builds.

Code:
- Extract output formatters into an Azure-free `formatters` module so they
  are unit-testable without the Kusto SDK; client re-exports for compat.
- De-duplicate the repeated "no cluster/database" CLI messages into constants.

Tests & CI/CD:
- Add a pytest suite covering formatters, query rendering, and config
  precedence (21 tests).
- Add GitHub Actions CI (ruff lint + pytest on Python 3.9-3.13 + build check).
- Add a tag-triggered release workflow that publishes to PyPI via Trusted
  Publishing (OIDC, no stored tokens).

Docs:
- README: fix the install command, add CI/PyPI/license badges, document the
  package-vs-command naming, and add development + releasing sections.
- Add CHANGELOG.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B777V3WPGhuCdFuZiHYds4

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request prepares the repository for its first public release (v1.0.0) under the package name kql-cli. Key changes include refactoring the output formatters into a dedicated, Azure-free module (src/kq/formatters.py) to enable isolated unit testing, adding a comprehensive test suite, and updating project metadata, documentation, and CI configurations. Feedback is provided on the manual CSV formatting implementation in src/kq/formatters.py, recommending the use of Python's built-in csv module to robustly handle edge cases like double quotes in headers and carriage returns.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/kq/formatters.py Outdated
claude added 2 commits July 7, 2026 09:53
Address review feedback on src/kq/formatters.py: the hand-rolled CSV writer
had two RFC 4180 correctness gaps — a double quote inside a column header was
emitted unescaped, and a cell containing a bare carriage return (\r without
\n) was not quoted. Delegate to the stdlib csv module, which handles every
quoting edge case and is well optimized.

Output shape is preserved: headers stay fully quoted (QUOTE_ALL), row cells
use minimal quoting, and there is no trailing newline. Add tests for the two
fixed edge cases plus the no-trailing-newline contract.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B777V3WPGhuCdFuZiHYds4
The 3.9/3.10 CI jobs failed on test_csv_quotes_bare_carriage_return: Python
< 3.11's csv.writer does not quote a field containing a bare "\r" when the
line terminator is "\n" (it only quotes characters that appear in the line
terminator), whereas 3.11+ always quotes "\r"/"\n".

Rather than emit CRLF (which would regress the tool's LF output), escalate a
row to QUOTE_ALL when any cell contains "\r". CSV output is now RFC 4180
correct and byte-identical across all supported Python versions, while plain
rows keep minimal quoting and LF line endings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B777V3WPGhuCdFuZiHYds4
@cptfinch
cptfinch merged commit bd6654b into main Jul 7, 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.

2 participants