$ show lucassabreu/clockify-cli
This is a well-crafted Go CLI application for interacting with the Clockify time-tracking API. It provides a comprehensive set of commands for managing time entries, projects, tasks, clients, tags, workspaces, and users. The architecture follows the GitHub CLI pattern with Cobra commands, Viper configuration, and dependency injection via a Factory interface. The application supports both interactive and non-interactive modes, multiple output formats (table, JSON, CSV, Markdown, Go templates), and name-to-ID resolution for convenience. Key features include a step-pipeline pattern for composable time entry modifications, a generic pagination helper for API list endpoints, and a search package with approximate matching. The codebase is well-tested with extensive unit tests using generated mocks, and the project is actively maintained with a robust CI/CD pipeline (GoReleaser, GitHub Actions, Netlify docs site).
The LLM identified 6 files worth highlighting for reuse:
Implements a pipeline of Step functions that sequentially modify a TimeEntryDTO. Each step is a function that takes a context and the current DTO and returns a modified DTO or error. The Do function orchestrates these steps, supporting interactive prompts, flag-based fill, validation, and closing logic. This pattern cleanly separates concerns and allows easy composition of behaviors (e.g., fill with flags then validate then interactively edit). Highly reusable for any CLI command that requires multi-step data collection.
Provides the complete Clockify API client with generic pagination via `paginate[K any]`, which supports requesting all pages or a specific page/limit. Implements token-bucket rate limiting (50 requests/second) using a buffered channel. All API methods consistently use error wrapping with `defer wrapError`, and custom error types (EntityNotFound, InvalidIDError) implement Go 1.13 Unwrap for error chain inspection. The generic pagination is cleanly separated from API logic and could be extracted for any paginated REST API.
Implements a generic Find function that searches a slice of objects by name using both exact and approximate (case-insensitive, substring) matching. Returns clear error types: ErrNotFound when no match and ErrAmbiguous when multiple matches. The Approx function is reused across entity-specific search functions (project, tag, task, user, client). This pattern is reusable for any CLI that needs to resolve user-provided names to IDs with helpful error messages.
Provides parsing of relative time expressions (e.g., 'last monday', '2 hours ago', 'today') into absolute time.Time values, with timezone support from the config. Includes helpers for work-week day calculation and date range construction. The parsing is robust and handles various natural language patterns. This package is self-contained and could be reused in any time-tracking or scheduling application.
Implements the default table output for time entries using Go's text/tabwriter. Part of a consistent pattern across entity outputs (project, task, etc.) where each entity has a Default, JSON, CSV, Quiet, and Template printer. The printers accept an io.Writer and a slice of DTOs, following a clean interface. The Template printer allows custom Go templates, and the Quiet printer outputs only IDs for scripting. This output abstraction is reusable for any CLI that needs flexible formatting.
Defines a Config interface with methods for all configuration values (token, workspace, interactive mode, allow-name-for-id, timezone, etc.) and provides a concrete implementation using Viper. The interface allows easy mocking in tests. Includes methods to load from file, save, and manage API tokens. The clean separation between config definition and storage backend makes this reusable for any CLI that needs persistent configuration.