Skip to content
Open
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
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ timetrace start <PROJECT KEY> [+TAG1, +TAG2, ...]
| ---------------- | ----- | ---------------------------------------------------------------------------------------------------------- |
| `--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). |
| `--description` | `-d` | Add a description to your record |

**Example:**

Expand All @@ -195,6 +196,12 @@ Start working on the `make-coffee` project and add two tags:
timetrace start make-coffee +espresso +morning
```

Start working on the `make-coffee` project and add a description:

```
timetrace start make-coffee -d "first time using the new beans"
```

### Print the tracking status

**Syntax:**
Expand Down
12 changes: 8 additions & 4 deletions cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ func createRecordCommand(t *core.Timetrace) *cobra.Command {
}

record := core.Record{
Project: project,
Start: start,
End: &end,
IsBillable: options.isBillable,
Project: project,
Start: start,
End: &end,
IsBillable: options.isBillable,
Description: options.description,
}

collides, err := t.RecordCollides(record)
Expand All @@ -127,5 +128,8 @@ func createRecordCommand(t *core.Timetrace) *cobra.Command {
createRecord.Flags().BoolVarP(&options.isBillable, "billable", "b",
false, `mark tracked time as billable`)

createRecord.Flags().StringVarP(&options.description, "description", "d",
"", `set a description for your record`)

return createRecord
}
7 changes: 4 additions & 3 deletions cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,22 @@ func listRecordsCommand(t *core.Timetrace) *cobra.Command {
billable = "yes"
}

rows[i] = make([]string, 7)
rows[i] = make([]string, 8)
rows[i][0] = strconv.Itoa(len(records) - i)
rows[i][1] = t.Formatter().RecordKey(record)
rows[i][2] = record.Project.Key
rows[i][3] = t.Formatter().TimeString(record.Start)
rows[i][4] = end
rows[i][5] = billable
rows[i][6] = t.Formatter().FormatTags(record.Tags)
rows[i][7] = record.Description
}

footer := make([]string, 7)
footer := make([]string, 8)
footer[len(footer)-2] = "Total: "
footer[len(footer)-1] = t.Formatter().FormatDuration(getTotalTrackedTime(records))

out.Table([]string{"#", "Key", "Project", "Start", "End", "Billable", "Tags"}, rows, footer)
out.Table([]string{"#", "Key", "Project", "Start", "End", "Billable", "Tags", "Description"}, rows, footer)
},
}

Expand Down
8 changes: 7 additions & 1 deletion cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const TagsPrefix = "+"
type startOptions struct {
isBillable bool
isNonBillable bool // Used for overwriting `billable: true` in the project config.
description string
}

func startCommand(t *core.Timetrace) *cobra.Command {
Expand All @@ -36,6 +37,8 @@ func startCommand(t *core.Timetrace) *cobra.Command {

isBillable := options.isBillable

description := options.description

// If there is a default configuration for the project key, use that configuration.
if projectConfig, ok := t.Config().Projects[projectKey]; ok {
isBillable = projectConfig.Billable
Expand All @@ -51,7 +54,7 @@ func startCommand(t *core.Timetrace) *cobra.Command {
return
}

if err := t.Start(projectKey, isBillable, tagNames); err != nil {
if err := t.Start(projectKey, isBillable, tagNames, description); err != nil {
out.Err("failed to start tracking: %s", err.Error())
return
}
Expand All @@ -66,6 +69,9 @@ func startCommand(t *core.Timetrace) *cobra.Command {
start.Flags().BoolVar(&options.isNonBillable, "non-billable",
false, `mark tracked time as non-billable if the project is configured as billable`)

start.Flags().StringVarP(&options.description, "description", "d",
"", `set a description for your record`)

return start
}

Expand Down
11 changes: 6 additions & 5 deletions core/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ var (
)

type Record struct {
Start time.Time `json:"start"`
End *time.Time `json:"end"`
Project *Project `json:"project"`
IsBillable bool `json:"is_billable"`
Tags []string `json:"tags"`
Start time.Time `json:"start"`
End *time.Time `json:"end"`
Project *Project `json:"project"`
IsBillable bool `json:"is_billable"`
Tags []string `json:"tags"`
Description string `json:"description"`
}

// Duration calculates time duration for a specific record. If the record doesn't
Expand Down
11 changes: 6 additions & 5 deletions core/timetrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func New(config *config.Config, fs Filesystem) *Timetrace {
// record with the current time as start time.
//
// Since parallel work isn't supported, the previous work must be stopped first.
func (t *Timetrace) Start(projectKey string, isBillable bool, tags []string) error {
func (t *Timetrace) Start(projectKey string, isBillable bool, tags []string, description string) error {
latestRecord, err := t.LoadLatestRecord()
if err != nil && !errors.Is(err, ErrAllDirectoriesEmpty) {
return err
Expand All @@ -87,10 +87,11 @@ func (t *Timetrace) Start(projectKey string, isBillable bool, tags []string) err
}

record := Record{
Start: time.Now(),
Project: project,
IsBillable: isBillable,
Tags: tags,
Start: time.Now(),
Project: project,
IsBillable: isBillable,
Tags: tags,
Description: description,
}

return t.SaveRecord(record, false)
Expand Down