refactor(cli): moved all commands to seperate functions

This commit is contained in:
lisk77 2025-09-21 15:49:24 +02:00
parent 0e0d1fa1ef
commit bb961f0437

View file

@ -21,32 +21,7 @@ static void usage(int exitcode) {
exit(exitcode); exit(exitcode);
} }
int main(int argc, char** argv) { static int init() {
if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
usage(0);
}
const char* subcmd = argv[1];
if (strcmp(subcmd, "diff") != 0 &&
strcmp(subcmd, "init") != 0 &&
strcmp(subcmd, "status") != 0 &&
strcmp(subcmd, "commit") != 0 &&
strcmp(subcmd, "log") != 0 &&
strcmp(subcmd, "test") != 0
) {
fprintf(stderr, "ERROR: Unknown subcommand: '%s'\n", subcmd);
usage(2);
}
// Initializes a merk repository in the current directory
if (strcmp(subcmd, "init") == 0) {
if (argc != 2) {
printf("ERROR: too many agruments given!\n");
printf("Usage: merk init");
exit(1);
}
if (mkdir(".merk", 0755) == 0) { if (mkdir(".merk", 0755) == 0) {
printf("Initialized merk repository\n"); printf("Initialized merk repository\n");
} }
@ -55,12 +30,12 @@ int main(int argc, char** argv) {
struct stat st; struct stat st;
if (stat(".merk", &st) == 0 && S_ISDIR(st.st_mode)) { if (stat(".merk", &st) == 0 && S_ISDIR(st.st_mode)) {
printf("This directory is already a merk repository\n"); printf("This directory is already a merk repository\n");
return 0; return 1;
} }
} }
int branch = open(".merk/BRANCH", O_WRONLY | O_CREAT, 0666); int branch = open(".merk/BRANCH", O_WRONLY | O_CREAT, 0666);
if (branch < 0) return -1; if (branch < 0) return 0;
write(branch, "main", 4); write(branch, "main", 4);
close(branch); close(branch);
@ -72,35 +47,29 @@ int main(int argc, char** argv) {
mkdir(".merk/logs/branches", 0755); mkdir(".merk/logs/branches", 0755);
int main_branch = open(".merk/refs/branches/main", O_WRONLY | O_CREAT, 0666); int main_branch = open(".merk/refs/branches/main", O_WRONLY | O_CREAT, 0666);
if (main_branch < 0) return -1; if (main_branch < 0) return 0;
close(main_branch); close(main_branch);
int main_info = open(".merk/info/main", O_WRONLY | O_CREAT, 0666); int main_info = open(".merk/info/main", O_WRONLY | O_CREAT, 0666);
if (main_info < 0) return -1; if (main_info < 0) return 0;
close(main_info); close(main_info);
int main_log = open(".merk/logs/branches/main", O_WRONLY | O_CREAT, 0666); int main_log = open(".merk/logs/branches/main", O_WRONLY | O_CREAT, 0666);
if (main_log < 0) return -1; if (main_log < 0) return 0;
close(main_log); close(main_log);
CommitLog* empty = commit_log_new(); CommitLog* empty = commit_log_new();
if (!empty) { perror("ERROR: failed to create commit log for branch main!"); return -1; } if (!empty) { perror("ERROR: failed to create commit log for branch main!"); return 0; }
if (!write_commit_log(empty, ".merk/logs/branches/main")) { perror("ERROR: failed to write initial main commit log!"); commit_log_free(empty); return -1; } if (!write_commit_log(empty, ".merk/logs/branches/main")) { perror("ERROR: failed to write initial main commit log!"); commit_log_free(empty); return 0; }
commit_log_free(empty); commit_log_free(empty);
return 1;
} }
// Prints out a visual representation of the diff of the files provided static int diff(char* file1_path, char* file2_path) {
else if (strcmp(subcmd, "diff") == 0) {
if (argc != 4) {
printf("ERROR: too many/little arguments given!\n");
printf("Usage: merk diff <PATH> <PATH>");
exit(1);
}
File* file1; File* file1;
switch (get_path_type(argv[2])) { switch (get_path_type(file1_path)) {
case PT_FILE: file1 = new_file(argv[2]); break; case PT_FILE: file1 = new_file(file1_path); break;
case PT_DIR: file1 = NULL; printf("ERROR: first path is a directory and no file!"); break; case PT_DIR: file1 = NULL; printf("ERROR: first path is a directory and no file!"); break;
case PT_NOEXIST: file1 = NULL; printf("ERROR: first path does not exist!"); break; case PT_NOEXIST: file1 = NULL; printf("ERROR: first path does not exist!"); break;
default: file1 = NULL; printf("ERROR: unknown first path!"); default: file1 = NULL; printf("ERROR: unknown first path!");
@ -108,8 +77,8 @@ int main(int argc, char** argv) {
if (!file1) exit(1); if (!file1) exit(1);
File* file2; File* file2;
switch (get_path_type(argv[3])) { switch (get_path_type(file2_path)) {
case PT_FILE: file2 = new_file(argv[3]); break; case PT_FILE: file2 = new_file(file2_path); break;
case PT_DIR: file2 = NULL; printf("ERROR: second path is a directory and no file!"); break; case PT_DIR: file2 = NULL; printf("ERROR: second path is a directory and no file!"); break;
case PT_NOEXIST: file2 = NULL; printf("ERROR: second path does not exist!"); break; case PT_NOEXIST: file2 = NULL; printf("ERROR: second path does not exist!"); break;
default: file2 = NULL; printf("ERROR: unknown second path!"); default: file2 = NULL; printf("ERROR: unknown second path!");
@ -119,15 +88,10 @@ int main(int argc, char** argv) {
ActionList* actions = myers_diff(file1, file2, 0, 0); ActionList* actions = myers_diff(file1, file2, 0, 0);
if (!actions) printf("ERROR: something went wrong while taking the diff!"); if (!actions) printf("ERROR: something went wrong while taking the diff!");
else visualize_diff(file1, file2, actions); else visualize_diff(file1, file2, actions);
} return 1;
// Gives a list of untracked files in the repo as well as meta information
else if (strcmp(subcmd, "status") == 0) {
if (argc != 2) {
printf("ERROR: too many arguments given!\n");
printf("Usage: merk status");
exit(1);
} }
static int status() {
FileInfoBuffer* files = file_info_buffer_new(); FileInfoBuffer* files = file_info_buffer_new();
char relative[PATH_MAX] = ""; char relative[PATH_MAX] = "";
char* root = find_root(relative); char* root = find_root(relative);
@ -199,7 +163,6 @@ int main(int argc, char** argv) {
File* comparison_file = basefile; File* comparison_file = basefile;
// If there are previous diffs, we need to compare against the last committed version
if (base_file->diff_num > 0) { if (base_file->diff_num > 0) {
size_t prev_diff = base_file->diff_num - 1; size_t prev_diff = base_file->diff_num - 1;
char prev_diff_hash[41]; char prev_diff_hash[41];
@ -268,16 +231,10 @@ int main(int argc, char** argv) {
file_info_buffer_free(files); file_info_buffer_free(files);
free(root); free(root);
return 0; return 1;
}
// Commits changes to the repo
else if (strcmp(subcmd, "commit") == 0) {
if (argc < 3) {
printf("ERROR: too little arguments given!\n");
printf("Usage: merk commit [-m <COMMIT MESSAGE>] <FILE> ...\n");
exit(1);
} }
static int commit(int argc, char** argv) {
char* commit_message = NULL; char* commit_message = NULL;
int file_start_index = 2; int file_start_index = 2;
@ -297,7 +254,6 @@ int main(int argc, char** argv) {
exit(1); exit(1);
} }
// Ensure files to commit are correctly identified
for (int i = file_start_index; i < argc; i++) { for (int i = file_start_index; i < argc; i++) {
if (strcmp(argv[i], "-m") == 0) { if (strcmp(argv[i], "-m") == 0) {
printf("ERROR: Unexpected -m flag in file list!\n"); printf("ERROR: Unexpected -m flag in file list!\n");
@ -731,14 +687,16 @@ int main(int argc, char** argv) {
free(root); free(root);
free_config(&config); free_config(&config);
free(commit_message); free(commit_message);
return 1;
} }
else if (strcmp(subcmd, "log") == 0) {
static int commit_log() {
CommitLog* log = commit_log_new(); CommitLog* log = commit_log_new();
if (!log) return 1; if (!log) return 0;
char* root = find_root(NULL); char* root = find_root(NULL);
if (!root) { if (!root) {
return 1; return 0;
} }
char branch_path[PATH_MAX]; char branch_path[PATH_MAX];
@ -747,7 +705,7 @@ int main(int argc, char** argv) {
char* branch = get_file_content(branch_path); char* branch = get_file_content(branch_path);
if (!branch) { if (!branch) {
free(root); free(root);
return 1; return 0;
} }
char log_path[PATH_MAX]; char log_path[PATH_MAX];
@ -763,7 +721,7 @@ int main(int argc, char** argv) {
free(branch); free(branch);
free(root); free(root);
commit_log_free(log); commit_log_free(log);
return -1; return 0;
} }
char head[41] = ""; char head[41] = "";
read(ref, head, 40); read(ref, head, 40);
@ -792,6 +750,76 @@ int main(int argc, char** argv) {
free(branch); free(branch);
free(root); free(root);
commit_log_free(log); commit_log_free(log);
return 1;
}
int main(int argc, char** argv) {
if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
usage(0);
}
const char* subcmd = argv[1];
if (strcmp(subcmd, "diff") != 0 &&
strcmp(subcmd, "init") != 0 &&
strcmp(subcmd, "status") != 0 &&
strcmp(subcmd, "commit") != 0 &&
strcmp(subcmd, "log") != 0 &&
strcmp(subcmd, "test") != 0
) {
fprintf(stderr, "ERROR: Unknown subcommand: '%s'\n", subcmd);
usage(2);
}
// Initializes a merk repository in the current directory
if (strcmp(subcmd, "init") == 0) {
if (argc != 2) {
printf("ERROR: too many arguments given!\n");
printf("Usage: merk init");
exit(1);
}
init();
}
// Prints out a visual representation of the diff of the files provided
else if (strcmp(subcmd, "diff") == 0) {
if (argc != 4) {
printf("ERROR: too many/little arguments given!\n");
printf("Usage: merk diff <PATH> <PATH>");
exit(1);
}
diff(argv[2], argv[3]);
}
// Gives a list of untracked files in the repo as well as meta information
else if (strcmp(subcmd, "status") == 0) {
if (argc != 2) {
printf("ERROR: too many arguments given!\n");
printf("Usage: merk status");
exit(1);
}
status();
}
// Commits changes to the repo
else if (strcmp(subcmd, "commit") == 0) {
if (argc < 3) {
printf("ERROR: too little arguments given!\n");
printf("Usage: merk commit [-m <COMMIT MESSAGE>] <FILE> ...\n");
exit(1);
}
commit(argc, argv);
}
else if (strcmp(subcmd, "log") == 0) {
if (argc != 2) {
printf("ERROR: too many arguments given!\n");
printf("Usage: merk log");
exit(1);
}
commit_log();
} }
else if (strcmp(subcmd, "test") == 0) {} else if (strcmp(subcmd, "test") == 0) {}
else { else {