Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions cli/ArgumentParser.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ namespace PlanifyCLI {
LIST_PROJECTS,
LIST,
UPDATE,
BACKUP
BACKUP,
DELETE
}

public class TaskArguments : Object {
Expand Down Expand Up @@ -66,12 +67,19 @@ namespace PlanifyCLI {
public string? output { get; set; default = null; }
}

public class DeleteArguments : Object {
public string? task_id { get; set; default = null; }
public string? project_id { get; set; default = null; }
public string? section_id { get; set; default = null; }
}

public class ParsedCommand : Object {
public CommandType command_type { get; set; default = CommandType.NONE; }
public TaskArguments? task_args { get; set; default = null; }
public ListArguments? list_args { get; set; default = null; }
public UpdateArguments? update_args { get; set; default = null; }
public BackupArguments? backup_args { get; set; default = null; }
public DeleteArguments? delete_args { get; set; default = null; }
}

public class ArgumentParser : Object {
Expand Down Expand Up @@ -130,9 +138,14 @@ namespace PlanifyCLI {
parsed.backup_args = parse_backup_command (command_args);
return parsed;

case "delete":
parsed.command_type = CommandType.DELETE;
parsed.delete_args = parse_delete_command (command_args);
return parsed;

default:
stderr.printf ("Error: Unknown command '%s'\n", command);
stderr.printf ("Available commands: add, list, update, list-projects, backup\n");
stderr.printf ("Available commands: add, list, update, list-projects, backup, delete\n");
exit_code = 1;
return null;
}
Expand Down Expand Up @@ -313,6 +326,35 @@ namespace PlanifyCLI {
}
}

private static DeleteArguments parse_delete_command (string[] args) throws OptionError {
string? task_id = null;
string? project_id = null;
string? section_id = null;

var options = new OptionEntry[4];
options[0] = { "task-id", 't', 0, OptionArg.STRING, ref task_id,
"Task ID to delete", "ID" };
options[1] = { "project-id", 'i', 0, OptionArg.STRING, ref project_id,
"Project ID to delete", "ID" };
options[2] = { "section-id", 's', 0, OptionArg.STRING, ref section_id,
"Section ID to delete", "ID" };
options[3] = { null };

var context = new OptionContext ("- Delete a task, project or section");
context.add_main_entries (options, null);
context.set_help_enabled (true);

unowned string[] tmp = args;
context.parse (ref tmp);

var delete_args = new DeleteArguments ();
delete_args.task_id = task_id;
delete_args.project_id = project_id;
delete_args.section_id = section_id;

return delete_args;
}

private static BackupArguments parse_backup_command (string[] args) throws OptionError {
string? output = null;

Expand Down Expand Up @@ -340,7 +382,8 @@ namespace PlanifyCLI {
stdout.printf (" list List tasks from a project\n");
stdout.printf (" update Update an existing task\n");
stdout.printf (" list-projects List all projects\n");
stdout.printf (" backup Export a JSON backup\n\n");
stdout.printf (" backup Export a JSON backup\n");
stdout.printf (" delete Delete a task, project or section\n\n");
stdout.printf ("Run '%s <command> --help' for command-specific options\n\n", program_name);
stdout.printf ("Examples:\n");
stdout.printf (" %s add --help\n", program_name);
Expand Down
1 change: 1 addition & 0 deletions cli/DBusClient.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
public interface DBusClientInterface : Object {
public abstract void add_item (string id) throws Error;
public abstract void update_item (string id) throws Error;
public abstract void delete_item (string id) throws Error;
}

public class DBusClient : Object {
Expand Down
39 changes: 39 additions & 0 deletions cli/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,43 @@ namespace PlanifyCLI {
return 0;
}

private static int delete_item (DeleteArguments args) {
if (args.task_id == null && args.project_id == null && args.section_id == null) {
stderr.printf ("Error: one of --task-id, --project-id or --section-id is required\n");
return 1;
}

Services.Database.get_default ().init_database ();

if (args.task_id != null) {
Objects.Item? item = Services.Store.instance ().get_item (args.task_id.strip ());
if (item == null) {
stderr.printf ("Error: Task ID '%s' not found\n", args.task_id);
return 1;
}
item.delete_item ();
stdout.printf ("Task '%s' deleted\n", item.content);
} else if (args.section_id != null) {
Objects.Section? section = Services.Store.instance ().get_section (args.section_id.strip ());
if (section == null) {
stderr.printf ("Error: Section ID '%s' not found\n", args.section_id);
return 1;
}
section.delete_section (null);
stdout.printf ("Section '%s' deleted\n", section.name);
} else {
Objects.Project? project = Services.Store.instance ().get_project (args.project_id.strip ());
if (project == null) {
stderr.printf ("Error: Project ID '%s' not found\n", args.project_id);
return 1;
}
project.delete_project (null);
stdout.printf ("Project '%s' deleted\n", project.name);
}

return 0;
}

private static int backup (BackupArguments args) {
Services.Database.get_default ().init_database ();

Expand Down Expand Up @@ -410,6 +447,8 @@ namespace PlanifyCLI {
return add_task (parsed.task_args);
case CommandType.BACKUP:
return backup (parsed.backup_args);
case CommandType.DELETE:
return delete_item (parsed.delete_args);
default:
stderr.printf ("Error: Unknown command\n");
return 1;
Expand Down
48 changes: 48 additions & 0 deletions test/cli/test-argument-parser.vala
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,51 @@ namespace PlanifyCLI.Tests.ArgumentParser {
print (" ✓ Returns error for unknown option\n---\n");
}

void test_delete_task () {
print ("Testing: 'delete' command with task-id\n");
int exit_code;
string[] args = {"planify-cli", "delete", "-t", "task-123"};

var parsed = PlanifyCLI.ArgumentParser.parse (args, out exit_code);

assert (parsed != null);
assert (exit_code == 0);
assert (parsed.command_type == PlanifyCLI.CommandType.DELETE);
assert (parsed.delete_args != null);
assert (parsed.delete_args.task_id == "task-123");
print (" ✓ Parses delete command with task-id\n---\n");
}

void test_delete_project () {
print ("Testing: 'delete' command with project-id\n");
int exit_code;
string[] args = {"planify-cli", "delete", "-i", "project-456"};

var parsed = PlanifyCLI.ArgumentParser.parse (args, out exit_code);

assert (parsed != null);
assert (exit_code == 0);
assert (parsed.command_type == PlanifyCLI.CommandType.DELETE);
assert (parsed.delete_args != null);
assert (parsed.delete_args.project_id == "project-456");
print (" ✓ Parses delete command with project-id\n---\n");
}

void test_delete_section () {
print ("Testing: 'delete' command with section-id\n");
int exit_code;
string[] args = {"planify-cli", "delete", "-s", "section-789"};

var parsed = PlanifyCLI.ArgumentParser.parse (args, out exit_code);

assert (parsed != null);
assert (exit_code == 0);
assert (parsed.command_type == PlanifyCLI.CommandType.DELETE);
assert (parsed.delete_args != null);
assert (parsed.delete_args.section_id == "section-789");
print (" ✓ Parses delete command with section-id\n---\n");
}

public void register_tests () {
Test.add_func ("/cli/argument_parser/no_command", test_no_command);
Test.add_func ("/cli/argument_parser/unknown_command", test_unknown_command);
Expand All @@ -277,5 +322,8 @@ namespace PlanifyCLI.Tests.ArgumentParser {
Test.add_func ("/cli/argument_parser/invalid_pin_value", test_invalid_pin_value);
Test.add_func ("/cli/argument_parser/invalid_complete_value", test_invalid_complete_value);
Test.add_func ("/cli/argument_parser/unknown_option", test_unknown_option);
Test.add_func ("/cli/argument_parser/delete_task", test_delete_task);
Test.add_func ("/cli/argument_parser/delete_project", test_delete_project);
Test.add_func ("/cli/argument_parser/delete_section", test_delete_section);
}
}