https://github.com/dominikbraun/timetrace
A simple CLI for tracking your working time.
https://github.com/dominikbraun/timetrace
cli hacktoberfest time-tracker time-tracking timetracker timetracking
Last synced: 7 months ago
JSON representation
A simple CLI for tracking your working time.
- Host: GitHub
- URL: https://github.com/dominikbraun/timetrace
- Owner: dominikbraun
- License: apache-2.0
- Created: 2021-05-11T19:17:24.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-06-28T03:43:49.000Z (over 1 year ago)
- Last Synced: 2025-05-13T07:58:22.128Z (7 months ago)
- Topics: cli, hacktoberfest, time-tracker, time-tracking, timetracker, timetracking
- Language: Go
- Homepage:
- Size: 5.07 MB
- Stars: 747
- Watchers: 10
- Forks: 80
- Open Issues: 56
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- awesome-time-tracking - timetrace - timetrace is a free and open-source CLI tool for tracking working time, offering simple and efficient time logging directly from the command line. ([Read more](/details/timetrace.md)) `open-source` `command-line` `personal-use` `simple` (Time Tracking CLI Tools)
- jimsghstars - dominikbraun/timetrace - A simple CLI for tracking your working time. (Go)
README
:alarm_clock: timetrace
> timetrace is a simple CLI for tracking your working time.

