A simple UI is developed at https://github.com/jansorg/tom-ui (Qt5 tested on Linux and macOS). A preview for mac is available there.
tom is a command line application to track time and to simplify office work. It's able to track time and to create HTML and PDF reports.
tom tracks time locally.
Instead of implementing billing, etc. it will rely on 3rd-party tools, i.e. mostly cloud-based services.
Prebuilt binaries are available on the releases page:
- Linux (amd64):
.tar.gzarchive or.debpackage, which also installs the bash completion - macOS (Apple Silicon):
.tar.gzarchive, signed and notarized - Windows (amd64):
.tar.gzarchive, signed
Each archive contains tom and tom-pdf.
With Go 1.27 or later installed, you can also install tom with:
go install github.com/jansorg/tom@latestAfter that tom will be available, assuming that $(go env GOPATH)/bin is in your $PATH.
See Building to build tom from source.
A typical session looks like this:
tom create project acme
tom start acme
sleep 10
tom stop
tom report --month 0Documentation about the command line is available at docs/markdown
The data is stored in a few JSON files on disk. It's easy to backup and still fast.
Right now it's on disk at $HOME/.tom/.
The available commands make it easy to export it into different target formats. Most commands are supporting plain text
and JSON at this time. Other formats may be added in the future.
tom supports nested projects. The separator character is the slash '/'. The simplest form is a project without any subprojects.
If you need to bill a single client for several distinct project then it's better to use subprojects. For example:
tom create project client1 client1/web client1/backend
tom start client1/web
tom stop
tom report --split project -p client1This will create a report on all projects which belong to client1 with the tracked time per project.
The reporting allows to split the tracked time into multiple pieces. Multiple levels of splitting is possible. Possible values:
- year
- month
- project
For example, -split year creates a report where the tracked time is grouped into the years which are covered by tracked time.
-split year,project will renders groups of years which are further grouped by the projects which were tracked in this particular year.
-split project,month groups the tracked time by project first and then lists the summaries grouped by month for each project.
tom import watsonThis needs a custom CSV export (to be documented).
tom import fanurio complete-export.csvThis imports the CSV format exported by Mac Time Tracker.
tom import macTimeTracker export.csvRequirements: Go 1.27 or later. No other tools are needed, the report templates in templates/ are embedded into the binary with go:embed.
git clone https://github.com/jansorg/tom.git
cd tom
go build . # builds ./tom
go build -o tom-pdf ./go-tom-pdf # builds ./tom-pdf, the PDF converter
go test ./...To build the release artifacts locally without publishing anything, install GoReleaser v2 and run:
goreleaser check
goreleaser release --snapshot --clean --skip=publishThe archives and the .deb package are written to dist/.
Generated files, updated automatically for each release:
scripts/completions/tom.sh: bash completion, created bytom completiondocs/markdownanddocs/man: command line documentation, created byupdate_docs.bash
Releases are built by the GitHub Actions workflow release.yml with GoReleaser.
Every release is created as a draft and must be published manually.
- Start the release workflow on
master, either from the Actions tab or with:The workflow runs the tests, updates the version ingh workflow run release.yml -f version=0.14.0
main.go, the bash completion and the documentation (asprep:commits onmaster), creates and pushes the tagv0.14.0and builds the draft release. The macOS binaries are signed and notarized during the build. - Sign the Windows binaries of the draft release with the code signing certificate on the YubiKey:
The script asks for the YubiKey PIN, signs
./sign-windows.bash v0.14.0
tom.exeandtom-pdf.exe, and replaces the Windows archive andchecksums.txtof the draft release. Use--dry-runto sign without uploading. It needsgh,jsign,javaandyubico-piv-tool. If jsign doesn't find the certificate, setJSIGN_ALIAS, e.g.JSIGN_ALIAS="X.509 Certificate for Digital Signature"for PIV slot 9c. - Review the draft on the releases page and publish it.
Published releases can't be signed anymore by
sign-windows.bash.
Pushing a tag (e.g. with release.bash) also builds a draft release, but doesn't update the version in main.go.
macOS signing and notarization needs these repository secrets. Without them, the macOS binaries are not signed.
| Secret | Content |
|---|---|
MACOS_SIGN_P12 |
"Developer ID Application" certificate with private key as .p12, base64-encoded (base64 -w0 cert.p12) |
MACOS_SIGN_PASSWORD |
Password of the .p12 file |
MACOS_NOTARY_ISSUER_ID |
App Store Connect API issuer ID |
MACOS_NOTARY_KEY_ID |
App Store Connect API key ID |
MACOS_NOTARY_KEY |
App Store Connect API key (AuthKey_XXXX.p8), base64-encoded |
To be decided