A cross-platform terminal stopwatch application built with .NET 8.0 that persists timing data across sessions.
- Cross-platform support (Windows, macOS, Linux)
- Persistent state using JSON file storage
- Single-instance enforcement
- Commands:
start,stop,clear,quit - Display format:
DD:HH:MM:SS - Atomic file writes for crash safety
- Hexagonal architecture with DDD principles
The application follows a hexagonal (ports and adapters) architecture:
- Domain: Core business logic, entities, and value objects
- Ports: Interfaces defining contracts
- Adapters: Platform-specific implementations (filesystem, console, singleton)
- Application: Use-cases and orchestration
- CLI: Composition root and entry point
- .NET 8.0 SDK or later
Build the entire solution:
dotnet buildBuild in Release mode:
dotnet build -c ReleaseRun the application directly:
dotnet run --project src/Stopwatch.Cli/Stopwatch.Cli.csprojRun all tests:
dotnet testRun specific test projects:
dotnet test tests/Stopwatch.Unit/Stopwatch.Unit.csproj
dotnet test tests/Stopwatch.Integration/Stopwatch.Integration.csproj
dotnet test tests/Stopwatch.E2E/Stopwatch.E2E.csprojCreate self-contained single-file executables for each platform:
dotnet publish src/Stopwatch.Cli/Stopwatch.Cli.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o ./publish/win-x64dotnet publish src/Stopwatch.Cli/Stopwatch.Cli.csproj -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -o ./publish/linux-x64dotnet publish src/Stopwatch.Cli/Stopwatch.Cli.csproj -c Release -r osx-x64 --self-contained true -p:PublishSingleFile=true -o ./publish/osx-x64dotnet publish src/Stopwatch.Cli/Stopwatch.Cli.csproj -c Release -r osx-arm64 --self-contained true -p:PublishSingleFile=true -o ./publish/osx-arm64Once the application is running, use the following commands:
start- Start or resume the stopwatchstop- Pause the stopwatchclear- Reset the stopwatch and clear all persisted dataquit- Exit the application
The elapsed time is displayed in the format DD:HH:MM:SS and updates every second when the stopwatch is running.
The application stores its state in platform-specific locations:
- Windows:
%APPDATA%\PersistentStopwatch\stopwatch.json - macOS:
~/Library/Application Support/PersistentStopwatch/stopwatch.json - Linux:
~/.local/share/PersistentStopwatch/stopwatch.json
The data is stored as an array of Unix epoch timestamps representing start/stop pairs.
The application enforces single-instance execution. If you try to run multiple instances simultaneously, the second instance will display an error message and exit.
The repository includes a GitHub Actions workflow that builds and tests the application on Windows, macOS, and Linux.
.
├── src/
│ ├── Stopwatch.Domain/ # Core entities and business logic
│ ├── Stopwatch.Ports/ # Interface definitions
│ ├── Stopwatch.Adapters.FileSystem/ # File-based persistence
│ ├── Stopwatch.Adapters.Console/ # Console I/O
│ ├── Stopwatch.Adapters.Singleton/ # Single-instance enforcement
│ ├── Stopwatch.App/ # Application use-cases
│ └── Stopwatch.Cli/ # Executable entry point
├── tests/
│ ├── Stopwatch.Unit/ # Unit tests
│ ├── Stopwatch.Integration/ # Integration tests
│ └── Stopwatch.E2E/ # End-to-end tests
└── PersistentStopwatch.sln
This project is provided as-is for demonstration purposes.