:fire: **New:** [Add tags for records](#start-tracking)
:fire: **New:** [Use decimal hours when displaying durations](#prefer-decimal-hours-for-status-and-reports)
:fire: **New:** [Restore records when restoring the associated project](#delete-a-project)
:fire: **New:** [Support for per-project configuration](#per-project-configuration)
---
- [Installation](#installation)
- [Homebrew](#homebrew)
- [Snap](#snap)
- [AUR](#aur)
- [Scoop](#scoop)
- [Docker](#docker)
- [Binary](#binary)
- [Usage example](#usage-example)
- [Project modules](#project-modules)
- [Shell integration](#shell-integration)
- [Starship](#starship)
- [Command reference](#command-reference)
- [Start tracking](#start-tracking)
- [Print the tracking status](#print-the-tracking-status)
- [Stop tracking](#stop-tracking)
- [Create a project](#create-a-project)
- [Create a record](#create-a-record)
- [Get a project](#get-a-project)
- [Get a record](#get-a-record)
- [List all projects](#list-all-projects)
- [List all records from a date](#list-all-records-from-a-date)
- [Edit a project](#edit-a-project)
- [Edit a record](#edit-a-record)
- [Delete a project](#delete-a-project)
- [Delete a record](#delete-a-record)
- [Generate a report `[beta]`](#generate-a-report-beta)
- [Print version information](#print-version-information)
- [Configuration](#configuration)
- [Prefer 12-hour clock for storing records](#prefer-12-hour-clock-for-storing-records)
- [Prefer decimal hours for status and reports](#prefer-decimal-hours-for-status-and-reports)
- [Set your preferred editor](#set-your-preferred-editor)
- [Configure defaults for projects](#configure-defaults-for-projects)
- [Credits](#credits)
---
## Installation
### Homebrew
```
brew tap dominikbraun/timetrace
brew install timetrace
```
### Snap
```
sudo snap install timetrace --edge --devmode
```
### AUR
```
yay -S timetrace-bin
```
### Scoop
```
scoop bucket add https://github.com/Br1ght0ne/scoop-bucket
scoop install timetrace
```
### Docker
The timetrace Docker image stores all data in the `/data` directory. To persist
this data on disk, you should create a bind mount or named volume like so:
```
docker container run -v my-volume:/data dominikbraun/timetrace version
```
### Binary
Download the [latest release](https://github.com/dominikbraun/timetrace/releases)
and extract the binary into a directory like `/usr/local/bin` or
`C:\Program Files\timetrace`. Make sure the directory is in the `PATH` variable.
## Usage example
First, create a project you're working for:
```
timetrace create project make-coffee
```
Once the project is created, you're able to track work on that project.
```
timetrace start make-coffee
```
You can obtain your currently worked time using `timetrace status`. When you've
finished your work, stop tracking:
```
timetrace stop
```
### Project modules
To refine what part of a project you're working on, timetrace supports _project modules_. These are the exact same thing
as normal projects, except that they have a key in the form `@`.
Creating a `grind-beans` module for the `make-coffee` project is simple:
```
timetrace create project grind-beans@make-coffee
```
The new module will be listed as part of the `make-coffee` project:
```
timetrace list projects
+-----+-------------+-------------+
| # | KEY | MODULES |
+-----+-------------+-------------+
| 1 | make-coffee | grind-beans |
+-----+-------------+-------------+
```
When filtering by projects, for example with `timetrace list records -p make-coffee today`, the modules of that project
will be included.
## Shell integration
### Starship
To integrate timetrace into Starship, add the following lines to `$HOME/.config/starship.toml`:
```
[custom.timetrace]
command = """ timetrace status --format "Current project: {project} - Worked today: {trackedTimeToday}" """
when = "timetrace status"
shell = "sh"
```
You can find a list of available formatting variables in the [`status` reference](#print-the-tracking-status).
## Command reference
### Start tracking
**Syntax:**
```
timetrace start [+TAG1, +TAG2, ...]
```
**Arguments:**
| Argument | Description |
| ------------------- | -------------------------------------------- |
| `PROJECT KEY` | The key of the project. |
| `+TAG1, +TAG2, ...` | One or more optional tags starting with `+`. |
**Flags:**
| Flag | Short | Description |
| ---------------- | ----- | ---------------------------------------------------------------------------------------------------------- |
| `--billable` | `-b` | Mark the record as billable. |
| `--non-billable` | | Mark the record as non-billable, even if the project is [billable by default](#per-project-configuration). |
**Example:**
Start working on a project called `make-coffee` and mark it as billable:
```
timetrace start --billable make-coffee
```
Start working on the `make-coffee` project and add two tags:
```
timetrace start make-coffee +espresso +morning
```
### Print the tracking status
**Syntax:**
```
timetrace status
```
**Flags:**
| Flag | Short | Description |
| ---------- | ----- | ------------------------------------------------------------- |
| `--format` | `-f` | Display the status in a custom format (see below). |
| `--output` | `-o` | Display the status in a specific output. Valid values: `json` |
**Formatting variables:**
The names of the formatting variables are the same as the JSON keys printed by `--output json`.
| Variable | Description |
| ---------------------- | ---------------------------------------- |
| `{project}` | The key of the current project. |
| `{trackedTimeCurrent}` | The time tracked for the current record. |
| `{trackedTimeToday}` | The time tracked today. |
| `{breakTimeToday}` | The break time since the first record. |
**Example:**
Print the current tracking status:
```
timetrace status
+-------------------+----------------------+----------------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY |
+-------------------+----------------------+----------------+
| make-coffee | 1h 15min | 4h 30min |
+-------------------+----------------------+----------------+
```
Print the current project and the total working time as a custom string. Given the example above, the output will be
`Current project: make-coffee - Worked today: 3h 30min`.
```
timetrace status --format "Current project: {project} - Worked today: {trackedTimeToday}"
```
Print the status as JSON:
```
timetrace status -o json
```
The output will look as follows:
```json
{
"project": "web-store",
"trackedTimeCurrent": "1h 45min",
"trackedTimeToday": "7h 30min",
"breakTimeToday": "0h 30min"
}
```
### Stop tracking
**Syntax:**
```
timetrace stop
```
**Example:**
Stop working on your current project:
```
timetrace stop
```
### Create a project
**Syntax:**
```
timetrace create project
```
**Arguments:**
| Argument | Description |
| -------- | ---------------------- |
| `KEY` | An unique project key. |
**Example:**
Create a project called `make-coffee`:
```
timetrace create project make-coffee
```
### Create a record
:warning: You shouldn't use this command for normal tracking but only for belated records.
**Syntax:**
```
timetrace create record {|today|yesterday}
```
**Arguments:**
| Argument | Description |
| ------------- | -------------------------------------------------------------------------------- |
| `PROJECT KEY` | The project key the record should be created for. |
| `YYYY-MM-DD` | The date the record should be created for. Alternatively `today` or `yesterday`. |
| `HH:MM` | The start time of the record. |
| `HH:MM` | The end time of the record. |
**Example:**
Create a record for the `make-coffee` project today from 07:00 to 08:30:
```
timetrace create record make-coffee today 07:00 08:30
```
### Get a project
**Syntax:**
```
timetrace get project
```
**Arguments:**
| Argument | Description |
| -------- | ---------------- |
| `KEY` | The project key. |
**Example:**
Display a project called `make-coffee`:
```
timetrace get project make-coffee
```
### Get a record
**Syntax:**
```
timetrace get record
```
**Arguments:**
| Argument | Description |
| ------------------ | ------------------------------------- |
| `YYYY-MM-DD-HH-MM` | The start time of the desired record. |
**Example:**
By default, records can be accessed using the 24-hour format, meaning 3:00 PM is 15. Display a record created on May 1st 2021, 3:00 PM:
```
timetrace get record 2021-05-01-15-00
```
This behavior [can be changed](#prefer-12-hour-clock-for-storing-records).
### List all projects
**Syntax:**
```
timetrace list projects
```
**Example:**
List all projects stored within the timetrace filesystem:
```
timetrace list projects
+---+-------------+
| # | KEY |
+---+-------------+
| 1 | make-coffee |
| 2 | my-website |
| 3 | web-shop |
+---+-------------+
```
### List all records from a date
**Syntax:**
```
timetrace list records {|today|yesterday}
```
**Arguments:**
| Argument | Description |
| ------------ | ----------------------------------------------------------- |
| `YYYY-MM-DD` | The date of the records to list, or `today` or `yesterday`. |
| today | List today's records. |
| yesterday | List yesterday's records. |
**Flags:**
| Flag | Short | Description |
| ------------ | ----- | ------------------------------ |
| `--billable` | `-b` | only display billable records. |
| `--project` | `-p` | filter records by project key. |
**Example:**
Display all records created on May 1st 2021:
```
timetrace list records 2021-05-01
+-----+-------------+---------+-------+------------+
| # | PROJECT | START | END | BILLABLE |
+-----+-------------+---------+-------+------------+
| 1 | my-website | 17:30 | 21:00 | yes |
| 2 | my-website | 08:31 | 17:00 | no |
| 3 | make-coffee | 08:25 | 08:30 | no |
+-----+-------------+---------+-------+------------+
```
Filter records by the `make-coffee` project:
```
timetrace list records -p make-coffee 2021-05-01
+-----+-------------+---------+-------+------------+
| # | PROJECT | START | END | BILLABLE |
+-----+-------------+---------+-------+------------+
| 1 | make-coffee | 08:25 | 08:30 | no |
+-----+-------------+---------+-------+------------+
```
This will include records for [project modules](#project-modules) like `grind-beans@make-coffee`.
### Edit a project
**Syntax:**
```
timetrace edit project
```
**Arguments:**
| Argument | Description |
| -------- | ---------------- |
| `KEY` | The project key. |
**Flags:**
| Flag | Short | Description |
| ---------- | ----- | ------------------------------------------------------- |
| `--revert` | `-r` | Revert the project to its state prior to the last edit. |
**Example:**
Edit a project called `make-coffee`:
```
timetrace edit project make-coffee
```
:fire: **New:** Restore the project to its state prior to the last edit:
```
timetrace edit project make-coffee --revert
```
### Edit a record
**Syntax:**
```
timetrace edit record {|latest}
```
**Arguments:**
| Argument | Description |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `KEY` | The project key. `YYYY-MM-DD-HH-MM` by default or `YYYY-MM-DD-HH-MMPM` if [`use12hours` is set](#prefer-12-hour-clock-for-storing-records). |
**Flags:**
| Flag | Short | Description |
| ---------- | ----- | ----------------------------------------------------------------------------- |
| `--plus` | `-p` | Add the given duration to the record's end time, e.g. `--plus 1h 10m` |
| `--minus` | `-m` | Subtract the given duration from the record's end time, e.g. `--minus 1h 10m` |
| `--revert` | `-r` | Revert the record to its state prior to the last edit. |
**Example:**
Edit the latest record. Specifying no flag will open the record in your editor:
```
timetrace edit record latest
```
Add 15 minutes to the end of the record created on May 1st, 3PM:
```
timetrace edit record 2021-05-01-15-00 --plus 15m
```
:fire: **New:** Restore the record to its state prior to the last edit:
```
timetrace edit record 2021-05-01-15-00 --revert
```
Tip: You can get the record key `2021-05-01-15-00` using [`timetrace list records`](#list-all-records-from-a-date).
### Delete a project
**Syntax:**
```
timetrace delete project
```
**Arguments:**
| Argument | Description |
| -------- | ---------------- |
| `KEY` | The project key. |
**Flags:**
| Flag | Short | Description |
| ------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `--revert` | `-r` | Restore a deleted project. |
| `--exclude-records` | `-e` | Exclude associated project records from the deletion. If used together with `--revert`, excludes restoring project records from backup. |
**Example:**
Delete a project called `make-coffee`. Note that submodules will be deleted along with the parent project:
```
timetrace delete project make-coffee
```
The command will prompt for confirmation of whether project records should be deleted too.
:fire: **New:** Restore the project to its pre-deletion state. Submodules will be restored along with the parent project:
```
timetrace delete project make-coffee --revert
```
The command will prompt for confirmation of whether project records should be restored from backup too. This is a
potentially dangerous operation since records edited in the meantime will be overwritten by the backup.
### Delete a record
**Syntax:**
```
timetrace delete record
```
**Arguments:**
| Argument | Description |
| ------------------ | ------------------------------------- |
| `YYYY-MM-DD-HH-MM` | The start time of the desired record. |
| Flag | Short | Description |
| ---------- | ----- | --------------------------- |
| `--yes` | | Do not ask for confirmation |
| `--revert` | `-r` | Restore a deleted record. |
**Example:**
Delete a record created on May 1st 2021, 3:00 PM:
```
timetrace delete record 2021-05-01-15-00
```
:fire: **New:** Restore the record to its pre-deletion state:
```
timetrace delete record 2021-05-01-15-00 --revert
```
### Generate a report `[beta]`
**Syntax:**
```
timetrace report
```
**Flags:**
| Flag | Short | Description |
| ----------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--billable` | `-b` | Filter report for only billable records. |
| `--non-billable` | | Filter report for non-billable records. |
| `--start ` | `-s` | Filter report from a specific point in time (start is inclusive). |
| `--end ` | `-e` | Filter report to a specific point in time (end is inclusive). |
| `--project ` | `-p` | Filter report for only one project. |
| `--output ` | `-o` | Write report as JSON to file. |
| `--file path/to/report` | `-f` | Write report to a specific file
(if not given will use config `report-dir`
if config not present writes to `$HOME/.timetrace/reports/report-`). |
### Print version information
**Syntax:**
```
timetrace version
```
**Example:**
Print your installed timetrace version:
```
timetrace version
```
## Configuration
You may provide your own configuration in a file called `config.yaml` within
`$HOME/.timetrace`.
### Prefer 12-hour clock for storing records
If you prefer to use the 12-hour clock instead of the default 24-hour format,
add this to your `config.yaml` file:
```yaml
# config.yml
use12hours: true
```
This will allow you to [view a record](#get-a-record) created at 3:00 PM as
follows:
```
timetrace get record 2021-05-14-03-00PM
```
### Prefer decimal hours for status and reports
If your prefer to use decimal hours for durations, e.g. `1.5h` instead of `1h 30m`,
add this to your `config.yaml` file:
```yaml
useDecimalHours: "On"
```
To display durations in _both_ formats at the same time, use:
```yaml
useDecimalHours: "Both"
```
**Examples with durations in different formats:**
```
default (useDecimalHours = "Off")
+-------------------+----------------------+----------------+----------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+----------+
| make-coffee | 1h 8min | 3h 8min | 0h 11min |
+-------------------+----------------------+----------------+----------+
Decimal Hours (useDecimalHours = "On")
+-------------------+----------------------+----------------+----------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+----------+
| make-coffee | 1.2h | 3.2h | 0.2h |
+-------------------+----------------------+----------------+----------+
Both (useDecimalHours = "Both")
+-------------------+----------------------+----------------+---------------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+---------------+
| make-coffee | 1h 8min 1.2h | 3h 8min 3.2h | 0h 11min 0.2h |
+-------------------+----------------------+----------------+---------------+
```
### Set your preferred editor
By default, timetrace will open the editor specified in `$EDITOR` or fall back
to `vi`. You may set your provide your preferred editor like so:
```yaml
# config.yml
editor: nano
```
### Configure defaults for projects
To add a configuration for a specific project, use the `projects` key which accepts
a map with the project key as key and the project configuration as value.
Each project configuration currently has the following schema:
```yaml
billable: bool
```
For example, always make records for the `make-coffee` project billable:
```yaml
# config.yml
projects:
make-coffee:
billable: true
```
## Credits
This project depends on the following packages:
- [spf13/cobra](https://github.com/spf13/cobra)
- [spf13/viper](https://github.com/spf13/viper)
- [fatih/color](https://github.com/fatih/color)
- [olekukonko/tablewriter](https://github.com/olekukonko/tablewriter)
- [enescakir/emoji](https://github.com/enescakir/emoji)