We’re going to write a “read it later”-tool (ril) in Go, and test it using the BATS (Bash Automated Testing System). Its purpose is to save URLs to an SQLite database for later viewing.
Each URL is assigned an integer id. IDs are formatted right-aligned in fields of width 4. The ID used in the examples below is 17.
A newly added URL is retrieved and the <title> element is parsed (e.g. https://www.example.com -> Example Domain). Use a User-Agent string containing “Read-it-later”. If the URL does not resolve with a 200 status, use “[Unknown Title]” as the title.
$ ril https://www.example.com
* [ 17] added.
Example Domain
https://www.example.com$ ril https://www.example.com https://www.example.org
* [ 17] added.
Example Domain
https://www.example.com
* [ 18] added.
Example Domain 2
https://www.example.org$ ril foo bar
* Error: `foo` is not a valid URL
* Error: `bar` is not a valid URL$ ril https://www.example.com
* [ 17] (previously added on 2025-12-19)
Example Domain
https://www.example.com$ ril https://www.example.com
* [ 17] (previously read on 2025-12-19, marked unread)
Example Domain
https://www.example.com$ ril https://www.example.com
* [ 17] (exists, snoozed until 2026-01-11)
Example Domain
https://www.example.com$ ril 17
* [ 17] Marked as read!
Example Domain
https://www.example.com$ ril read https://www.example.com <alias: ril r>
* [ 17] Marked as read!
Example Domain
https://www.example.com$ ril rm 17 <aliases: ril remove, ril delete>
* [ 17] REMOVED
Example Domain
https://www.example.comThe bare command lists the five oldest, unread and un-snoozed URLs.
$ ril
* [ 17]
Example Domain
https://www.example.com
* [ 18]
Example Domain
https://www.example.org
* <lists up to 3 more>
$ ril -n 20
<lists the 20 oldest unread and unsnoozed URLs>$ ril open <aliases: ril lucky, ril o>
* [ 17]
Example Domain
https://www.example.org
<web browser opens with that URL>Defaults to snoozing for 7 days.
$ ril snooze 17 --days 14
* [ 17] Snoozed until 2026-01-11
Example Domain
https://www.example.comIf the URL is already snoozed, the earlier of the snooze dates takes effect.
$ ril https://www.example.com
* [ 17]
Example Domain
https://www.example.com
$ ril undo
* [ 17] REMOVED
Example Domain
https://www.example.com$ ril 17
* [ 17] Marked as read!
Example Domain
https://www.example.com
$ ril undo
* [ 17] Marked as unread!
Example Domain
https://www.example.com$ ril s 17
* [ 17] Snoozed until 2026-01-11
Example Domain
https://www.example.com
$ ril undo
* [ 17] Marked as ready!
Example Domain
https://www.example.comNote that it is fine to lose the previous snoozed_until date when undoing a snooze that modified an already-snoozed URL.
The database is stored in ~/.local/share/ril/ril.db, but the location can be overridden using the --database/-D flag.