godoo

package module
v0.0.0-...-d06d904 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2022 License: MIT Imports: 5 Imported by: 0

README

Go-doo

Description

Go-doo is a command line notes/todo manager that lets you create, read & edit your notes or todo items - deletions coming soon. It supports both local and remote storage. Local is the default, and the remote option is determined by a config file. It uses SQLite for storage.

The remote storage option is only intended for use on the same LAN, rather than over the internet, to allow multiple machines/people to share share the same database for notes/todo items.

Notable features

Go-doo is intended for quick note-taking in the terminal so it uses a forgiving input parser. It can handle spaces in input, so you're not required to use quotation marks like you are in commit messages, for example. So godoo add -b input with spaces would create an item with a body of "input with spaces". You can also leave out some flags in different contexts, so the above example could be shortened to godoo add input with spaces and it would still be valid input.

It also uses a shorthand date format, where e.g. 1y1m8d is interpreted as 1 year, 1 month and 8 days from now. Full date strings like 2022-06-01 are also supported. The date shorthand also allows negative numbers, so searching for an item with a deadline of -8m means the deadline was 8 months ago. You can work with date ranges using the same shorthand. E.g. godoo get -d -7d:7d would return items with a deadline within a 14 day range, from 7 days before to 7 days from now.

In remote mode, there is also the option to run a priority queue based on the priority rating of items in the database. When creating or editing items, you can set their priority - none (n), low (l), medium (m), or high (h). You can then use godoo get -n to retrieve the item with the highest priority.

Usage

Creating new items

To create items, you use the add command with any combination of the following flags:

Flag Name Description Example Notes
-b body sets the body/content of the item you're creating add -b this is the body of the item -b can be omitted here and often elsewhere
-c childOf the item will be the child of the item whose id is passed as the argument add -c 8
-d deadline sets a deadline for the created item add -d 1 m 3 d same as add -d 1m3d
-m mode sets the priority rating of the new item add important note -m h support values are: n, l, m, h (none, low, medium, high)
-t tag adds tag to created item add -t work item given 'work' tag
Notes

Date ranges aren't supported for item creation. Multiple tag input is supported by add -t t1*t2*t3. The created item would have 't1', 't2' and 't3' tags. The delimiter (*) is configurable, but CLI interpreters don't allow certain characters, like semicolons.

You can often omit the body flag -b as the parser will try to figure out when the flag is missing and where to add it in. This is to allow for quick item creation, basically getting your thoughts out quickly. Typically, if the body is the first thing you write then you won't need to explicitly state the -b flag, but if the body follows other flags with string-based arguments then you're more likely to run into problems.

Examples:
  • godoo add this item has no body flag
    • would create a new item with a body of "this item has no body flag"
  • godoo add flagless body -d 3d
    • would create a new item with a deadline 3 days from now, and a body of "flagless body"
  • godoo add -d 3d flagless body
    • would return an error because, when creating items, arguments for the deadline flag can be upto 10 characters (configurable) so the parser can't (yet) determine where one argument ends and the next one begins
  • godoo add -c 77 flagless body
    • would create an item with body of "flagless body" whose parent item's id is 77 because the parser is able to figure out where the argument for the -c flag (77) ends and can implicitly add the -b flag

You can use these flags in various combinations when creating items. As above, the -b flag will be assumed where possible:

  • godoo add add tests to project -t dev*testing d 1m
    • would create an item with a body of "add tests to project", tags of "dev" & "testing", and a deadline one month from now.

Retrieving items

To search for items that you have already created you use the get command, which supports the following flags:

Flag Name Description Example Notes
-b body search by key phrase within body godoo get -b salmon fishcakes find items whose body contains phrase 'salmon fishcakes'
-i id search by id number godoo get -i 8 get item with id of 8
-d deadline search by deadline date godoo get -d 0d get items with a deadline of today
-e creationDate search by date item was created godoo get -e -7d:-3d get items created in a 4 day window between 7 and 3 days ago
-c childOf search by item's parent id godoo get -c 8 get items with a parentId of 8
-t tag search by tag godoo get -t dev return items marked with 'dev' tag
-a all get all items godoo get -a get every item
-f finished search by items marked as complete godoo get -f get all finished items
-F unfinished search by items marked as incomplete godoo get -F get all unfinished items
-n next get the next item with the highest priority godoo get -n the priority queue only contains unfinished items
Notes

Whenever a new item is successfully created, the prompt outputs the id number of the created item. It's this id number that you can search for using the -i flag.

You can use most of the flags listed in the above table in various combinations to build up very specific search criteria. The body flag can often be inferred in the same way described above, so it can be omitted in certain contexts.

