그냥 머리 좀 비우고 싶어서 만들게 된 CLI 환경에서 사용하기 위한 TODO LIST 입니다.
대충 만든거라 대단한 기능도 없고 버그도 조금 있을 수 있습니다 ㅎㅎ
라이브러리 하나만 추가했습니다.
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