Giter VIP home page Giter VIP logo

grit's Introduction

Grit

Grit is an experimental personal task manager that represents tasks as nodes of a multitree, a class of directed acyclic graphs. The structure enables the subdivision of tasks, and supports short-term as well as long-term planning.

Contents

Installation

From source

Make sure go (>=1.14) and gcc are installed on your system. Get the latest release, and run:

$ make && sudo make install

External repositories

Introduction

(This section is a little technical — you may want to skip over to Practical guide first.)

Grit's design is based on two premises:

  1. Breaking a problem up into smaller, more manageable parts is generally a good approach to problem-solving.
  2. Tracking progress across time improves focus by removing the mental overhead associated with many parallel tasks spanning multiple days.

Tasks may be represented as tree nodes, enabling their subdivision. By introducing date nodes into the structure, and viewing the trees in the context of a larger multitree, we can distribute work on root tasks across multiple days by creating cross links to their descendants.

Trees

A big task may be represented as a tree, e.g.:

[~] Digitize family photos
 ├──[x] Scan album 1
 ├──[x] Scan album 2
 ├──[ ] Scan album 3
 └──[ ] ...

In the example above, the parent task is divided into a number of subtasks. Completing the subtasks is equivalent to completing the parent task.

Multitrees

In Multitrees: Enriching and Reusing Hierarchical Structure, George W. Furnas and Jeff Zachs introduce the structure:

[...] a class of directed acyclic graphs (DAGs) with the unusual property that they have large easily identifiable substructures that are trees. These subtrees have a natural semantic interpretation providing alternate hierarchical contexts for information, as well as providing a natural model for hierarchical reuse.

Unlike tree nodes, nodes of a multitree can have multiple parents, allowing us to create cross links between different task trees (see Links below).

Multitrees are digraphs, so the nodes are connected to one another by directed links. For our purposes, the direction flows from parent tasks to their subtasks. From any node we can induce a valid tree by following the outgoing links:

We also get valid inverted trees by going in the opposite direction, from nodes to their parents! This property is used by Grit to propagate changes made at the lower levels all the way up to the roots.

States

At any given time, a Grit task is said to be in one of the three states:

  1. [ ]inactive; task is yet to be completed
  2. [~]in progress; some of the subtasks have been completed
  3. [x] or [*]completed; [*] is used when the task is viewed in the context of a date that is different from the task's completion date

Date nodes

To add a time dimension to the structure, the idea of a date node is introduced.

A date node is a root node with a special name that follows the standard date format YYYY-MM-DD. Descendants of date nodes are supposed to be completed on the stated date. Date nodes exist so long as they link to at least one descendant—they are created and destroyed automatically.

Practical guide

Basic usage

Let's add a few things we want to do today:

$ grit add Take out the trash
(1) -> (2)
$ grit add Do the laundry
(1) -> (3)
$ grit add Call Dad
(1) -> (4)

Run grit without arguments to display the current date tree:

$ grit
[ ] 2020-11-10 (1)
 ├──[ ] Call Dad (4)
 ├──[ ] Do the laundry (3)
 └──[ ] Take out the trash (2)

So far it looks like an old-fashioned to-do list. We can check a task to mark it as completed:

$ grit check 2
$ grit
[~] 2020-11-10 (1)
 ├──[ ] Call Dad (4)
 ├──[ ] Do the laundry (3)
 └──[x] Take out the trash (2)

The change is automatically propagated through the graph. We can see that the status of the parent task (the date node) has changed to in progress.

Subtasks

Let's add another task:

$ grit add Get groceries
(1) -> (5)

To divide it into subtasks, we have to specify the parent (when no parent is given, add defaults to the current date node):

$ grit add -p 5 Bread
(5) -> (6)
$ grit add -p 5 Milk
(5) -> (7)
$ grit add -p 5 Eggs
(5) -> (8)

Task 5 is now pointing to subtasks 6, 7 and 8. We can create infinitely many levels, if needed.

$ grit
[~] 2020-11-10 (1)
 ├──[ ] Call Dad (4)
 ├──[ ] Do the laundry (3)
 ├──[ ] Get groceries (5)
 │   ├──[ ] Bread (6)
 │   ├──[ ] Eggs (8)
 │   └──[ ] Milk (7)
 └──[x] Take out the trash (2)

Check the entire branch:

$ grit check 5
$ grit tree 5
 [x] Get groceries (5)
  ├──[x] Bread (6)
  ├──[x] Eggs (8)
  └──[x] Milk (7)

The tree command prints out a tree rooted at the given node. When running grit without arguments, tree is invoked implicitly, defaulting to the current date node.

Roots

Some tasks are big—they can't realistically be completed in one day, so we can't associate them with a single date node. The trick is to add it as a root task and break it up into smaller subtasks. Then we can associate the subtasks with specific dates.

To create a root, run add with the -r flag:

$ grit add -r Work through Higher Algebra - Henry S. Hall
(9)

It's useful to assign aliases to frequently used nodes. An alias is an alternative identifier that can be used in place of a numeric one.

$ grit alias 9 textbook

The book contains 35 chapters—adding each of them individually would be very laborious. We can use a Bash loop to make the job easier (a feature like this will probably be added in a future release):