The -a and -n flags can only be used in isolation - i.e. not as part of a larger query. If you do include them as part of a larger query/command, then the other flags & arguments will be ignored.

Examples
  • godoo get -F -d 0d
    • find any unfinished (not done) items with a deadline of today
  • godoo get -f -d -8d
    • find any complete/finished items with a deadline of 8 days ago
  • godoo get unique phrase -F -e -7d:0d
    • find any unfinished items created in the last 7 days whose body contains the words 'unique phrase'
  • godoo get unique phrase -F -e -7d
    • find any unfinished items created exactly 7 days ago whose body contains the words 'unique phrase'
  • godoo get -d -1m:1m -t notes -c 17 interesting fact -F -e -17d:0d
    • find items with a deadline between 1 month ago and 1 month from now; with a tag called 'notes'; which is a child of item 17; whose body contains the phrase 'interesting fact'; that is not marked as finished/complete; and that was created some time over the last 17 days

Note that there is no sense checking for conflicting dates. So it is possible that the last example above could return one or more items with a deadline that pre-dates its creationDate. I think it's useful for retrospective note-taking but there are reasonable grounds for adding sense-checking in future.

Editing existing items

The command to use for changing or updating existing items is edit. There are two categories of flag for editing: lowercase for searching, or determining which item(s) to edit, and uppercase for actually modifiying the data of one or more items.

This distinction enables you to use a single command to simultaneously search for and edit items. The searching component of this works in exactly the same way as it does for the get command (see above).

Flag Function Name Description Notes
-b search body search by key phrase in item body
-i search id search by item idNumber
-d search deadline search by item deadline supports shorthand, longhand, date ranges
-c search childOf search by parent idNumber
-e search creationDate search by creation date supports shorthand, longhand, date ranges
-f search finished search by completed items
-B edit changeBody edit the body field
-C edit changeParent change item's parent idNumber
-D edit changeDeadline change item's deadline no date ranges
-F edit toggleComplete toggle item's completion status if complete, change to incomplete; if incomplete, change to complete
-M edit changeMode change the item's/items' priority as above, supported values are n/l/m/h
--append behaviour append add new data to existing field only relevant for string fields like item's body
--replace behaviour replace replace existing data with new data only relevant for string fields like item's body
Notes

Date ranges are only supported by lowercase flags, or those with a 'search' function. Uppercase or editing flags do not support date ranges because a deadline is a specific date.

Examples
  • godoo edit -i 15 -F
    • ex. 1: item is incomplete
      • item with idNumber 15 marked complete
    • ex. 2: item is complete
      • item with idNumber 15 marked incomplete
  • godoo edit -c 3 -F
    • ex. 1: item incomplete
      • mark items with a parentId of 3 as done
    • ex. 2: item complete
      • mark items with a parentId of 3 as not done
  • godoo edit -b key phrase -D 1y
    • find item/s with 'key phrase' in the body and change the deadline to 1 year from now
  • godoo edit -i 3 -B --append something interesting
    • find item with id 3 and append the phrase 'something interesting' to the existing body
    • use the --replace flag to completely replace the body
      • if you don't pass either of them, you will be prompted to enter 'a' or 'r'
    • placement of standalone flags like --append, --replace, -f, -F doesn't matter
  • godoo edit -d -1m:5d -b golden badgers -e -3d:0d -B more common than you might think -D 12d --append
    • find items that: have a deadline of between 1 month before today, and 5 days after today; whose bodies contain the phrase 'golden badgers'; and which were created at some point over the last 3 days
    • append the phrase 'more common than you might think' to the existing body, and change the deadline to 12 days from now

Deleting items

Not yet supported but will be.

TODO

  • Easier setup/installation
    • Configuration is via an env file (Viper). The path for this is currently set in the SetConfigVals() method in go-doo/app/app.go
    • example config/env file in go-doo/example-env
  • Support deletions
    • need to decide if it should be by id only, or to allow the same search functionality as in the get and edit commands but maybe with user confirmation

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CMD_FLAG

type CMD_FLAG string

Flags used throughout the system

const (
	All             CMD_FLAG = "-a"
	Body            CMD_FLAG = "-b"
	Child           CMD_FLAG = "-c"
	Date            CMD_FLAG = "-d"
	Creation        CMD_FLAG = "-e" // e for existence!
	Finished        CMD_FLAG = "-f" // item complete
	ItmId           CMD_FLAG = "-i"
	Mode            CMD_FLAG = "-m"
	Next            CMD_FLAG = "-n"
	Parent          CMD_FLAG = "-p"
	Tag             CMD_FLAG = "-t"
	ChangeBody      CMD_FLAG = "-B" //append or replace
	ChangeParent    CMD_FLAG = "-C"
	ChangedDeadline CMD_FLAG = "-D"
	MarkComplete    CMD_FLAG = "-F"
	ChangeMode      CMD_FLAG = "-M"
	ChangeTag       CMD_FLAG = "-T" //append, replace, or remove
	AppendMode      CMD_FLAG = "--append"
	ReplaceMode     CMD_FLAG = "--replace"
	// Modifies the behaviour of the -n flag (next) in get command.
	// Instead of next by priority, it's next by date.
	DateMode CMD_FLAG = "--date"
)

