[Java] 간단한 CLI 환경 TODO 만들어보기

식빵·2025년 2월 15일
0

Java Lab

목록 보기
30/30

그냥 머리 좀 비우고 싶어서 만들게 된 CLI 환경에서 사용하기 위한 TODO LIST 입니다.
대충 만든거라 대단한 기능도 없고 버그도 조금 있을 수 있습니다 ㅎㅎ


Maven 의존성 추가

라이브러리 하나만 추가했습니다.
TODO List 이쁘게 출력하려고 넣었습니다.

<dependency>
	<groupId>com.github.freva</groupId>
	<artifactId>ascii-table</artifactId>
	<version>1.8.0</version>
</dependency>



코드

package coding.toast.todolist;

import com.github.freva.asciitable.AsciiTable;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TodoListApplication {
	
	public static final File TODO_LIST_FILE = new File("todo-list.csv");
	
	static String[] headers = {"id", "todo", "done"};
	
	static final String FINISH_STRING = "✔";
	
	public static void main(String[] args) throws IOException {
		
		// args : []
		// ==> read all todos
		if (args == null || args.length == 0) {
			readAll();
		}
		
		// args : add "eat breakfast"
		// ==> add new row
		// ==> when adding new row, give new serial Number for row id
		else if (args.length >= 2 && "add".equalsIgnoreCase(args[0])) {
			
			if (args[1] == null || args[1].trim().isEmpty()) {
				System.out.println("you didn't add what to do!");
				return;
			}
			
			addTodo(args);
		}
		
		// args : done <serial number>[ <serial number2> <serial number3> ...]
		else if (args.length >= 2 && "done".equalsIgnoreCase(args[0])) {
			if (args[1] == null || args[1].trim().isEmpty()) {
				System.out.println("no id value present");
				return;
			}
			
			String[] idList = Arrays.copyOfRange(args, 1, args.length);
			checkDoneOnId(idList);
		}
		
		// args : reset
		// ==> remove todolist file
		else if (args.length == 1 && "reset".equalsIgnoreCase(args[0])) {
			resetTodo();
		}
	}
	
	private static void resetTodo() {
		if (TODO_LIST_FILE.delete()) {
			System.out.println("todo-list.csv file has been deleted [==> RESET]");
		}
	}
	
	private static void addTodo(String[] args) throws IOException {
		String lastId = getLastId();
		
		// append to do list
		Files.writeString(TODO_LIST_FILE.toPath(),
			lastId + "," + args[1].trim() + "," + System.lineSeparator(),
			StandardOpenOption.CREATE,
			StandardOpenOption.APPEND);
	}
	
	private static void checkDoneOnId(String ...idList) {
		try {
			Path path = TODO_LIST_FILE.toPath();
			List<String> lines = Files.readAllLines(path);
			ArrayList<String> rewrite = new ArrayList<>();
			for (String line : lines) {
				if (line.trim().isEmpty()) {
					continue;
				}
				String[] split = line.split(",", -1);
				String id = split[0];
				if (Arrays.binarySearch(idList, id) >= 0) {
					rewrite.addLast(String.join(",", id, split[1], FINISH_STRING));
				} else {
					rewrite.addLast(line);
				}
			}
			Files.deleteIfExists(path);
			Files.write(path,rewrite, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	private static String getLastId() {
		try {
			if(!TODO_LIST_FILE.exists()) return "1";
			
			List<String> lines = Files.readAllLines(TODO_LIST_FILE.toPath());
			
			if (lines.isEmpty()) {
				return "1";
			} else {
				String lastLine = lines.reversed().getFirst().split("-1", -1)[0];
				String[] split = lastLine.split(",", -1);
				long idVal = Long.parseLong(split[0]);
				return String.valueOf(idVal + 1);
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	private static void readAll() {
		
		try {
			if (!TODO_LIST_FILE.exists()) return;
			
			List<String> allLines
				= Files.readAllLines(TODO_LIST_FILE.toPath(), StandardCharsets.UTF_8);
			
			if(allLines.isEmpty()) return;
			
			String[][] data = new String[allLines.size()][3];
			
			for (int i = 0; i < allLines.size(); i++) {
				String csvFormat = allLines.get(i);
				if (csvFormat == null || csvFormat.isEmpty()) {
					continue;
				}
				String[] split = csvFormat.split(",", -1);
				data[i][0] = split[0];
				data[i][1] = split[1];
				data[i][2] = split[2];
			}
			
			showAsciiTable(data);
			
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		
	}
	
	private static void showAsciiTable(String[][] data) {
		System.out.println(AsciiTable.getTable(headers, data));
	}
	
}



사용법

# todo 추가
java --jar todo-list.jar add "task 1"

# todo 조회
java --jar todo-list.jar

# todo 체크
java --jar todo-list.jar done 1

# todo 리셋
java --jar todo-list.jar reset

profile
백엔드 개발자로 일하고 있는 식빵(🍞)입니다.

0개의 댓글

관련 채용 정보