Giter Club home page Giter Club logo

timetrace's Introduction

โฐ timetrace

timetrace is a simple CLI for tracking your working time.

CLI screenshot 64x16

๐Ÿ”ฅ New: Add tags for records
๐Ÿ”ฅ New: Use decimal hours when displaying durations
๐Ÿ”ฅ New: Restore records when restoring the associated project
๐Ÿ”ฅ New: Support for per-project configuration



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 <name> 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 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 <module>@<project>.

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.

Command reference

Start tracking

Syntax:

timetrace start <PROJECT KEY> [+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.

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:

{
  "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 <KEY>

Arguments:

Argument Description
KEY An unique project key.

Example:

Create a project called make-coffee:

timetrace create project make-coffee

Create a record

โš ๏ธ You shouldn't use this command for normal tracking but only for belated records.

Syntax:

timetrace create record <PROJECT KEY> {<YYYY-MM-DD>|today|yesterday} <HH:MM> <HH:MM>

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 <KEY>

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 <YYYY-MM-DD-HH-MM>

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.

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 {<YYYY-MM-DD>|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 like grind-beans@make-coffee.

Edit a project

Syntax:

timetrace edit project <KEY>

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

๐Ÿ”ฅ 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 {<KEY>|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.

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

๐Ÿ”ฅ 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.

Delete a project

Syntax:

timetrace delete project <KEY>

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.

๐Ÿ”ฅ 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 <YYYY-MM-DD-HH-MM>

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

๐Ÿ”ฅ 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 <YYYY-MM-DD> -s Filter report from a specific point in time (start is inclusive).
--end <YYYY-MM-DD> -e Filter report to a specific point in time (end is inclusive).
--project <KEY> -p Filter report for only one project.
--output <json> -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-<time.unix>).

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:

# config.yml
use12hours: true

This will allow you to view 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:

useDecimalHours: "On"

To display durations in both formats at the same time, use:

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:

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

billable: bool

For example, always make records for the make-coffee project billable:

# config.yml
projects:
    make-coffee:
        billable: true

Credits

This project depends on the following packages:

timetrace's People

Contributors

aaronsheah avatar adzo261 avatar alksmt avatar dboslee avatar dependabot[bot] avatar dhanushsr avatar dominikbraun avatar felixtheodor avatar gmalette avatar joshuaherrera avatar jwnpoh avatar krishnaindani avatar mattkasun avatar nrobinson2000 avatar perniciosius avatar redemptionc avatar retronav avatar rocar avatar sfrique avatar sudiptog81 avatar thatinfrastructureguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

timetrace's Issues

Move `Format*` functions into `Formatter`

There are some Format* functions in timetrace.go:

timetrace/core/timetrace.go

Lines 180 to 190 in bf934a8

// FormatTodayTime returns the formated string of the total
// time of today follwoing the format convention
func (report *Report) FormatTodayTime() string {
return formatDuration(report.TrackedTimeToday)
}
// FormatCurrentTime returns the formated string of the current
// report time follwoing the format convention
func (report *Report) FormatCurrentTime() string {
return formatDuration(*report.TrackedTimeCurrent)
}

Those functions should be part of the Formatter type in formatter.go. Once those functions are moved, they can then be called with t.Formatter().FormatXxx from the cli package.

Timetrace does not handle projects with '/' in the name

Hey,

I am currently working on multiple subprojects and want to use Timetrace to track my work time on these.

My initial idea was to do something like this : parentProject/SubProject, but it confuses Timetrace ๐Ÿ˜„

image

Cheers

Command `timetrace edit record <key>` does not rename file

Similar to issue #81 , the timetrace edit record <key> command does not rename the file. This shouldn't be an issue when we pass either the --plus or --minus flags, since these edit the end times, but without those flags, the user can edit the json file and potentially change the start time, which is the key for a record. The documentation recommends using timetrace list records in conjunction with the timetrace edit record command, but this does not work as intended if a flag is not used.

The code expects the key to correspond to the filename, but since it is not changed, the file is not found.

In the image, I demonstrate the above with record 1. Note that this also occurs when use12Hours is false.
editrecord

I'd imagine the solution would be similar to those mentioned in issue #81 .

Introduce `today` and `yesterday` aliases for commands

Instead of writing timetrace list records 2021-05-17 every time, I'd like to be able to just write timetrace list records today.

This means there should be aliases called today and yesterday that translate those arguments to the respective dates.

Total time spent on a project ?

Hi,

Nice tool! Maybe I didn't RTFM correctly but I can't find a way to display the total time spent on a single project ?

Is this implemented or will it be ?

Thanks,

Prevent users from creating modules for non-existent projects

Currently, creating project modules like grind-beans@make-coffee is possible even if the parent project, make-coffee, doesn't exist. This shouldn't be allowed and throw an error instead.

More information about project modules and their design can be found in proposal #53.

Implement `timetrace delete record` command

Just like a record can be displayed using timetrace get record <YYYY-MM-DD-HH-MM>, a record should be deletable using timetrace delete record <YYYY-MM-DD-HH-MM>.

This means that the delete command should get a new sub-command called record, which takes the record date as argument - and there needs to be a DeleteRecord method of core.Timetrace.

The documentation needs to be updated as well.

Include project name in records list

I think the output of timetrace list records YYYY-MM-DD would be more useful if the project name was included in the output table

Current output of timetrace list records YYYY-MM-DD:
Screen Shot 2021-05-16 at 7 59 30 PM

Desired output:
Screen Shot 2021-05-16 at 7 55 01 PM

Beautify durations displayed on `timetrace status`

At the moment, the output of timetrace status looks as follows:

+-----------------+--------------------+-----------------+
| CURRENT PROJECT | WORKED SINCE START |  WORKED TODAY   |
+-----------------+--------------------+-----------------+
| make-coffee     | 8h25m26.147239s    | 8h25m26.147239s |
+-----------------+--------------------+-----------------+

Displaying durations like 8h25m26.147239s is precise, but unnecessary und unreadable. It should rather look something like 8h 25min.

Introduce `--revert` flag for `timetrace edit` and `timetrace delete` commands

There should be a new --revert flag for timetrace edit project, timetrace edit record (once it is implemented through #19), timetrace delete project and timetrace delete record.

If the --revert flag is specified, the edited/deleted project/record should be restored. This means that the edit and delete commands also need to create a backup file before modifications are performed. There always should be one backup file per project/record.

Those backup files must not be taken into account by functions like ListRecords.

If the --revert flag is specified, nothing except the rollback should happen.

Affected commands

Command Flag Action
timetrace edit project --revert Restores the backed-up project to the state before it was edited.
timetrace edit record ยน --revert Restores the backed-up record to the state before it was edited.
timetrace delete project --revert Restores the backed-up project to the state before it was deleted.
timetrace delete record --revert Restores the backed-up record to the state before it was deleted.

ยน This command doesn't exist yet.

Remove hard-coded `"15:04"` strings

At some places in the code base, there is the hard-coded time string "15:04". This should be replaced with a defaultTime constant which should be used instead. Plus, if Timetrace.Config().Use12Hours is true, that default constant should be replaced with 03:04PM.

Error: Failed to start tracking

Hi,
After creating a project as per README usage instructions, whenever I try to start tracking I get this error on Mac:
$ timetrace start coding
โ— Failed to start tracking: start tracking first

Please advise. Thank you!!

`--billable` filter for record list

It would be nice to filter the listed records so that only billable records will be displayed:

timetrace list records --billable
# Only lists billable records

Proposal: Add `notify` command

I just stumbled across this project: https://github.com/gen2brain/beeep
It makes sending notifications to the user very easy. Then I had an idea - my main concern with time-tracking software is that I always forget the tracking when I'm in the middle of something.
Therefore, it could be a useful feature for timetrace if the user can set a timer to get a notification when the current task he is tracking is running for x minutes.

I already implemented a first version of this and opened a WIP-Pull-Request for it.

You can start a record and then run timetrace notify 5m & (the &-symbol makes the process run in background). As soon as the task is running for 5 minutes, a notification should pop up and the notify process finishes. If the tracking is stopped before 5 minutes are over, no notification should be send. On my linux system, this already works fine.

What do you think of this idea and the first implementation, @dominikbraun ?

Proposal: Project modules

Project modules, also known as sub-projects, are a frequently requested feature. This is my proposal on how to implement them.

Proposal

The idea

Project modules are the exact same thing as projects, expect that they can be associated with a parent project. This association is marked by an @. For example, grind-beans@make-coffee is a module of the project make-coffee.

Creating a project module

The syntax is the same as for creating a "normal" project. The logic for creating the project remains unchanged - it will simply create a file called [email protected] internally.

timetrace create project grind-beans@make-coffee

Tracking time for a project module

The start logic remains unchanged as well.

timetrace start grind-beans@make-coffee

Filtering records for a module

Once #52 is implemented, the list records command has a --project flag for filtering projects. With project modules, the respective logic would have to take an @ into account and additionally filter by module.

timetrace list records --project grind-beans@make-coffee today

Implementation

As mentioned above, project modules are stored in the exact same way as projects. Our example module will be stored as [email protected] inside the projects directory.

To list all available modules of the project make-coffee, all "projects" - e.g. modules - suffixed with @make-coffee can be displayed.

Copy command reference into Go files, e.g. `list.go`

The goal of #84 was to find a way to auto-generate documentation out of the Cobra commands. @obnoxiousnerd found a simple way to do this natively with Cobra. Thanks!

As a next step, the command references from README.md should me copied into the Cobra commands. Each Cobra command has a Long field for long help texts, and the existing documentation should be moved into that field.

Ideally, as a result, generating the documentation from the commands should produce the same output as the current Markdown documentation in README.md.

`timetrace list projects`: Display project modules

Regarding Proposal #53:

The timetrace list projects command shall not only list projects and project modules row-by-row, e.g.:

# Key
1 make-coffee
2 grind-beans@make-coffee
3 brew-coffee@make-coffee

Instead, modules should be listed as part of their respective project:

# Key Modules
1 make-coffee grind-beans, brew-coffee

This should be relatively easy to implement - just create a function that loads all modules of a project and display them with the project.

`timetrace status` doesn't work if there was no time tracking yet

Running timetrace status leads to an error if time hasn't been tracked on that day yet:

timetrace status
โ— Failed to obtain status: open /Users/dominik/.timetrace/records/2021-05-15: no such file or directory

This is because the record directory of that day, in this case 2021-05-15, hasn't been created yet. It will be created when running timetrace start.

To fix this, Fs.EnsureDirectories should also create a record directory for the current day:

timetrace/fs/fs.go

Lines 151 to 166 in 16b10a9

// EnsureDirectories creates all required timetrace directories. If they already
// exist, nothing happens.
func (fs *Fs) EnsureDirectories() error {
dirs := []string{
fs.projectsDir(),
fs.recordsDir(),
}
for _, dir := range dirs {
if err := os.MkdirAll(dir, 0777); err != nil {
return err
}
}
return nil
}

EnsureDirectories is executed in advance on each timetrace command.

`timetrace stop` prints success message even if there is no tracking

Description:

If there is no active time tracking, timetrace stop still prints a success message that tracking has been stopped.

Steps to reproduce:

  1. Start tracking time.
  2. Stop tracking time.
  3. Stop tracking time again: โœ”๏ธ Stopped tracking time

Expected behavior:

If there is no active time tracking, stop should do nothing. There should be an info (probably not an error?) message indicating that time isn't being tracked at the moment:

There is no active time tracking. Start tracking using `timetrace start` first.

Installation error

If you follow the instructions:

sudo snap install timetrace --edge
error: The publisher of snap "timetrace" has indicated that they do not consider this revision to
       be of production quality and that it is only meant for development or testing at this point.
       As a consequence this snap will not refresh automatically and may perform arbitrary system
       changes outside of the security sandbox snaps are generally confined to, which may put your
       system at risk.

       If you understand and want to proceed repeat the command including --devmode; if instead you
       want to install the snap forcing it into strict confinement repeat the command including
       --jailmode.

Info:

  • snap 2.50
  • snapd 2.50
  • series 16
  • ubuntu 18.04
  • kernel 4.15.0-143-generic

Add `break since start` field to `timetrace status`

The timetrace status command prints how long I've been working today. It would be nice to see how long I've been taking breaks since the beginning of my day. For example:

timetrace status
+-------------------+----------------------+----------------+--------+
|  CURRENT PROJECT  |  WORKED SINCE START  |  WORKED TODAY  | BREAKS |
+-------------------+----------------------+----------------+--------+
| web-store         | 0h 3min              | 4h 15min       | 30min  |
+-------------------+----------------------+----------------+--------+

12 hour format does not differentiate between AM and PM

Hi,
In working on issue #17 in version 0.4.0, I noticed that, when 12 hour time format is configured with config.yaml, one must always pass in the PM portion of the flag, even if the time logged was in the AM, as shown.

timetrace-time-format

It seems to me the command should allow for the user to input AM or PM, or perhaps allow the user to omit the PM entirely, with the assumption that any time entered without PM is assumed to have been logged in the AM. Thoughts?

Make command argument syntax sensitive for configuration

For example, the get record command has the following syntax:

timetrace/cli/get.go

Lines 53 to 56 in 16b10a9

getRecord := &cobra.Command{
Use: "record YYYY-MM-DD-HH-MM",
Short: "Display a record",
Args: cobra.ExactArgs(1),

Actually, YYYY-MM-DD-HH-MM is only the default syntax. If the user has set use12hours: true in their config, the expected format is YYYY-MM-DD-HH-MMPM instead, as you can see here:

timetrace/cli/get.go

Lines 58 to 62 in 16b10a9

layout := defaultRecordArgLayout
if t.Config().Use12Hours {
layout = "2006-01-02-03-04PM"
}

The Use field of the command should be changed accordingly, being sensitive to the actual configuration.

Failed to stop tracking time

Hi there,

thanks for the project. It looks nice.
However I encountered a bug trying to stop tracking:

timetrace create project test
โœ”๏ธ Created project test
timetrace start test
โœ”๏ธ Started tracking time
timetrace stop
โ— Failed to stop tracking: record already exists

timetrace status works fine.

The json looks like this:

{
	"start": "2021-05-26T10:23:37.5685406+02:00",
	"end": null,
	"project": {
		"key": "test"
	},
	"is_billable": false
}

I use timetrace version 0.6.0 on Windows 10.

Implement `timetrace list records` command

Just as timetrace list projects displays a list of projects, timetrace list records should list records. It probably would make sense to limit those records to a specific date, so that the command syntax looks as follows:

timetrace list records <YYYY-MM-DD>

The output should be a table analogous to list projects.

Add --format optional arg

Hey, thanks for this awesome tool! Makes the time tracking part of my life easier ๐Ÿ‘

Right now I have the current task that I am working on in my status bar.

timetrace status | awk -F'|' 'NR == 4 {gsub(/ /, "", $0); print $2 " " $3}'

And this works, but it would be nice to add a format parameter to timetrace status to fx format the output as JSON, which is easier to work with in scripts :-)

`timetrace list records` should include "record key"

The table displayed by timetrace list records should contain a new column "key". This should be the "record key" in the form YYYY-MM-DD-HH-MM - i.e. the exact value that you would pass to timetrace get record to display that record.

`timetrace status` uses current time instead of end time for stopped records

The bug

timetrace status uses <current time> - <start time of the last record> to determine the worked time. This is correct if the time is being tracked, but incorrect when tracking has been stopped. In that case, <end time of the record> - <start time of the record> would be correct.

As a result, if you run timetrace status multiple times after stopping time tracking, it looks like time is still being tracked.

Steps to reproduce

  1. Run timetrace start ....
  2. Wait.
  3. Run timetrace stop.
  4. Run timetrace status.
  5. Wait.
  6. Run timetrace status again.
  7. It looks like the time is still being tracked, because the tracked time between the first and the second status command increased - even though tracking has been stopped before.

Expected behavior

After running timetrace stop, the worked time for the last record displayed with status shouldn't change anymore.

Beautify output of tables

Thanks to tablewriter, tables already look pretty good! However, the out.Table function could be improved: tablewriter allows to stylize and colorize tables. I think it would be nice to have at least bold table headings.

To do this, table.SetHeaderColor needs to be called here:

timetrace/out/out.go

Lines 33 to 39 in 16b10a9

// Table renders a table with the given rows to the standard output.
func Table(header []string, rows [][]string) {
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader(header)
table.AppendBulk(rows)
table.Render()
}

table.SetHeaderColor expects one function argument per table column. This has to be done automatically, depending of the length of header.

Implement `timetrace edit record` command

Just as projects are editable via timetrace edit project, records should be editable using timetrace edit record. The command syntax should look just like the syntax of timetrace get record:

timetrace edit record [options] <YYYY-MM-DD-HH-MM>
  • Running edit without any options should open the default editor to directly edit the record file (see edit project).
  • Running edit with options should load the record internally, apply the option values and save the record. The supported options are explained below.

Command options

Flag Short Type Description Example
--plus -p String Adds the given duration to the end time of the record. --add 10m
--minus -m String Substracts the given duration of the end time of the record. --minus 10m

Those options probably aren't too hard to implement if the durations can be parsed as time.Duration. In that case, calling something like record.End.Add(plus) should be sufficient.

`timetrace config` command

At the moment, to get and set configuration values, users have to create a config.yaml file inside their .timetrace directory and set the values manually.

It would be nice to have a timetrace config command with two sub-commands to do this:

  • timetrace config set <KEY> <VALUE>
  • timetrace config get <KEY>

This way, users wouldn't have to touch their configuration file anymore.

Migrate to `promptui` (or a more interactive cli)

Just a suggestion, we could move to use a more interactive cli library. This might be useful for example where you can run timetrace start without arguments and you can use arrow keys to select the project you would like to start.

What do you think? I can come up with a proof of concept first before we decide.

Command ```create project <key>``` is not checking for existing projects correctly

Running the create project <key> is not checking for existing projects correctly, even though there is code to handle this case.
I'm running Manjaro Linux, in case this is an issue with how the os package interacts with linux, and I tested on timetrace 0.5.0.
timetrace_dupes_project

Per the code, this would also effect the record.SaveRecord function.

Change output of `timetrace version`

At the moment, the output of timetrace version looks as follows:

$ timetrace version
โ— timetrace version v0.1.0

This error-styled output should be replaced with an info-styled output, which can be accomplished by replacing out.Err with out.Info:

timetrace/cli/version.go

Lines 13 to 15 in 16b10a9

Run: func(cmd *cobra.Command, args []string) {
out.Err("timetrace version %s", value)
},

Implement `timetrace create record` command

Sometimes, it would make sense to directly "insert" a new record with a given time span instead of fiddling around with timetrace edit record on existing records.

To do so, a timetrace create record command is needed. I have the following syntax in mind:

timetrace create record <PROJECT KEY> {<YYYY-MM-DD>|today|yesterday} <HH-MM> <HH-MM>

Important: This command should check for collisions with other records, so probably all records from that date have to be loaded and checked internally.

command `timetrace edit project <key>` does not rename file

Currently, when a user edits a project using timetrace edit project <key> the text editor is opened so the user can change the key.
It seems to me that any subsequent calls to this command should reference the new key, but trying to run this command this way causes the file to not be found.
editproj
Since some functions like project.LoadProject assume that the key will be part of the path, it seems like this command should also rename the json file with the new key.

Add "padding" to table headers

Currently, tables look as follows:

Bildschirmfoto 2021-05-19 um 10 02 26

Those headers are nice, but there should be a padding so that they look like so:

Bildschirmfoto 2021-05-19 um 10 03 34

This can be done by prepending and appending a whitespace before and each header name: "Project" should become " Project ". This modification should be performed by out.Table:

timetrace/out/out.go

Lines 43 to 50 in 938230f

// Table renders a table with the given rows to the standard output.
func Table(header []string, rows [][]string) {
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader(header)
setHeaderColor(table, header)
table.AppendBulk(rows)
table.Render()
}

Just create a function headersWithPadding(headers []string) []string and use it in out.Table.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.