bashject: refactor to hub style, add help, add alias config
authorBenjamin Doumenc <big.clop@gmail.com>
Mon, 15 Jul 2013 13:40:11 +0000 (15:40 +0200)
committerBenjamin Doumenc <big.clop@gmail.com>
Mon, 15 Jul 2013 13:40:11 +0000 (15:40 +0200)
bash/bashject

index 842cc0a..866a772 100644 (file)
 # Projects config is stored on a centralized file
 # Each project contains a local bash configuration, sourced when setting it
 #  
-# Usage:
-#    - Add a project with 'addProject name path'
-#    - Enter a project with 'setProject name'
-#    - Customize his environment with 'editProject name' (or editing his ${PRJ_PATH}/${PRJ_FILE})
-#
-# Exported vars:
-#    - PRJ_NAME: name of the project
-#    - PRJ_PATH: path to the root of the project
-#  
-# Exported functions
-#    - addProject      name path     # Adds a project
-#    - setProject      name          # Enter a project
-#    - sourceProject   name          # Source the project file of the specified project (useful to handle common envs)
-#    - editProject     name          # Edit the project file of the specified project with ${EDITOR}
-#    - getProjectPath  name          # Echoes a project's path
-#    - getProjectNames               # Echoes all projects, separated by whitespaces
-#    - getProjectList                # Echoes all projects, separated by newlines (useful with dmenu, for example)
-#    - cdProject                     # cd to the current project root path
-#
-# Configuration (to override values, define them before sourcing this file)
-#    - PRJ_STORE                     # File in which we store all projects configuration (default: ${HOME}/work/.projects)
-#    - PRJ_FILE                      # Name of the project file, created at his root and sourced on setProject (default: '.prj_env')
-#    - PRJ_CHANGE_PROMPT             # 1 to change the prompt to '[ $PRJ_NAME ] PS1' > on setProject (default: 1)
-#
+
+BASHJECT_HELP_ADD="    - bashject add      name path     # Adds a project"
+BASHJECT_HELP_SET="    - bashject set      name          # Enter a project"
+BASHJECT_HELP_SOURCE="    - bashject source   name          # Source the project file of the specified project (useful to handle common envs)"
+BASHJECT_HELP_EDIT="    - bashject edit     name          # Edit the project file of the specified project with ${EDITOR}"
+BASHJECT_HELP_PATH="    - bashject path     name          # Echoes a project's path"
+BASHJECT_HELP_NAMES="    - bashject names                  # Echoes all projects, separated by whitespaces"
+BASHJECT_HELP_LIST="    - bashject list                   # Echoes all projects, separated by newlines (useful with dmenu, for example)"
+BASHJECT_HELP_CD="    - bashject cd                     # cd to the current project root path"
+BASHJECT_HELP_HELP="    - bashject help     [cmd]         # Display global or specific command help"
+
+read -d '' BASHJECT_HELP << EOF
+ Usage:
+    - Add a project with 'bashject add name path'
+    - Enter a project with 'bashject set name'
+    - Customize his environment with 'bashject edit name' (or editing his ${BASHJECT_PRJ_DIR}/${BASHJECT_PRJ_FILE})
+
+ Exported vars:
+    - BASHJECT_PRJ_NAME: name of the project
+    - BASHJECT_PRJ_PATH: path to the root of the project
+
+ Commands:
+${BASHJECT_HELP_ADD}
+${BASHJECT_HELP_SET}
+${BASHJECT_HELP_SOURCE}
+${BASHJECT_HELP_EDIT}
+${BASHJECT_HELP_PATH}
+${BASHJECT_HELP_NAMES}
+${BASHJECT_HELP_LIST}
+${BASHJECT_HELP_CD}
+${BASHJECT_HELP_HELP}
+
+ Configuration (to override values, define them before sourcing this file)
+    - BASHJECT_PRJ_STORE                     # File in which we store all projects configuration (default: ${HOME}/work/.projects)
+    - BASHJECT_PRJ_FILE                      # Name of the project file, created at his root and sourced on 'bashject set' (default: '.prj_env')
+    - BASHJECT_CHANGE_PROMPT                 # 1 to change the prompt to '[ $BASHJECT_PRJ_NAME ] PS1' > on 'bashject set' (default: 1)
+    - BASHJECT_ALIAS                         # Name of an alias for bashject to define (i.e: 'bj'), autocompletion will be handled (default: "")
+EOF
 #
+# End of help file
 
 OLD_PS1="$PS1"
+BASHJECT_COMMANDS="add set source edit  path names list cd help"
 
 # Configuration
 
