Skip to content

Commit

Permalink
Fixed error propagation and return status code
Browse files Browse the repository at this point in the history
  • Loading branch information
d4r1us-drk committed Sep 22, 2024
1 parent 8ad425a commit fdc7777
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 140 deletions.
52 changes: 23 additions & 29 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,40 @@ func NewCompletionCmd() *cobra.Command {
Bash:
$ source <(clido completion bash)
$ source <(clido completion bash)
# To load completions for each session, execute once:
# Linux:
$ clido completion bash > /etc/bash_completion.d/clido
# macOS:
$ clido completion bash > /usr/local/etc/bash_completion.d/clido
To load completions for each session, execute once:
Linux:
$ clido completion bash > /etc/bash_completion.d/clido
macOS:
$ clido completion bash > /usr/local/etc/bash_completion.d/clido
Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
If shell completion is not already enabled in your environment,
you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ clido completion zsh > "${fpath[1]}/_clido"
To load completions for each session, execute once:
$ clido completion zsh > "${fpath[1]}/_clido"
# You will need to start a new shell for this setup to take effect.
You will need to start a new shell for this setup to take effect.
fish:
$ clido completion fish | source
$ clido completion fish | source
# To load completions for each session, execute once:
$ clido completion fish > ~/.config/fish/completions/clido.fish
To load completions for each session, execute once:
$ clido completion fish > ~/.config/fish/completions/clido.fish
PowerShell:
PS> clido completion powershell | Out-String | Invoke-Expression
PS> clido completion powershell | Out-String | Invoke-Expression
# To load completions for every new session, run:
PS> clido completion powershell > clido.ps1
# and source this file from your PowerShell profile.
To load completions for every new session, run:
PS> clido completion powershell > clido.ps1
and source this file from your PowerShell profile.
`, // Detailed usage instructions for each shell

DisableFlagsInUseLine: true, // Disables flag usage display in the command usage line
Expand All @@ -59,16 +59,10 @@ PowerShell:
"fish",
"powershell",
}, // Specifies valid arguments for shell types
Args: func(cmd *cobra.Command, args []string) error {
// Ensures exactly one argument (shell type) is provided
if len(args) != 1 {
cmd.PrintErrln(
"Error: requires exactly one argument: bash, zsh, fish, or powershell",
)
return cobra.NoArgs(cmd, args) // Returns an error if no arguments are provided
}
return cobra.OnlyValidArgs(cmd, args) // Validates the argument
},
Args: cobra.MatchAll(
cobra.ExactArgs(1),
cobra.OnlyValidArgs,
), // Use MatchAll to enforce both conditions

Run: func(cmd *cobra.Command, args []string) {
// Switch case to handle shell type provided as argument
Expand Down
73 changes: 34 additions & 39 deletions cmd/edit.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"errors"
"strconv"

"github.com/d4r1us-drk/clido/controllers"
Expand All @@ -17,77 +18,72 @@ func NewEditCmd(
Use: "edit [project|task] <id>",
Short: "Edit an existing project or task",
Long: "Edit the details of an existing project or task identified by its ID.",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
// Ensure the command receives sufficient arguments (either "project" or "task" followed by an ID)
if len(args) < MinArgsLength {
cmd.Println("Insufficient arguments. Use 'edit project <id>' or 'edit task <id>'.")
return
return errors.New(
"insufficient arguments. Use 'edit project <id>' or 'edit task <id>'",
)
}

// Parse the ID argument into an integer
id, err := strconv.Atoi(args[1])
if err != nil {
cmd.Println("Invalid ID. Please provide a numeric ID.")
return
return errors.New("invalid ID. Please provide a numeric ID")
}

// Determine whether the user wants to edit a project or a task
switch args[0] {
case "project":
editProject(cmd, projectController, id)
return editProject(cmd, projectController, id)
case "task":
editTask(cmd, taskController, id)
return editTask(cmd, taskController, id)
default:
cmd.Println("Invalid option. Use 'edit project <id>' or 'edit task <id>'.")
return errors.New("invalid option. Use 'edit project <id>' or 'edit task <id>'")
}
},
}

// Define flags for the edit command, allowing users to specify what fields they want to update
cmd.Flags().
StringP("name", "n", "", "New name")
cmd.Flags().
StringP("description", "d", "", "New description")
cmd.Flags().
StringP("project", "p", "", "New parent project name or ID")
cmd.Flags().
StringP("task", "t", "", "New parent task ID for subtasks")
cmd.Flags().
StringP("due", "D", "", "New due date for task (format: YYYY-MM-DD HH:MM)")
cmd.Flags().StringP("name", "n", "", "New name")
cmd.Flags().StringP("description", "d", "", "New description")
cmd.Flags().StringP("project", "p", "", "New parent project name or ID")
cmd.Flags().StringP("task", "t", "", "New parent task ID for subtasks")
cmd.Flags().StringP("due", "D", "", "New due date for task (format: YYYY-MM-DD HH:MM)")
cmd.Flags().
IntP("priority", "P", 0, "New priority for task (1: High, 2: Medium, 3: Low, 4: None)")

return cmd
}

// editProject handles updating an existing project by its ID.
// It retrieves input from flags (name, description, and parent project), and uses the ProjectController.
func editProject(cmd *cobra.Command, projectController *controllers.ProjectController, id int) {
func editProject(
cmd *cobra.Command,
projectController *controllers.ProjectController,
id int,
) error {
name, _ := cmd.Flags().GetString("name")
description, _ := cmd.Flags().GetString("description")
parentProjectIdentifier, _ := cmd.Flags().GetString("project")

// Check if any fields are provided for update
if name == "" && description == "" && parentProjectIdentifier == "" {
cmd.Println(
"No fields provided for update. Use flags to update the name, description, or parent project.",
)
return
return errors.New("no fields provided for update. " +
"Use flags to update the name, description, or parent project")
}

// Call the controller to edit the project
err := projectController.EditProject(id, name, description, parentProjectIdentifier)
if err != nil {
cmd.Printf("Error updating project: %v\n", err)
return
return errors.New("error updating project: " + err.Error())
}

cmd.Printf("Project with ID '%d' updated successfully.\n", id)
cmd.Println("Project with ID '" + strconv.Itoa(id) + "' updated successfully.")
return nil
}

// editTask handles updating an existing task by its ID.
// It retrieves input from flags (name, description, due date, priority, and parent task) and uses the TaskController.
func editTask(cmd *cobra.Command, taskController *controllers.TaskController, id int) {
func editTask(cmd *cobra.Command, taskController *controllers.TaskController, id int) error {
name, _ := cmd.Flags().GetString("name")
description, _ := cmd.Flags().GetString("description")
dueDateStr, _ := cmd.Flags().GetString("due")
Expand All @@ -96,17 +92,16 @@ func editTask(cmd *cobra.Command, taskController *controllers.TaskController, id

// Validate priority if provided
if priority != 0 && (priority < PriorityHigh || priority > PriorityNone) {
cmd.Println("Invalid priority. Use 1 for High, 2 for Medium, 3 for Low, or 4 for None.")
return
return errors.New(
"invalid priority. Use 1 for High, 2 for Medium, 3 for Low, or 4 for None",
)
}

// Check if any fields are provided for update
if name == "" && description == "" && dueDateStr == "" && priority == 0 &&
parentTaskIdentifier == "" {
cmd.Println(
"No fields provided for update. Use flags to update the name, description, due date, priority, or parent task.",
)
return
return errors.New("no fields provided for update. " +
"Use flags to update the name, description, due date, priority, or parent task")
}

// Call the controller to edit the task
Expand All @@ -119,8 +114,7 @@ func editTask(cmd *cobra.Command, taskController *controllers.TaskController, id
parentTaskIdentifier,
)
if err != nil {
cmd.Printf("Error updating task: %v\n", err)
return
return errors.New("error updating task: " + err.Error())
}

// Format and display the new details
Expand All @@ -131,6 +125,7 @@ func editTask(cmd *cobra.Command, taskController *controllers.TaskController, id
formattedDueDate = utils.FormatDate(parsedDueDate)
}

cmd.Printf("Task with ID '%d' updated successfully.\n", id)
cmd.Printf("New details: Priority: %s, Due Date: %s\n", priorityStr, formattedDueDate)
cmd.Println("Task with ID '" + strconv.Itoa(id) + "' updated successfully.")
cmd.Println("New details: Priority: " + priorityStr + ", Due Date: " + formattedDueDate)
return nil
}
25 changes: 13 additions & 12 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"encoding/json"
"errors"
"os"
"strconv"

Expand All @@ -22,10 +23,9 @@ func NewListCmd(
Use: "list [projects|tasks]",
Short: "List projects or tasks",
Long: "List all projects or tasks, optionally filtered by project for tasks.",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
cmd.Println("Insufficient arguments. Use 'list projects' or 'list tasks'.")
return
return errors.New("insufficient arguments. Use 'list projects' or 'list tasks'")
}

// Retrieve flags for output format
Expand All @@ -34,10 +34,10 @@ func NewListCmd(

switch args[0] {
case "projects":
listProjects(cmd, projectController, outputJSON, treeView)
return listProjects(cmd, projectController, outputJSON, treeView)
case "tasks":
projectFilter, _ := cmd.Flags().GetString("project")
listTasks(
return listTasks(
cmd,
taskController,
projectController,
Expand All @@ -46,7 +46,7 @@ func NewListCmd(
treeView,
)
default:
cmd.Println("Invalid option. Use 'list projects' or 'list tasks'.")
return errors.New("invalid option. Use 'list projects' or 'list tasks'")
}
},
}
Expand All @@ -64,11 +64,10 @@ func listProjects(
projectController *controllers.ProjectController,
outputJSON bool,
treeView bool,
) {
) error {
projects, err := projectController.ListProjects()
if err != nil {
cmd.Printf("Error listing projects: %v\n", err)
return
return errors.New("error listing projects: " + err.Error())
}

switch {
Expand All @@ -79,6 +78,7 @@ func listProjects(
default:
printProjectTable(cmd, projects)
}
return nil
}

// listTasks lists tasks, optionally filtered by a project, in table, tree view, or JSON format.
Expand All @@ -89,11 +89,10 @@ func listTasks(
projectFilter string,
outputJSON bool,
treeView bool,
) {
) error {
tasks, project, err := taskController.ListTasksByProjectFilter(projectFilter)
if err != nil {
cmd.Printf("Error listing tasks: %v\n", err)
return
return errors.New("error listing tasks: " + err.Error())
}

if !outputJSON {
Expand All @@ -108,6 +107,7 @@ func listTasks(
default:
printTaskTable(taskController, projectController, tasks)
}
return nil
}

// printTaskHeader prints the header for the task list, either all tasks or tasks within a specific project.
Expand All @@ -119,6 +119,7 @@ func printTaskHeader(cmd *cobra.Command, project *models.Project) {
}
}

// printProjectsJSON outputs the projects in JSON format.
func printProjectsJSON(cmd *cobra.Command, projects []*models.Project) {
jsonData, jsonErr := json.MarshalIndent(projects, "", " ")
if jsonErr != nil {
Expand Down
Loading

0 comments on commit fdc7777

Please sign in to comment.