Skip to content

Commit

Permalink
edit command implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
KDesp73 committed Aug 14, 2024
1 parent 8a7a9ce commit d033093
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 10 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Added

- edit command implemented

### Changed

- Updated version to 0.0.4


## [0.0.3] - 2024-08-15

### Added

- list command implemented

### Changed
Expand Down Expand Up @@ -58,4 +69,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

[0.0.1]: https://github.com/KDesp73/changelogger/releases/tag/v0.0.1
[0.0.2]: https://github.com/KDesp73/changelogger/releases/tag/v0.0.2
[0.0.3]: https://github.com/KDesp73/changelogger/releases/tag/v0.0.3

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A cli tool to help you keep a changelog in all your projects
$ git clone https://github.com/KDesp73/changelogger --depth=1

# Checkout to the latest release
$ git checkout v0.0.2
$ git checkout v0.0.4

# Build and Install
$ ./install.sh
Expand Down
2 changes: 1 addition & 1 deletion include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#define CHANGELOG_FILE "CHANGELOG.md"
#define CHANGELOG_DIR ".changelog"
#define SQLITE_DB ".changelog/changelog.db"
#define VERSION "0.0.2"
#define VERSION "0.0.4"
#define EXECUTABLE_NAME "changelogger"

#endif // CONFIG_H
2 changes: 2 additions & 0 deletions include/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef enum {
ABBR_VERSION_FULL = 'V',
ABBR_YES = 'y',
ABBR_REMOTE_REPO = 'R',
ABBR_TITLE = 't',
} ArgumentAbbr;

typedef struct {
Expand All @@ -30,6 +31,7 @@ typedef struct {
const char* new;
_Bool always_export;
const char* remote_repo;
const char* title;
} Options;

int always_export_set(Options options);
Expand Down
163 changes: 159 additions & 4 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#include "status.h"
#include "templates.h"
#include "version.h"
#include <ctype.h>
#include <stdio.h>
#include <strings.h>
#define CLIB_IMPLEMENTATION
#include "extern/clib.h"
#include "utils.h"
Expand Down Expand Up @@ -168,7 +168,7 @@ void command_export(Options options)
clib_str_append_ln(&release_buffer, "");
}

if(i == 0 || status != entries[i].status){
if(i == 0 || status != entries[i].status || !STREQ(version, entries[i].version.full)){
clib_str_append_ln(&buffer, "");
clib_str_append_ln(&release_buffer, "");
clib_str_append_ln(&buffer, TEMPLATE_STATUS(entries[i].status));
Expand Down Expand Up @@ -215,9 +215,163 @@ void command_export(Options options)
INFO("Export complete.");
}

void clear_input_buffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF); // Discard characters until newline or EOF
}

void command_edit(Options options)
{
Options list_options = {
.version.full = VERSION_UNRELEASED,
.argc = 1,
.argv = (char**) malloc(sizeof(char*) * 4)
};

if (list_options.argv == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return;
}

list_options.argv[0] = malloc(strlen("-V") + 1);
if (list_options.argv[0] == NULL) {
fprintf(stderr, "Memory allocation for argv[0] failed\n");
free(list_options.argv);
return;
}
strcpy(list_options.argv[0], "-V");

command_list(list_options);

sqlite3* db;
sqlite3_open(SQLITE_DB, &db);

size_t count;
Entry* entries = select_entries(db, "version = 'unreleased'", "date DESC", &count);
sqlite3_close(db);

int index = -1;
char index_str[10];
printf("\n");
while (1) {
printf("Enter index to edit: ");
if (scanf("%9s", index_str) != 1) {
ERRO("Error reading input.\n");
clear_input_buffer();
continue;
}

if (!is_number(index_str)) {
ERRO("'%s' is not a number\n", index_str);
clear_input_buffer();
continue;
}

index = atoi(index_str);

if(index < 1 || index > count) {
if(count == 1) ERRO("index can only be 1\n");
else ERRO("index must be between 1 and %zu\n", count);
continue;
}

break;
}

_Bool arguments_used = status_set(options) || options.title != NULL;
if(arguments_used){
if(options.title != NULL){
char* condition = clib_format_text("message = '%s' AND date = '%s'", entries[index-1].message, entries[index-1].date.full);
char* formated_message = clib_format_text("'%s'", options.title);
update(TABLE_ENTRIES, ENTRIES_MESSAGE, formated_message, condition);
free(formated_message);
free(condition);
}

if(status_set(options)){
char* condition = clib_format_text("message = '%s' AND date = '%s'", entries[index-1].message, entries[index-1].date.full);
char* formated_status = clib_format_text("%d", options.status);
update(TABLE_ENTRIES, ENTRIES_STATUS, formated_status, condition);
free(formated_status);
free(condition);
}
return;
}

char choice[2];
while (1) {
printf("Select value to edit {(t)itle | (s)tatus}: ");
if (scanf("%1s", choice) != 1) {
ERRO("Error reading input.\n");
clear_input_buffer();
continue;
}

if (choice[0] == 't' || choice[0] == 's') {
break;
} else {
ERRO("'%s' is not a valid option. Please enter 'm' or 's'.\n", choice);
clear_input_buffer();
}
}

char message[50];
Status s = STATUS_UNSET;
if(choice[0] == 't'){
clear_input_buffer();
while(1){
printf("Enter new message: ");
if (fgets(message, sizeof(message), stdin) == NULL) {
fprintf(stderr, "Error reading input.\n");
continue;
}

message[strcspn(message, "\n")] = '\0';

if (is_blank(message)) {
ERRO("New message cannot be blank\n");
clear_input_buffer();
continue;
}
break;
}

char* condition = clib_format_text("message = '%s' AND date = '%s'", entries[index-1].message, entries[index-1].date.full);
char* formated_message = clib_format_text("'%s'", message);
update(TABLE_ENTRIES, ENTRIES_MESSAGE, formated_message, condition);
free(formated_message);
free(condition);
} else if(choice[0] == 's'){
char status[10];
clear_input_buffer();
while(1){
printf("Enter new status: ");
if (fgets(status, sizeof(status), stdin) == NULL) {
fprintf(stderr, "Error reading input.\n");
continue;
}

status[strcspn(status, "\n")] = '\0';

if (is_blank(status)) {
ERRO("New status cannot be blank\n");
clear_input_buffer();
continue;
}
s = get_status(status);
if(s == STATUS_NONE || s == STATUS_UNSET || s == STATUS_UNKNOWN){
ERRO("Invalid status: '%s'\n", status);
continue;
}
break;
}

char* condition = clib_format_text("message = '%s' AND date = '%s'", entries[index-1].message, entries[index-1].date.full);
char* formated_status = clib_format_text("%d", s);
update(TABLE_ENTRIES, ENTRIES_STATUS, formated_status, condition);
free(formated_status);
free(condition);
}
}

