fix ./scripts/env delete
[openwrt/svn-archive/archive.git] / scripts / env
1 #!/usr/bin/env bash
2 BASEDIR="$PWD"
3 ENVDIR="$PWD/env"
4
5 usage() {
6 cat <<EOF
7 Usage: $0 [options] <command> [arguments]
8 Commands:
9 help This help text
10 list List environments
11 clear Delete all environment and revert to flat config/files
12 new <name> Create a new environment
13 switch <name> Switch to a different environment
14 delete <name> Delete an environment
15 rename <newname> Rename the current environment
16 diff Show differences between current state and environment
17 save Save your changes to the environment
18 revert Revert your changes since last save
19
20 Options:
21
22 EOF
23 exit ${1:-1}
24 }
25
26 error() {
27 echo "$0: $*"
28 exit 1
29 }
30
31 ask_bool() {
32 local DEFAULT="$1"; shift
33 local def defstr val
34 case "$DEFAULT" in
35 1) def=0; defstr="Y/n";;
36 0) def=1; defstr="y/N";;
37 *) def=; defstr="y/n";;
38 esac
39 while [ -z "$val" ]; do
40 local VAL
41
42 echo -n "$* ($defstr): "
43 read VAL
44 case "$VAL" in
45 y*|Y*) val=0;;
46 n*|N*) val=1;;
47 *) val="$def";;
48 esac
49 done
50 return "$val"
51 }
52
53 env_init() {
54 local CREATE="$1"
55 if [ -z "$CREATE" ]; then
56 [ -d "$ENVDIR" ] || exit 0
57 fi
58 [ -x "$(which git 2>/dev/null)" ] || error "Git is not installed"
59 mkdir -p "$ENVDIR" || error "Failed to create the environment directory"
60 cd "$ENVDIR" || error "Failed to switch to the environment directory"
61 [ -d .git ] || {
62 git init &&
63 touch .config &&
64 mkdir files &&
65 git add . &&
66 git commit -q -m "Initial import"
67 } || {
68 rm -rf .git
69 error "Failed to initialize the environment directory"
70 }
71 }
72
73 env_sync_data() {
74 [ \! -L "$BASEDIR/.config" -a -f "$BASEDIR/.config" ] && mv "$BASEDIR/.config" "$ENVDIR"
75 git add .
76 git add -u
77 }
78
79 env_sync() {
80 local STR="$1"
81 env_sync_data
82 git commit -m "${STR:-Update} at $(date)"
83 }
84
85 env_link_config() {
86 rm -f "$BASEDIR/.config"
87 ln -s env/.config "$BASEDIR/.config"
88 mkdir -p "$ENVDIR/files"
89 [ -L "$BASEDIR/files" ] || ln -s env/files "$BASEDIR/files"
90 }
91
92 env_do_reset() {
93 git reset --hard HEAD
94 git clean -d -f
95 }
96
97 env_list() {
98 env_init
99 git branch | grep -vE '^. master$'
100 }
101
102 env_diff() {
103 env_init
104 env_sync_data
105 git diff --cached
106 }
107
108 env_save() {
109 env_init
110 env_sync
111 env_link_config
112 }
113
114 env_revert() {
115 env_init
116 env_do_reset
117 env_link_config
118 }
119
120 env_ask_sync() {
121 LINES="$(env_diff | wc -l)" # implies env_init
122 [ "$LINES" -gt 0 ] && {
123 if ask_bool 1 "Do you want to save your changes"; then
124 env_sync
125 else
126 env_sync_data
127 env_do_reset
128 fi
129 }
130 }
131
132 env_clear() {
133 env_init
134 [ -L "$BASEDIR/.config" ] && rm -f "$BASEDIR/.config"
135 [ -L "$BASEDIR/files" ] && rm -f "$BASEDIR/files"
136 [ -f "$ENVDIR/.config" ] || ( cd "$ENVDIR/files" && find | grep -vE '^\.$' > /dev/null )
137 env_sync_data
138 if ask_bool 1 "Do you want to keep your current config and files"; then
139 mkdir -p "$BASEDIR/files"
140 cp -a "$ENVDIR/files/*" "$BASEDIR/files" 2>/dev/null >/dev/null
141 cp "$ENVDIR/.config" "$BASEDIR/"
142 else
143 rm -rf "$BASEDIR/files" "$BASEDIR/.config"
144 fi
145 cd "$BASEDIR"
146 rm -rf "$ENVDIR"
147 }
148
149 env_delete() {
150 local name="${1##*/}"
151 env_init
152 [ -z "$name" ] && usage
153 [ -f "$ENVDIR/.git/refs/heads/$name" ] || error "environment '$name' not found"
154 branch="$(git branch | grep '^\* ' | awk '{print $2}')"
155 [ "$name" = "$branch" ] && error "cannot delete the currently selected environment"
156 git branch -D "$name"
157 }
158
159 env_switch() {
160 local name="${1##*/}"
161 [ -z "$name" ] && usage
162 [ -f "$ENVDIR/.git/refs/heads/$name" ] || error "environment '$name' not found"
163
164 env_init
165 env_ask_sync
166 git checkout "$name"
167 env_link_config
168 }
169
170 env_rename() {
171 local NAME="${1##*/}"
172 env_init
173 git branch -m "$NAME"
174 }
175
176 env_new() {
177 local NAME="$1"
178 local branch
179 local from="master"
180
181 [ -z "$NAME" ] && usage
182 env_init 1
183
184 branch="$(git branch | grep '^\* ' | awk '{print $2}')"
185 if [ -n "$branch" -a "$branch" != "master" ]; then
186 env_ask_sync
187 if ask_bool 0 "Do you want to clone the current environment?"; then
188 from="$branch"
189 fi
190 rm -f "$BASEDIR/.config" "$BASEDIR/files"
191 fi
192 git checkout -b "$1" "$from"
193 if [ -f "$BASEDIR/.config" -o -d "$BASEDIR/files" ]; then
194 if ask_bool 1 "Do you want to keep your current config and files?"; then
195 [ -d "$BASEDIR/files" -a \! -L "$BASEDIR/files" ] && {
196 mv "$BASEDIR/files/"* "$ENVDIR/" 2>/dev/null
197 rmdir "$BASEDIR/files"
198 }
199 env_sync
200 else
201 rm -rf "$BASEDIR/.config" "$BASEDIR/files"
202 fi
203 fi
204 env_link_config
205 }
206
207 COMMAND="$1"; shift
208 case "$COMMAND" in
209 help) usage 0;;
210 new) env_new "$@";;
211 list) env_list "$@";;
212 clear) env_clear "$@";;
213 switch) env_switch "$@";;
214 delete) env_delete "$@";;
215 rename) env_rename "$@";;
216 diff) env_diff "$@";;
217 save) env_save "$@";;
218 revert) env_revert "$@";;
219 *) usage;;
220 esac