Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,48 @@ go build -o tmpo .
./tmpo --help
```

### Development Mode

To prevent corrupting your real tmpo data during development, use the `TMPO_DEV` environment variable:

```bash
# Enable development mode (uses ~/.tmpo-dev/ instead of ~/.tmpo/)
export TMPO_DEV=1

# Now all commands use the development database
./tmpo start "Testing new feature"
./tmpo status
./tmpo stop
```

**Database Locations:**

- **Production mode** (default): `~/.tmpo/tmpo.db`
- **Development mode** (`TMPO_DEV=1`): `~/.tmpo-dev/tmpo.db`

> [!NOTE]
> The `export TMPO_DEV=1` command only applies to your **current terminal session**. When you close the terminal, it resets to production mode. This is intentional for safety - you must explicitly enable dev mode each time.

**Making it persistent (optional):**

If you prefer to always use dev mode, add it to your shell profile:

```bash
# For zsh (macOS default)
echo 'export TMPO_DEV=1' >> ~/.zshrc

# For bash
echo 'export TMPO_DEV=1' >> ~/.bashrc
```

Then restart your terminal or run `source ~/.zshrc` (or `source ~/.bashrc`).

**Benefits of development mode:**

- Your real time tracking data stays safe
- You can test database changes without risk
- You can easily clean up test data (`rm -rf ~/.tmpo-dev/`)

### Building with Version Information

To build with version information injected (useful for testing version display):
Expand Down Expand Up @@ -120,16 +162,22 @@ tmpo/
All user data is stored locally in:

```
~/.tmpo/
└── tmpo.db # SQLite database
~/.tmpo/ # Production (default)
└── tmpo.db

~/.tmpo-dev/ # Development (when TMPO_DEV=1)
└── tmpo.db
```

The database schema includes:

- Time entries (start/end times, project, description)
- Time entries (start/end times, project, description, hourly rate)
- Project metadata (derived from entries)
- Automatic indexing for fast queries

> [!NOTE]
> See [Development Mode](#development-mode) for information on using the development database during local development.

### How Project Detection Works

When a user runs `tmpo start`, the project name is detected in this priority order:
Expand Down
16 changes: 12 additions & 4 deletions internal/storage/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ type Database struct {

// Initialize ensures the on-disk storage for the application exists, opens the
// SQLite database, and returns a Database wrapper.
//
//
// Specifically, Initialize:
// - determines the current user's home directory,
// - creates the directory "$HOME/.tmpo" if it does not already exist,
// - opens (or creates) the SQLite database file "$HOME/.tmpo/tmpo.db",
// - checks the TMPO_DEV environment variable:
// - if TMPO_DEV is "1" or "true", uses "$HOME/.tmpo-dev" (development mode),
// - otherwise uses "$HOME/.tmpo" (production mode, the default),
// - creates the appropriate directory if it does not already exist,
// - opens (or creates) the SQLite database file "tmpo.db" in that directory,
// - ensures the time_entries table exists with the schema:
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// project_name TEXT NOT NULL,
Expand All @@ -42,12 +45,17 @@ type Database struct {
// responsible for closing the database when finished.
func Initialize() (*Database, error) {
homeDir, err := os.UserHomeDir()

if err != nil {
return nil, fmt.Errorf("failed to get home directory: %w", err)
}

// Switch out directory depending on build environment
tmpoDir := filepath.Join(homeDir, ".tmpo")
if devMode := os.Getenv("TMPO_DEV"); devMode == "1" || devMode == "true" {
tmpoDir = filepath.Join(homeDir, ".tmpo-dev")
}

if err := os.MkdirAll(tmpoDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create .tmpo directory: %w", err)
}
Expand Down