From 15dbb12758a2a435f684fafec12ef2866c36565a Mon Sep 17 00:00:00 2001 From: Andrej Rasevic <andrej@rasevicengineering.com> Date: Fri, 14 Jan 2022 00:11:25 -0500 Subject: [PATCH] adding exercise 2 --- exercises/exercise2/Exercise2_Description.md | 16 ++++ exercises/exercise2/cmd/todo/main.go | 86 ++++++++++++++++++ exercises/exercise2/go.mod | 3 + exercises/exercise2/todo.go | 92 ++++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 exercises/exercise2/Exercise2_Description.md create mode 100644 exercises/exercise2/cmd/todo/main.go create mode 100644 exercises/exercise2/go.mod create mode 100644 exercises/exercise2/todo.go diff --git a/exercises/exercise2/Exercise2_Description.md b/exercises/exercise2/Exercise2_Description.md new file mode 100644 index 0000000..8d426c6 --- /dev/null +++ b/exercises/exercise2/Exercise2_Description.md @@ -0,0 +1,16 @@ +# Exercise 2: + +## Due Date: Sunday, January 16, 2022 11:59 PM +## Objectives: To get familiar with using fundamentals of Go idioms and data structures. + +## Specifications/Requirements +1. You are given a go module: __exercise2__. The interface for your command line interface application has been provided for you. It is inside of the __cmd/todo__ directory. You need to complete the TODO items inside of __todo.go__. They consist of the following: +* complete the definition of the type item struct +* complete the Add method which adds a new todo item to the list +* complete the Complete method which updates the given todo item as completed +* complete the Delete method which removes the given todo item from the list + + +To deliver your submission you will need to commit your changes locally and push to your repo on the university gitlab server. +__NOTE__: You should not commit any executables or binaries as a result of compiling and building your application. + diff --git a/exercises/exercise2/cmd/todo/main.go b/exercises/exercise2/cmd/todo/main.go new file mode 100644 index 0000000..190fba7 --- /dev/null +++ b/exercises/exercise2/cmd/todo/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "gitlab.cs.umd.edu/arasevic/cmsc398Bwinter2022-student/exercises/exercise2" +) + +// Default file name +var todoFileName = "todo.json" + +func main() { + // Parsing command line flags + task := flag.String("task", "", "Task to be added to the ToDo list") + list := flag.Bool("list", false, "List all tasks") + complete := flag.Int("complete", 0, "Item to be completed") + delete := flag.Int("delete", -1, "Item to be deleted") + + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), + "%s cli client. CMSC398B Winter 2022 Exercise 2\n", os.Args[0]) + fmt.Fprintln(flag.CommandLine.Output(), "Usage information:") + flag.PrintDefaults() + } + + flag.Parse() + + // Check if the user defined the ENV VAR for a custom file name + if os.Getenv("TODO_FILENAME") != "" { + todoFileName = os.Getenv("TODO_FILENAME") + } + + // Define an items list + l := &todo.List{} + + // Use the Get command to read to do items from file + if err := l.Get(todoFileName); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + // Decide what to do based on the provided flags + switch { + case *list: + // List current to do items + fmt.Print(l) + case *complete > 0: + // Complete the given item + if err := l.Complete(*complete); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + // Save the new list + if err := l.Save(todoFileName); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + case *task != "": + // Add the task + l.Add(*task) + + // Save the new list + if err := l.Save(todoFileName); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + case *delete >= 0: + // Delete the given todo + if err := l.Delete(*delete); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + // Save the new list + if err := l.Save(todoFileName); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + default: + // Invalid flag provided + flag.Usage() + os.Exit(1) + } +} diff --git a/exercises/exercise2/go.mod b/exercises/exercise2/go.mod new file mode 100644 index 0000000..9dd05a9 --- /dev/null +++ b/exercises/exercise2/go.mod @@ -0,0 +1,3 @@ +module gitlab.cs.umd.edu/arasevic/cmsc398Bwinter2022-student/exercises/exercise2 + +go 1.17 diff --git a/exercises/exercise2/todo.go b/exercises/exercise2/todo.go new file mode 100644 index 0000000..8a05cf4 --- /dev/null +++ b/exercises/exercise2/todo.go @@ -0,0 +1,92 @@ +package todo + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + "time" +) + +//TODO +// item struct represents a ToDo item +// Members: Task (string) Done (bool) CreateAt (time.Time) CompletedAt (time.Time) +type item struct { + +} + +// List represents a list of ToDo items +type List []item + +//String prints out a formatted list +//Implements the fmt.Stringer interface +func (l *List) String() string { + formatted := "" + + for k, t := range *l { + prefix := " " + if t.Done { + prefix = "X " + } + + // Adjust the item number k to print numbers starting from 1 instead of 0 + formatted += fmt.Sprintf("%s%d: %s\n", prefix, k+1, t.Task) + } + + return formatted +} + +// TODO +// Add creates a new todo item and appends it to the list +func (l *List) Add(task string) { + +} + +//TODO +// Complete method marks a ToDo item as completed by +// setting Done = true and CompletedAt to the current time +func (l *List) Complete(i int) error { + + //if i <= 0 || i > len(ls) { + //return fmt.Errorf("Item %d does not exist", i) + //} + + return nil +} + +//TODO +// Delete method deletes a ToDo item from the list +func (l *List) Delete(i int) error { + + return nil +} + +// Save method encodes the List as JSON and saves it +// using the provided file name +func (l *List) Save(filename string) error { + data, err := json.Marshal(l) + if err != nil { + return err + } + + return ioutil.WriteFile(filename, data, 0644) +} + +// Get method opens the provided file name, decodes +// the JSON data and parse into a List +func (l *List) Get(filename string) error { + file, err := ioutil.ReadFile(filename) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil + } + return err + } + + if len(file) == 0 { + return nil + } + + return json.Unmarshal(file, l) +} -- GitLab