URI: 
       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