void command_get(Options options)
Expand Down Expand Up @@ -308,6 +462,7 @@ void command_list(Options options)

size_t count;
Entry* entries = select_entries(db, condition, order_by, &count);
sqlite3_close(db);
if(condition != NULL) free(condition);

if(count == 0){
Expand All @@ -318,7 +473,7 @@ void command_list(Options options)
int status_offset = -10;
int version_offset = -10;
int date_offset = -19;
char* index_dashes = char_repeat('-', -index_offset + 2);
char* index_dashes = char_repeat('-', -index_offset + 2); // +2 for left and right padding
char* title_dashes = char_repeat('-', -title_offset + 2);
char* status_dashes = char_repeat('-', -status_offset + 2);
char* version_dashes = char_repeat('-', -version_offset + 2);
Expand Down Expand Up @@ -349,14 +504,14 @@ void command_list(Options options)
);
}

free(entries);
free(index_dashes);
free(title_dashes);
free(status_dashes);
free(version_dashes);
free(date_dashes);
}

sqlite3_close(db);
}

void command_set(Options options)
Expand Down
2 changes: 2 additions & 0 deletions src/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,6 @@ void edit_help()
PTN("");
PTN("%sOPTIONS%s", BOLD, RESET);
PTNI("-h --help Prints this message");
PTNI("-s --status Specify new status");
PTNI("-t --title Specify new title/message")
}
17 changes: 13 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Options parse_options(int argc, char** argv, Command* command)

// NOTE: The help fields are not set since
// the help message is written by hand
CliArguments args = clib_make_cli_arguments(12,
CliArguments args = clib_make_cli_arguments(13,
clib_create_argument(ABBR_HELP, "help", "", no_argument),
clib_create_argument(ABBR_VERSION, "version", "", no_argument),
clib_create_argument(ABBR_STATUS, "status", "", required_argument),
Expand All @@ -72,7 +72,8 @@ Options parse_options(int argc, char** argv, Command* command)
clib_create_argument(ABBR_YES, "yes", "", no_argument),
clib_create_argument(ABBR_INDEX, "index", "", no_argument),
clib_create_argument(ABBR_ALWAYS_EXPORT, "always-export", "", required_argument),
clib_create_argument(ABBR_VERSION_FULL, "version-full", "", required_argument)
clib_create_argument(ABBR_VERSION_FULL, "version-full", "", required_argument),
clib_create_argument(ABBR_TITLE, "title", "", required_argument)
);

int opt;
Expand Down Expand Up @@ -134,6 +135,11 @@ Options parse_options(int argc, char** argv, Command* command)
) options.always_export = true;
else options.always_export = false;
break;
case ABBR_TITLE:
if(*command != COMMAND_EDIT) PANIC("--title can only be used with `edit`");

options.title = optarg;
break;
default:
exit(1);
}
Expand Down Expand Up @@ -166,8 +172,11 @@ int main(int argc, char** argv)

if(
export &&
(command == COMMAND_ADD ||
command == COMMAND_DELETE)
(
command == COMMAND_ADD ||
command == COMMAND_EDIT ||
command == COMMAND_DELETE
)
) {
execute_command(COMMAND_EXPORT, options);
}
Expand Down

0 comments on commit d033093

Please sign in to comment.