-PRJ_STORE=${PRJ_STORE:-${HOME}/work/.projects} 
-PRJ_FILE=${PRJ_FILE:-".prj_env"}              
-PRJ_CHANGE_PROMPT=${PRJ_CHANGE_PROMPT:-1}    
+BASHJECT_PRJ_STORE=${BASHJECT_PRJ_STORE:-${HOME}/work/.projects} 
+BASHJECT_PRJ_FILE=${BASHJECT_PRJ_FILE:-".prj_env"}              
+BASHJECT_CHANGE_PROMPT=${BASHJECT_CHANGE_PROMPT:-1}    
+BASHJECT_ALIAS=${BASHJECT_ALIAS:-""}    
+
 
 # Real stuff
-addProject() {
+_bj_add_project() {
     if [ "$#" -eq "2" ]; then
         local name=$1
         local path=$(readlink -f $2)
-        echo "$name $path" >> ${PRJ_STORE}
-        if [ ! -f ${path}/${PRJ_FILE} ]; then
-            echo "Creating ${path}/${PRJ_FILE}"
-            echo "# Project ${name} " > ${path}/${PRJ_FILE}
+        echo "$name $path" >> ${BASHJECT_PRJ_STORE}
+        if [ ! -f ${path}/${BASHJECT_PRJ_FILE} ]; then
+            echo "Creating ${path}/${BASHJECT_PRJ_FILE}"
+            echo "# Project ${name} " > ${path}/${BASHJECT_PRJ_FILE}
         fi
     else
-        echo "Usage: addProject name path" >&2
+        echo "Usage: bashject add name path" >&2
     fi
 }
 
-getProjectNames() {
+_bj_get_project_names() {
     local NAMES=""
-    if [ -f ${PRJ_STORE} ]; then
+    if [ -f ${BASHJECT_PRJ_STORE} ]; then
         while read name path; do
             NAMES="$NAMES $name"
-        done < ${PRJ_STORE}
+        done < ${BASHJECT_PRJ_STORE}
         echo ${NAMES}
     fi
     return 0
 }
 
-getProjectList() {
+_bj_get_project_list() {
     local NAMES=""
-    if [ -f ${PRJ_STORE} ]; then
+    if [ -f ${BASHJECT_PRJ_STORE} ]; then
         while read name path; do
             echo $name
-        done < ${PRJ_STORE}
+        done < ${BASHJECT_PRJ_STORE}
     fi
     return 0
 }
 
-_failedPath() {
+_bj_failed_path() {
     echo "No project named '$1'." >&2
     echo "Similar projects: " >&2
-    for name in $(compgen -W "$(getProjectNames)" -- $1); do
+    for name in $(compgen -W "$(_bj_get_project_names)" -- $1); do
         echo "  - $name" >&2
     done
 }
 
-getProjectPath() {
-    if [ -f ${PRJ_STORE} ]; then
+_bj_get_project_path() {
+    if [ -f ${BASHJECT_PRJ_STORE} ]; then
         while read name path; do
             if [ "$1" = "$name" ]; then
                 echo $path
                 return 0
             fi
-        done < ${PRJ_STORE}
+        done < ${BASHJECT_PRJ_STORE}
     fi
     return 1
 }
 
-sourceProject() {
-    local path=$(getProjectPath $1)
+_bj_source_project() {
+    local path=$(_bj_get_project_path $1)
     if [ ! -z "$path" ]; then
-        source $path/${PRJ_FILE}
+        source $path/${BASHJECT_PRJ_FILE}
         return 0
     else
-        _failedPath $1
+        _bj_failed_path $1
     fi
     return 1
 }
 
-editProject() {
-    local path=$(getProjectPath $1)
+_bj_edit_project() {
+    local path=$(_bj_get_project_path $1)
     if [ ! -z "$path" ]; then
-        ${EDITOR} $path/${PRJ_FILE}
+        ${EDITOR} $path/${BASHJECT_PRJ_FILE}
         return 0
     else
-        _failedPath $1
+        _bj_failed_path $1
     fi
     return 1
 }
 
-setProject() {
+_bj_set_project() {
     # Find dir
-    PRJ_NAME=$1
-    PRJ_DIR=$(getProjectPath $PRJ_NAME)
-    if [ ! -z "$PRJ_DIR" ]; then
-        export PRJ_DIR
-        export PRJ_NAME
-        cd $PRJ_DIR
-        source $PRJ_DIR/${PRJ_FILE}
-        if [ "1" -eq "$PRJ_CHANGE_PROMPT" ]; then 
-            export PS1="[$PRJ_NAME] $OLD_PS1"
+    BASHJECT_PRJ_NAME=$1
+    BASHJECT_PRJ_DIR=$(_bj_get_project_path $BASHJECT_PRJ_NAME)
+    if [ ! -z "$BASHJECT_PRJ_DIR" ]; then
+        export BASHJECT_PRJ_DIR
+        export BASHJECT_PRJ_NAME
+        cd $BASHJECT_PRJ_DIR
+        source $BASHJECT_PRJ_DIR/${BASHJECT_PRJ_FILE}
+        if [ "1" -eq "$BASHJECT_CHANGE_PROMPT" ]; then 
+            export PS1="[$BASHJECT_PRJ_NAME] $OLD_PS1"
         fi
     else
-        _failedPath $PRJ_NAME
+        _bj_failed_path $BASHJECT_PRJ_NAME
+    fi
+}
+
+function _bj_cd_project() {
+       cd $BASHJECT_PRJ_DIR
+}
+
+function _bj_help() {
+    if [ -z $1 ]; then 
+        echo -e "${BASHJECT_HELP}" >&2
+    else
+        case "$1" in
+            a|add)       echo -e "${BASHJECT_HELP_ADD}" ;;
+            s|set)       echo -e "${BASHJECT_HELP_SET}" ;;
+            source)      echo -e "${BASHJECT_HELP_SOURCE}" ;;
+            e|edit)      echo -e "${BASHJECT_HELP_EDIT}" ;;
+            path)        echo -e "${BASHJECT_HELP_PATH}" ;;
+            names)       echo -e "${BASHJECT_HELP_NAMES}" ;;
+            list)        echo -e "${BASHJECT_HELP_LIST}" ;;
+            cd)          echo -e "${BASHJECT_HELP_CD}" ;;
+            help)        echo -e "${BASHJECT_HELP_HELP}" ;;
+            *)
+                echo "Unknown command: $1" >&2
+                return 1
+                ;;
+        esac
     fi
 }
 
