Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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: 4 days ago
JSON representation

A simple CLI for tracking your working time.

Awesome Lists containing this project

README

        

:alarm_clock: timetrace




> timetrace is a simple CLI for tracking your working time.

![CLI screenshot 64x16](timetrace.png)

: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)