$ for i in {1..35}; do grit add -p textbook "Chapter $i"; done
(9) -> (10)
(9) -> (11)
...
(9) -> (44)

Working through a chapter involves reading it and solving all the exercise problems included at the end. Chapter 1 has 28 exercises.

$ grit add -p 10 Read the chapter
(10) -> (45)
$ grit add -p 10 Solve the exercises
(10) -> (46)
$ for i in {1..28}; do grit add -p 46 "Solve ex. $i"; done
(46) -> (47)
(46) -> (48)
...
(46) -> (74)

Our tree so far:

$ grit tree textbook
[ ] Work through Higher Algebra - Henry S. Hall (9:textbook)
 ├──[ ] Chapter 1 (10)
 │   ├──[ ] Read the chapter (45)
 │   └──[ ] Solve the exercises (46)
 │       ├──[ ] Solve ex. 1 (47)
 │       ├──[ ] Solve ex. 2 (48)
 │       ├──[ ] ...
 │       └──[ ] Solve ex. 28 (74)
 ├──[ ] Chapter 2 (11)
 ├──[ ] Chapter ...
 └──[ ] Chapter 35 (44)

We can do this for each chapter, or leave it for later, building our tree as we go along. In any case, we are ready to use this tree to schedule our day.

Before we proceed, let's run stat to see some more information about the node:

$ grit stat textbook

(9) ───┬─── (10)
       ├─── (11)
       :
       └─── (44)

ID: 9
Name: Work through Higher Algebra - Henry S. Hall
Status: inactive (0/63)
Parents: 0
Children: 35
Alias: textbook

We can confirm that the node is a root—it has no parents. There's a little map showing the node's parents and children. Progress is also displayed, calculated by counting all the leaves reachable from the node.

Links

Say we want to read the first chapter of our Algebra book, and solve a few exercises today. Let's add a new task to the current date node:

$ grit add Work on ch. 1 of the Algebra textbook
(1) -> (75)

Create cross links from this node to the relevant textbook nodes (the first argument to link is the origin, the ones following it are targets):

$ grit link 75 45 47 48 49
$ grit
[~] 2020-11-10 (1)
 ├──[x] ...
 └──[ ] Work on ch. 1 of the Algebra textbook (75)
     ├··[ ] Read the chapter (45)
     ├··[ ] Solve ex. 1 (47)
     ├··[ ] Solve ex. 2 (48)
     └··[ ] Solve ex. 3 (49)

The dotted lines indicate that the node has multiple parents. We can confirm this by taking a closer look at one of them using stat:

$ grit stat 45

(10) ───┐
(75) ───┴─── (45)

ID: 45
Name: Read the chapter
Status: inactive
Parents: 2
Children: 0

If we wanted to draw an accurate representation of the entire multitree at this point, it might look something like this:

This looks somewhat readable, but attempts to draw a complete representation of a structure even slightly more complex than this typically result in a tangled mess. Because of this, Grit only gives us glimpses of the digraph, one tree (or ls) at a time. Beyond that it relies on the user to fill in the gaps.

We can check the nodes and see how the changes propagate through the graph:

$ grit check 75
$ grit
[x] 2020-11-10 (1)
 ├──[x] ...
 └──[x] Work on ch. 1 of the algebra textbook (75)
     ├··[x] Read the chapter (45)
     ├··[x] Solve ex. 1 (47)
     ├··[x] Solve ex. 2 (48)
     └··[x] Solve ex. 3 (49)

The nodes are the same, so the change is visible in the textbook tree as well as the date tree:

$ grit tree textbook
[~] Work through Higher Algebra - Henry S. Hall (9:textbook)
 ├──[~] Chapter 1 (10)
 │   ├··[x] Read the chapter (45)
 │   └──[~] Solve the exercises (46)
 │       ├··[x] Solve ex. 1 (47)
 │       ├··[x] Solve ex. 2 (48)
 │       ├··[x] Solve ex. 3 (49)
 │       ├──[ ] Solve ex. 4 (50)
 │       ├──[ ] ...
 │       └──[ ] Solve ex. 28 (74)
 ├──[ ] ...
 └──[ ] Chapter 35 (44)

We've completed all the tasks for the day, but there's still work to be done under textbook. We can schedule more work for tomorrow:

$ grit add -p 2020-11-11 Work on the algebra textbook
(149) -> (150)
$ grit add -p 150 Solve exercises from ch. 1
(149) -> (151)
$ grit link 151 50 51 52 53 54
$ grit add -p 150 Work on ch. 2
(149) -> (152)
$ grit link 152 76 78 79 80
$ grit tree 2020-11-11
[x] 2020-11-10 (149)
 └──[ ] Work on the algebra textbook (150)
     ├──[ ] Solve exercises from ch. 1 (151)
     │   ├··[ ] Solve ex. 4 (50)
     │   ├··[ ] Solve ex. 5 (51)
     │   ├··[ ] Solve ex. 6 (52)
     │   ├··[ ] Solve ex. 7 (53)
     │   └··[ ] Solve ex. 8 (54)
     └──[ ] Work on ch. 2 (152)
         ├··[ ] Read the chapter (76)
         ├··[ ] Solve ex. 1 (78)
         ├··[ ] Solve ex. 2 (79)
         └··[ ] Solve ex. 3 (80)

Pointers

