Rename into dossier - dossier - console collection manager
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
DIR LICENSE
---
DIR commit a1a5058a5a89c4d2b50fbf778d7a12979b097359
DIR parent e3c84c638f14e965a28fc7c610261d37036ed184
HTML Author: Solene Rapenne <solene@perso.pw>
Date: Tue, 24 Jul 2018 10:31:00 +0200
Rename into dossier
Diffstat:
M Makefile | 4 ++--
M README | 38 ++++++++++++++++----------------
D cdb | 277 -------------------------------
D cdb.1 | 124 -------------------------------
D cdb_sqlite | 142 -------------------------------
A dossier | 277 +++++++++++++++++++++++++++++++
A dossier.1 | 124 +++++++++++++++++++++++++++++++
7 files changed, 422 insertions(+), 564 deletions(-)
---
DIR diff --git a/Makefile b/Makefile
@@ -1,10 +1,10 @@
-# cdb – a console collection manage
+# dossier – a console collection manage
# See the LICENSE file for copyright and license details.
.POSIX:
VERSION = 0.1
-BIN = cdb
+BIN = dossier
PREFIX = /usr
BINDIR = ${PREFIX}/bin
MANDIR = ${PREFIX}/share/man
DIR diff --git a/README b/README
@@ -1,41 +1,41 @@
-How to use cdb
-==============
+How to use dossier
+==================
$ mkdir -p ~/collections/games
- $ cdb collections register ~/collections/games games
- $ cdb collections games
- $ cdb collections
+ $ dossier collections register ~/collections/games games
+ $ dossier collections games
+ $ dossier collections
games *
- $ cdb supertux rate 5 multiplayer yes
- $ cdb nexuiz rate 9 mutpliplayer yes
- $ cdb minetest rate 10 multiplayer yes
- $ cdb opensonic rate 2
- $ cdb openmw multiplayer no rate 10 style rpg
- $ cdb search multiplayer
+ $ dossier supertux rate 5 multiplayer yes
+ $ dossier nexuiz rate 9 mutpliplayer yes
+ $ dossier minetest rate 10 multiplayer yes
+ $ dossier opensonic rate 2
+ $ dossier openmw multiplayer no rate 10 style rpg
+ $ dossier search multiplayer
supertux:yes
nexuiz:yes
minetest:yes
openmw:no
- $ cdb search multiplayer no
+ $ dossier search multiplayer no
openmw
- $ cdb search multiplayer yes rate 5
+ $ dossier search multiplayer yes rate 5
supertux
- $ cdb supertux rate 6
- $ cdb show
+ $ dossier supertux rate 6
+ $ dossier show
supertux (2)
nexuiz (2)
minetest (2)
openmw (3)
opensonic (1)
- $ cdb show openmw
+ $ dossier show openmw
openmw:
multiplayer: no
style: rpg
rate: 10
- $ cdb opensonic
+ $ dossier opensonic
opensonic:
rate: 2
- $ cdb opensonic rate 3
- $ cdb opensonic
+ $ dossier opensonic rate 3
+ $ dossier opensonic
opensonic:
rate: 3
DIR diff --git a/cdb b/cdb
@@ -1,277 +0,0 @@
-#!/bin/sh
-
-REPOSITORY="${HOME}/.collections"
-mkdir -p "$REPOSITORY"
-test -f "${REPOSITORY}/current" && . "${REPOSITORY}/current"
-
-if [ -n "$CONTEXT" ]
-then
- REPO="${REPOSITORY}/${CONTEXT}/"
- cd "$REPO"
- test ! -d ".git" && git init
-else
- printf 'No current collection in use\n'
-fi
-
-
-# displays the values of an identifier
-# $1 identifier
-show() {
- cd "${REPO}"
- SEEN=0
- for attribute in *
- do
- if [ -f "${attribute}/${1}" ]
- then
- if [ "$SEEN" -eq 0 ]
- then
- printf "%s:\n" "$1"
- SEEN=1
- fi
- printf "%15s: %s\n" ${attribute} "$(cat "${attribute}/${1}")"
- fi
- done
- if [ "$SEEN" -eq 1 ]
- then
- exit 0
- else
- printf '%s is not in the library.\n' "$1"
- exit 1
- fi
-}
-
-# export the data in csv format "data","data","data"
-# we assume it'll works with the dataset
-export_csv() {
- cd "${REPO}"
-
- # display header
- printf '"identifier",'
- find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq | while read attr
- do
- printf '"%s",' $attr
- done
- printf '\n'
-
- # print database
- find . -name '.git' -prune -o -type f -print | cut -d '/' -f 3 | sort | uniq | while read id
- do
- printf '"%s",' "$id"
- find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq | while read attr
- do
- # for faster processing, we do not check existence of file before
- awk '{ printf "\"%s\",",$0}' "${attr}/${id}" 2>/dev/null \
- || printf '"",'
- done
- printf '\n'
- done
- IFS=$OLDIFS
- exit 0
-}
-
-# delete identifier from attributes
-# $1 identifier
-delete() {
- cd "${REPO}"
- SEEN=0
- for attribute in *
- do
- if [ -f "${attribute}/${1}" ]
- then
- git rm "${attribute}/${1}"
- git commit -m "Delete ${attribute} ${1}" "${attribute}/${1}"
- rmdir "${attribute}" 2> /dev/null
- SEEN=1
- fi
- done
-
- # did we find it?
- if [ "$SEEN" -eq 0 ]
- then
- printf "%s is not in the library!\n" "$1"
- exit 1
- else
- exit 0
- fi
-}
-
-# displays list of identifiers
-show_list() {
- cd "${REPO}"
- find . -name '.git' -prune -o -type f -print | cut -d '/' -f 3 | sort | uniq -c | \
- awk '{ for(i=2;i<=NF;i=i+1) { printf "%s ", $i }
- printf "(%i)\n", $1
- }'
- exit 0
-}
-
-# displays attributes used
-show_attributes() {
- cd "${REPO}"
- find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq -c | \
- awk '{ for(i=2;i<=NF;i=i+1) { printf "%s ", $i }
- printf "(%i)\n", $1
- }'
- exit 0
-}
-
-# add/modify a value
-# $@ identifier / attr / value / attr / value / ....
-# shift to have attr / value again and again
-add_value() {
- cd "$REPO"
- ID="$1"
- shift
-
- while [ "$#" -gt 1 ]
- do
- ATTRIBUTE="$1"
- VALUE="$2"
- shift 2
-
- mkdir -p "$ATTRIBUTE"
- printf '%s' "$VALUE" > "${ATTRIBUTE}/${ID}"
- git add "${ATTRIBUTE}/${ID}"
- git commit -m "Modify ${ATTRIBUTE} on ${ID}" "${ATTRIBUTE}/${ID}"
- done
- exit 0
-}
-
-# returns identifiers having attribute=value
-# $1 attribute
-# $2 value
-search_value() {
- cd "$REPO"
- shift
-
- RESULT=$(mktemp /tmp/cdb.XXXXXXXXXXXX)
- COUNT=0
- if [ -f "$RESULT" ]
- then
- while [ "$#" -gt 1 ]
- do
- ATTRIBUTE="$1"
- VALUE="$2"
- shift 2
- if [ ! -d "$ATTRIBUTE" ]
- then
- printf 'The attribute %s do not exists\n' "${ATTRIBUTE}"
- exit 5
- fi
- grep -rl "$VALUE" "$ATTRIBUTE" | cut -d '/' -f 2 >> "$RESULT"
- COUNT=$(( COUNT + 1 ))
- done
- sort "$RESULT" | uniq -c | \
- awk -v count=$COUNT \
- '{ if($1==count) {
- $1="" # remove uniq result
- gsub(/^[ ]+/,"",$0) # remove leading space due to uniq
- print
- }}'
- else
- printf 'Cannot create a temporary file in /tmp\n'
- exit 6
- fi
-
- exit 0
-}
-
-# returns list of identifiers in a attribute
-# $1 attribute
-list() {
- cd "$REPO"
- grep -r . "$1" | cut -d '/' -f 2- | sort
- exit 0
-}
-
-# displays usage
-usage() {
- printf '%s\n' \
- "Get help" \
- ": cdb help" \
- "" \
- "Export data as CSV" \
- ": cdb export" \
- "" \
- "Show collections, register collections, switch current collection" \
- ": cdb collections [register path name] [name]" \
- "" \
- "Show items and display informations about an item" \
- ": cdb show [identifier]" \
- "" \
- "Look at attributes, search items having some values" \
- ": cdb search [attribute [value]] ... [attribute [value]] ..." \
- "" \
- "Add / Modify attributes values on an item" \
- ": cdb identifier attribute value ... attribute value ..."
- exit 0
-}
-
-switch() {
- if [ ! -L "${REPOSITORY}/${1}" ]
- then
- printf 'Collection %s is not registered\n' "${1}"
- exit 9
- else
- printf 'Switching to collection %s\n' "${1}"
- printf 'CONTEXT=%s\n' $1 > "${REPOSITORY}/current"
- exit $?
- fi
-}
-
-collections() {
- ls "${REPOSITORY}" | grep -v 'current' | sed "s/^${CONTEXT}$/& */"
- exit 0
-}
-
-# create symlink to register a collection
-# $1 absolute path to collection
-# $2 name of collection
-register() {
- set -x
- if [ -d "${1}" ]
- then
- if ! expr "${1}" : '^/'
- then
- printf 'Aborting, the path of the collection must be an absolute path. %s is not valid\n' "${1}"
- fi
- test -L "${REPOSITORY}/${2}" && rm "${REPOSITORY}/${2}"
- ln -s "${1}" "${REPOSITORY}/${2}"
- exit 0
- else
- printf 'Aborting, %s is not a directory\n' "${2}"
- exit 8
- fi
-}
-
-if [ "$1" = "export" ] ; then export_csv ; fi
-if [ "$1" = "rm" ] && [ "$#" -eq 2 ] ; then delete "$2" ; fi
-if [ "$1" = "help" ] ; then usage ; fi
-
-# dealing with identifiers
-if [ "$1" = "show" ]
-then
- if [ "$#" -eq 1 ]; then show_list ; fi
- if [ "$#" -eq 2 ]; then show "$2" ; fi
-fi
-
-# dealing with attributes
-if [ "$1" = "search" ];
-then
- if [ "$#" -eq 1 ]; then show_attributes ; fi
- if [ "$#" -eq 2 ]; then list "$2" ; fi
- if [ "$#" -ge 3 ]; then search_value "$@" ; fi
-fi
-
-if [ "$1" = "collections" ]; then
- if [ "$#" -eq 1 ]; then collections ; fi
- if [ "$#" -eq 2 ]; then switch "$2" ; fi
- if [ "$2" = "register" ] && [ "$#" -eq 4 ]; then register "$3" "$4" ; fi
-fi
-
-if [ "$#" -ge 3 ]; then add_value "$@" ; fi
-
-# no command, maybe it's an item, try it
-if [ "$#" -eq 1 ]; then show "$1" ; fi
-
-usage
DIR diff --git a/cdb.1 b/cdb.1
@@ -1,124 +0,0 @@
-.Dd $Mdocdate: July 18 2018 $
-.Dt CDB 1
-.Os
-.Sh NAAME
-.Nm cdb
-.Nd a console collection manager
-.Sh SYNOPSIS
-.Nm
-.Op Cm show | Cm help | Cm export | Cm collections | Cm search | Ar item Op attribute value
-.Sh DESCRIPTION
-.Pp
-.Nm
-is a tool to register "items" into collections with metadata. Allowing to
-keep tracks of collections like wine, tea, video games, movie, music etc...
-.Pp
-Collections are a set of items, attributes and values.
-.Nm
-allows to manage different collections to not mix everything.
-.Bl -tag -width Ds
-.It Nm Cm help
-Show help
-.It Nm Cm show Op item-name
-the command
-.Cm show
-without argument will display the list of items in the current collection.
-.Pp
-With the argument
-.Ar item-name
-it will show all the attributes known for that item.
-.It Nm Cm export
-Export the data of the current collection as CSV (Comma Separated Values).
-.It Nm Cm collections Oo collection Oc | Oo register Pa full-path Ar collection-name Oc
-the command
-.Cm collections
-with no argument will show the list of collections that
-.Nm
-is aware of aka the collections that have been registered. The collection currently in use
-will be displayed with a
-.Sy *
-symbol after the name.
-.Pp
-the command
-.Cm collections
-with one parameter
-will switch the current collection in use to the collection
-.Ar collection.
-.Pp
-the command
-.Cm collections
-using the parameter
-.Ar register
-will make
-.Nm
-aware of a collection, this requires the full path
-.Ar full-path
-where is stored the collection and a name
-.Ar collection-name
-to identify it. When a collection is registered,
-.Nm
-will initialize a
-.Xr git 1
-repository in it if possible.
-.It Nm Cm search Oo attribute Oo value Oc Oc Op attribute value
-the command
-.Cm search
-with no argument will return the list of known attributes in the collections with the
-number of items for which the attribute is set.
-.Pp
-the command
-.Nm search
-with one parameter will return the list of the items for which
-.Ar attribute
-has been recorded and the associated value, using a semi colon as separator.
-.Pp
-The command
-.Nm search
-with two parameters will return the list of the items having the value
-.Ar value
-in the attribute
-.Ar attribute.
-.Pp
-Using more arguments will return the list of the items matching all the conditions of values in attributes.
-.It Nm Ar item-name
-shows all the attributes known for that item.
-.Pp
-In case you need to use an
-.Ar item-name
-like "collections" or any other name being a
-.Nm
-command, the command
-.Cm show Ar item-name
-is required.
-.It Nm Ar item-name Ar attribute Ar value Op Ar attribute2 Ar value2 Ar ...
-Associate the value
-.Ar value
-to the attribute
-.Ar attribute
-for item
-.Ar item-name.
-Multiples couple of
-.Ar attribute value
-can be used on the same command line to define multiples values.
-.Pp
-This is the way to add and update data inside a collection.
-.Pp
-Every modification is recorded with
-.Xr git 1 .
-
-.Sh FILES
-.Bl -tag -width "~/.collections" -compact
-.It Pa ~/.collections
-The directory where
-.Nm
-stores the collections registered as symlinks to their full path.
-.Sh EXIT
-.Ex -std cdb
-.Sh SEE ALSO
-.Xr git 1
-.Sh Authors
-.An -nosplit
-The
-.Nm
-program was written by
-.An Solène Rapenne Aq Mt solene@perso.pw
DIR diff --git a/cdb_sqlite b/cdb_sqlite
@@ -1,142 +0,0 @@
-#!/bin/sh
-
-if [ ! -f "database.sqlite" ]
-then
- printf 'CREATE TABLE collection ( id text primary key );' | \
- sqlite3 database.sqlite || exit 1
-fi
-#mkdir -p "${REPO}" || exit 1
-
-# displays the values of an identifier
-# $1 identifier
-show() {
- printf "SELECT * FROM collection WHERE id = '%s';" \
- "$1" | \
- sqlite3 database.sqlite -line
-
- if [ "$?" -eq 0 ]
- then
- exit 0
- else
- printf '%s is not in the library.\n' "$1"
- exit 1
- fi
-}
-
-# export the data in csv format "data","data","data"
-# we assume it'll works with the dataset
-export_csv() {
- sqlite3 database.sqlite -header -csv 'select * from collection;'
- exit $?
-}
-
-# delete identifier from attributes
-# $1 identifier
-delete() {
- printf "DELETE from collection where id = '%s';" "$1" | \
- sqlite3 database.sqlite
-
- if [ "$?" -ne 0 ]
- then
- printf "%s is not in the library!\n" "$1"
- exit 1
- else
- exit 0
- fi
-}
-
-# displays list of identifiers
-show_list() {
- printf "SELECT id from collection;" | \
- sqlite3 database.sqlite
- exit 0
-}
-
-# displays attributes used
-show_attributes() {
- sqlite3 database.sqlite 'PRAGMA table_info(collection)' | \
- cut -d '|' -f 2
- exit 0
-}
-
-# add/modify a value
-# $@ identifier / attr / value / attr / value / ....
-# shift to have attr / value again and again
-add_value() {
- ID="$1"
- shift
-
- while [ "$#" -gt 1 ]
- do
- ATTRIBUTE="$1"
- VALUE="$2"
- shift 2
-
- # add a column if it doesn't exist
- if [ -z "$(sqlite3 database.sqlite 'PRAGMA table_info(collection);' | grep "|${ATTRIBUTE}|")" ]
- then
- printf 'ALTER TABLE collection ADD COLUMN %s text;' "${ATTRIBUTE}" | \
- sqlite3 database.sqlite
- fi
- printf "INSERT INTO collection('id') VALUES ('%s');" "$ID" | \
- sqlite3 database.sqlite >/dev/null 2>&1
-
- printf "UPDATE collection SET %s = '%s' WHERE id = '%s';" \
- "$ATTRIBUTE" "$VALUE" "$ID" | \
- sqlite3 database.sqlite
- done
- exit 0
-}
-
-# returns identifiers having attribute=value
-# $1 attribute
-# $2 value
-search_value() {
- printf "SELECT id FROM collection WHERE %s = '%s';" \
- "$1" "$2" | \
- sqlite3 database.sqlite
- exit 0
-}
-
-# returns list of identifiers in a attribute
-# $1 attribute
-list() {
- printf "SELECT id,%s as attribute FROM collection WHERE attribute <> '';" \
- "$1" | \
- sqlite3 database.sqlite
- exit 0
-}
-
-# displays usage
-usage() {
- printf '%s\n' \
- "cdb help" \
- "cdb export" \
- "cdb show [identifier]" \
- "cdb search [attribute [value]]" \
- "cdb identifier attribute value ... attribute value ..."
- exit 0
-}
-
-if [ "$1" = "export" ] ; then export_csv ; fi
-if [ "$1" = "rm" ] && [ "$#" -eq 2 ] ; then delete "$2" ; fi
-if [ "$1" = "help" ] ; then usage ; fi
-
-# dealing with identifiers
-if [ "$1" = "show" ]
-then
- if [ "$#" -eq 1 ]; then show_list ; fi
- if [ "$#" -eq 2 ]; then show "$2" ; fi
-fi
-
-# dealing with attributes
-if [ "$1" = "search" ];
-then
- if [ "$#" -eq 1 ]; then show_attributes ; fi
- if [ "$#" -eq 2 ]; then list "$2" ; fi
- if [ "$#" -eq 3 ]; then search_value "$2" "$3" ; fi
-fi
-
-if [ "$#" -ge 3 ]; then add_value "$@" ; fi
-
-usage
DIR diff --git a/dossier b/dossier
@@ -0,0 +1,277 @@
+#!/bin/sh
+
+REPOSITORY="${HOME}/.collections"
+mkdir -p "$REPOSITORY"
+test -f "${REPOSITORY}/current" && . "${REPOSITORY}/current"
+
+if [ -n "$CONTEXT" ]
+then
+ REPO="${REPOSITORY}/${CONTEXT}/"
+ cd "$REPO"
+ test ! -d ".git" && git init
+else
+ printf 'No current collection in use\n'
+fi
+
+
+# displays the values of an identifier
+# $1 identifier
+show() {
+ cd "${REPO}"
+ SEEN=0
+ for attribute in *
+ do
+ if [ -f "${attribute}/${1}" ]
+ then
+ if [ "$SEEN" -eq 0 ]
+ then
+ printf "%s:\n" "$1"
+ SEEN=1
+ fi
+ printf "%15s: %s\n" ${attribute} "$(cat "${attribute}/${1}")"
+ fi
+ done
+ if [ "$SEEN" -eq 1 ]
+ then
+ exit 0
+ else
+ printf '%s is not in the library.\n' "$1"
+ exit 1
+ fi
+}
+
+# export the data in csv format "data","data","data"
+# we assume it'll works with the dataset
+export_csv() {
+ cd "${REPO}"
+
+ # display header
+ printf '"identifier",'
+ find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq | while read attr
+ do
+ printf '"%s",' $attr
+ done
+ printf '\n'
+
+ # print database
+ find . -name '.git' -prune -o -type f -print | cut -d '/' -f 3 | sort | uniq | while read id
+ do
+ printf '"%s",' "$id"
+ find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq | while read attr
+ do
+ # for faster processing, we do not check existence of file before
+ awk '{ printf "\"%s\",",$0}' "${attr}/${id}" 2>/dev/null \
+ || printf '"",'
+ done
+ printf '\n'
+ done
+ IFS=$OLDIFS
+ exit 0
+}
+
+# delete identifier from attributes
+# $1 identifier
+delete() {
+ cd "${REPO}"
+ SEEN=0
+ for attribute in *
+ do
+ if [ -f "${attribute}/${1}" ]
+ then
+ git rm "${attribute}/${1}"
+ git commit -m "Delete ${attribute} ${1}" "${attribute}/${1}"
+ rmdir "${attribute}" 2> /dev/null
+ SEEN=1
+ fi
+ done
+
+ # did we find it?
+ if [ "$SEEN" -eq 0 ]
+ then
+ printf "%s is not in the library!\n" "$1"
+ exit 1
+ else
+ exit 0
+ fi
+}
+
+# displays list of identifiers
+show_list() {
+ cd "${REPO}"
+ find . -name '.git' -prune -o -type f -print | cut -d '/' -f 3 | sort | uniq -c | \
+ awk '{ for(i=2;i<=NF;i=i+1) { printf "%s ", $i }
+ printf "(%i)\n", $1
+ }'
+ exit 0
+}
+
+# displays attributes used
+show_attributes() {
+ cd "${REPO}"
+ find . -name '.git' -prune -o -type f -print | cut -d '/' -f 2 | sort | uniq -c | \
+ awk '{ for(i=2;i<=NF;i=i+1) { printf "%s ", $i }
+ printf "(%i)\n", $1
+ }'
+ exit 0
+}
+
+# add/modify a value
+# $@ identifier / attr / value / attr / value / ....
+# shift to have attr / value again and again
+add_value() {
+ cd "$REPO"
+ ID="$1"
+ shift
+
+ while [ "$#" -gt 1 ]
+ do
+ ATTRIBUTE="$1"
+ VALUE="$2"
+ shift 2
+
+ mkdir -p "$ATTRIBUTE"
+ printf '%s' "$VALUE" > "${ATTRIBUTE}/${ID}"
+ git add "${ATTRIBUTE}/${ID}"
+ git commit -m "Modify ${ATTRIBUTE} on ${ID}" "${ATTRIBUTE}/${ID}"
+ done
+ exit 0
+}
+
+# returns identifiers having attribute=value
+# $1 attribute
+# $2 value
+search_value() {
+ cd "$REPO"
+ shift
+
+ RESULT=$(mktemp /tmp/dossier.XXXXXXXXXXXX)
+ COUNT=0
+ if [ -f "$RESULT" ]
+ then
+ while [ "$#" -gt 1 ]
+ do
+ ATTRIBUTE="$1"
+ VALUE="$2"
+ shift 2
+ if [ ! -d "$ATTRIBUTE" ]
+ then
+ printf 'The attribute %s do not exists\n' "${ATTRIBUTE}"
+ exit 5
+ fi
+ grep -rl "$VALUE" "$ATTRIBUTE" | cut -d '/' -f 2 >> "$RESULT"
+ COUNT=$(( COUNT + 1 ))
+ done
+ sort "$RESULT" | uniq -c | \
+ awk -v count=$COUNT \
+ '{ if($1==count) {
+ $1="" # remove uniq result
+ gsub(/^[ ]+/,"",$0) # remove leading space due to uniq
+ print
+ }}'
+ else
+ printf 'Cannot create a temporary file in /tmp\n'
+ exit 6
+ fi
+
+ exit 0
+}
+
+# returns list of identifiers in a attribute
+# $1 attribute
+list() {
+ cd "$REPO"
+ grep -r . "$1" | cut -d '/' -f 2- | sort
+ exit 0
+}
+
+# displays usage
+usage() {
+ printf '%s\n' \
+ "Get help" \
+ ": dossier help" \
+ "" \
+ "Export data as CSV" \
+ ": dossier export" \
+ "" \
+ "Show collections, register collections, switch current collection" \
+ ": dossier collections [register path name] [name]" \
+ "" \
+ "Show items and display informations about an item" \
+ ": dossier show [identifier]" \
+ "" \
+ "Look at attributes, search items having some values" \
+ ": dossier search [attribute [value]] ... [attribute [value]] ..." \
+ "" \
+ "Add / Modify attributes values on an item" \
+ ": dossier identifier attribute value ... attribute value ..."
+ exit 0
+}
+
+switch() {
+ if [ ! -L "${REPOSITORY}/${1}" ]
+ then
+ printf 'Collection %s is not registered\n' "${1}"
+ exit 9
+ else
+ printf 'Switching to collection %s\n' "${1}"
+ printf 'CONTEXT=%s\n' $1 > "${REPOSITORY}/current"
+ exit $?
+ fi
+}
+
+collections() {
+ ls "${REPOSITORY}" | grep -v 'current' | sed "s/^${CONTEXT}$/& */"
+ exit 0
+}
+
+# create symlink to register a collection
+# $1 absolute path to collection
+# $2 name of collection
+register() {
+ set -x
+ if [ -d "${1}" ]
+ then
+ if ! expr "${1}" : '^/'
+ then
+ printf 'Aborting, the path of the collection must be an absolute path. %s is not valid\n' "${1}"
+ fi
+ test -L "${REPOSITORY}/${2}" && rm "${REPOSITORY}/${2}"
+ ln -s "${1}" "${REPOSITORY}/${2}"
+ exit 0
+ else
+ printf 'Aborting, %s is not a directory\n' "${2}"
+ exit 8
+ fi
+}
+
+if [ "$1" = "export" ] ; then export_csv ; fi
+if [ "$1" = "rm" ] && [ "$#" -eq 2 ] ; then delete "$2" ; fi
+if [ "$1" = "help" ] ; then usage ; fi
+
+# dealing with identifiers
+if [ "$1" = "show" ]
+then
+ if [ "$#" -eq 1 ]; then show_list ; fi
+ if [ "$#" -eq 2 ]; then show "$2" ; fi
+fi
+
+# dealing with attributes
+if [ "$1" = "search" ];
+then
+ if [ "$#" -eq 1 ]; then show_attributes ; fi
+ if [ "$#" -eq 2 ]; then list "$2" ; fi
+ if [ "$#" -ge 3 ]; then search_value "$@" ; fi
+fi
+
+if [ "$1" = "collections" ]; then
+ if [ "$#" -eq 1 ]; then collections ; fi
+ if [ "$#" -eq 2 ]; then switch "$2" ; fi
+ if [ "$2" = "register" ] && [ "$#" -eq 4 ]; then register "$3" "$4" ; fi
+fi
+
+if [ "$#" -ge 3 ]; then add_value "$@" ; fi
+
+# no command, maybe it's an item, try it
+if [ "$#" -eq 1 ]; then show "$1" ; fi
+
+usage
DIR diff --git a/dossier.1 b/dossier.1
@@ -0,0 +1,124 @@
+.Dd $Mdocdate: July 18 2018 $
+.Dt DOSSIER 1
+.Os
+.Sh NAAME
+.Nm dossier
+.Nd a console collection manager
+.Sh SYNOPSIS
+.Nm
+.Op Cm show | Cm help | Cm export | Cm collections | Cm search | Ar item Op attribute value
+.Sh DESCRIPTION
+.Pp
+.Nm
+is a tool to register "items" into collections with metadata. Allowing to
+keep tracks of collections like wine, tea, video games, movie, music etc...
+.Pp
+Collections are a set of items, attributes and values.
+.Nm
+allows to manage different collections to not mix everything.
+.Bl -tag -width Ds
+.It Nm Cm help
+Show help
+.It Nm Cm show Op item-name
+the command
+.Cm show
+without argument will display the list of items in the current collection.
+.Pp
+With the argument
+.Ar item-name
+it will show all the attributes known for that item.
+.It Nm Cm export
+Export the data of the current collection as CSV (Comma Separated Values).
+.It Nm Cm collections Oo collection Oc | Oo register Pa full-path Ar collection-name Oc
+the command
+.Cm collections
+with no argument will show the list of collections that
+.Nm
+is aware of aka the collections that have been registered. The collection currently in use
+will be displayed with a
+.Sy *
+symbol after the name.
+.Pp
+the command
+.Cm collections
+with one parameter
+will switch the current collection in use to the collection
+.Ar collection.
+.Pp
+the command
+.Cm collections
+using the parameter
+.Ar register
+will make
+.Nm
+aware of a collection, this requires the full path
+.Ar full-path
+where is stored the collection and a name
+.Ar collection-name
+to identify it. When a collection is registered,
+.Nm
+will initialize a
+.Xr git 1
+repository in it if possible.
+.It Nm Cm search Oo attribute Oo value Oc Oc Op attribute value
+the command
+.Cm search
+with no argument will return the list of known attributes in the collections with the
+number of items for which the attribute is set.
+.Pp
+the command
+.Nm search
+with one parameter will return the list of the items for which
+.Ar attribute
+has been recorded and the associated value, using a semi colon as separator.
+.Pp
+The command
+.Nm search
+with two parameters will return the list of the items having the value
+.Ar value
+in the attribute
+.Ar attribute.
+.Pp
+Using more arguments will return the list of the items matching all the conditions of values in attributes.
+.It Nm Ar item-name
+shows all the attributes known for that item.
+.Pp
+In case you need to use an
+.Ar item-name
+like "collections" or any other name being a
+.Nm
+command, the command
+.Cm show Ar item-name
+is required.
+.It Nm Ar item-name Ar attribute Ar value Op Ar attribute2 Ar value2 Ar ...
+Associate the value
+.Ar value
+to the attribute
+.Ar attribute
+for item
+.Ar item-name.
+Multiples couple of
+.Ar attribute value
+can be used on the same command line to define multiples values.
+.Pp
+This is the way to add and update data inside a collection.
+.Pp
+Every modification is recorded with
+.Xr git 1 .
+
+.Sh FILES
+.Bl -tag -width "~/.collections" -compact
+.It Pa ~/.collections
+The directory where
+.Nm
+stores the collections registered as symlinks to their full path.
+.Sh EXIT
+.Ex -std dossier
+.Sh SEE ALSO
+.Xr git 1
+.Sh Authors
+.An -nosplit
+The
+.Nm
+program was written by
+.An Solène Rapenne Aq Mt solene@perso.pw