Skip to content

feat: extract shared atlassian-go package#12

Merged
rianjs merged 1 commit intomainfrom
feature/2-shared-atlassian-go
Jan 29, 2026
Merged

feat: extract shared atlassian-go package#12
rianjs merged 1 commit intomainfrom
feature/2-shared-atlassian-go

Conversation

@rianjs
Copy link
Copy Markdown
Contributor

@rianjs rianjs commented Jan 29, 2026

Summary

Create a shared Go module (github.com/open-cli-collective/atlassian-go) containing common code for both cfl and jtk CLIs.

Packages

Package Purpose Coverage
auth/ BasicAuthHeader() for Atlassian API authentication 100%
client/ HTTP client with Do/Get/Post/Put/Delete methods 93.6%
config/ GetEnvWithFallback() for environment variable precedence 100%
errors/ APIError struct, sentinel errors, ParseAPIError() 97.9%
view/ Output formatting (table/JSON/plain) with colored messages 93.4%

Overall test coverage: 95.1%

Changes

  • Add shared/ module with 5 packages
  • Update go.work to include shared module
  • Add CI jobs for shared module (build-test-shared, lint-shared)
  • Update Makefile with shared module targets

Test plan

  • go build ./shared/... succeeds
  • go test -race ./shared/... passes (all 71 tests)
  • golangci-lint run passes in shared/
  • Existing tool builds still work (make build)
  • Existing tool tests still pass (make test)

Closes #2

🤖 Generated with Claude Code

Create shared Go module (github.com/open-cli-collective/atlassian-go)
with common code for both cfl and jtk CLIs:

- auth/: BasicAuthHeader() for Atlassian API authentication
- client/: HTTP client with Do/Get/Post/Put/Delete methods
- config/: GetEnvWithFallback() for environment variable precedence
- errors/: APIError struct, sentinel errors, ParseAPIError()
- view/: Output formatting (table/JSON/plain) with colored messages

All packages have >80% test coverage (95.1% overall).

Closes #2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@rianjs
Copy link
Copy Markdown
Contributor Author

rianjs commented Jan 29, 2026

Test Coverage Assessment for PR #12

Summary

This PR introduces a new shared/ module with 5 packages. The test coverage is excellent overall at 95.1% as claimed. The tests are well-structured with table-driven patterns and appropriate edge case coverage.

Package-by-Package Analysis

auth/ - Authentication Utilities

Coverage: Excellent

  • BasicAuthHeader() is thoroughly tested with 4 test cases
  • Tests cover: standard credentials, empty email, empty token, special characters
  • Additional assertions verify output format and base64 validity
  • Verdict: No gaps identified

client/ - HTTP Client

Coverage: Very Good (93.6%)

  • All HTTP methods tested (GET, POST, PUT, DELETE)
  • Error handling tested for all common HTTP status codes (400, 401, 403, 404, 429, 500)
  • Verbose output mode tested
  • Context cancellation tested
  • Options configuration tested (timeout defaults, custom values)
  • Path normalization tested (leading slash handling)
  • Minor gap: No test for connection errors (DNS failures, network unreachable), but these are standard library behaviors. Acceptable.

config/ - Environment Variable Utilities

Coverage: Excellent (100%)

  • GetEnvWithFallback() tested with 4 cases: primary set, primary empty uses fallback, both empty, explicitly empty string
  • GetEnvWithDefault() tested with 3 cases: env set, env not set, env empty
  • Proper environment cleanup in tests
  • Verdict: No gaps identified

errors/ - Error Handling

Coverage: Very Good (97.9%)

  • APIError.UnmarshalJSON() tested for both Jira and Confluence error formats
  • APIError.Error() tested for all message types (message, errorMessages, field errors, error list, empty)
  • ParseAPIError() tested for all sentinel errors (401, 403, 404, 400, 429, 500, 502)
  • All Is* helper functions tested with direct errors and wrapped errors
  • Complex response formats tested (Jira with errorMessages + field errors, Confluence with message + errors array)
  • Verdict: Excellent coverage of error parsing logic

view/ - Output Formatting

Coverage: Good (93.4%)

  • All three formats tested (table, json, plain)
  • ValidateFormat() tested with valid and invalid inputs
  • Table() tested for all format types (dispatches to JSON/Plain correctly)
  • Message helpers tested (Success, Error, Warning, Info, Print, Println)
  • Truncate() tested with boundary conditions
  • SetOutput() and SetError() writer customization tested
  • Minor gap: The Render() method with FormatJSON bypasses Table() and uses jsonData directly - this is tested, but the interaction between the two paths could be clearer. Acceptable.

Test Quality Observations

Strengths:

  1. Consistent use of table-driven tests
  2. Proper test isolation (e.g., environment cleanup in config tests)
  3. httptest.Server used for HTTP client tests (no network dependencies)
  4. Edge cases covered (empty inputs, special characters, boundary conditions)
  5. Both Jira and Confluence API response formats handled and tested

No Critical Gaps Found

The test coverage is appropriate for library code that will be shared across CLI tools. The error handling is robust, and the happy/sad paths are covered.

Recommendations (Non-blocking)

  1. Consider adding a test for client.Do() when JSON marshaling of the request body fails (e.g., pass an unmarshallable type like chan int)
  2. The view package sets color.NoColor globally in New() - this could cause test interference in parallel tests, but it's a reasonable trade-off for this use case

Verdict

Approve from a test coverage perspective. The claimed 95.1% coverage is substantiated, and the tests cover the critical paths and edge cases that matter for shared library code.

@rianjs rianjs merged commit 3f89d8b into main Jan 29, 2026
7 checks passed
@rianjs rianjs deleted the feature/2-shared-atlassian-go branch January 29, 2026 12:44
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.

Phase 2: Extract shared atlassian-go package

1 participant