+# Frontend
+function bashject {
+    fun=$1
+    shift
+    case "$fun" in
+        a|add)       _bj_add_project           "$@" ; return $? ;;
+        s|set)       _bj_set_project           "$@" ; return $? ;;
+        source)      _bj_source_project        "$@" ; return $? ;;
+        e|edit)      _bj_edit_project          "$@" ; return $? ;;
+        path)        _bj_get_project_path      "$@" ; return $? ;;
+        names)       _bj_get_project_names     "$@" ; return $? ;;
+        list)        _bj_get_project_list      "$@" ; return $? ;;
+        cd)          _bj_cd_project            "$@" ; return $? ;;
+        help)        _bj_help                  "$@" ; return $? ;;
+        "") 
+            echo "No command provided. Available:"
+            for cmd in ${BASHJECT_COMMANDS}; do
+                echo "  - $cmd "
+            done
+            return 1
+            ;;
+        *)
+            echo "Unknown command: $fun" >&2
+            return 1
+            ;;
+    esac
+} 
+
+
 # Define autocompletion functions 
-_project ()
+
+_bj_complete_project_name ()
+{
+        local cur
+        _get_comp_words_by_ref cur
+        COMPREPLY=()
+        COMPREPLY=( $(compgen -W "$(_bj_get_project_names)" -- ${cur}) ) 
+        return 0
+} 
+
+_bj_complete_command ()
 {
         local cur
         _get_comp_words_by_ref cur
         COMPREPLY=()
-        local NAMES=$(getProjectNames)
-        COMPREPLY=( $(compgen -W "$(getProjectNames)" -- ${cur}) ) 
+        COMPREPLY=($(compgen -W "${BASHJECT_COMMANDS}" -- "$cur"))
         return 0
 } 
 
-complete -F _project setProject
-complete -F _project sourceProject
-complete -F _project editProject
+function _bj_complete {
+    local cur
+    _get_comp_words_by_ref cur
+    COMPREPLY=()
+    # Complete command name 
+    if [ $COMP_CWORD -eq 1 ]; then
+        _bj_complete_command 1
+    else
+        case ${COMP_WORDS[1]} in
+            s|set|source|edit|path)      _bj_complete_project_name           1 ;;
+            help)                        _bj_complete_command                1 ;;
+            names|list|cd)                                                     ;;
+            a|add)                                                             ;;
+        esac
+    fi
+} 
 
-# HELPERS
-function cdProject() {
-       cd $PRJ_DIR
-}
+complete -F _bj_complete bashject 
+
+if [ ! -z "${BASHJECT_PRJ_ALIAS}" ]; then
+    alias ${BASHJECT_PRJ_ALIAS}='bashject'
+    complete -F _bj_complete ${BASHJECT_PRJ_ALIAS} 
+fi