type ConfigVals

type ConfigVals struct {
	Args       []string
	Client     http.Client
	TodoRepo   IRepository
	Instance   InstanceType
	RemoteUrl  string
	DateLayout string
	NowString  string
	Conn       string
	MaxLen     int
	IntDigits  int
	TagDelim   string
	Parser     IFlagParser
}

type DbType

type DbType string

Differnt kinds of supported RDBMS

const (
	Sqlite DbType = "sqlite3"
)

type FullUserQuery

type FullUserQuery struct {
	QueryOptions []UserQueryOption `json:"qryOpts"`
	QueryData    TodoItem          `json:"qryData"`
}

Single query object to combine query options alongside the relevant query data. Ex. ById is the query option and '8' is the query data

type ICliContext

type ICliContext interface {
	SetupCliContext(args []string)
	SetupFlagParser()
	GetCommand() (ICommand, error)
}

passed to different commands to run cli

type ICommand

type ICommand interface {
	ParseInput() error
	Run(io.Writer) error
	BuildItemFromInput() (TodoItem, error)
}

Sets out the methods implemented by commands that the user can execute

type IFlagParser

type IFlagParser interface {
	ParseUserInput() ([]string, error)
}

type IQueryingCommand

type IQueryingCommand interface {
	DetermineQueryType(qType QueryType) ([]UserQueryOption, error)
}

type IRepository

type IRepository interface {
	GetAll() ([]TodoItem, error)
	GetWhere(query FullUserQuery) ([]TodoItem, error)
	Add(itm *TodoItem) (int64, error)
	UpdateWhere(srchQry, edtQry FullUserQuery) (int, error)
}

Defines methods used to interact with data storage

type IServerContext

type IServerContext interface {
	SetupServerContext(conf ServerConfigVals)
	Serve()
}

type ITodoCollection

type ITodoCollection interface {
	Add(itm TodoItem) error
	Delete(id int) error
	Update(itm *TodoItem) error
	GetById(id int) (*TodoItem, error)
	GetNext() (*TodoItem, error)
}

Defines common behaviour of different collection types

type InstanceType

type InstanceType int

Denotes app instance's use of local, remote, or multiple storage options; determined via an environment variable

const (
	Local InstanceType = iota
	Remote
	Multiple // allows for simultaneous use of multiple storage options - all local, all remote, or a mix.

)

type ItemIdAlreadyExistsError

type ItemIdAlreadyExistsError struct{}

func (*ItemIdAlreadyExistsError) Error

func (e *ItemIdAlreadyExistsError) Error() string

type ItemIdNotFoundError

type ItemIdNotFoundError struct{}

func (*ItemIdNotFoundError) Error

func (i *ItemIdNotFoundError) Error() string

type ItemNotAddedToPriorityListError

type ItemNotAddedToPriorityListError struct{}

func (*ItemNotAddedToPriorityListError) Error

type ItemsList

type ItemsList struct {
	List  ITodoCollection
	LType ListType
}

ItemsList is a container for specific implementations of ITodoCollection

func NewItemsList

func NewItemsList(o ListOption) *ItemsList

type ListOption

type ListOption func(lst *ItemsList)

func WithListType

func WithListType(lt ListType) ListOption

type ListType

type ListType int
const (
	Simple ListType = iota
	Queue
)

type NegativeParentIdError

type NegativeParentIdError struct{}

func (*NegativeParentIdError) Error

func (e *NegativeParentIdError) Error() string

type PriorityLevel

type PriorityLevel int
const (
	None PriorityLevel = iota
	Low
	Medium
	High
	DateBased
)

type PriorityList

type PriorityList struct {
	DateMode bool
	List     PriorityQueue
}

PriorityList is an implementation of ITodoCollection

func NewPriorityList

func NewPriorityList() *PriorityList

Constructor for PriorityList()

func (*PriorityList) Add

func (pl *PriorityList) Add(itm TodoItem) error

Add item to queue - ITodoCollection implementation

func (*PriorityList) Delete

func (pl *PriorityList) Delete(id int) error

Delete item from queue - ITodoCollection implementation

func (*PriorityList) GetById

