Skip to content
Closed
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Binaries for programs and plugins
tmpo
dist/
result/
*.exe
*.exe~
*.dll
Expand Down Expand Up @@ -47,4 +48,4 @@ node_modules/
.tmporc

# AI Tools
CLAUDE.md
CLAUDE.md
20 changes: 20 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ Thank you for your interest in contributing to tmpo! This document provides guid
git remote add upstream https://github.com/DylanDevelops/tmpo.git
```

### Using Nix (optional)

If you'd rather use Nix, you can enter a development shell that provides every required dependencies:

```bash
nix develop
```

Once inside the shell, `TMPO_DEV=1` is automatically enabled and you run the same commands as in any other environment.

## Development Workflow

### Building
Expand All @@ -37,6 +47,13 @@ go build -o tmpo .
./tmpo --help
```

Nix also allows to run these without entering a devshell:

```bash
nix build
nix run . -- --help
```

### Development Mode

To prevent corrupting your real tmpo data during development, use the `TMPO_DEV` environment variable:
Expand Down Expand Up @@ -77,6 +94,9 @@ echo 'export TMPO_DEV=1' >> ~/.bashrc

Then restart your terminal or run `source ~/.zshrc` (or `source ~/.bashrc`).

> [!TIP]
> In NixOS, dev move persistence can also be configured in [modules](docs/installation/linux_installation.md#nixos-module).

**Benefits of development mode:**

- Your real time tracking data and settings stay safe
Expand Down
13 changes: 9 additions & 4 deletions cmd/utilities/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ var (
Date = "unknown"
)

var releaseVersionRegex = regexp.MustCompile(`^v?\d+\.\d+\.\d+(-[\w.]+)?$`)

func VersionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Expand Down Expand Up @@ -54,17 +56,16 @@ func GetFormattedDate(inputDate string) string {
func GetChangelogUrl(version string) string {
path := "https://github.com/DylanDevelops/tmpo"

r := regexp.MustCompile(`^v?\d+\.\d+\.\d+(-[\w.]+)?$`)
if !r.MatchString(version) {
if !isReleaseVersion(version) {
return fmt.Sprintf("%s/releases/latest", path)
}

return fmt.Sprintf("%s/releases/tag/v%s", path, strings.TrimPrefix(version, "v"))
}

func checkForUpdates() {
// Only check if we have a valid version (not "dev" or empty)
if Version == "" || Version == "dev" {
// Only check for released semantic versions.
if !isReleaseVersion(Version) {
return
}

Expand All @@ -79,3 +80,7 @@ func checkForUpdates() {
fmt.Printf("%s\n\n", ui.Muted(updateInfo.UpdateURL))
}
}

func isReleaseVersion(version string) bool {
return releaseVersionRegex.MatchString(version)
}
5 changes: 5 additions & 0 deletions cmd/utilities/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ func TestGetChangelogUrl(t *testing.T) {
version: "dev",
expected: "https://github.com/DylanDevelops/tmpo/releases/latest",
},
{
name: "unstable version returns latest",
version: "unstable",
expected: "https://github.com/DylanDevelops/tmpo/releases/latest",
},
{
name: "empty version returns latest",
version: "",
Expand Down
74 changes: 73 additions & 1 deletion docs/installation/linux_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This guide will walk you through installing tmpo on Linux.
- **x86_64 (64-bit)**: `tmpo_X.X.X_Linux_x86_64.tar.gz`
- **ARM64**: `tmpo_X.X.X_Linux_arm64.tar.gz`

> [!NOTE]
> [!NOTE]
> Replace `X.X.X` with the latest version number, e.g., `0.1.0`

You can also download using curl or wget:
Expand Down Expand Up @@ -138,6 +138,78 @@ chmod +x ~/bin/tmpo
tmpo --version
```

## Method 3: Nix (flake)

Run tmpo without installing:

```bash
# Pass any tmpo command after "--"
nix run github:DylanDevelops/tmpo -- start
```

Or add `tmpo` to your flake inputs and your favorite install method in the outputs:

```nix
{
inputs = {
tmpo = {
url = "github:DylanDevelops/tmpo";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs = { nixpkgs, ... }@inputs:
{
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
modules = [
# Package only
({ pkgs, ... }: {
environment.systemPackages = [ inputs.tmpo.packages.${pkgs.system}.default ];
})
# OR NixOS Module
inputs.tmpo.nixosModules.tmpo
];
};

# OR Home Manager module
homeConfigurations."me" = home-manager.lib.homeManagerConfiguration {
modules = [
inputs.tmpo.homeManagerModules.tmpo
];
};
};
};
}
```

### NixOS module

```nix
{
programs.tmpo = {
enable = true;
devMode = false;
};
}
```

### Home Manager module

```nix
{
programs.tmpo = {
enable = true;
settings = {
currency = "USD";
dateFormat = "MM/DD/YYYY"; # `MM/DD/YYYY`, `DD/MM/YYYY`, `YYYY-MM-DD`
timeFormat = "24-hour"; # `24-hour`, `12-hour (AM/PM)`
timezone = "America/New_York";
exportPath = "~/Documents/timesheets";
};
};
}
```

## Determining Your Architecture

If you're not sure which binary to download:
Expand Down
4 changes: 4 additions & 0 deletions docs/installation/macos_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ sudo chmod +x /usr/local/bin/tmpo
tmpo --version
```

## Method 4: Nix (flake)

Nix installation is configured in a similar fashion to Linux. Follow the same steps from [Method 3: Nix (flake)](./linux_installation.md#method-3-nix-flake) and use nix-darwin/Home Manager where applicable.

## Alternative Installation Locations

If you prefer not to use `/usr/local/bin/`, you can install to your home directory:
Expand Down
61 changes: 61 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
description = "tmpo CLI time tracker";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};

outputs =
{
self,
nixpkgs,
flake-utils,
...
}:
let
lib = nixpkgs.lib;
sourceInfo = self.sourceInfo or { };
ref = sourceInfo.ref or "";
version = if lib.hasPrefix "v" ref then lib.removePrefix "v" ref else "unstable";
in
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
goPkg = pkgs.go_1_25 or pkgs.go;
rev = self.rev or (self.dirtyRev or "dirty");
lastModified = sourceInfo.lastModifiedDate or self.lastModifiedDate or "19700101000000";
date =
"${builtins.substring 0 4 lastModified}-"
+ "${builtins.substring 4 2 lastModified}-"
+ "${builtins.substring 6 2 lastModified}T"
+ "${builtins.substring 8 2 lastModified}:"
+ "${builtins.substring 10 2 lastModified}:"
+ "${builtins.substring 12 2 lastModified}Z";
package = pkgs.callPackage ./nix/package.nix {
inherit version;
commit = rev;
inherit date;
go = goPkg;
srcPath = ./.;
};
in
{
packages = {
default = package;
tmpo = package;
};
apps.default = flake-utils.lib.mkApp { drv = package; };
devShells.default = pkgs.mkShell {
TMPO_DEV = "1";
packages = [
goPkg
pkgs.gopls
pkgs.gotools
pkgs.goreleaser
pkgs.sqlite
];
};
}
)
// {
nixosModules.tmpo = import ./nix/modules/nixos.nix { inherit self; };
homeManagerModules.tmpo = import ./nix/modules/home-manager.nix { inherit self; };
};
}
Loading