forked from mitechie/workit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathworkit.sh
executable file
·381 lines (332 loc) · 10.3 KB
/
workit.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# Functions to load working code projects
#
# heavily influenced/copied from Doug Hellmanns, virtualenvwrapper
# http://bitbucket.org/dhellmann/virtualenvwrapper/overview/
#
# set -x
# In order to support for multiple users with their own scripts in the same project
# we are going to store all workit processing scripts in the following
# directory structure:
# [project name]/.workit/[username]/[hostname]
#
# Where [project name] is your project
# [username] is the system username you logged in with
# [hostname] is the hostname of the system
#
# This allows a team of developers to work on the same project and have
# differnt activation scripts to suit their own needs
# Shell check; mitechie LOVES zsh, so we need to accommodate. :)
CUR_SHELL="$( ps | grep $$ | awk '{ print $4 }' )"
# TODO
# virtualenv sets the VIRTUAL_ENV system variable, need to replicate a bit
# source the helper script functions
# assuming its in the same dir as this file
#BASEDIR=`dirname $0`
#source $BASEDIR/process_functions.sh
# You can override this setting in your .zshrc/.bashrc
if [[ "$WORKIT_DIRS" == "" ]]
then
WORKIT_DIRS=( "$HOME/src" "$HOME/configs" "$HOME/gitbox" )
export WORKIT_DIRS
fi
### Functions
# Verify that the WORKON_HOME directory exists
function verify_workit_home () {
#for zpath in ${WORKIT_DIRS[@]}; do
# if [ ! -d "$zpath" ]
# then
# echo "WARNING: projects directory '$zpath' does not exist." >&2
# fi
#done
return 0
}
# Verify that the requested project exists
function verify_workit_project () {
env_name="$1"
proj_count=0
proj_list=()
# Sanity chcks
if [[ "${USER}" == "" ]]; then
echo -e "Can't determine user name based on USER environment variable."
return 1
fi
WORKIT_HOST="$(hostname -s)"
if [[ "${WORKIT_HOST}" == "" ]]; then
echo -e "Can't determine hostname based on 'hostname -s' command."
return 1
fi
for zpath in ${WORKIT_DIRS[@]}; do
target_path="$zpath/$env_name"
if [[ -d $target_path ]]; then
#proj_list+=("$target_path")
# BASH version 3 doesn't like the += operator
proj_list=($proj_list "$target_path")
((proj_count+=1))
fi
done
if [[ $proj_count -eq 1 ]]; then
RET_VAL="${proj_list[0]}"
return 0
else
select item in "${proj_list[@]}"
do
case "$item" in
*)
RET_VAL="$item"
break
;;
esac
done
return 0
fi
}
# Verify that the active project exists
function verify_active_project () {
if [ ! -n "${PROJECT_DIR}" ] || [ ! -d "${PROJECT_DIR}" ]
then
echo "ERROR: no project active, or active project is missing" >&2
return 1
fi
return 0
}
# source the pre/post hooks
# NOTE: This function expects the FULL path to the script
function workit_source_hook () {
scriptname="$1"
if [ -f "$scriptname" ]
then
source "$scriptname"
fi
}
# run the pre/post hooks
function workit_run_hook () {
scriptname="$1"
shift
if [ -x "$scriptname" ]
then
"$scriptname" "$@"
fi
}
# Create a new project, either based on a WORKIT_DIRS
# or directly specified.
#
# Usage: mkworkit [ directory_in_WORKIT_DIRS | path_to_directory ]
function mkworkit () {
if [[ "$1" == "" ]]; then
echo -e "\nUsage: mkworkit [ directory_in_WORKIT_DIRS | path_to_directory ]\n"
return 1
fi
# check if we're given a direct path
if [[ "$1" == */* || "$1" == "." || "$1" == ".." ]]; then
DIRECT=1
canonpath "$1"
PROJ_PATH="$RET_VAL"
if [[ -d "$PROJ_PATH" ]]; then
echo "workit: mkworkit setting up on direct path $PROJ_PATH"
else
echo "workit: Can't find $PROJ_PATH"
return 1
fi
else
DIRECT=0
verify_workit_home || return 1
workit_home_count=${#WORKIT_DIRS[*]}
if [ $workit_home_count -gt 1 ]
then
OLD_IFS="$IFS"
# Remove the space from the IFS so we can show a "None / Cancel" option
IFS=$'\t\n'
DIR_LIST=('None / Cancel')
DIR_LIST+=("${WORKIT_DIRS[@]}")
select PROJ_PATH in ${DIR_LIST[@]}
do
case "$PROJ_PATH" in
"None / Cancel")
IFS=$OLD_IFS
return 0
;;
*)
break
;;
esac
done
IFS="$OLD_IFS"
else
PROJ_PATH=$WORKIT_DIRS
fi
PROJ_NAME="$1"
PROJ_PATH="$PROJ_PATH/$PROJ_NAME"
echo "workit: mkworkit setting up $PROJ_NAME from WORKIT_DIRS path [${PROJ_PATH%/*}]"
fi
build_workit_script_path "$PROJ_PATH"
SCRIPT_PATH=$RET_VAL
# test for existing proj dir, if not create it, otherwise add
# the script files to the existing dir
if [[ ! -d $SCRIPT_PATH ]]; then
mkdir -p "$SCRIPT_PATH"
echo "workit: New scripts added to $SCRIPT_PATH in $PROJ_PATH"
else
echo "workit: Scripts already exist at $SCRIPT_PATH in $PROJ_PATH"
fi
FILES="activate deactivate"
for FILE in $FILES; do
if [[ ! -f "${SCRIPT_PATH}/$FILE" ]]; then
touch "${SCRIPT_PATH}/$FILE"
fi
if [[ ! -x "${SCRIPT_PATH}/$FILE" ]]; then
chmod +x "${SCRIPT_PATH}/$FILE"
fi
done
# Now actually switch/workit into our new project
if [[ $DIRECT == 0 ]]; then
workit "$PROJ_NAME"
else
workit "$PROJ_PATH"
fi
}
# List the available environments.
function show_workit_projects () {
verify_workit_home || return 1
# NOTE: DO NOT use ls here because colorized versions spew control characters
# into the output list.
# Handle case where we just want to see the contents of 1 specified
# directory.
if [[ "$1" != "" ]]; then
tpath=$1
echo -e "Workit directory ${tpath}:"
echo -e "----------------------------------------"
if [[ -d $tpath ]]; then
ls --color=auto -C $tpath
else
echo -e "Directory ${tpath} doesn't exist"
fi
echo -e "\n"
else
for tpath in ${WORKIT_DIRS[@]}; do
echo -e "Workit directory ${tpath}:"
echo -e "----------------------------------------"
if [[ -d $tpath ]]; then
ls --color=auto -C $tpath
else
echo -e "Directory ${tpath} doesn't exist"
fi
echo -e "\n"
done
fi
}
# list the available workit home directories for adding a new project to
function show_workit_home_options () {
verify_workit_home || return 1
for ((i=1;i<${#WORKIT_DIRS[*]};i++)); do
proj=${WORKIT_DIRS[$i]}
echo "$i - $proj"
done
}
# List or change workit projects
#
# Usage: workit [environment_name]
#
function workit () {
PROJ_NAME="$1"
# check if a path was provided; if so then just try to "workit" directly on that path
if [[ "$PROJ_NAME" == */* || "$PROJ_NAME" == "." || "$PROJ_NAME" == ".." ]]; then
# Allow the current working directory to be specified.
canonpath "$PROJ_NAME"
PROJ_NAME="$RET_VAL"
if [[ -d "$PROJ_NAME" ]]; then
echo "workit: activating direct path $PROJ_NAME"
canonpath "$PROJ_NAME"
PROJ_PATH="$RET_VAL"
else
echo "workit: Can't find $PROJ_NAME"
return 1
fi
else
if [[ "$PROJ_NAME" == "" ]]; then
workit_home_count=${#WORKIT_DIRS[*]}
if [ $workit_home_count -gt 1 ]
then
OLD_IFS="$IFS"
# Remove the space from the IFS so we can show a "None / Cancel" option
IFS=$'\t\n'
DIR_LIST=('None / Cancel')
DIR_LIST+=('All')
DIR_LIST+=("${WORKIT_DIRS[@]}")
echo "Select a directory to see available projects"
select PROJ_PATH in ${DIR_LIST[@]}
do
case "$PROJ_PATH" in
"None / Cancel")
IFS=$OLD_IFS
return 1
;;
"All")
unset PROJ_PATH
break
;;
*)
break
;;
esac
done
IFS="$OLD_IFS"
else
PROJ_PATH=$WORKIT_DIRS
fi
show_workit_projects "$PROJ_PATH"
return 1
fi
if verify_workit_project "$PROJ_NAME"
then
PROJ_PATH=$RET_VAL
else
return 1
fi
verify_workit_home || return 1
echo "workit: activating $PROJ_NAME from WORKIT_DIRS path [${PROJ_PATH%/*}]"
fi
# Deactivate any current environment "destructively"
# before switching so we use our override function,
# if it exists.
type workitdone >/dev/null 2>&1
if [ $? -eq 0 ]
then
workitdone
fi
cd $PROJ_PATH
# Set prompt
OLD_PS1="$PS1"
PS1="[workit]$PS1"
build_workit_script_path "$PROJ_PATH"
SCRIPT_PATH=$RET_VAL
eval 'function workitdone () {
workit_source_hook "'$SCRIPT_PATH'/deactivate"
unset workitdone
# Remote the prompt add-on
PS1="${PS1/\[workit\]/}"
}'
workit_source_hook "$SCRIPT_PATH/activate"
return 0
}
function build_workit_script_path () {
base_path="$1"
WORKIT_HOST=$(hostname -s)
if [[ "${USER}" == "" ]]; then
echo -e "Can't determine user name based on USER environment variable."
RET_VAL=""
else
RET_VAL="$base_path/.workit/${USER}/${WORKIT_HOST}"
fi
}
# from: http://snipplr.com/view/18026/canonical-absolute-path/
function canonpath ()
{
RET_VAL=$(cd $(dirname $1); pwd -P)/$(basename $1)
}
#
# Set up tab completion. (Adapted from Arthur Koziel's version at
# http://arthurkoziel.com/2008/10/11/virtualenvwrapper-bash-completion/)
#
if [[ $CUR_SHELL == "zsh" ]]; then
compctl -g "`show_workit_projects`" workit
fi