We can define a pointer as a non-task node whose purpose is to link to other nodes. Pointers can be used to classify tasks, or as placeholders for tasks expected to be added in the future.

Organizing tasks

One aspect where Grit differs from other productivity tools is the lack of tags. This is by choice—Grit is an experiment, and the idea is to solve problems by utilizing the multitree as much as possible.

How do we organize tasks without tags, then? As we add more and more nodes at the root level, things start to get messy. Running grit ls may result in a long list of assorted nodes. The Grit way to solve this is to make pointers.

For example, if our algebra textbook was just one of many textbooks, we could create a node named "Textbooks" and point it at them:

$ grit add -r Textbooks
(420)
$ grit alias 420 textbooks
$ grit link textbooks 81 184 349
$ grit ls textbooks
[~] Calculus - Michael Spivak (184)
[x] Higher Algebra - Henry S. Hall (81)
[ ] Linear Algebra - Jim Hefferon (349)

This gives them a parent, so they no longer appear at the root level.

Note that the same node can be pointed to by an infinite number of nodes, allowing us to create overlapping categories, e.g. the same node may be reachable from "Books to read" and "Preparation for the upcoming talk", etc.

Reading challenge

A challenge can be a good motivational tool:

$ grit add -r Read 24 books in 2020
(76)
$ grit alias 76 rc2020

We could simply add books to it as we go, but this wouldn't give us a nice way to track our progress. Let's go a step further and create a pointer (or "slot") for each of the 24 books.

$ for i in {1..24}; do grit add -p rc2020 "Book $i"; done
(76) -> (77)
(76) -> (78)
...
(76) -> (100)
$ grit tree rc2020
[ ] Challenge: Read 24 books in 2020 (76:rc2020)
 ├──[ ] Book 1 (77)
 ├──[ ] Book 2 (78)
 ├──[ ] ...
 └──[ ] Book 24 (100)

Now, whenever we decide what book we want to read next, we can simply create a new task and link the pointer to it:

$ grit add 1984 - George Orwell
(1) -> (101)
$ grit link 77 101
$ grit check 101
$ grit tree rc2020
[~] Challenge: Read 24 books in 2020 (76:rc2020)
 ├──[x] Book 1 (77)
 │   └──[x] 1984 - George Orwell (101)
 └──[ ] ...

The number of leaves remains the same, so stat will correctly display our progress:

$ grit stat rc2020
...
Status: in progress (1/24)
...

More information

For more information about specific commands, refer to grit --help.

License

This project is released under the MIT license.

grit's People

Contributors

climech avatar herbygillot avatar strogiyotec avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grit's Issues

Backup and cloud sync

Hi!

Thank you for the awesome tool!

I have two questions about the backup and cloud sync.

  1. Where can I find sqlite db file?
  2. What do you think about the cloud syncronization with rclone? If I will not modify database on the two place at the same time. Am I able to avoid any coherency problem?

diamonds are not allowed

when i tried to link two tasks , following error occurred :

Couldn't create link (5) -> (3): diamonds are not allowed

my terminal is alacritty ans OS is Arch Linux

[PANIC] When trying to link node from non-date root to date node 0

I'm getting panic when trying to link an existing node (from non date root) to not-yet-created date node 0.

Steps to reproduce

grit add -r Root # say it's num (1)
=> (1)
grit add -p 1 Child
=> (1) -> (2)
grit link 0 2

Full Backtrace

panic: invalid date node name: 0 [recovered]
	panic: invalid date node name: 0

