4 # This project manager allows you to have a quick way to switch between several different work environments
5 # Projects config is stored on a centralized file
6 # Each project contains a local bash configuration, sourced when setting it
9 BASHJECT_HELP_ADD="bashject a|add name path # Adds a project"
10 BASHJECT_HELP_SET="bashject s|set name # Enter a project"
11 BASHJECT_HELP_SOURCE="bashject source name # Source the project file of the specified project (useful to handle common envs)"
12 BASHJECT_HELP_EDIT="bashject edit name # Edit the project file of the specified project with ${EDITOR}"
13 BASHJECT_HELP_REMOVE="bashject rm|remove name # Remove the project (no filesystem modifications)"
14 BASHJECT_HELP_RENAME="bashject rename old new # Rename the project (no filesystem modifications)"
15 BASHJECT_HELP_PATH="bashject path name # Echoes a project's path"
16 BASHJECT_HELP_NAMES="bashject names # Echoes all projects, separated by whitespaces"
17 BASHJECT_HELP_LIST="bashject list # Echoes all projects, separated by newlines (useful with dmenu, for example)"
18 BASHJECT_HELP_CD="bashject cd # cd to the current project root path"
19 BASHJECT_HELP_HELP="bashject help [cmd] # Display global or specific command help"
21 # Configuration defaults
23 BASHJECT_PRJ_STORE_DEFAULT=${HOME}/work/.projects
24 BASHJECT_PRJ_FILE_DEFAULT=".prj_env"
25 BASHJECT_CHANGE_PROMPT_DEFAULT=-1
26 BASHJECT_ALIAS_DEFAULT=""
27 BASHJECT_TMP_DEFAULT="/tmp/bashject.tmp"
29 # Configuration values
31 BASHJECT_PRJ_STORE=${BASHJECT_PRJ_STORE:-${BASHJECT_PRJ_STORE_DEFAULT}}
32 BASHJECT_PRJ_FILE=${BASHJECT_PRJ_FILE:-${BASHJECT_PRJ_FILE_DEFAULT}}
33 BASHJECT_CHANGE_PROMPT=${BASHJECT_CHANGE_PROMPT:-${BASHJECT_CHANGE_PROMPT_DEFAULT}}
34 BASHJECT_ALIAS=${BASHJECT_ALIAS:-${BASHJECT_ALIAS_DEFAULT}}
35 BASHJECT_TMP=${BASHJECT_TMP:-${BASHJECT_TMP_DEFAULT}}
37 read -d '' BASHJECT_HELP << EOF
39 - Add a project with 'bashject add name path'
40 - Enter a project with 'bashject set name'
41 - Customize his environment with 'bashject edit name' (or editing his ${BASHJECT_PRJ_DIR}/${BASHJECT_PRJ_FILE})
44 - BASHJECT_PRJ_NAME: name of the project
45 - BASHJECT_PRJ_PATH: path to the root of the project
48 - ${BASHJECT_HELP_ADD}
49 - ${BASHJECT_HELP_SET}
50 - ${BASHJECT_HELP_SOURCE}
51 - ${BASHJECT_HELP_EDIT}
52 - ${BASHJECT_HELP_REMOVE}
53 - ${BASHJECT_HELP_RENAME}
54 - ${BASHJECT_HELP_PATH}
55 - ${BASHJECT_HELP_NAMES}
56 - ${BASHJECT_HELP_LIST}
58 - ${BASHJECT_HELP_HELP}
60 Configuration (to override values, define them before sourcing this file)
61 - BASHJECT_PRJ_STORE # File in which we store all projects configuration (default: '${BASHJECT_PRJ_STORE_DEFAULT}', current: '${BASHJECT_PRJ_STORE}')
62 - BASHJECT_PRJ_FILE # Name of the project file, created at his root and sourced on 'bashject set' (default: '${BASHJECT_PRJ_FILE_DEFAULT}', current: '${BASHJECT_PRJ_FILE}')
63 - BASHJECT_CHANGE_PROMPT # 1 to change the prompt to '[ BASHJECT_PRJ_NAME ] PS1' > on 'bashject set' (default: '${BASHJECT_CHANGE_PROMPT_DEFAULT}', current: '${BASHJECT_CHANGE_PROMPT}')
64 - BASHJECT_ALIAS # Name of an alias for bashject to define (i.e: 'bj'), autocompletion will be handled (default: '${BASHJECT_ALIAS_DEFAULT}', current: '${BASHJECT_ALIAS}')
65 - BASHJECT_TMP # Temp file used for rename and remove operations (default: '${BASHJECT_TMP_DEFAULT}', current: '${BASHJECT_TMP}')
71 BASHJECT_COMMANDS="help add set source remove rename edit path names list cd"
77 echo -e "${BASHJECT_HELP}" >&2
80 a|add) echo -e "${BASHJECT_HELP_ADD}" ;;
81 s|set) echo -e "${BASHJECT_HELP_SET}" ;;
82 source) echo -e "${BASHJECT_HELP_SOURCE}" ;;
83 e|edit) echo -e "${BASHJECT_HELP_EDIT}" ;;
84 rm|remove) echo -e "${BASHJECT_HELP_REMOVE}" ;;
85 rename) echo -e "${BASHJECT_HELP_RENAME}" ;;
86 path) echo -e "${BASHJECT_HELP_PATH}" ;;
87 names) echo -e "${BASHJECT_HELP_NAMES}" ;;
88 list) echo -e "${BASHJECT_HELP_LIST}" ;;
89 cd) echo -e "${BASHJECT_HELP_CD}" ;;
90 help) echo -e "${BASHJECT_HELP_HELP}" ;;
92 echo "Unknown command: $1" >&2
100 if [ "$#" -eq "2" ]; then
102 local path=$(readlink -f $2)
103 echo "$name $path" >> ${BASHJECT_PRJ_STORE}
104 if [ ! -f ${path}/${BASHJECT_PRJ_FILE} ]; then
105 echo "Creating ${path}/${BASHJECT_PRJ_FILE}"
106 echo "# Project ${name} " > ${path}/${BASHJECT_PRJ_FILE}
114 echo "No project named '$1'." >&2
115 echo "Similar projects: " >&2
116 for name in $(compgen -W "$(_bj_get_project_names)" -- $1); do
121 _bj_get_project_path() {
122 if [ -f ${BASHJECT_PRJ_STORE} ]; then
123 while read name path; do
124 if [ "$1" = "$name" ]; then
128 done < ${BASHJECT_PRJ_STORE}
133 _bj_source_project() {
134 local path=$(_bj_get_project_path $1)
135 if [ ! -z "$path" ]; then
136 source $path/${BASHJECT_PRJ_FILE}
145 local path=$(_bj_get_project_path $1)
146 if [ ! -z "$path" ]; then
147 ${EDITOR} $path/${BASHJECT_PRJ_FILE}
158 BASHJECT_PRJ_DIR=$(_bj_get_project_path $BASHJECT_PRJ_NAME)
159 if [ ! -z "$BASHJECT_PRJ_DIR" ]; then
160 export BASHJECT_PRJ_DIR
161 export BASHJECT_PRJ_NAME
163 source $BASHJECT_PRJ_DIR/${BASHJECT_PRJ_FILE}
164 if [ "1" -eq "$BASHJECT_CHANGE_PROMPT" ]; then
165 export PS1="[$BASHJECT_PRJ_NAME] $OLD_PS1"
168 _bj_failed_path $BASHJECT_PRJ_NAME
172 _bj_remove_project() {
173 if [ -f ${BASHJECT_PRJ_STORE} ]; then
174 while read name path; do
175 if [ ! "$1" = "$name" ]; then
176 echo "$name $path" >> ${BASHJECT_TMP}
178 done < ${BASHJECT_PRJ_STORE}
179 mv ${BASHJECT_TMP} ${BASHJECT_PRJ_STORE}
184 _bj_rename_project() {
185 if [ -f ${BASHJECT_PRJ_STORE} ]; then
186 while read name path; do
187 if [ "$1" = "$name" ]; then
188 echo "$2 $path" >> ${BASHJECT_TMP}
190 echo "$name $path" >> ${BASHJECT_TMP}
192 done < ${BASHJECT_PRJ_STORE}
193 mv ${BASHJECT_TMP} ${BASHJECT_PRJ_STORE}
198 _bj_get_project_names() {
200 if [ -f ${BASHJECT_PRJ_STORE} ]; then
201 while read name path; do
203 done < ${BASHJECT_PRJ_STORE}
209 _bj_get_project_list() {
211 if [ -f ${BASHJECT_PRJ_STORE} ]; then
212 while read name path; do
214 done < ${BASHJECT_PRJ_STORE}
219 function _bj_cd_project() {
228 a|add) _bj_add_project "$@" ; return $? ;;
229 s|set) _bj_set_project "$@" ; return $? ;;
230 source) _bj_source_project "$@" ; return $? ;;
231 e|edit) _bj_edit_project "$@" ; return $? ;;
232 rm|remove) _bj_remove_project "$@" ; return $? ;;
233 rename) _bj_rename_project "$@" ; return $? ;;
234 path) _bj_get_project_path "$@" ; return $? ;;
235 names) _bj_get_project_names "$@" ; return $? ;;
236 list) _bj_get_project_list "$@" ; return $? ;;
237 cd) _bj_cd_project "$@" ; return $? ;;
238 help) _bj_help "$@" ; return $? ;;
240 echo "No command provided. Available:"
241 for cmd in ${BASHJECT_COMMANDS}; do
247 echo "Unknown command: $fun" >&2
254 # Define autocompletion functions
256 _bj_complete_project_name()
259 _get_comp_words_by_ref cur
261 COMPREPLY=( $(compgen -W "$(_bj_get_project_names)" -- ${cur}) )
265 _bj_complete_command()
268 _get_comp_words_by_ref cur
270 COMPREPLY=($(compgen -W "${BASHJECT_COMMANDS}" -- "$cur"))
274 function _bj_complete() {
276 _get_comp_words_by_ref cur
278 # Complete command name
279 if [ $COMP_CWORD -eq 1 ]; then
280 _bj_complete_command 1
282 if [ $COMP_CWORD -eq 2 ]; then
283 case ${COMP_WORDS[1]} in
284 s|set|source|edit|path|rm|remove|rename) _bj_complete_project_name 1 ;;
285 help) _bj_complete_command 1 ;;
293 complete -F _bj_complete bashject
295 if [ ! -z "${BASHJECT_ALIAS}" ]; then
296 alias ${BASHJECT_ALIAS}='bashject'
297 complete -F _bj_complete ${BASHJECT_ALIAS}