Skip to content

Latest commit

 

History

History
125 lines (91 loc) · 5.04 KB

File metadata and controls

125 lines (91 loc) · 5.04 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Clockify CLI is a command-line tool for managing time entries and projects on Clockify from the terminal. It's written in Go and built on the Cobra framework for CLI command handling.

Key Technologies:

  • Go 1.24+ (module-based)
  • Cobra for CLI commands
  • Viper for configuration management
  • Survey for interactive prompts
  • GoReleaser for releases

Building and Development

Installation and Preparation

make deps-install       # Install Go dependencies

Building

make go-install         # Build and install dev version to $GOBIN
make dist              # Build all versions (darwin, linux, windows) → dist/
go run cmd/clockify-cli/main.go <args>  # Run directly from source

Testing

make test              # Run all tests with gotestsum
make test-watch        # Run tests with file watcher (fails fast)
make test-coverage     # Run tests with coverage report

Code Generation

make go-generate       # Regenerate mocks using mockery

Project Structure

  • cmd/ - Main executable packages

    • cmd/clockify-cli/main.go - Entry point (version info, error handling, Viper config binding)
    • cmd/release/ - Release automation
    • cmd/gendocs/ - Documentation generation
  • api/ - Clockify API client implementation

    • api/client.go - Main HTTP client for API calls
    • api/dto/ - Data transfer objects and request builders
  • pkg/cmd/ - CLI command implementation (follows directory-based routing)

    • Subdirectories for command groups: client/, config/, project/, tag/, task/, time-entry/, user/, version/, workspace/
    • Pattern: Command at pkg/cmd/<entity>/<subcommand>/<subcommand>.go
    • Each command has a NewCmd<SubCommand>() factory function returning *cobra.Command
  • pkg/output/ - Output formatters

    • Pattern: pkg/output/<entity>/<format>.go
    • Formats: table (default), json, quiet (ID only), template (Go template), csv
  • pkg/ - Shared packages

    • cmdutil/ - Command utilities, configuration constants (CONF_TOKEN, CONF_WORKSPACE, etc.)
    • cmdcomplutil/ - Completion utilities
    • outpututil/ - Shared output logic
    • timeentryhlp/, timehlp/ - Time entry and time helpers
    • ui/ - UI components (prompts, selections)
  • internal/ - Project-specific test utilities

    • testhlp/ - Test helpers
    • consoletest/ - Console testing utilities
    • mocks/ - Generated mocks

Command Architecture

Commands follow the Cobra pattern:

  1. Factory Functions: Each command is created via NewCmd<Name>(factory cmdutil.Factory) *cobra.Command
  2. Command Groups: Parent commands register subcommands (e.g., pkg/cmd/client/client.go registers its subcommands)
  3. Configuration: Commands access config through factory.Config() which reads from:
    • Environment variables (prefix: CLOCKIFY_)
    • Config file: ~/.config/clockify-cli/config.yaml or ~/.clockify-cli
    • CLI flags (with viper binding)

Adding a New Command:

  1. Create pkg/cmd/<entity>/<subcommand>/<subcommand>.go
  2. Implement NewCmd<SubCommand>(factory cmdutil.Factory) *cobra.Command
  3. Register in parent command's NewCmd<Entity>() function
  4. If first command for entity, create output formatters at pkg/output/<entity>/ for: table, json, quiet, template, csv

Key Patterns and Conventions

  • Configuration keys: Defined in pkg/cmdutil/ (e.g., CONF_TOKEN, CONF_WORKSPACE, CONF_USER_ID)
  • CLI Flags: Bound to Viper config via bindViper() in main.go, allowing env var and config file overrides
  • Environment Variables: Use CLOCKIFY_ prefix (e.g., CLOCKIFY_TOKEN, CLOCKIFY_WORKSPACE)
  • Output: Commands use output formatters from pkg/output/ to support multiple formats
  • Mocks: Generated by mockery during make go-generate — run this before testing if interfaces change

Testing

  • Framework: testify assertions + gotestsum runner
  • Test Discovery: **/*_test.go pattern
  • Mocks: internal/mocks/ — regenerate with make go-generate when interfaces change
  • Flags: Use -failfast in make test-watch (configured in Makefile)

Changelog

Every code change must be documented in CHANGELOG.md under the ## [Unreleased] section. Follow the Keep a Changelog format:

  • Added — for new features or functionality
  • Changed — for changes to existing functionality
  • Deprecated — for soon-to-be removed features
  • Removed — for removed features
  • Fixed — for bug fixes
  • Security — for security fixes

Each change is one bullet point written from the user's perspective (what changed, not implementation details). Do not commit changes without updating the changelog first.

Git Commits

Always ask the user for permission before creating any commit. Do not run git commit without explicit user approval — confirm what will be committed and ask for approval before proceeding.