Skip to content

Commit bd69278

Browse files
committed
feat: initial working setup
0 parents  commit bd69278

27 files changed

+2089
-0
lines changed

.github/workflows/build.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Go build
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: '1.22.3'
20+
21+
- name: Build
22+
run: go build -v ./...

.github/workflows/release.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: '1.22.0'
20+
- name: Build
21+
run: go build -v ./...
22+
- name: Install Cosign
23+
uses: sigstore/cosign-installer@v3
24+
with:
25+
cosign-release: 'v2.2.3'
26+
- name: Store Cosign private key in a file
27+
run: 'echo "$COSIGN_KEY" > cosign.key'
28+
shell: bash
29+
env:
30+
COSIGN_KEY: ${{secrets.COSIGN_KEY}}
31+
- name: Release Binaries
32+
uses: goreleaser/goreleaser-action@v6
33+
with:
34+
distribution: goreleaser
35+
version: "~> v2"
36+
args: release --clean
37+
env:
38+
GITHUB_TOKEN: ${{secrets.GH_PAT}}
39+
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dist
2+
cosign.key
3+
cosign.pub
4+
hours
5+
debug.log
6+
.quickrun
7+
justfile

.goreleaser.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
version: 2
2+
3+
before:
4+
hooks:
5+
- go mod tidy
6+
- go generate ./...
7+
8+
builds:
9+
- env:
10+
- CGO_ENABLED=0
11+
goos:
12+
- linux
13+
- darwin
14+
15+
signs:
16+
- cmd: cosign
17+
stdin: "{{ .Env.COSIGN_PASSWORD }}"
18+
args:
19+
- "sign-blob"
20+
- "--key=cosign.key"
21+
- "--output-signature=${signature}"
22+
- "${artifact}"
23+
- "--yes" # needed on cosign 2.0.0+
24+
artifacts: all
25+
26+
27+
brews:
28+
- name: hours
29+
repository:
30+
owner: dhth
31+
name: homebrew-tap
32+
directory: Formula
33+
license: MIT
34+
homepage: "https://github.com/dhth/hours"
35+
description: "Track time on your tasks"
36+
37+
changelog:
38+
sort: asc
39+
filters:
40+
exclude:
41+
- "^docs:"
42+
- "^test:"
43+
- "^ci:"

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: run-gofmt
5+
name: run-gofmt
6+
entry: gofmt -w .
7+
types: [go]
8+
language: golang

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Dhruv Thakur
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# hours
2+
3+
✨ Overview
4+
---
5+
6+
"hours" is a simple CLI app that allows you to track time on tasks you care
7+
about.
8+
9+
💾 Install
10+
---
11+
12+
**go**:
13+
14+
```sh
15+
go install github.com/dhth/hours@latest
16+
```

cmd/db.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package cmd
2+
3+
import "database/sql"
4+
5+
const (
6+
DB_VERSION = "1"
7+
)
8+
9+
func setupDB(dbpath string) (*sql.DB, error) {
10+
11+
db, err := sql.Open("sqlite", dbpath)
12+
db.SetMaxOpenConns(1)
13+
db.SetMaxIdleConns(1)
14+
if err != nil {
15+
return nil, err
16+
}
17+
18+
if _, err = db.Exec(`
19+
CREATE TABLE IF NOT EXISTS task (
20+
id INTEGER PRIMARY KEY AUTOINCREMENT,
21+
summary TEXT NOT NULL,
22+
secsSpent INTEGER NOT NULL DEFAULT 0,
23+
done BOOLEAN NOT NULL,
24+
created_at TIMESTAMP NOT NULL,
25+
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
26+
);
27+
28+
CREATE TABLE IF NOT EXISTS task_log (
29+
id INTEGER PRIMARY KEY AUTOINCREMENT,
30+
task_id INTEGER,
31+
begin_ts TIMESTAMP NOT NULL,
32+
end_ts TIMESTAMP,
33+
comment VARCHAR(255),
34+
active BOOLEAN NOT NULL,
35+
FOREIGN KEY(task_id) REFERENCES task(id)
36+
);
37+
38+
CREATE TRIGGER IF NOT EXISTS prevent_duplicate_active_insert
39+
BEFORE INSERT ON task_log
40+
BEGIN
41+
SELECT CASE
42+
WHEN EXISTS (SELECT 1 FROM task_log WHERE active = 1)
43+
THEN RAISE(ABORT, 'Only one row with active=1 is allowed')
44+
END;
45+
END;
46+
`); err != nil {
47+
return nil, err
48+
}
49+
50+
return db, nil
51+
}

cmd/root.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cmd
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"os/user"
8+
9+
"github.com/dhth/hours/internal/ui"
10+
)
11+
12+
func die(msg string, args ...any) {
13+
fmt.Fprintf(os.Stderr, msg+"\n", args...)
14+
os.Exit(1)
15+
}
16+
17+
func Execute() {
18+
currentUser, err := user.Current()
19+
20+
if err != nil {
21+
die("Error getting your home directory, This is a fatal error; let @dhth know about this.\n%s\n", err)
22+
}
23+
24+
defaultDBPath := fmt.Sprintf("%s/hours.v%s.db", currentUser.HomeDir, DB_VERSION)
25+
dbPath := flag.String("db-path", defaultDBPath, "location where hours should create its DB file")
26+
27+
flag.Usage = func() {
28+
fmt.Fprintf(os.Stdout, "Track time on your tasks.\n\nFlags:\n")
29+
flag.CommandLine.SetOutput(os.Stdout)
30+
flag.PrintDefaults()
31+
}
32+
flag.Parse()
33+
34+
if *dbPath == "" {
35+
die("db-path cannot be empty")
36+
}
37+
38+
dbPathFull := expandTilde(*dbPath)
39+
40+
db, err := setupDB(dbPathFull)
41+
if err != nil {
42+
fmt.Fprintf(os.Stderr, "Couldn't set up hours' local database. This is a fatal error; let @dhth know about this.\n%s\n", err)
43+
os.Exit(1)
44+
}
45+
46+
ui.RenderUI(db)
47+
48+
}

cmd/utils.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package cmd
2+
3+
import (
4+
"os"
5+
"os/user"
6+
"strings"
7+
)
8+
9+
func expandTilde(path string) string {
10+
if strings.HasPrefix(path, "~") {
11+
usr, err := user.Current()
12+
if err != nil {
13+
os.Exit(1)
14+
}
15+
return strings.Replace(path, "~", usr.HomeDir, 1)
16+
}
17+
return path
18+
}

0 commit comments

Comments
 (0)