scripts/ipkg-make-index.sh: use bash instead of /bin/sh to fix use of [[ ]]
[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 --color | grep -vE '^. master$'
100 }
101
102 env_diff() {
103 env_init
104 env_sync_data
105 git diff --cached --color
106 env_link_config
107 }
108
109 env_save() {
110 env_init
111 env_sync
112 env_link_config
113 }
114
115 env_revert() {
116 env_init
117 env_do_reset
118 env_link_config
119 }
120
121 env_ask_sync() {
122 env_sync_data
123 LINES="$(env_diff | wc -l)" # implies env_init
124 [ "$LINES" -gt 0 ] && {
125 if ask_bool 1 "Do you want to save your changes"; then
126 env_sync
127 else
128 env_do_reset
129 fi
130 }
131 }
132
133 env_clear() {
134 env_init
135 [ -L "$BASEDIR/.config" ] && rm -f "$BASEDIR/.config"
136 [ -L "$BASEDIR/files" ] && rm -f "$BASEDIR/files"
137 [ -f "$ENVDIR/.config" ] || ( cd "$ENVDIR/files" && find | grep -vE '^\.$' > /dev/null )
138 env_sync_data
139 if ask_bool 1 "Do you want to keep your current config and files"; then
140 mkdir -p "$BASEDIR/files"
141 shopt -s dotglob
142 cp -a "$ENVDIR/files/"* "$BASEDIR/files" 2>/dev/null >/dev/null
143 shopt -u dotglob
144 cp "$ENVDIR/.config" "$BASEDIR/"
145 else
146 rm -rf "$BASEDIR/files" "$BASEDIR/.config"
147 fi
148 cd "$BASEDIR"
149 rm -rf "$ENVDIR"
150 }
151
152 env_delete() {
153 local name="${1##*/}"
154 env_init
155 [ -z "$name" ] && usage
156 branch="$(git branch | grep '^\* ' | awk '{print $2}')"
157 [ "$name" = "$branch" ] && error "cannot delete the currently selected environment"
158 git branch -D "$name"
159 }
160
161 env_switch() {
162 local name="${1##*/}"
163 [ -z "$name" ] && usage
164
165 env_init
166 env_ask_sync
167 git checkout "$name" || error "environment '$name' not found"
168 env_link_config
169 }
170
171 env_rename() {
172 local NAME="${1##*/}"
173 env_init
174 git branch -m "$NAME"
175 }
176
177 env_new() {
178 local NAME="$1"
179 local branch
180 local from="master"
181
182 [ -z "$NAME" ] && usage
183 env_init 1
184
185 branch="$(git branch | grep '^\* ' | awk '{print $2}')"
186 if [ -n "$branch" -a "$branch" != "master" ]; then
187 env_ask_sync
188 if ask_bool 0 "Do you want to clone the current environment?"; then
189 from="$branch"
190 fi
191 rm -f "$BASEDIR/.config" "$BASEDIR/files"
192 fi
193 git checkout -b "$1" "$from"
194 if [ -f "$BASEDIR/.config" -o -d "$BASEDIR/files" ]; then
195 if ask_bool 1 "Do you want to start your configuration repository with the current configuration?"; then
196 [ -d "$BASEDIR/files" -a \! -L "$BASEDIR/files" ] && {
197 mkdir -p "$ENVDIR/files"
198 shopt -s dotglob
199 mv "$BASEDIR/files/"* "$ENVDIR/files/" 2>/dev/null
200 shopt -u dotglob
201 rmdir "$BASEDIR/files"
202 }
203 env_sync
204 else
205 rm -rf "$BASEDIR/.config" "$BASEDIR/files"
206 fi
207 fi
208 env_link_config
209 }
210
211 COMMAND="$1"; shift
212 case "$COMMAND" in
213 help) usage 0;;
214 new) env_new "$@";;
215 list) env_list "$@";;
216 clear) env_clear "$@";;
217 switch) env_switch "$@";;
218 delete) env_delete "$@";;
219 rename) env_rename "$@";;
220 diff) env_diff "$@";;
221 save) env_save "$@";;
222 revert) env_revert "$@";;
223 *) usage;;
224 esac