goroutine 1 [running]:
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007e870, 0x4290e40, 0xc0000548f0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:39 +0xd8
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007e8d0, 0x4290e40, 0xc0000548f0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007eb40, 0x4290e40, 0xc0000548f0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).callDo.func1(0xc00007eb70, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:52 +0x4e
panic(0x4290e40, 0xc0000548f0)
	/usr/local/go/src/runtime/panic.go:965 +0x1b9
github.com/climech/grit/db.(*Database).CreateLinkFromDateNode(0xc00000e2a0, 0x7ffeefbff722, 0x1, 0x6, 0x0, 0x0, 0xc00011b9c8)
	/Users/vaporyhumo/git/tools/grit/db/link.go:97 +0x12b
github.com/climech/grit/app.(*App).LinkNodes(0xc000010180, 0x42891c0, 0xc000054800, 0x42891c0, 0xc000054810, 0x73, 0x0, 0x0)
	/Users/vaporyhumo/git/tools/grit/app/app.go:231 +0x188
main.cmdLink.func1()
	/Users/vaporyhumo/git/tools/grit/cmd/grit/cmds.go:190 +0x1a5
github.com/jawher/mow.cli/internal/flow.(*Step).callDo(0xc00007eb70, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:55 +0x70
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007eb70, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:25 +0x45
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007eb10, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc00007e8a0, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000051eb8, 0x0, 0x0)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow%2ecli.(*Cmd).parse(0xc000110700, 0xc0000120e0, 0x2, 0x2, 0xc000051eb8, 0xc00007e8a0, 0xc00007e8d0, 0xc00007e200, 0xc00005e100)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/commands.go:693 +0x53c
github.com/jawher/mow%2ecli.(*Cmd).parse(0xc000110000, 0xc0000120d0, 0x3, 0x3, 0xc000051eb8, 0xc000051eb8, 0xc00007e870, 0x0, 0x42a9e00)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/commands.go:707 +0x785
github.com/jawher/mow%2ecli.(*Cli).parse(0xc000051f48, 0xc0000120d0, 0x3, 0x3, 0xc000051eb8, 0xc000051eb8, 0xc00007e870, 0x1, 0xc000114080)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/cli.go:76 +0x85
github.com/jawher/mow%2ecli.(*Cli).Run(0xc000051f48, 0xc0000120c0, 0x4, 0x4, 0x18, 0x42c8b58)
	/Users/vaporyhumo/go/pkg/mod/github.com/jawher/[email protected]/cli.go:105 +0x12b
main.main()
	/Users/vaporyhumo/git/tools/grit/cmd/grit/main.go:36 +0x5bf

tree --progress: Feature to save space from children of checked nodes

Assuming the tree:

$ grit tree 2020-11-11
[~] 2020-11-10 (149)
 └──[~] Work on the algebra textbook (150)
     ├──[~] Solve exercises from ch. 1 (151)
     │   ├··[x] Solve ex. 4 (50)
     │   ├··[x] Solve ex. 5 (51)
     │   ├··[x] Solve ex. 6 (52)
     │   ├··[ ] Solve ex. 7 (53)
     │   └··[x] Solve ex. 8 (54)
     │       ├··[x] Solve ex. 8a (55)
     │       └··[x] Solve ex. 8b (56)
     └──[x] Work on ch. 2 (152)
         ├··[x] Read the chapter (76)
         ├··[x] Solve ex. 1 (78)
         ├··[x] Solve ex. 2 (79)
         └··[x] Solve ex. 3 (80)

it would be nice to have the more concise tree --progress:

$ grit tree --progress 2020-11-11
[~] 2020-11-10 (149)
 └──[~] Work on the algebra textbook (150)
     ├──[~] Solve exercises from ch. 1 (151)
     │   ├··[x] Solve ex. 4 (50)
     │   ├··[x] Solve ex. 5 (51)
     │   ├··[x] Solve ex. 6 (52)
     │   ├··[ ] Solve ex. 7 (53)
     │   └··[x] Solve ex. 8 (54)
     └──[x] Work on ch. 2 (152)

The goal here is to save space from children of checked nodes.
Or tree --concise may be better.

BTW, nice work! Thanks.

Labels

It would be nice to CRUD labels on tasks, links, etc and then be able to query them as well

Dockerfile

Hello!

Thanks for this amazing project. I saw it from lobste.rs.
I discovered the existence of multitree, and I will dig into that field.

Nonetheless, I am not fond of golang and don't want to install it on my machine, so I created a Dockerfile to compile and then run your project.

In a Dockerfile file at the root of your project:

FROM golang:1.16.3 AS build-env

WORKDIR /src
ADD . /src

RUN make

FROM ubuntu
COPY --from=build-env /src/grit /
ENTRYPOINT ["/grit"]

I built like this:

$ docker build -t grit .

And an alias:

$ alias grit='docker run --rm -it -v "$HOME/.config/grit":"/root/.config/grit" grit'

And I was able to follow your samples.

You may perhaps take advantage of the dockerhub automated builds and propose a built version of your project.

Note: I tried to make a distroless image, but I fall for the libc6 dependencies.
Note2: I can create a PR if you like the idea.

I love it

Just a pointless comment to tell you that I've been using grit for a couple of days now and I think it's great. I like how it handles nesting.. which is usually what keeps bringing me back to the pen and pad. Excited to see where this goes.

Task order

Ooh, I love it already, this has a lot of potential.

I was wondering though, now tasks are sorted alphabetically, instead of the order in which they are added. Is this on purpose? Because I tend to order my tasks and start at the top.

Would it be possible to sort tasks based on ID (so based on when they were added)? Or don't you want to get into the mess of allowing reordering? :P

Build fails on Windows Subsystem for Linux

Haven't had time to investigate yet, but linking is failing on WSL (Windows 10, Linux my-pc-name 4.4.0-19041-Microsoft #488-Microsoft Mon Sep 01 13:43:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux).

$ make
github.com/jawher/mow.cli/internal/flow
golang.org/x/sys/unix
github.com/climech/naturalsort
github.com/jawher/mow.cli/internal/lexer
github.com/kirsle/configdir
github.com/jawher/mow.cli/internal/container
github.com/jawher/mow.cli/internal/values
github.com/jawher/mow.cli/internal/matcher
github.com/mattn/go-sqlite3
github.com/jawher/mow.cli/internal/fsm
github.com/jawher/mow.cli/internal/parser
github.com/mattn/go-isatty
github.com/mattn/go-colorable
github.com/jawher/mow.cli
github.com/fatih/color
github.com/climech/grit/multitree
github.com/climech/grit/db
github.com/climech/grit/app
github.com/climech/grit/cmd/grit
# github.com/climech/grit/cmd/grit
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-620432474/000015.o: unrecognized relocation (0x2a) in section `.text'
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

make: *** [grit] Error 2

Things I've tried to no effect so far:

  • Clearing ~/.cache/go-build/
  • Running apt upgrade and apt update

Go version:

$ go version
go version go1.16.3 linux/amd64

GCC:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.4' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)

Feature Request: Task weight and Gantt Rendering

Thank you for this tool - it is much needed in the space.

To aid in capacity planning, the ability to add weights to tasks would offer considerable utility.

With the addition of task weights, a gantt chart could be rendered from the graph structure.

This would also make for a beautiful terminal experience 🙂

Cannot build on Ubuntu 18.04

Hi,
I'm having problems building the binary on my pc.
I extracted the release to my scripts folder on /home/USERNAME/scripts/grit-0.2.0
After running make && sudo make install I get the following error message.

can't load package: package /home/USERNAME/go/grit-0.2.0/cmd/grit: import "/home/USERNAME/go/grit-0.2.0/cmd/grit": cannot import absolute path
Makefile:15: recipe for target 'grit' failed
make: *** [grit] Error 1

The System is Ubuntu 18.04.5 LTS.
gcc is 7.5.0
go is 1.10.4 linux/amd64

Thank you very much

List all nodes

Thanks for this nifty little tool. I might be overseeing something but is there a way for the lazy to list all children nodes? I'm currently doing it this way but I was hoping there was a bit more elegant way :)

alias gritshowall="grit list-dates | grep -o '(.*)' | sed 's/(//' | sed 's/)//' | xargs -l grit ls"

Task "Submodules"

It would be really useful to be able to "mount" a multitree stored in a separate directory. Ideally it would be great if we could store this sub-directory in a project folder under git. The hope is that we can use this tool to create per-project task lists and manage/monitor these via git.

nil pointer error when link to non-existent task

When i create link to non-existent task, i get this error:

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x532ca6]

goroutine 1 [running]:
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000100870, 0x643f80, 0x790df0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:39 +0xd8
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc0001008d0, 0x643f80, 0x790df0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000100b40, 0x643f80, 0x790df0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).callDo.func1(0xc000100b70, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:52 +0x4e
panic(0x643f80, 0x790df0)
	/usr/lib/go/src/runtime/panic.go:965 +0x1b9
github.com/climech/grit/multitree.validateNewLink(0x0, 0xc000124070, 0xc0001243f0, 0xc000124700)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/multitree/node.go:313 +0x26
github.com/climech/grit/multitree.LinkNodes(0x0, 0xc000124070, 0xc000124070, 0x0)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/multitree/node.go:345 +0x39
github.com/climech/grit/db.createLink(0xc000118280, 0xa, 0x6, 0x0, 0x0, 0x6)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/db/link.go:55 +0x9f
github.com/climech/grit/db.(*Database).CreateLink.func1(0xc000118280, 0xc000118280, 0x0)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/db/link.go:73 +0x46
github.com/climech/grit/db.(*Database).execTxFunc(0xc00000e288, 0xc00011f938, 0x0, 0x0)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/db/db.go:79 +0x5d
github.com/climech/grit/db.(*Database).CreateLink(0xc00000e288, 0xa, 0x6, 0x6, 0x0, 0x0)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/db/link.go:80 +0x79
github.com/climech/grit/app.(*App).LinkNodes(0xc000010180, 0x638ec0, 0xc000056800, 0x638ec0, 0xc000056810, 0x73, 0x0, 0x0)
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/app/app.go:206 +0x225
main.cmdLink.func1()
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/cmd/grit/cmds.go:190 +0x1a5
github.com/jawher/mow.cli/internal/flow.(*Step).callDo(0xc000100b70, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:55 +0x70
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000100b70, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:25 +0x45
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000100b10, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc0001008a0, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow.cli/internal/flow.(*Step).Run(0xc000053eb8, 0x0, 0x0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/internal/flow/flow.go:29 +0xbb
github.com/jawher/mow%2ecli.(*Cmd).parse(0xc000116700, 0xc0000120e0, 0x2, 0x2, 0xc000053eb8, 0xc0001008a0, 0xc0001008d0, 0xc000100200, 0xc000060100)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/commands.go:693 +0x53c
github.com/jawher/mow%2ecli.(*Cmd).parse(0xc000116000, 0xc0000120d0, 0x3, 0x3, 0xc000053eb8, 0xc000053eb8, 0xc000100870, 0x0, 0x659bc0)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/commands.go:707 +0x785
github.com/jawher/mow%2ecli.(*Cli).parse(0xc000053f48, 0xc0000120d0, 0x3, 0x3, 0xc000053eb8, 0xc000053eb8, 0xc000100870, 0x1, 0xc000118080)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/cli.go:76 +0x85
github.com/jawher/mow%2ecli.(*Cli).Run(0xc000053f48, 0xc0000120c0, 0x4, 0x4, 0x18, 0x678d00)
	/home/anton/go/pkg/mod/github.com/jawher/[email protected]/cli.go:105 +0x12b
main.main()
	/home/anton/.cache/pacaur/grit-task-manager/src/grit/cmd/grit/main.go:36 +0x5bf

Question: Bullet Journaling Usecase

First of all thanks for putting time and effort into this, it looks really neat and has really narrow interface which I totally like.
I am also a big fan of bullet journaling, I don't know if you have heard of that technique - it is basically scheduling tasks on dates and moving them manually when you don't manage to complete them on the given date which in turn makes you reconsider if the task is really worth doing.

grit comes really close to resembling this workflow. However, one thing I am currently missing on the default view is a way for me to see if a node has been linked to another date/root.

Is that also something you had in mind when designing this or do you have other plans with this?

Visual example of what I mean.

>> grit
[ ] 2021-04-04 (1)
 └──[>] escalation (2) -> (2021-04-05, Textbox)* 
     ├──[ ] placeholder (5)
     └──[ ] sent email (3)

* This could be any alias.

Shell auto completion

I think a CLI tool like this would benefit greatly from having a robust shell auto completion.

Did some basic research and saw that the CLI lib you're using doesn't seem to have this feature either: jawher/mow.cli#113 -- which is a shame. Would you consider vendoring in these changes until the library devs figure out what to do?

I'd love to provide an MR instead of just a feature request, but I don't really know Go and its packaging well enough.

Moving nodes

I'm not sure I clearly see how to move a node/subgraph. I was expecting a grit move <node-id> [-p ]<parent-node-id> or if the node is to be a root node: grit move -r <node-id>.

Error building in osx 10.15.7

  • go version:

go version go1.15.5 darwin/amd64

  • gcc --version:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

  • Install output:
    make && sudo make install
    go: downloading github.com/fatih/color v1.10.0
    go: downloading github.com/jawher/mow.cli v1.2.0
    go: downloading github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
    go: downloading github.com/climech/naturalsort v0.1.0
    go: downloading github.com/mattn/go-sqlite3 v2.0.3+incompatible
    go: downloading github.com/mattn/go-colorable v0.1.8
    go: downloading github.com/mattn/go-isatty v0.0.12
    go: downloading golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae
    github.com/jawher/mow.cli/internal/flow
    golang.org/x/sys/unix
    github.com/kirsle/configdir
    github.com/climech/naturalsort
    github.com/jawher/mow.cli/internal/lexer
    github.com/jawher/mow.cli/internal/container
    github.com/jawher/mow.cli/internal/values
    github.com/jawher/mow.cli/internal/matcher
    github.com/jawher/mow.cli/internal/fsm
    github.com/jawher/mow.cli/internal/parser
    github.com/jawher/mow.cli
    github.com/mattn/go-isatty
    github.com/mattn/go-sqlite3
    github.com/mattn/go-colorable
    github.com/fatih/color
    github.com/climech/grit/multitree
    github.com/climech/grit/db
    github.com/climech/grit/app
    github.com/climech/grit/cmd/grit
    Password:
    install: illegal option -- D
    usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
    [-o owner] file1 file2
    install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
    [-o owner] file1 ... fileN directory
    install -d [-v] [-g group] [-m mode] [-o owner] directory ...
    make: *** [install] Error 64

Feature Request: Notes and search

Hi!
Thanks for the great tool.
It seems like it has big potential. Would be great to have ability to add notes to tasks and search through them.

The name `grit`.

I know changing a repositories name can lead to many problems. But I still think it should be changed.The name grit is already used a lot by other projects - often related to git which this is not. The name therefore doesn't seem very creative.

It seems to be a task node manager.

Brew formula

Thank you for making this! I found this project through HN and love the idea and execution.

I made a simple formula that enables the installation of grit using brew. It currently uses ab30f86 instead of a release version, because v0.2.0 does not build on macOS.

https://github.com/nvgrw/homebrew-formulae/blob/master/Formula/grit.rb

Installation is as simple as running brew install nvgrw/formulae/grit.

Obviously this is your project. Would you be able to set up your own brew tap and maintain a grit formula that is in sync with the releases in this repository? I'm pretty much a brew noob so this formula I whipped up probably doesn't follow any established best practices—it could be a useful starting point, though!

import -p=<n> doesn't work

Importing with a specified predecessor just creates a new root node no matter what.

> grit stat 1
(1) ──── (2)

ID: 1
Name: 2021-04-04
Status: inactive (0/5)
Parents: 0
Children: 1
Created: 2021-04-04 15:10:15
> grit import -p=1 (cat | psub)
Test node
^D
[ ] Test node (12)
Imported 1 trees (1 nodes)
> grit stat 12
ID: 12
Name: Test node
Status: inactive (0/1)
Parents: 0
Children: 0
Created: 2021-04-04 16:07:51

$XDG_CONFIG_HOME is ignored on macOS

grit stores the graph in ~/Library/Application Support/grit rather than $XDG_CONFIG_HOME/grit. Question: can configdir be adapted to this circumstance, or will the environment variable be ignored intentionally no matter what? I ask this because this is now my only CLI utility that stores stuff in my Library folder.

all commands panic on mac

I've install using make && make install, and I have go 1.17 + gcc. here's the panic:

$ grit                                                                                                                                                                                          [8:53:27]
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x7fff205d7cbe]

runtime stack:
runtime: unexpected return pc for runtime.sigpanic called from 0x7fff205d7cbe
stack: frame={sp:0x7ffeefbff5b8, fp:0x7ffeefbff608} stack=[0x7ffeefb80658,0x7ffeefbff6c0)
0x00007ffeefbff4b8:  0x01007ffeefbff4d8  0x0000000000000004
0x00007ffeefbff4c8:  0x000000000000001f  0x00007fff205d7cbe
0x00007ffeefbff4d8:  0x0b01dfacedebac1e  0x0000000000000001
0x00007ffeefbff4e8:  0x0000000004034df1 <runtime.throw+0x0000000000000071>  0x00007ffeefbff588
0x00007ffeefbff4f8:  0x000000000428e7af  0x00007ffeefbff540
0x00007ffeefbff508:  0x00000000040350a8 <runtime.fatalthrow.func1+0x0000000000000048>  0x00000000043c8e00
0x00007ffeefbff518:  0x0000000000000001  0x0000000000000001
0x00007ffeefbff528:  0x00007ffeefbff588  0x0000000004034df1 <runtime.throw+0x0000000000000071>
0x00007ffeefbff538:  0x00000000043c8e00  0x00007ffeefbff578
0x00007ffeefbff548:  0x0000000004035030 <runtime.fatalthrow+0x0000000000000050>  0x00007ffeefbff558
0x00007ffeefbff558:  0x0000000004035060 <runtime.fatalthrow.func1+0x0000000000000000>  0x00000000043c8e00
0x00007ffeefbff568:  0x0000000004034df1 <runtime.throw+0x0000000000000071>  0x00007ffeefbff588
0x00007ffeefbff578:  0x00007ffeefbff5a8  0x0000000004034df1 <runtime.throw+0x0000000000000071>
0x00007ffeefbff588:  0x00007ffeefbff590  0x0000000004034e20 <runtime.throw.func1+0x0000000000000000>
0x00007ffeefbff598:  0x0000000004291700  0x000000000000002a
0x00007ffeefbff5a8:  0x00007ffeefbff5f8  0x000000000404a3f6 <runtime.sigpanic+0x0000000000000396>
0x00007ffeefbff5b8: <0x0000000004291700  0x000000000401a8e5 <runtime.(*fixalloc).alloc+0x0000000000000085>
0x00007ffeefbff5c8:  0x00007ffeefbff638  0x00000000040280a6 <runtime.(*mheap).allocSpan+0x0000000000000546>
0x00007ffeefbff5d8:  0x000000c000110000  0x0000000000002000
0x00007ffeefbff5e8:  0x000000c000000008  0x000000000409f440 <syscall.libc_stat64_trampoline+0x0000000000000000>
0x00007ffeefbff5f8:  0x00007ffeefbff640 !0x00007fff205d7cbe
0x00007ffeefbff608: >0x00007ffeefbff640  0x00000000043a8000
0x00007ffeefbff618:  0x00000000000002b2  0x0000000004112205 <golang.org/x/sys/unix.libc_ioctl_trampoline+0x0000000000000005>
0x00007ffeefbff628:  0x0000000004065c3f <runtime.syscall+0x000000000000001f>  0x000000c000051848
0x00007ffeefbff638:  0x00007ffeefbff680  0x000000c000051818
0x00007ffeefbff648:  0x0000000004063ad0 <runtime.asmcgocall+0x0000000000000070>  0x0000000000000001
0x00007ffeefbff658:  0x000000c000062600  0x2600000004294fd0
0x00007ffeefbff668:  0x0000000000000010  0x0000000004268160
0x00007ffeefbff678:  0x0000000000000810  0x000000c0000001a0
0x00007ffeefbff688:  0x0000000004061be9 <runtime.systemstack+0x0000000000000049>  0x0000000000000004
0x00007ffeefbff698:  0x00000000042bb278  0x00000000043c8e00
0x00007ffeefbff6a8:  0x00007ffeefbff6f0  0x0000000004061ae5 <runtime.mstart+0x0000000000000005>
0x00007ffeefbff6b8:  0x0000000004061a9d <runtime.rt0_go+0x000000000000013d>
runtime.throw({0x4291700, 0x401a8e5})
	/usr/local/Cellar/go/1.17/libexec/src/runtime/panic.go:1198 +0x71
runtime: unexpected return pc for runtime.sigpanic called from 0x7fff205d7cbe
stack: frame={sp:0x7ffeefbff5b8, fp:0x7ffeefbff608} stack=[0x7ffeefb80658,0x7ffeefbff6c0)
0x00007ffeefbff4b8:  0x01007ffeefbff4d8  0x0000000000000004
0x00007ffeefbff4c8:  0x000000000000001f  0x00007fff205d7cbe
0x00007ffeefbff4d8:  0x0b01dfacedebac1e  0x0000000000000001
0x00007ffeefbff4e8:  0x0000000004034df1 <runtime.throw+0x0000000000000071>  0x00007ffeefbff588
0x00007ffeefbff4f8:  0x000000000428e7af  0x00007ffeefbff540
0x00007ffeefbff508:  0x00000000040350a8 <runtime.fatalthrow.func1+0x0000000000000048>  0x00000000043c8e00
0x00007ffeefbff518:  0x0000000000000001  0x0000000000000001
0x00007ffeefbff528:  0x00007ffeefbff588  0x0000000004034df1 <runtime.throw+0x0000000000000071>
0x00007ffeefbff538:  0x00000000043c8e00  0x00007ffeefbff578
0x00007ffeefbff548:  0x0000000004035030 <runtime.fatalthrow+0x0000000000000050>  0x00007ffeefbff558
0x00007ffeefbff558:  0x0000000004035060 <runtime.fatalthrow.func1+0x0000000000000000>  0x00000000043c8e00
0x00007ffeefbff568:  0x0000000004034df1 <runtime.throw+0x0000000000000071>  0x00007ffeefbff588
0x00007ffeefbff578:  0x00007ffeefbff5a8  0x0000000004034df1 <runtime.throw+0x0000000000000071>
0x00007ffeefbff588:  0x00007ffeefbff590  0x0000000004034e20 <runtime.throw.func1+0x0000000000000000>
0x00007ffeefbff598:  0x0000000004291700  0x000000000000002a
0x00007ffeefbff5a8:  0x00007ffeefbff5f8  0x000000000404a3f6 <runtime.sigpanic+0x0000000000000396>
0x00007ffeefbff5b8: <0x0000000004291700  0x000000000401a8e5 <runtime.(*fixalloc).alloc+0x0000000000000085>
0x00007ffeefbff5c8:  0x00007ffeefbff638  0x00000000040280a6 <runtime.(*mheap).allocSpan+0x0000000000000546>
0x00007ffeefbff5d8:  0x000000c000110000  0x0000000000002000
0x00007ffeefbff5e8:  0x000000c000000008  0x000000000409f440 <syscall.libc_stat64_trampoline+0x0000000000000000>
0x00007ffeefbff5f8:  0x00007ffeefbff640 !0x00007fff205d7cbe
0x00007ffeefbff608: >0x00007ffeefbff640  0x00000000043a8000
0x00007ffeefbff618:  0x00000000000002b2  0x0000000004112205 <golang.org/x/sys/unix.libc_ioctl_trampoline+0x0000000000000005>
0x00007ffeefbff628:  0x0000000004065c3f <runtime.syscall+0x000000000000001f>  0x000000c000051848
0x00007ffeefbff638:  0x00007ffeefbff680  0x000000c000051818
0x00007ffeefbff648:  0x0000000004063ad0 <runtime.asmcgocall+0x0000000000000070>  0x0000000000000001
0x00007ffeefbff658:  0x000000c000062600  0x2600000004294fd0
0x00007ffeefbff668:  0x0000000000000010  0x0000000004268160
0x00007ffeefbff678:  0x0000000000000810  0x000000c0000001a0
0x00007ffeefbff688:  0x0000000004061be9 <runtime.systemstack+0x0000000000000049>  0x0000000000000004
0x00007ffeefbff698:  0x00000000042bb278  0x00000000043c8e00
0x00007ffeefbff6a8:  0x00007ffeefbff6f0  0x0000000004061ae5 <runtime.mstart+0x0000000000000005>
0x00007ffeefbff6b8:  0x0000000004061a9d <runtime.rt0_go+0x000000000000013d>
runtime.sigpanic()
	/usr/local/Cellar/go/1.17/libexec/src/runtime/signal_unix.go:719 +0x396

goroutine 1 [syscall, locked to thread]:
syscall.syscall(0x4112200, 0x1, 0x40487413, 0xc0000518d8)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/sys_darwin.go:22 +0x3b fp=0xc000051848 sp=0xc000051828 pc=0x406093b
syscall.syscall(0x409b306, 0x400f2d4, 0xc000051900, 0x409b238)
	<autogenerated>:1 +0x26 fp=0xc000051890 sp=0xc000051848 pc=0x40663c6
golang.org/x/sys/unix.ioctl(0x4288624, 0x4, 0x1000000000008)
	/Users/Cam/go/pkg/mod/golang.org/x/[email protected]/unix/zsyscall_darwin_amd64.go:746 +0x39 fp=0xc0000518c0 sp=0xc000051890 pc=0x4111e99
golang.org/x/sys/unix.IoctlGetTermios(...)
	/Users/Cam/go/pkg/mod/golang.org/x/[email protected]/unix/ioctl.go:63
github.com/mattn/go-isatty.IsTerminal(0x4288624)
	/Users/Cam/go/pkg/mod/github.com/mattn/[email protected]/isatty_bsd.go:10 +0x50 fp=0xc000051930 sp=0xc0000518c0 pc=0x41122b0
github.com/fatih/color.init()
	/Users/Cam/go/pkg/mod/github.com/fatih/[email protected]/color.go:21 +0x7a fp=0xc000051968 sp=0xc000051930 pc=0x4112ffa
runtime.doInit(0x43ae220)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:6498 +0x123 fp=0xc000051aa0 sp=0xc000051968 pc=0x4044363
runtime.doInit(0x43ae1c0)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:6475 +0x71 fp=0xc000051bd8 sp=0xc000051aa0 pc=0x40442b1
runtime.doInit(0x43ad440)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:6475 +0x71 fp=0xc000051d10 sp=0xc000051bd8 pc=0x40442b1
runtime.doInit(0x43adfe0)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:6475 +0x71 fp=0xc000051e48 sp=0xc000051d10 pc=0x40442b1
runtime.doInit(0x43ae5a0)
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:6475 +0x71 fp=0xc000051f80 sp=0xc000051e48 pc=0x40442b1
runtime.main()
	/usr/local/Cellar/go/1.17/libexec/src/runtime/proc.go:238 +0x1e6 fp=0xc000051fe0 sp=0xc000051f80 pc=0x4037446
runtime.goexit()
	/usr/local/Cellar/go/1.17/libexec/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000051fe8 sp=0xc000051fe0 pc=0x4063dc1
FAIL

I've tried uninstalling and reinstalling. any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.