summaryrefslogtreecommitdiff
path: root/jt.md
blob: ca4f1088fea7c5c91f9437740a0c2d83756c67f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
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/