summaryrefslogtreecommitdiff
path: root/jt.md
diff options
context:
space:
mode:
Diffstat (limited to 'jt.md')
-rw-r--r--jt.md339
1 files changed, 339 insertions, 0 deletions
diff --git a/jt.md b/jt.md
new file mode 100644
index 0000000..ca4f108
--- /dev/null
+++ b/jt.md
@@ -0,0 +1,339 @@
+# Introduction
+
+The **jt** software (short for "journalling tool") is a helper for
+maintaining a journal or personal knowledge base. It has been written
+for the personal use of its authors, but might be useful for others.
+
+The guiding principle for jt is that having longevity for one's data
+and complete control over it are crucial. Because of these, the
+approach taken by jt is to build a static web site from source files
+stored in a version control system. The files will be edited with a
+text editor chosen by the journal writer, rather than via a custom
+web, desktop, or mobile application. The built journal is then served
+with some suitable web server.
+
+The role of jt is to make it easier to create new journal entries (new
+Markdown files), and to make all the common tasks of maintaining a
+knowledge base have minimal friction.
+
+## Example
+
+The following example creates a new journal, which will be the default
+journal for the user, and a new journal entry. The entry is a draft
+until it's finished.
+
+~~~sh
+$ jt --dirname ~/Journal init default "My private journal"
+$ jt new --tag meta --tag journalling "My first journal entry"
+... # text editor is opened so the new entry can be written
+$ jt finish 0 first-entry
+~~~
+
+
+# Acceptance criteria and their verification
+
+This chapter defines detailed acceptance criteria and how they're
+verified using *scenarios* for the [Subplot][] tool.
+
+[Subplot]: https://subplot.liw.fi/
+
+## Configuration file handling
+
+These scenarios verify that jt handles its configuration file
+correctly.
+
+### Shows defaults if no configuration file is present
+
+~~~scenario
+given an installed jt
+when I run jt config
+then stdout matches regex dirname:.*/\.local.share/jt
+then stdout matches regex editor: "/usr/bin/editor"
+~~~
+
+### Gives error if configuration missing file specified
+
+~~~scenario
+given an installed jt
+when I try to run jt --config does-not-exist config
+then command fails
+then stderr contains "does-not-exist"
+~~~
+
+### Accepts empty configuration file
+
+~~~scenario
+given an installed jt
+given file empty.yaml
+when I run jt --config empty.yaml config
+then stdout matches regex dirname:.*/\.local.share/jt
+then stdout matches regex editor: "/usr/bin/editor"
+~~~
+
+~~~{#empty.yaml .file .yaml}
+{}
+~~~
+
+### Accepts configuration file
+
+Note that the configuration file uses a tilde syntax to refer to the
+user's home directory.
+
+~~~scenario
+given an installed jt
+given file config.yaml
+when I run jt --config config.yaml config
+then stdout matches regex dirname:.*/.*/journal
+then stdout matches regex editor: "emacs"
+~~~
+
+~~~{#config.yaml .file .yaml}
+dirname: ~/journal
+editor: emacs
+~~~
+
+### Command line options override configuration file fields
+
+~~~scenario
+given an installed jt
+given file config.yaml
+when I run jt --config config.yaml --dirname xxx --editor yyy config
+then stdout matches regex dirname: "xxx"
+then stdout matches regex editor: "yyy"
+~~~
+
+
+
+### Rejects configuration file with extra entries
+
+~~~scenario
+given an installed jt
+given file toomuch.yaml
+when I try to run jt --config toomuch.yaml config
+then command fails
+then stderr contains "unknown_field"
+~~~
+
+~~~{#toomuch.yaml .file .yaml}
+unknown_field: foo
+~~~
+
+
+## Create a new local journal repository
+
+`jt` works on a local repository, and it can be created an initialised
+using the tool.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+and directory jrnl exists
+then there are no uncommitted changes in jrnl
+
+when I run jt --dirname jrnl is-journal
+then command is successful
+
+when I try to run jt --dirname bogus is-journal
+then command fails
+~~~
+
+
+## Create a new draft, edit it, then publish it
+
+Verify that we can create a new draft entry for the journal.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+and there are no drafts in jrnl
+and there are no journal entries in jrnl
+
+when I run jt --editor=none --dirname=jrnl new "Abracadabra"
+then command is successful
+and there is one draft in jrnl
+and draft 0 in jrnl contains "Abracadabra"
+and draft 0 in jrnl contains "!meta date="
+
+when I run jt --dirname=jrnl list
+then stdout matches regex ^0 Abracadabra$
+
+given an executable script append.sh
+when I run jt --editor=./append.sh --dirname=jrnl edit 0
+then command is successful
+and draft 0 in jrnl contains "Open sesame!"
+
+when I run jt --dirname=jrnl finish 0 abra
+then command is successful
+and there is one journal entry in jrnl, at FILE
+and file name <FILE> ends with .mdwn
+and journal entry <FILE> contains "Abracadabra"
+and journal entry <FILE> contains "Open sesame!"
+and there are no drafts in jrnl
+and there are no uncommitted changes in jrnl
+~~~
+
+~~~{#append.sh .file .numberLines}
+#!/bin/sh
+set -eux
+echo "Open sesame!" >> "$1"
+~~~
+
+## Create two drafts
+
+Verify that we can create two draft entries at the same time.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+then there are no drafts in jrnl
+then there are no journal entries in jrnl
+
+when I run jt --editor=none --dirname=jrnl new "Abracadabra"
+then command is successful
+then there is one draft in jrnl
+then draft 0 in jrnl contains "Abracadabra"
+
+when I run jt --editor=none --dirname=jrnl new "Simsalabim"
+then command is successful
+then there are two drafts in jrnl
+then draft 0 in jrnl contains "Abracadabra"
+then draft 1 in jrnl contains "Simsalabim"
+
+given an executable script append.sh
+when I run jt --editor=./append.sh --dirname=jrnl edit 0
+then draft 0 in jrnl contains "Open sesame!"
+when I run jt --editor=./append.sh --dirname=jrnl edit 1
+then draft 1 in jrnl contains "Open sesame!"
+
+when I run jt --dirname=jrnl finish 0 abra
+then command is successful
+then there is one journal entry in jrnl, at FILE
+then journal entry <FILE> contains "Abracadabra"
+then journal entry <FILE> contains "Open sesame!"
+then there is one draft in jrnl
+
+when I run jt --dirname=jrnl finish 1 sim
+then command is successful
+then there are two journal entries in jrnl, at FILE1 and FILE2
+then journal entry <FILE1> contains "Abracadabra"
+then journal entry <FILE2> contains "Simsalabim"
+then there are no drafts in jrnl
+then there are no uncommitted changes in jrnl
+~~~
+
+
+
+
+
+## Remove a draft
+
+Verify that we can remove a draft, and then create a new one.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+and there are no drafts in jrnl
+and there are no journal entries in jrnl
+
+when I run jt --editor=none --dirname=jrnl new "Hulabaloo"
+then command is successful
+and there is one draft in jrnl
+and draft 0 in jrnl contains "Hulabaloo"
+and draft 0 in jrnl contains "!meta date="
+
+when I run jt --dirname=jrnl remove 0
+then command is successful
+and there are no drafts in jrnl
+and there are no journal entries in jrnl
+
+when I run jt --editor=none --dirname=jrnl new "Abracadabra"
+then command is successful
+and there is one draft in jrnl
+and draft 0 in jrnl contains "Abracadabra"
+and draft 0 in jrnl contains "!meta date="
+~~~
+
+## Override template for new journal entries
+
+Verify that we can have a custom template for new journal entries.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+
+given file jrnl/.config/templates/new_entry from new_entry_template
+
+when I run jt --editor=none --dirname=jrnl new "Abracadabra"
+then command is successful
+and there is one draft in jrnl
+and draft 0 in jrnl contains "custom new entry template"
+~~~
+
+~~~{#new_entry_template .file .numberLines}
+This is a custom new entry template.
+~~~
+
+## Use topic pages
+
+Verify that we can create a new topic page and a new entry referring
+to that topic page.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+
+when I try to run jt --editor=none --dirname=jrnl new --topic foo.bar "Abracadabra"
+then command fails
+then stderr contains "foo.bar"
+
+when I run jt --editor=none --dirname=jrnl new-topic topics/foo.bar "Things about Foobars"
+then command is successful
+then file jrnl/topics/foo.bar.mdwn contains "Things about Foobars"
+then there are no uncommitted changes in jrnl
+
+when I run jt --editor=none --dirname=jrnl new --topic topics/foo.bar "Abracadabra"
+then command is successful
+and there is one draft in jrnl
+and draft 0 in jrnl links to "topics/foo.bar"
+~~~
+
+## Allow many topics per post
+
+Sometimes a post relates to several topics.
+
+~~~scenario
+given an installed jt
+
+when I run jt --dirname jrnl init default "My test journal"
+then command is successful
+
+when I run jt --editor=none --dirname=jrnl new-topic topics/foo "Foo"
+when I run jt --editor=none --dirname=jrnl new-topic topics/bar "Bar"
+
+when I run jt --editor=none --dirname=jrnl new --topic topics/foo --topic topics/bar "Abracadabra"
+then command is successful
+then there is one draft in jrnl
+then draft 0 in jrnl links to "topics/foo"
+then draft 0 in jrnl links to "topics/bar"
+~~~
+
+
+# Colophon
+
+This document is meant to be processed with the [Subplot][] program to
+typeset into HTML or PDF or to generate a program that automatically
+verifies that all acceptance criteria are met.
+
+[Subplot]: https://subplot.liw.fi/