func (pl *PriorityList) GetById(id int) (*TodoItem, error)

func (*PriorityList) GetNext

func (pl *PriorityList) GetNext() (*TodoItem, error)

Get next item from queue based on priority - ITodoCollection implementation

func (*PriorityList) Update

func (pl *PriorityList) Update(itm *TodoItem) error

Update existing queue item - ITodoCollection implementation

type PriorityOption

type PriorityOption func(itm *TodoItem)

Function used in TodoItem initialisation to set PriorityLevel

func WithDateBasedPriority

func WithDateBasedPriority(date, dateFormat string) PriorityOption

func WithPriorityLevel

func WithPriorityLevel(p PriorityLevel) PriorityOption

type PriorityQueue

type PriorityQueue struct {
	DateMode bool
	Items    map[int]*TodoItem
}

PriorityQueue implements heap interface methods

func NewPriorityQueue

func NewPriorityQueue() *PriorityQueue

NewPriorityQueue constructor for PriorityQueue

func (PriorityQueue) Len

func (pq PriorityQueue) Len() int

Len required by heap.Interface

func (PriorityQueue) Less

func (pq PriorityQueue) Less(a, b int) bool

Less required by heap.Interface

func (*PriorityQueue) Pop

func (pq *PriorityQueue) Pop() interface{}

Pop required by heap.Interface

func (*PriorityQueue) Push

func (pq *PriorityQueue) Push(todoItm interface{})

Push required by heap.Interface

func (*PriorityQueue) Swap

func (pq *PriorityQueue) Swap(a, b int)

Swap required by heap.Interface

type QueryType

type QueryType int

Enum for basic CRUD operations. Used to switch on to get relevant SQL.

const (
	Add QueryType = iota
	Get
	Update
	Delete
)

type ServerConfigVals

type ServerConfigVals struct {
	Repo            IRepository
	Conn            string
	DateFormat      string
	PriorityList    *PriorityList
	RunPriorityList bool
	Port            int
}

type SimpleList

type SimpleList struct {
	List map[int]*TodoItem
}

SimpleList is an implementation of ITodoCollection

func NewSimpleList

func NewSimpleList() *SimpleList

func (*SimpleList) Add

func (sl *SimpleList) Add(itm TodoItem) error

func (*SimpleList) Delete

func (sl *SimpleList) Delete(id int) error

func (*SimpleList) GetById

func (sl *SimpleList) GetById(id int) (*TodoItem, error)

func (*SimpleList) GetNext

func (sl *SimpleList) GetNext() (*TodoItem, error)

func (*SimpleList) Update

func (sl *SimpleList) Update(itm *TodoItem) error

type TagAlreadyExistsError

type TagAlreadyExistsError struct{}

func (*TagAlreadyExistsError) Error

func (e *TagAlreadyExistsError) Error() string

type TodoItem

type TodoItem struct {
	Id           int                 `json:"itemId"`
	ParentId     int                 `json:"parentId"`
	IsChild      bool                `json:"isChild"`
	CreationDate time.Time           `json:"creationDate"`
	Deadline     time.Time           `json:"deadlineDate"`
	Priority     PriorityLevel       `json:"priority"`
	Body         string              `json:"itemText"`
	IsComplete   bool                `json:"isComplete"`
	ChildItems   map[int]struct{}    `json:"children"` // map of TodoItem.id with empty struct
	Tags         map[string]struct{} `json:"tags"`
	Index        int                 // for the implementation of a priority list
}

func NewTodoItem

func NewTodoItem(p PriorityOption) *TodoItem

NewTodoItem constructor initialises maps

func (*TodoItem) AddChildItem

func (itm *TodoItem) AddChildItem(childId int)

func (*TodoItem) AddTag

func (itm *TodoItem) AddTag(t string) error

func (*TodoItem) RemoveChildItem

func (itm *TodoItem) RemoveChildItem(childId int) error

func (*TodoItem) RemoveParent

func (itm *TodoItem) RemoveParent(parent *TodoItem) error

func (*TodoItem) SetParent

func (itm *TodoItem) SetParent(parentId int) error

type UserQueryElement

type UserQueryElement int

Enums describing the different item attributes that the user can query & edit

const (
	ById UserQueryElement = iota
	ByChildId
	ByParentId
	ByTag
	ByBody
	ByNextPriority
	ByNextDate
	ByDeadline
	ByCreationDate
	ByReplacement
	ByAppending
	ByCompletion
)

type UserQueryOption

type UserQueryOption struct {
	Elem           UserQueryElement `json:"elem"`
	UpperBoundDate time.Time        `json:"upperBound"`
}

Wrapper for a single UserQueryElement and a SetUpperDateBound function to allow for date range searching

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL