tagger

Simple tagging system for any types of files
git clone git://git.konyahin.xyz/tagger
Log | Files | Refs | LICENSE

tagger (3725B)


      1 #!/usr/bin/env sh
      2 # disable warnings about variables are declared indirectly
      3 # shellcheck disable=SC2154
      4 
      5 ## tagger - simple tagging system for any types of files
      6 
      7 # Developer notes
      8 # - 'tagger alias folder' for output alias and completion commands
      9 # - add '_tagger_completion name folder` for aliases completion
     10 # - check command for test tagger folder correctnes
     11 # - you can make completition as separate task, maybe?
     12 #   so you can get arguments and decide wath to complete
     13 
     14 set -e
     15 
     16 # Error handling and checks
     17 err () {
     18     echo "$@" >&2
     19     exit
     20 }
     21 
     22 check () {
     23     name="$1"
     24     value="$2"
     25     desc="$3"
     26 
     27     pexist "$value" "$desc"
     28     shift 3
     29 
     30     for chk in "$@"
     31     do
     32         "$chk" "$value" "$desc"
     33     done
     34 
     35     [ -n "$name" ] && eval "$name=$value"
     36 }
     37 
     38 check_all () {
     39     name="$1"
     40     vars="$2"
     41     desc="$3"
     42 
     43     pexist "$vars" "$desc"
     44     shift 3
     45 
     46     for chk in "$@"
     47     do
     48         for var in $vars
     49         do
     50             "$chk" "$var" "$desc"
     51         done
     52     done
     53 
     54     [ -n "$name" ] && eval "$name=\"$vars\""
     55 }
     56 
     57 pexist () {
     58     [ -z "$1" ] &&
     59 	err "$2 should be specified"
     60 }
     61 
     62 pnotagger () {
     63     [ -d "$BASE" ] &&
     64 	err "$2 is already contain tagger: $1"
     65 }
     66 
     67 pfile () {
     68     [ ! -f "$1" ] &&
     69 	err "$2 should exist and be a file: $1"
     70 }
     71 
     72 pdir () {
     73     [ ! -d "$1" ] &&
     74 	err "$2 should exist and be a directory: $1"
     75 }
     76 
     77 ptagged () {
     78     [ ! -f "$BASE/$1" ] &&
     79 	err "$2 should be added before: $1"
     80 }
     81 
     82 ptag () {
     83     [ ! -d "$BASE/../$1" ] &&
     84 	  err "$2 should exist: $1"
     85 }
     86 
     87 pbase () {
     88     [ ! -d "$BASE" ] &&
     89 	err "$2 should be initialized by tagger: $1"
     90 }
     91 
     92 # Script logic
     93 
     94 ##
     95 ## Usage:
     96 ##
     97 ## Common pattern is:
     98 ## 	tagger _folder_ command [arguments ...]
     99 ## 
    100 print_help () {
    101 	awk '/^##/{print substr($0, 4);}' "$SCRIPT"
    102 	exit
    103 }
    104 
    105 ## tagger _folder_ init
    106 ## 	create new folder structure, for
    107 ## 	keeping files and tags
    108 ##
    109 init_tagger () {
    110     check "" "$1" folder pnotagger
    111 
    112     mkdir -p "$BASE"
    113 }
    114 
    115 ## tagger _folder_ add [_file_ ...]
    116 ## 	move file to tagger in tagger folder
    117 ##
    118 add_file () {
    119     check ""   "$1" "tagger folder" pdir pbase
    120     #check file "$3" file            pfile
    121     shift 2
    122     check_all files "$*" files pfile
    123 
    124     mv "$files" "$BASE"
    125 }
    126 
    127 ## tagger _folder_ tag _file_ _tag_
    128 ## 	add tag to file from tagger folder
    129 ##
    130 tag_file () {
    131     check folder "$1" "tagger folder" pdir pbase
    132     check file   "$3" file            ptagged
    133     check tag    "$4" tag
    134 
    135     tag_folder="$folder/$tag"
    136     mkdir -p "$tag_folder"
    137     ln -s "../.base/$file" "$tag_folder"
    138 }
    139 
    140 ## tagger _folder_ untag _file_ _tag_
    141 ## 	remove tag from file in tagger folder
    142 ##
    143 untag_file () {
    144     check folder "$1" "tagger folder" pdir pbase
    145     check file   "$3" file            ptagged
    146     check tag    "$4" tag             ptag
    147 
    148     tag_folder="$folder/$tag"
    149     rm -f "$tag_folder/$file"
    150 }
    151 
    152 ## tagger _folder_ ls
    153 ## 	list all files under tagger folder
    154 ##
    155 list () {
    156     check "" "$1" "tagger folder" pdir pbase
    157     ls -1 "$BASE"
    158 }
    159 
    160 ## tagger _folder_ path _file_
    161 ## 	get path for tagged file
    162 ##
    163 path () {
    164     check ""   "$1" "tagger folder" pdir pbase
    165     check file "$3" file            ptagged
    166 
    167     echo "$BASE/$file"
    168 }
    169 
    170 ## tagger _folder_ rm _file_
    171 ##  remove file from tagger
    172 ##
    173 remove () {
    174     check ""   "$1" "tagger folder" pdir pbase
    175     check file "$3" file            ptagged
    176 
    177     rm -f "$BASE"/../*/"$file"
    178     rm "$BASE/$file"
    179 }
    180 
    181 # Process arguments
    182 
    183 SCRIPT=$(dirname "$0")/tagger
    184 [ "$#" -lt 2 ] && print_help
    185 
    186 BASE="$1/.base"
    187 COMMAND="$2"
    188 
    189 case "$COMMAND" in
    190     init)  init_tagger "$@" ;;
    191     add)   add_file    "$@" ;;
    192     tag)   tag_file    "$@" ;;
    193     untag) untag_file  "$@" ;;
    194     ls)    list        "$@" ;;
    195     path)  path        "$@" ;;
    196     rm)    remove      "$@" ;;
    197     *) err "Unknown command $COMMAND" ;;
    198 esac