A simple durable command-line task manager built with Spring Boot, Picocli and Spring Data JPA. Data is stored in a H2 file database (./taskdb) so your task persist across runs.
- Add tasks with title, description, due date, and priority(LOW/MEDIUM/HIGH/CRITICAL)
- Update tasks (title, description, due date, status)
- Assign tasks to users
- Track progress (0-100%; auto-sets status)
- Prioritize + list tasks with filters(by assignee or status), sorted by priority
CLI entrypoint: task with subcommands: add, update, assign, progress, list, seed-user.
- Java 17+
- Spring Boot 3.x
- Picocli (via
picocli-spring-boot-starter - Spring Data JPA
- H2 (file mode; switchable to postgres/SQLite later)
- Lombok
com.example.taskcli
├─ App.java
├─ domain/
│ ├─ Task.java
│ ├─ User.java
│ ├─ Priority.java
│ └─ Status.java
├─ repository/
│ ├─ TaskRepository.java
│ └─ UserRepository.java
├─ service/
│ ├─ TaskService.java
│ └─ UserService.java
└─ cli/
├─ RootCommand.java
├─ AddTaskCommand.java
├─ UpdateTaskCommand.java
├─ AssignTaskCommand.java
├─ ProgressTaskCommand.java
├─ ListTaskCommand.java
└─ SeedUserCommand.java
- Java 17+
- Maven 3.8+
git clone https://github.com/rudrat0319/task-tracker-cli.git
cd task-tracker-cli
mvn -q -DskipTests package
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task --help
The app uses a H2 file database by default.
src/main/resources/application.properties
Properties
spring.datasource.url=jdbc:h2:file:./taskdb;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.main.web-application-type=none
The database file lives in the project root as ./taskdb (plus H2’s side files). Swap to Postgres by updating the properties (see Switching to Postgres).
General Pattern:
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task <subcommand> [options]
task seed-user --username rahul --name "Rahul Sharma"
task add --title "Write README" --desc "Initial docs" --priority HIGH --due 2025-10-20
task update 1 --title "Write full README" --status IN_PROGRESS --priority CRITICAL --due 2025-10-22
task assign 1 --user rahul
task progress 1 --pct 40
# 100% auto-sets status to DONE; >0 from TODO auto-sets to IN_PROGRESS
task list
task list --assignee rahul
task list --status DONE
task list --priority-first=false # keep original insertion order
| Subcommand | Purpose | Key Options |
|---|---|---|
seed-user |
Create user if missing | --username (req), --name |
add |
Create task | --title (req), --desc, --priority, --due(yyyy-MM-dd) |
update <id> |
Edit task fields | --title, --desc, --priority, --status, --due |
assign <id> |
Assign to user | --user (req) |
progress <id> |
Set progress 0–100 | --pct (req) |
list |
View tasks | --assignee, --status, --priority-first |
Tip: Add and alias in your shell so task maps to java -jar target/taskcli-0.0.1-SNAPSHOT.jar task.
Task
id(Long)title(String, Required)description(String)priority(Priority: LOW/MEDIUM/HIGH/CRITICAL; default MEDIUM)status(Status: TODO/IN_PROGRESS/DONE/BLOCKED; default TODO)progress(0–100; progress=100 → status=DONE)assigness(User, nullable)dueDate(LocalDate, nullable)createdAt,updatedAt(audit) Userid(Long)userName(unique, required)displayName(optional)
- Picocli gives robust CLI parsing and help text.
- Spring Boot wires services/repositories and manages lifecycle.
- Together, you get clean commands with DI and a tiny footprint.
Note: Picocli is not shown in Spring Initializr. Add the dependency manually:
<dependency> <groupId>info.picocli</groupId> <artifactId>picocli-spring-boot-starter</artifactId> <version>4.7.6</version> </dependency>
- Add dependency (in pom.xml):
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
- Update application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/taskcli
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=update
- Picocli not found: Ensure the
picocli-spring-boot-starterdependency is inpom.xml, then Reimport Maven or runmvn -U clean package. - Java version errors: Confirm java -version is 17+ and your IDE project SDK matches.
- Database “locked”: Stop other running app instances using the same ./taskdb. H2’s AUTO_SERVER=TRUE helps when multiple JVMs are involved, but a single CLI instance is recommended.
- Command not recognized: Use the full java -jar ... task form or add a shell alias.
task list --jsonoutput for scriptingtask block <id> --reason "..."task due-soon --days 3- Full-text search on titles/descriptions
- SQLite profile for a single portable DB file
- Fork & create a feature branch
- Write clean, small commits
- Add/adjust tests if you introduce logic
- Open a PR with a clear description
mvn -q -DskipTests package
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task seed-user --username rahul --name "Rahul Sharma"
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task add --title "Write README" --desc "Initial docs" --priority HIGH --due 2025-10-20
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task list
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task assign 1 --user rahul
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task progress 1 --pct 40
java -jar target/taskcli-0.0.1-SNAPSHOT.jar task update 1 --status IN_PROGRESS --priority CRITICAL