forked from jm/shin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.sh
391 lines (313 loc) · 8.48 KB
/
functions.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
382
383
384
385
386
387
388
389
390
391
function shin() {
case "$1" in
install)
__shin_install "$2"
;;
uninstall)
__shin_uninstall "$2"
;;
update)
__shin_update "$2"
;;
list)
__shin_list "$2"
;;
bucket)
__shin_edit_bucket
;;
ps1)
__shin_set_ps1 "$2"
;;
init)
__shin_init
;;
esac
}
function .install() {
__shin_install "$1"
}
function .uninstall() {
__shin_uninstall "$1"
}
function .update() {
__shin_update "$1"
}
function .list() {
__shin_list "$1"
}
function .ps1() {
__shin_set_ps1 "$1"
}
function .prompt() {
__shin_set_ps1 "$1"
}
function .bucket() {
__shin_edit_bucket
}
function __shin_home() {
echo "$HOME/.shin"
}
function __shin_init()
{
echo "PS1=\"$PS1\"" > `__shin_home`/ps1_reset.sh
if [ -e "`__shin_home`/sets/all.sh" ]
then
source `__shin_home`/sets/all.sh
fi
}
function __shin_install() {
local install_target=$1
local return_to=`pwd`
mkdir -p `__shin_home`/packages
cd `__shin_home`/packages
if [[ "$install_target" =~ "gist.github.com" ]]
then
echo "Installing from Gist repo $install_target..."
local repo_name=`echo ${install_target##*/}`
__shin_install_from_repo "$install_target" "gist-${repo_name/%.*}"
elif [[ "$install_target" =~ ^[0-9]*$ ]]
then
local gist_repo="git://gist.github.com/$install_target.git"
echo "Installing from Gist repo $gist_repo..."
__shin_install_from_repo "$install_target" "gist-$install_target"
elif [[ "$install_target" =~ ^http[s]?://.* ]]
then
__shin_http_install "$install_target" "$2"
elif [[ "$install_target" =~ ^git://.* ]]
then
echo "Installing from repo $install_target..."
echo ""
local repo_name=`echo ${install_target##*/}`
__shin_install_from_repo "$install_target" "${repo_name/%.*}"
elif [[ "$install_target" =~ .*/[a-zA-Z0-9\.\-_]* ]]
then
local repo=$1
# lolhax
local user=`dirname $1`
local repo_name=`basename $1`
local github_url="git://github.com/$user/$repo_name.git"
echo "Installing from GitHub repo $install_target..."
__shin_install_from_repo "$github_url" "$repo_name"
else
echo "I don't know what you're trying to install."
fi
cd $return_to
}
function __shin_http_install() {
local install_target=$1
local install_name=$2
if [ "$install_name" = "" ]
then
local trimmed_install_name=`echo ${install_target##*/}`
install_name="${trimmed_install_name/%.*}"
fi
echo "Installing script as $install_name..."
echo ""
local bucket_path="`__shin_home`/packages/$install_name"
mkdir -p $bucket_path
local script_text=`curl $install_target`
if [ $? -eq 0 ]
then
echo "$script_text" > $bucket_path/shinit.sh
echo "Downloaded from $install_target" > $bucket_path/.shin_description
echo "$install_target" > $bucket_path/.shin_origin
__shin_capture_function_list $install_name
__shin_regenerate_manifests
echo "$install_name installed."
else
echo "There was a problem fetching $install_target."
fi
}
function __shin_install_from_repo() {
local clone_url=$1
local repo_name=$2
git clone $clone_url $repo_name --depth 1
if [ $? -eq 0 ]
then
__shin_check_package_init $repo_name
if [ $__shin_package_init_result -eq 1 ]
then
if [ -e `__shin_home`/packages/$repo_name/shinstall.sh ]
then
source `__shin_home`/packages/$repo_name/shinstall.sh
fi
__shin_capture_function_list $repo_name
__shin_regenerate_manifests
echo ""
echo "$repo_name installed."
fi
else
echo "There was a problem cloning $repo. Make sure the repo exists and you have permission to access it."
fi
}
function __shin_uninstall() {
local package_name=$1
if [ -e `__shin_home`/packages/$package_name ]
then
rm -rf `__shin_home`/packages/$package_name
__shin_regenerate_manifests
echo "Package $package_name uninstalled."
else
echo "Package $package_name not found."
fi
}
function __shin_update() {
local package_name=$1
if [ "$package_name" = "self" ]
then
__shin_update_self
else
__shin_update_package "$package_name"
fi
}
function __shin_update_self() {
local return_to=`pwd`
echo "Updating shin system..."
echo ""
cd `__shin_home`/system
git pull origin master
source functions.sh
echo ""
echo "Updated!"
cd $return_to
}
function __shin_update_package() {
local package_name=$1
if [ -e `__shin_home`/packages/$package_name ]
then
local return_to=`pwd`
cd `__shin_home`/packages/$package_name
if [ -e `__shin_home`/packages/$package_name/.git ]
then
__shin_update_repo "$package_name"
elif [ -e `__shin_home`/packages/$package_name/.shin_origin ]
then
__shin_update_http "$package_name"
else
echo "No data present to update with. Aborting!"
fi
cd $return_to
else
echo "Package $package_name not found."
fi
}
function __shin_update_http() {
local package_name=$1
local package_path="`__shin_home`/packages/$package_name"
local package_origin="`cat $package_path/.shin_origin`"
local script_text=`curl $package_origin`
if [ $? -eq 0 ]
then
echo "$script_text" > $package_path/shinit.sh
__shin_capture_function_list $package_name
echo "$package_name updated from $package_origin."
else
echo "There was a problem updating from $package_origin."
fi
}
function __shin_update_repo() {
local package_name=$1
git pull
if [ $? -eq 0 ]
then
__shin_capture_function_list $package_name
__shin_regenerate_manifests
echo "Package $package_name updated."
else
echo "There was a problem updating $repo. Make sure the repo still exists on GitHub and you have permission to access it."
fi
}
function __shin_list() {
if [ -e "`__shin_home`/manifest" ]
then
echo "Listing all packages"
echo ""
cat `__shin_home`/manifest | while read line ; do
local name=`echo "$line" | sed "s/\:.*$//"`
local rest=`echo ${line#*:}`
if [ $name = "bucket" ]
then
continue
fi
echo "[$name]"
echo "$rest"
echo ""
done
else
echo "No packages installed."
fi
}
# We use this to unset functions added by a specific package. Useful for managing sets of
# functions RVM-style.
function __shin_capture_function_list() {
mkdir -p `__shin_home`/function_maps
# Get function list, init package, get function list again
local existing_function_list=`compgen -A function`
package_path="`__shin_home`/packages/$1"
source `__shin_home`/packages/$1/shinit.sh
local new_function_list=`compgen -A function`
# Basically diffing the function lists from before and after we init the package
local new_functions=`comm -13 -i <(echo "$existing_function_list") <(echo "$new_function_list")`
echo "$new_functions" > `__shin_home`/function_maps/$1
}
# Regenerates our toplevel manifest file so we know which packages we have installed.
function __shin_regenerate_manifests() {
local package_directories=`find $(__shin_home)/packages -maxdepth 1 -type d | sort -u`
mkdir -p `__shin_home`/sets
rm `__shin_home`/sets/all.sh 2>/dev/null
rm `__shin_home`/manifest 2>/dev/null
for package in $package_directories
do
local package_name=`basename $package`
# If it's the base directory or "..", skip it.
if [ "$package_name" = "packages" ] || [ "$package_name" = "" ]
then
continue
fi
__shin_check_package_init $package_name
if [ $__shin_package_init_result -eq 0 ]
then
break
fi
if [ -e `__shin_home`/packages/$package_name/.shin_description ]
then
echo "$package_name:$(cat `__shin_home`/packages/$package_name/.shin_description)" >> `__shin_home`/manifest
else
echo "$package_name:(No description given.)" >> `__shin_home`/manifest
fi
echo "package_path=\"`__shin_home`/packages/$package_name\"" >> `__shin_home`/sets/all.sh
echo "source `__shin_home`/packages/$package_name/shinit.sh" >> `__shin_home`/sets/all.sh
done
}
function __shin_check_package_init() {
if [ ! -e `__shin_home`/packages/$1/shinit.sh ]
then
echo ""
echo "!!!"
echo "$1 does not have a shinit.sh file; it's cloned but isn't usable at all."
echo "Make sure this is a package designed for use with shin."
echo "!!!"
__shin_package_init_result=0;
else
__shin_package_init_result=1;
fi
}
function __shin_edit_bucket() {
mkdir -p `__shin_home`/packages/bucket 2>/dev/null
touch `__shin_home`/packages/bucket/shinit.sh
${FCEDIT:-${VISUAL:-${EDITOR:-vi}}} `__shin_home`/packages/bucket/shinit.sh
source `__shin_home`/packages/bucket/shinit.sh
}
function __shin_set_ps1() {
local package_name=$1
if [ "$package_name" = "reset" ]
then
source `__shin_home`/ps1_reset.sh
echo "Prompt reset."
elif [ -e `__shin_home`/packages/$package_name/ps1.sh ]
then
source `__shin_home`/packages/$package_name/ps1.sh
else
echo "Package $package_name doesn't have a prompt script."
fi
}